diff --git a/.dotfiles b/.dotfiles index 91e7f571..d2d7580b 160000 --- a/.dotfiles +++ b/.dotfiles @@ -1 +1 @@ -Subproject commit 91e7f5710d6c8690ebc14023b2e4bf92f2541d31 +Subproject commit d2d7580b223e0b9a0c686c8cd9306cf68621685c diff --git a/.github/workflows/all-tests.yml b/.github/workflows/all-tests.yml new file mode 100644 index 00000000..933cd5ef --- /dev/null +++ b/.github/workflows/all-tests.yml @@ -0,0 +1,33 @@ +name: Run `TwitterAPIKit` Tests + +on: + pull_request: + paths: + - '*.swift' + +jobs: + linux-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: swift-actions/setup-swift@v2 + with: + swift-version: 5 + + - name: Run Unit Tests + uses: GetAutomaApp/opensource-actions/swifttesting@main + with: + compose: "false" + working-directory: "." + + macos-tests: + runs-on: [macOS, self-hosted] + steps: + - uses: actions/checkout@v4 + + - name: Run Unit Tests + uses: GetAutomaApp/opensource-actions/swifttesting@main + with: + compose: "false" + working-directory: "." \ No newline at end of file diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml deleted file mode 100644 index 20f1a3c1..00000000 --- a/.github/workflows/swift.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Swift - -on: - push: - branches: [main] - pull_request: - branches: [main] - -jobs: - build: - name: Lint & Build swift on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-12] - steps: - - uses: actions/checkout@v4 - - uses: actions/cache@v4 - id: "cache-spm" - with: - path: BuildTools/.build - key: ${{ runner.os }}-spm-${{ hashFiles('**/BuildTools/Package.resolved') }} - - uses: fwal/setup-swift@v1 - with: - swift-version: "5.7" - - name: Install Sourcery - run: brew update && brew install sourcery - - name: Check Flat API - run: ./flat-api.sh -c - - name: Build tools - if: steps.cache-spm.outputs.cache-hit != 'true' - run: ./build_tools.sh - - name: Lint - run: ./lint.sh - - name: Build - run: swift build - - test: - runs-on: macos-latest - steps: - - uses: actions/checkout@v4 - - name: Run tests - run: | - swift test --enable-code-coverage - xcrun llvm-cov export -format="lcov" .build/debug/TwitterAPIKitPackageTests.xctest/Contents/MacOS/TwitterAPIKitPackageTests -instr-profile .build/debug/codecov/default.profdata -ignore-filename-regex=".*\.generated.swift|.build|Tests" > info.lcov - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v2 diff --git a/.swift-version b/.swift-version deleted file mode 100644 index 358e78e6..00000000 --- a/.swift-version +++ /dev/null @@ -1 +0,0 @@ -6.1.0 \ No newline at end of file diff --git a/Package.resolved b/Package.resolved deleted file mode 100644 index b8438887..00000000 --- a/Package.resolved +++ /dev/null @@ -1,25 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "swift-asn1", - "repositoryURL": "https://github.com/apple/swift-asn1.git", - "state": { - "branch": null, - "revision": "a54383ada6cecde007d374f58f864e29370ba5c3", - "version": "1.3.2" - } - }, - { - "package": "swift-crypto", - "repositoryURL": "https://github.com/apple/swift-crypto.git", - "state": { - "branch": null, - "revision": "e8d6eba1fef23ae5b359c46b03f7d94be2f41fed", - "version": "3.12.3" - } - } - ] - }, - "version": 1 -} diff --git a/Package.swift b/Package.swift index 24bc1e44..08fd98ca 100644 --- a/Package.swift +++ b/Package.swift @@ -1,5 +1,4 @@ // swift-tools-version:5.5 -// The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription @@ -7,14 +6,16 @@ import PackageDescription // If CommonCrypto is not available, swift-crypto should be used. #if canImport(CommonCrypto) - let dependencies: [Package.Dependency] = [] - let tDependencies: [Target.Dependency] = [] + internal let dependencies: [Package.Dependency] = [] + internal let tDependencies: [Target.Dependency] = [] #else // for Linux - let dependencies: [Package.Dependency] = [.package(url: "https://github.com/apple/swift-crypto.git", from: "3.8.0")] - let tDependencies: [Target.Dependency] = [.product(name: "Crypto", package: "swift-crypto")] + internal let dependencies: [Package.Dependency] = [ + .package(url: "https://github.com/apple/swift-crypto.git", from: "3.8.0") + ] + internal let tDependencies: [Target.Dependency] = [.product(name: "Crypto", package: "swift-crypto")] #endif -let package = Package( +internal let package = Package( name: "TwitterAPIKit", platforms: [ .macOS(.v10_14), diff --git a/Sources/TwitterAPIKit/APIv1/Media/MediaAPIv1.swift b/Sources/TwitterAPIKit/APIv1/Media/MediaAPIv1.swift index 88b877ff..f52ddbc5 100644 --- a/Sources/TwitterAPIKit/APIv1/Media/MediaAPIv1.swift +++ b/Sources/TwitterAPIKit/APIv1/Media/MediaAPIv1.swift @@ -8,6 +8,7 @@ import Foundation +// swiftlint:disable function_body_length closure_body_length open class MediaAPIv1: TwitterAPIBase { /// For more details, see: /// https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/ @@ -232,3 +233,4 @@ open class MediaAPIv1: TwitterAPIBase { // De-init Logic Here } } +// swiftlint:enable function_body_length closure_body_length diff --git a/Sources/TwitterAPIKit/APIv1/Media/Requests/UploadMediaAppendRequestV1.swift b/Sources/TwitterAPIKit/APIv1/Media/Requests/UploadMediaAppendRequestV1.swift index 80d173c8..80fa4a1e 100644 --- a/Sources/TwitterAPIKit/APIv1/Media/Requests/UploadMediaAppendRequestV1.swift +++ b/Sources/TwitterAPIKit/APIv1/Media/Requests/UploadMediaAppendRequestV1.swift @@ -37,14 +37,12 @@ open class UploadMediaAppendRequestV1: TwitterAPIRequest { .multipartFormData } - open var parameters: [String: Any] { - [ - "command": command, - "media_id": mediaID, - "media": media, - "segment_index": segmentIndex, - "filename": filename, - "mime_type": mimeType + open var parameters: [String: MultipartFormDataPart] { + return [ + "command": .value(name: "command", value: command), + "media_id": .value(name: "media_id", value: mediaID), + "media": .data(name: "media", value: media, filename: filename, mimeType: mimeType), + "segment_index": .value(name: "segment_index", value: segmentIndex), ] } diff --git a/Sources/TwitterAPIKit/APIv1/Retweet/Requests/GetRetweetersRequestV1.swift b/Sources/TwitterAPIKit/APIv1/Retweet/Requests/GetRetweetersRequestV1.swift index 4f59d2eb..0e32c8bf 100644 --- a/Sources/TwitterAPIKit/APIv1/Retweet/Requests/GetRetweetersRequestV1.swift +++ b/Sources/TwitterAPIKit/APIv1/Retweet/Requests/GetRetweetersRequestV1.swift @@ -12,32 +12,41 @@ import Foundation /// https://developer.twitter.com/en/docs/twitter-api/v1/tweets/ /// post-and-engage/api-reference/get-statuses-retweeters-ids open class GetRetweetersRequestV1: TwitterAPIRequest { + // Status ID public let tweetID: String + public let count: Int? public let cursor: String? public let stringifyIDs: Bool? public var method: HTTPMethod { - .get + return .get } public var path: String { - "/1.1/statuses/retweeters/ids.json" + + return "/1.1/statuses/retweeters/ids.json" } open var parameters: [String: Any] { - var parameters = [String: Any]() - parameters["id"] = tweetID - cursor.map { parameters["cursor"] = $0 } - stringifyIDs.map { parameters["stringify_ids"] = $0 } - return parameters + + var params = [String: Any]() + + params["id"] = tweetID + count.map { params["count"] = $0 } + cursor.map { params["cursor"] = $0 } + stringifyIDs.map { params["stringify_ids"] = $0 } + + return params } public init( tweetID: String, + count: Int? = .none, cursor: String? = .none, stringifyIDs: Bool? = .none ) { self.tweetID = tweetID + self.count = count self.cursor = cursor self.stringifyIDs = stringifyIDs } diff --git a/Sources/TwitterAPIKit/Extensions/HMAC.swift b/Sources/TwitterAPIKit/Extensions/HMAC.swift index c8e9286f..81eb905d 100644 --- a/Sources/TwitterAPIKit/Extensions/HMAC.swift +++ b/Sources/TwitterAPIKit/Extensions/HMAC.swift @@ -8,6 +8,10 @@ import Foundation #if canImport(CommonCrypto) import CommonCrypto + internal protocol HMAC { + // Stub Logic for `swiftlint file_name` + } + fileprivate extension Data { func hmac(key: Data) -> Data { // Thanks: https://github.com/jernejstrasner/SwiftCrypto @@ -40,7 +44,7 @@ import Foundation /// - key: The key to use for signing /// - message: The message to sign /// - Returns: The HMAC-SHA1 signature as Data - func createHMACSHA1(key: Data, message: Data) -> Data { + public func createHMACSHA1(key: Data, message: Data) -> Data { message.hmac(key: key) } @@ -52,7 +56,7 @@ import Foundation /// - key: The key to use for signing /// - message: The message to sign /// - Returns: The HMAC-SHA1 signature as Data - func createHMACSHA1(key: Data, message: Data) -> Data { + public func createHMACSHA1(key: Data, message: Data) -> Data { Data(HMAC.authenticationCode(for: message, using: SymmetricKey(data: key))) } #else diff --git a/Sources/TwitterAPIKit/OAuthHelper.swift b/Sources/TwitterAPIKit/OAuthHelper.swift index 2fec8e6b..43ba73f2 100644 --- a/Sources/TwitterAPIKit/OAuthHelper.swift +++ b/Sources/TwitterAPIKit/OAuthHelper.swift @@ -11,7 +11,7 @@ import Foundation private let oauthVersion = "1.0" private let oauthSignatureMethod = "HMAC-SHA1" -// swiftlint:disable function_parameter_count +// swiftlint:disable function_parameter_count function_body_length /// Generates an OAuth authorization header for a given HTTP method, URL, and parameters. /// - Parameters: /// - method: The HTTP method to use. @@ -35,22 +35,18 @@ public func authorizationHeader( oauthTimestamp: String? = .none, oauthNonce: String? = .none ) -> String { - // swiftlint:enable function_parameter_count var authorizationParameters = [String: Any]() authorizationParameters["oauth_version"] = oauthVersion authorizationParameters["oauth_signature_method"] = oauthSignatureMethod authorizationParameters["oauth_consumer_key"] = consumerKey authorizationParameters["oauth_timestamp"] = oauthTimestamp ?? String(Int(Date().timeIntervalSince1970)) authorizationParameters["oauth_nonce"] = oauthNonce ?? UUID().uuidString - if let oauthToken { authorizationParameters["oauth_token"] = oauthToken } - for (key, value) in parameters where key.hasPrefix("oauth_") { authorizationParameters.updateValue(value, forKey: key) } - let combinedParameters = authorizationParameters.merging(parameters) { $1 } authorizationParameters["oauth_signature"] = oauthSignature( @@ -76,6 +72,7 @@ public func authorizationHeader( return "OAuth " + headerComponents.joined(separator: ", ") } +// swiftlint:enable function_parameter_count function_body_length private func oauthSignature( for method: HTTPMethod, diff --git a/Sources/TwitterAPIKit/SessionTask/TwitterAPISessionDelegatedJSONTask.swift b/Sources/TwitterAPIKit/SessionTask/TwitterAPISessionDelegatedJSONTask.swift index 4790dd99..e01adef6 100644 --- a/Sources/TwitterAPIKit/SessionTask/TwitterAPISessionDelegatedJSONTask.swift +++ b/Sources/TwitterAPIKit/SessionTask/TwitterAPISessionDelegatedJSONTask.swift @@ -75,6 +75,7 @@ public class TwitterAPISessionDelegatedJSONTask: TwitterAPISessionJSONTask, Twit taskQueue.resume() } + // swiftlint:disable:next function_body_length private func getResponse() -> TwitterAPIResponse { guard completed, let data else { fatalError("Request not completed yet.") diff --git a/Sources/TwitterAPIKit/TwitterAPIClient.swift b/Sources/TwitterAPIKit/TwitterAPIClient.swift index 3bc4e317..fd2c9dd7 100644 --- a/Sources/TwitterAPIKit/TwitterAPIClient.swift +++ b/Sources/TwitterAPIKit/TwitterAPIClient.swift @@ -134,18 +134,7 @@ public extension TwitterAPIClient { forceRefresh: Bool = false, _ block: @escaping (Result) -> Void ) { - guard case let .oauth20(token) = apiAuth else { - block(.failure(.refreshOAuth20TokenFailed(reason: .invalidAuthenticationMethod(apiAuth)))) - return - } - - guard let refreshToken = token.refreshToken else { - block(.failure(.refreshOAuth20TokenFailed(reason: .refreshTokenIsMissing))) - return - } - - if !forceRefresh, !token.expired { - block(.success((token: token, refreshed: false))) + guard let (refreshToken, token) = handleBlockGuards(forceRefresh: forceRefresh, block) else { return } @@ -177,6 +166,29 @@ public extension TwitterAPIClient { self.refreshOAuth20TokenClient = nil } } + + /// Handles Block Guards for `refreshOAuth20Token` + func handleBlockGuards( + forceRefresh: Bool = false, + _ block: @escaping (Result) -> Void + ) -> (String, TwitterAuthenticationMethod.OAuth20)? { + guard case let .oauth20(token) = apiAuth else { + block(.failure(.refreshOAuth20TokenFailed(reason: .invalidAuthenticationMethod(apiAuth)))) + return nil + } + + guard let refreshToken = token.refreshToken else { + block(.failure(.refreshOAuth20TokenFailed(reason: .refreshTokenIsMissing))) + return nil + } + + if !forceRefresh, !token.expired { + block(.success((token: token, refreshed: false))) + return nil + } + + return (refreshToken, token) + } } /// Base class for Twitter API clients. diff --git a/Sources/TwitterAPIKit/TwitterAPIRequest.swift b/Sources/TwitterAPIKit/TwitterAPIRequest.swift index e3d0f5e5..57cbb87c 100644 --- a/Sources/TwitterAPIKit/TwitterAPIRequest.swift +++ b/Sources/TwitterAPIKit/TwitterAPIRequest.swift @@ -151,6 +151,7 @@ public extension TwitterAPIRequest { } } +// swiftlint:disable function_body_length public extension TwitterAPIRequest { /// Builds a URL request for the given environment. /// - Parameters: @@ -289,6 +290,7 @@ public extension TwitterAPIRequest { return body } } +// swiftlint:enable function_body_length private extension TwitterAPIEnvironment { func baseURL(for type: TwitterBaseURLType) -> URL { diff --git a/Sources/TwitterAPIKit/TwitterAPISession.swift b/Sources/TwitterAPIKit/TwitterAPISession.swift index 5529b700..5d8f0167 100644 --- a/Sources/TwitterAPIKit/TwitterAPISession.swift +++ b/Sources/TwitterAPIKit/TwitterAPISession.swift @@ -68,6 +68,7 @@ open class TwitterAPISession { } } + // swiftlint:disable:next function_body_length private func tryBuildURLRequest(_ request: TwitterAPIRequest) throws -> URLRequest { var urlRequest = try request.buildRequest(environment: environment) diff --git a/Tests/TwitterAPIKitTests/APIv1/DirectMessage/PostDirectMessageRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/DirectMessage/PostDirectMessageRequestV1Tests.swift index 0aaf82bb..cb77b7a8 100644 --- a/Tests/TwitterAPIKitTests/APIv1/DirectMessage/PostDirectMessageRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/DirectMessage/PostDirectMessageRequestV1Tests.swift @@ -33,6 +33,7 @@ internal class PostDirectMessageRequestV1Tests: XCTestCase { ) } + // swiftlint:disable:next function_body_length public func testQuickReplyOptions() throws { let req = PostDirectMessageRequestV1( targetUserID: "target", @@ -101,81 +102,78 @@ internal class PostDirectMessageRequestV1Tests: XCTestCase { ) } + // swiftlint:disable:next function_body_length public func testAttachLocation() throws { - XCTContext.runActivity(named: "coordinate") { _ in - let req = PostDirectMessageRequestV1( - targetUserID: "target", - message: "msg", - attachment: .location(.coordinate(.init(lat: 10, long: 20))) - ) + let req = PostDirectMessageRequestV1( + targetUserID: "target", + message: "msg", + attachment: .location(.coordinate(.init(lat: 10, long: 20))) + ) - XCTAssertEqual(req.method, .post) - XCTAssertEqual(req.path, "/1.1/direct_messages/events/new.json") - XCTAssertEqual(req.bodyContentType, .json) - AssertEqualAnyDict( - req.parameters, - [ - "event": [ - "type": "message_create", - "message_create": [ - "message_data": [ - "text": "msg", - "attachment": [ - "type": "location", - "location": [ - "type": "shared_coordinate", - "shared_coordinate": [ - "coordinates": [ - "type": "Point", - "coordinates": [10, 20], - ], + XCTAssertEqual(req.method, .post) + XCTAssertEqual(req.path, "/1.1/direct_messages/events/new.json") + XCTAssertEqual(req.bodyContentType, .json) + AssertEqualAnyDict( + req.parameters, + [ + "event": [ + "type": "message_create", + "message_create": [ + "message_data": [ + "text": "msg", + "attachment": [ + "type": "location", + "location": [ + "type": "shared_coordinate", + "shared_coordinate": [ + "coordinates": [ + "type": "Point", + "coordinates": [10, 20], ], ], ], ], - "target": ["recipient_id": "target"], ], + "target": ["recipient_id": "target"], ], - ] - ) - } + ], + ] + ) - XCTContext.runActivity(named: "place") { _ in - let req = PostDirectMessageRequestV1( - targetUserID: "target", - message: "msg", - attachment: .location(.place("place_id")) - ) + let req2 = PostDirectMessageRequestV1( + targetUserID: "target", + message: "msg", + attachment: .location(.place("place_id")) + ) - XCTAssertEqual(req.method, .post) - XCTAssertEqual(req.path, "/1.1/direct_messages/events/new.json") - XCTAssertEqual(req.bodyContentType, .json) - AssertEqualAnyDict( - req.parameters, - [ - "event": [ - "type": "message_create", - "message_create": [ - "message_data": [ - "text": "msg", - "attachment": [ - "type": "location", - "location": [ - "type": "shared_place", - "shared_place": [ - "place": [ - "id": "place_id", - ], + XCTAssertEqual(req2.method, .post) + XCTAssertEqual(req2.path, "/1.1/direct_messages/events/new.json") + XCTAssertEqual(req2.bodyContentType, .json) + AssertEqualAnyDict( + req2.parameters, + [ + "event": [ + "type": "message_create", + "message_create": [ + "message_data": [ + "text": "msg", + "attachment": [ + "type": "location", + "location": [ + "type": "shared_place", + "shared_place": [ + "place": [ + "id": "place_id", ], ], ], ], - "target": ["recipient_id": "target"], ], + "target": ["recipient_id": "target"], ], - ] - ) - } + ], + ] + ) } deinit { diff --git a/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoReverseGeocodeRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoReverseGeocodeRequestV1Tests.swift index 98999a02..48e79e80 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoReverseGeocodeRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoReverseGeocodeRequestV1Tests.swift @@ -10,129 +10,122 @@ import TwitterAPIKit import XCTest internal class GetGeoReverseGeocodeRequestV1Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func testAccuracy() throws { - XCTContext.runActivity(named: "ft") { _ in - let req = GetGeoReverseGeocodeRequestV1( - location: .init(lat: 1, long: 2.5), - accuracy: .ft(2), - maxResults: 10, - granularity: .neighborhood - ) - - XCTAssertEqual(req.method, .get) - XCTAssertEqual(req.baseURLType, .api) - XCTAssertEqual(req.path, "/1.1/geo/reverse_geocode.json") - XCTAssertEqual(req.bodyContentType, .wwwFormUrlEncoded) - AssertEqualAnyDict( - req.parameters, - [ - "lat": 1, - "long": 2.5, - "accuracy": "2ft", - "max_results": 10, - "granularity": "neighborhood", - ] - ) - } - XCTContext.runActivity(named: "meter") { _ in - - let req = GetGeoReverseGeocodeRequestV1( - location: .init(lat: 1, long: 2.5), - accuracy: .m(3), - maxResults: 10, - granularity: .neighborhood - ) - - AssertEqualAnyDict( - req.parameters, - [ - "lat": 1, - "long": 2.5, - "accuracy": "3m", - "max_results": 10, - "granularity": "neighborhood", - ] - ) - } + let req = GetGeoReverseGeocodeRequestV1( + location: .init(lat: 1, long: 2.5), + accuracy: .ft(2), + maxResults: 10, + granularity: .neighborhood + ) + + XCTAssertEqual(req.method, .get) + XCTAssertEqual(req.baseURLType, .api) + XCTAssertEqual(req.path, "/1.1/geo/reverse_geocode.json") + XCTAssertEqual(req.bodyContentType, .wwwFormUrlEncoded) + AssertEqualAnyDict( + req.parameters, + [ + "lat": 1, + "long": 2.5, + "accuracy": "2ft", + "max_results": 10, + "granularity": "neighborhood", + ] + ) + + let req2 = GetGeoReverseGeocodeRequestV1( + location: .init(lat: 1, long: 2.5), + accuracy: .m(3), + maxResults: 10, + granularity: .neighborhood + ) + + AssertEqualAnyDict( + req2.parameters, + [ + "lat": 1, + "long": 2.5, + "accuracy": "3m", + "max_results": 10, + "granularity": "neighborhood", + ] + ) } + // swiftlint:disable:next function_body_length public func testGranularity() throws { - XCTContext.runActivity(named: "neighborhood") { _ in - let req = GetGeoReverseGeocodeRequestV1( - location: .init(lat: 1, long: 2.5), - accuracy: .ft(2), - maxResults: 10, - granularity: .neighborhood - ) - - AssertEqualAnyDict( - req.parameters, - [ - "lat": 1, - "long": 2.5, - "accuracy": "2ft", - "max_results": 10, - "granularity": "neighborhood", - ] - ) - } - XCTContext.runActivity(named: "city") { _ in - let req = GetGeoReverseGeocodeRequestV1( - location: .init(lat: 1, long: 2.5), - accuracy: .ft(2), - maxResults: 10, - granularity: .city - ) - - AssertEqualAnyDict( - req.parameters, - [ - "lat": 1, - "long": 2.5, - "accuracy": "2ft", - "max_results": 10, - "granularity": "city", - ] - ) - } - XCTContext.runActivity(named: "admin") { _ in - let req = GetGeoReverseGeocodeRequestV1( - location: .init(lat: 1, long: 2.5), - accuracy: .ft(2), - maxResults: 10, - granularity: .admin - ) - - AssertEqualAnyDict( - req.parameters, - [ - "lat": 1, - "long": 2.5, - "accuracy": "2ft", - "max_results": 10, - "granularity": "admin", - ] - ) - } - XCTContext.runActivity(named: "country") { _ in - let req = GetGeoReverseGeocodeRequestV1( - location: .init(lat: 1, long: 2.5), - accuracy: .ft(2), - maxResults: 10, - granularity: .country - ) - - AssertEqualAnyDict( - req.parameters, - [ - "lat": 1, - "long": 2.5, - "accuracy": "2ft", - "max_results": 10, - "granularity": "country", - ] - ) - } + let req = GetGeoReverseGeocodeRequestV1( + location: .init(lat: 1, long: 2.5), + accuracy: .ft(2), + maxResults: 10, + granularity: .neighborhood + ) + + AssertEqualAnyDict( + req.parameters, + [ + "lat": 1, + "long": 2.5, + "accuracy": "2ft", + "max_results": 10, + "granularity": "neighborhood", + ] + ) + + let req2 = GetGeoReverseGeocodeRequestV1( + location: .init(lat: 1, long: 2.5), + accuracy: .ft(2), + maxResults: 10, + granularity: .city + ) + + AssertEqualAnyDict( + req2.parameters, + [ + "lat": 1, + "long": 2.5, + "accuracy": "2ft", + "max_results": 10, + "granularity": "city", + ] + ) + + let req3 = GetGeoReverseGeocodeRequestV1( + location: .init(lat: 1, long: 2.5), + accuracy: .ft(2), + maxResults: 10, + granularity: .admin + ) + + AssertEqualAnyDict( + req3.parameters, + [ + "lat": 1, + "long": 2.5, + "accuracy": "2ft", + "max_results": 10, + "granularity": "admin", + ] + ) + + let req4 = GetGeoReverseGeocodeRequestV1( + location: .init(lat: 1, long: 2.5), + accuracy: .ft(2), + maxResults: 10, + granularity: .country + ) + + AssertEqualAnyDict( + req4.parameters, + [ + "lat": 1, + "long": 2.5, + "accuracy": "2ft", + "max_results": 10, + "granularity": "country", + ] + ) } public func testDefaultArg() throws { diff --git a/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoSearchRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoSearchRequestV1Tests.swift index 36a8c297..36784373 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoSearchRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Geo/GetGeoSearchRequestV1Tests.swift @@ -10,61 +10,55 @@ import TwitterAPIKit import XCTest internal class GetGeoSearchRequestV1Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { - XCTContext.runActivity(named: "coordinate") { _ in - - let req = GetGeoSearchRequestV1( - location: .coordinate(.init(lat: 10.12, long: -20)), - maxResults: 13, - granularity: .country - ) + let req = GetGeoSearchRequestV1( + location: .coordinate(.init(lat: 10.12, long: -20)), + maxResults: 13, + granularity: .country + ) - XCTAssertEqual(req.method, .get) - XCTAssertEqual(req.baseURLType, .api) - XCTAssertEqual(req.path, "/1.1/geo/search.json") - XCTAssertEqual(req.bodyContentType, .wwwFormUrlEncoded) - AssertEqualAnyDict( - req.parameters, - [ - "lat": 10.12, - "long": -20, - "max_results": 13, - "granularity": "country", - ] - ) - } + XCTAssertEqual(req.method, .get) + XCTAssertEqual(req.baseURLType, .api) + XCTAssertEqual(req.path, "/1.1/geo/search.json") + XCTAssertEqual(req.bodyContentType, .wwwFormUrlEncoded) + AssertEqualAnyDict( + req.parameters, + [ + "lat": 10.12, + "long": -20, + "max_results": 13, + "granularity": "country", + ] + ) - XCTContext.runActivity(named: "query") { _ in - let req = GetGeoSearchRequestV1( - location: .query("日本"), - maxResults: 13, - granularity: .country - ) - AssertEqualAnyDict( - req.parameters, - [ - "query": "日本", - "max_results": 13, - "granularity": "country", - ] - ) - } + let req2 = GetGeoSearchRequestV1( + location: .query("日本"), + maxResults: 13, + granularity: .country + ) + AssertEqualAnyDict( + req2.parameters, + [ + "query": "日本", + "max_results": 13, + "granularity": "country", + ] + ) - XCTContext.runActivity(named: "ip") { _ in - let req = GetGeoSearchRequestV1( - location: .ip("0.0.0.0"), - maxResults: 13, - granularity: .country - ) - AssertEqualAnyDict( - req.parameters, - [ - "ip": "0.0.0.0", - "max_results": 13, - "granularity": "country", - ] - ) - } + let req3 = GetGeoSearchRequestV1( + location: .ip("0.0.0.0"), + maxResults: 13, + granularity: .country + ) + AssertEqualAnyDict( + req3.parameters, + [ + "ip": "0.0.0.0", + "max_results": 13, + "granularity": "country", + ] + ) } public func testDefaultArg() throws { diff --git a/Tests/TwitterAPIKitTests/APIv1/List/ListRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/List/ListRequestV1Tests.swift index c6764796..6ef7202f 100644 --- a/Tests/TwitterAPIKitTests/APIv1/List/ListRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/List/ListRequestV1Tests.swift @@ -42,18 +42,14 @@ internal class ListRequestV1Tests: XCTestCase { // https://developer.twitter.com/en/docs/twitter-api/v1/ \ // accounts-and-users/create-manage-lists/api-reference/get-lists-list public func testGetListsListRequestV1() throws { - XCTContext.runActivity(named: "with only required parameters") { _ in - let list = GetListsListRequestV1(user: .userID("1234")) + let list = GetListsListRequestV1(user: .userID("1234")) - XCTAssertEqual(list.method, .get) - XCTAssertEqual(list.path, "/1.1/lists/list.json") - AssertEqualAnyDict(list.parameters, ["user_id": "1234"]) - } + XCTAssertEqual(list.method, .get) + XCTAssertEqual(list.path, "/1.1/lists/list.json") + AssertEqualAnyDict(list.parameters, ["user_id": "1234"]) - XCTContext.runActivity(named: "with all parameters") { _ in - let list = GetListsListRequestV1(user: .screenName("name"), reverse: true) - AssertEqualAnyDict(list.parameters, ["screen_name": "name", "reverse": true]) - } + let list2 = GetListsListRequestV1(user: .screenName("name"), reverse: true) + AssertEqualAnyDict(list2.parameters, ["screen_name": "name", "reverse": true]) } public func testCustomListsListRequestV1() throws { diff --git a/Tests/TwitterAPIKitTests/APIv1/Media/PostMediaSubtitlesCreateRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Media/PostMediaSubtitlesCreateRequestV1Tests.swift index 1a57ce54..cf0a2892 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Media/PostMediaSubtitlesCreateRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Media/PostMediaSubtitlesCreateRequestV1Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class PostMediaSubtitlesCreateRequestV1Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = PostMediaSubtitlesCreateRequestV1( mediaID: "mediaID", diff --git a/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaAppendRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaAppendRequestV1Tests.swift index 3d7bb7c6..a131bd18 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaAppendRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaAppendRequestV1Tests.swift @@ -25,7 +25,7 @@ internal class UploadMediaAppendRequestV1Tests: XCTestCase { XCTAssertEqual(req.path, "/1.1/media/upload.json") XCTAssertEqual(req.bodyContentType, .multipartFormData) XCTAssertEqual( - req.parameters as? [String: MultipartFormDataPart], + req.parameters, [ "command": MultipartFormDataPart.value(name: "command", value: "APPEND"), "media_id": MultipartFormDataPart.value(name: "media_id", value: "m"), diff --git a/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaUtilTests.swift b/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaUtilTests.swift deleted file mode 100644 index aa80dec4..00000000 --- a/Tests/TwitterAPIKitTests/APIv1/Media/UploadMediaUtilTests.swift +++ /dev/null @@ -1,673 +0,0 @@ -// UploadMediaUtilTests.swift -// Copyright (c) 2025 GetAutomaApp -// All source code and related assets are the property of GetAutomaApp. -// All rights reserved. -// -// This Package is a heavily modified fork of https://github.com/mironal/TwitterAPIKit. -// This Package is distributable through a modified version of the MIT License. - -import TwitterAPIKit -import XCTest - -internal class UploadMediaUtilTests: XCTestCase { - // Helper function to safely serialize JSON - private func serializeJSON(_ object: [String: Any]) throws -> Data { - do { - return try JSONSerialization.data(withJSONObject: object, options: []) - } catch { - XCTFail("Failed to serialize JSON: \(error)") - throw error - } - } - - override public func tearDownWithError() throws { - MockURLProtocol.cleanup() - } - - // swiftlint:disable:next function_body_length - public func testWithProcessing() throws { - let config = URLSessionConfiguration.default - config.protocolClasses = [MockURLProtocol.self] - - let client = TwitterAPIClient( - .oauth10a(.init(consumerKey: "", consumerSecret: "", oauthToken: "", oauthTokenSecret: "")), - configuration: config - ) - - var requestCount = 0 - // swiftlint:disable:next closure_body_length - MockURLProtocol.requestHandler = { [weak self] request in - guard let self else { - throw URLError(.unknown) - } - - defer { - requestCount += 1 - } - let requestData = request.httpBodyStream.flatMap { - try? Data(reading: $0) - } - let requestBodyString = requestData.flatMap { - String(data: $0, encoding: .utf8) - } - var data = Data() - switch requestCount { - case 0: // INIT - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=INIT")) - } else { - XCTFail("Request body string is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "expires_after_secs": 1_000, - ]) - case 1: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - case 2: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - case 3: // FINALIZE - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=FINALIZE")) - } else { - XCTFail("Request body string is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "size": 10, - "expires_after_secs": 200, - "processingInfo": [ - "state": "pending", - "check_after_secs": 0, - ], - ]) - case 4: - XCTAssertEqual(request.httpMethod, "GET") - XCTAssertEqual(request.url?.path, "/1.1/media/upload.json") - if let url = request.url, let query = url.query { - XCTAssertTrue(query.contains("command=STATUS")) - } else { - XCTFail("URL or query is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "processing_info": [ - "state": "in_progress", - "progress_percent": 99, - "check_after_secs": 0, - ], - ]) - case 5: - XCTAssertEqual(request.httpMethod, "GET") - XCTAssertEqual(request.url?.path, "/1.1/media/upload.json") - if let url = request.url, let query = url.query { - XCTAssertTrue(query.contains("command=STATUS")) - } else { - XCTFail("URL or query is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "video": [ - "video_type": "video/mp4", - ], - "processing_info": [ - "state": "succeeded", - "progress_percent": 100, - ], - ]) - default: - XCTFail("Invalid Response") - } - - if let url = request.url { - return ( - HTTPURLResponse( - url: url, - statusCode: 200, - httpVersion: "2.0", - headerFields: [:] - ) ?? HTTPURLResponse(), - data - ) - } else { - XCTFail("Request URL is nil") - return (HTTPURLResponse(), data) - } - } - - let exp = expectation(description: "") - let data = Data([1, 2, 3]) - client.v1.media.uploadMedia(.init(media: data, mediaType: "m", filename: "f", uploadChunkSize: 2)) { response in - - XCTAssertFalse(response.isError) - XCTAssertEqual(response.success, "123") - exp.fulfill() - } - - wait(for: [exp], timeout: 10) - } - - public func testInitError() throws { - let config = URLSessionConfiguration.default - config.protocolinternal classes = [MockURLProtocol.self] - - let client = TwitterAPIClient( - .oauth10a(.init(consumerKey: "", consumerSecret: "", oauthToken: "", oauthTokenSecret: "")), - configuration: config - ) - - var requestCount = 0 - MockURLProtocol.requestHandler = { request in - defer { - requestCount += 1 - } - let requestData = request.httpBodyStream.flatMap { - try? Data(reading: $0) - } - let requestBodyString = requestData.flatMap { - String(data: $0, encoding: .utf8) - } - let data = Data("{}".utf8) - var statusCode = 200 - switch requestCount { - case 0: // INIT - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=INIT")) - } else { - XCTFail("Request body string is nil") - } - statusCode = 404 - - default: - XCTFail("Invalid Response") - } - - if let url = request.url { - return ( - HTTPURLResponse( - url: url, - statusCode: statusCode, - httpVersion: "2.0", - headerFields: [:] - ) ?? HTTPURLResponse(), - data - ) - } else { - XCTFail("Request URL is nil") - return (HTTPURLResponse(), data) - } - } - - let exp = expectation(description: "") - let data = Data([1, 2, 3]) - client.v1.media.uploadMedia(.init(media: data, mediaType: "m", filename: "f", uploadChunkSize: 2)) { response in - - XCTAssertTrue(response.isError) - - if case .responseFailed(reason: .unacceptableStatusCode(statusCode: 404, error: _, rateLimit: _)) = response - .error - { - } else { - XCTFail(response.prettyString) - } - - exp.fulfill() - } - - wait(for: [exp], timeout: 10) - } - - public func testAppendError() throws { - let config = URLSessionConfiguration.default - config.protocolClasses = [MockURLProtocol.self] - - let client = TwitterAPIClient( - .oauth10a(.init(consumerKey: "", consumerSecret: "", oauthToken: "", oauthTokenSecret: "")), - configuration: config - ) - - var requestCount = 0 - MockURLProtocol.requestHandler = { [weak self] request in - guard let self else { - throw URLError(.unknown) - } - - defer { - requestCount += 1 - } - let requestData = request.httpBodyStream.flatMap { - try? Data(reading: $0) - } - let requestBodyString = requestData.flatMap { - String(data: $0, encoding: .utf8) - } - var data = Data() - var statusCode = 200 - switch requestCount { - case 0: // INIT - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=INIT")) - } else { - XCTFail("Request body string is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "expires_after_secs": 1_000, - ]) - case 1: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - statusCode = 400 - case 2: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - statusCode = 200 - default: - XCTFail("Invalid Response") - } - - if let url = request.url { - return ( - HTTPURLResponse( - url: url, - statusCode: statusCode, - httpVersion: "2.0", - headerFields: [:] - ) ?? HTTPURLResponse(), - data - ) - } else { - XCTFail("Request URL is nil") - return (HTTPURLResponse(), data) - } - } - - let exp = expectation(description: "") - let data = Data([1, 2, 3]) - client.v1.media.uploadMedia(.init(media: data, mediaType: "m", filename: "f", uploadChunkSize: 2)) { response in - - XCTAssertTrue(response.isError) - - if case .responseFailed(reason: .unacceptableStatusCode(statusCode: 400, error: _, rateLimit: _)) = response - .error - { - } else { - XCTFail(response.prettyString) - } - - exp.fulfill() - } - - wait(for: [exp], timeout: 10) - } - - public func testFinalizeError() throws { - let config = URLSessionConfiguration.default - config.protocolClasses = [MockURLProtocol.self] - - let client = TwitterAPIClient( - .oauth10a(.init(consumerKey: "", consumerSecret: "", oauthToken: "", oauthTokenSecret: "")), - configuration: config - ) - - var statusCode = 200 - var requestCount = 0 - MockURLProtocol.requestHandler = { [weak self] request in - guard let self else { - throw URLError(.unknown) - } - - defer { - requestCount += 1 - } - let requestData = request.httpBodyStream.flatMap { - try? Data(reading: $0) - } - let requestBodyString = requestData.flatMap { - String(data: $0, encoding: .utf8) - } - var data = Data() - switch requestCount { - case 0: // INIT - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=INIT")) - } else { - XCTFail("Request body string is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "expires_after_secs": 1_000, - ]) - case 1: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - case 2: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - case 3: // FINALIZE - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=FINALIZE")) - } else { - XCTFail("Request body string is nil") - } - statusCode = 500 - default: - XCTFail("Invalid Response") - } - - if let url = request.url { - return ( - HTTPURLResponse( - url: url, - statusCode: statusCode, - httpVersion: "2.0", - headerFields: [:] - ) ?? HTTPURLResponse(), - data - ) - } else { - XCTFail("Request URL is nil") - return (HTTPURLResponse(), data) - } - } - - let exp = expectation(description: "") - let data = Data([1, 2, 3]) - client.v1.media.uploadMedia(.init(media: data, mediaType: "m", filename: "f", uploadChunkSize: 2)) { response in - - XCTAssertTrue(response.isError) - - if case .responseFailed(reason: .unacceptableStatusCode(statusCode: 500, error: _, rateLimit: _)) = response - .error - { - } else { - XCTFail(response.prettyString) - } - exp.fulfill() - } - - wait(for: [exp], timeout: 10) - } - - // swiftlint:disable:next function_body_length - public func testWithProcessingError() throws { - let config = URLSessionConfiguration.default - config.protocolClasses = [MockURLProtocol.self] - - let client = TwitterAPIClient( - .oauth10a(.init(consumerKey: "", consumerSecret: "", oauthToken: "", oauthTokenSecret: "")), - configuration: config - ) - - var requestCount = 0 - // swiftlint:disable:next closure_body_length - MockURLProtocol.requestHandler = { [weak self] request in - guard let self else { - throw URLError(.unknown) - } - - defer { - requestCount += 1 - } - let requestData = request.httpBodyStream.flatMap { - try? Data(reading: $0) - } - let requestBodyString = requestData.flatMap { - String(data: $0, encoding: .utf8) - } - var data = Data() - switch requestCount { - case 0: // INIT - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=INIT")) - } else { - XCTFail("Request body string is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "expires_after_secs": 1_000, - ]) - case 1: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - case 2: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - case 3: // FINALIZE - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=FINALIZE")) - } else { - XCTFail("Request body string is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "size": 10, - "expires_after_secs": 200, - "processingInfo": [ - "state": "pending", - "check_after_secs": 0, - ], - ]) - case 4: - XCTAssertEqual(request.httpMethod, "GET") - XCTAssertEqual(request.url?.path, "/1.1/media/upload.json") - if let url = request.url, let query = url.query { - XCTAssertTrue(query.contains("command=STATUS")) - } else { - XCTFail("URL or query is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "processing_info": [ - "state": "in_progress", - "progress_percent": 99, - "check_after_secs": 0, - ], - ]) - case 5: - XCTAssertEqual(request.httpMethod, "GET") - XCTAssertEqual(request.url?.path, "/1.1/media/upload.json") - if let url = request.url, let query = url.query { - XCTAssertTrue(query.contains("command=STATUS")) - } else { - XCTFail("URL or query is nil") - } - - data = try serializeJSON([ - "media_id_string": "123", - "processing_info": [ - "state": "failed", - "error": [ - "message": "Invalid media", - "code": 1, - ], - ], - ]) - default: - XCTFail("Invalid Response") - } - - if let url = request.url { - return ( - HTTPURLResponse( - url: url, - statusCode: 200, - httpVersion: "2.0", - headerFields: [:] - ) ?? HTTPURLResponse(), - data - ) - } else { - XCTFail("Request URL is nil") - return (HTTPURLResponse(), data) - } - } - - let exp = expectation(description: "") - let data = Data([1, 2, 3]) - client.v1.media.uploadMedia(.init(media: data, mediaType: "m", filename: "f", uploadChunkSize: 2)) { response in - XCTAssertTrue(response.isError) - XCTAssertTrue(response.error?.isUploadMediaFailed ?? false) - exp.fulfill() - } - - wait(for: [exp], timeout: 10) - } - - public func testWithoutProcessing() throws { - let config = URLSessionConfiguration.default - config.protocolinternal classes = [MockURLProtocol.self] - - let client = TwitterAPIClient( - .oauth10a(.init(consumerKey: "", consumerSecret: "", oauthToken: "", oauthTokenSecret: "")), - configuration: config - ) - - var requestCount = 0 - MockURLProtocol.requestHandler = { request in - defer { - requestCount += 1 - } - let requestData = request.httpBodyStream.flatMap { - try? Data(reading: $0) - } - let requestBodyString = requestData.flatMap { - String(data: $0, encoding: .utf8) - } - var data = Data() - switch requestCount { - case 0: // INIT - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=INIT")) - } else { - XCTFail("Request body string is nil") - } - - do { - data = try JSONSerialization.data( - withJSONObject: [ - "media_id_string": "123", - "expires_after_secs": 1_000, - ], - options: [] - ) - } catch { - XCTFail("Failed to serialize JSON: \(error)") - } - - case 1: // APPEND - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("\r\nAPPEND\r\n")) - } else { - XCTFail("Request body string is nil") - } - - case 2: // FINALIZE - XCTAssertEqual(request.url?.absoluteString, "https://upload.twitter.com/1.1/media/upload.json") - if let bodyString = requestBodyString { - XCTAssertTrue(bodyString.contains("command=FINALIZE")) - } else { - XCTFail("Request body string is nil") - } - - do { - data = try JSONSerialization.data( - withJSONObject: [ - "media_id_string": "123", - "size": 10, - "expires_after_secs": 200, - ], - options: [] - ) - } catch { - XCTFail("Failed to serialize JSON: \(error)") - } - - default: - XCTFail("Invalid Response") - } - - if let url = request.url { - return ( - HTTPURLResponse( - url: url, - statusCode: 200, - httpVersion: "2.0", - headerFields: [:] - ) ?? HTTPURLResponse(), - data - ) - } else { - XCTFail("Request URL is nil") - return (HTTPURLResponse(), data) - } - } - - let exp = expectation(description: "") - let data = Data([1, 2, 3]) - client.v1.media.uploadMedia(.init(media: data, mediaType: "m", filename: "f")) { response in - XCTAssertFalse(response.isError) - XCTAssertEqual(response.success, "123") - exp.fulfill() - } - - wait(for: [exp], timeout: 10) - } - - deinit { - // De-init Logic Here - } -} diff --git a/Tests/TwitterAPIKitTests/APIv1/Retweet/GetRetweetersRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Retweet/GetRetweetersRequestV1Tests.swift index 062cf72d..20fa6a21 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Retweet/GetRetweetersRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Retweet/GetRetweetersRequestV1Tests.swift @@ -12,7 +12,7 @@ import XCTest internal class GetRetweetersRequestV1Tests: XCTestCase { public func test() throws { let req = GetRetweetersRequestV1( - id: "_i_", + tweetID: "_i_", count: 100, cursor: "_c_", stringifyIDs: true @@ -35,7 +35,7 @@ internal class GetRetweetersRequestV1Tests: XCTestCase { public func testDefaultArg() throws { let req = GetRetweetersRequestV1( - id: "_i_" + tweetID: "_i_" ) AssertEqualAnyDict( diff --git a/Tests/TwitterAPIKitTests/APIv1/Search/GetSearchTweetsRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Search/GetSearchTweetsRequestV1Tests.swift index adca386e..4e4f2171 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Search/GetSearchTweetsRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Search/GetSearchTweetsRequestV1Tests.swift @@ -12,7 +12,7 @@ import XCTest internal class GetSearchTweetsRequestV1Tests: XCTestCase { public func test() throws { let req = GetSearchTweetsRequestV1( - q: "あああ", + query: "あああ", lang: "lang", count: 20, until: "2015-07-19", @@ -46,7 +46,7 @@ internal class GetSearchTweetsRequestV1Tests: XCTestCase { public func testDefaultArg() throws { let req = GetSearchTweetsRequestV1( - q: "_q_" + query: "_q_" ) AssertEqualAnyDict( diff --git a/Tests/TwitterAPIKitTests/APIv1/Tweet/PostStatusesUpdateRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Tweet/PostStatusesUpdateRequestV1Tests.swift index 80c441c1..4a1548a3 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Tweet/PostStatusesUpdateRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Tweet/PostStatusesUpdateRequestV1Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class PostStatusesUpdateRequestV1Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = PostStatusesUpdateRequestV1( status: "_s_", diff --git a/Tests/TwitterAPIKitTests/APIv1/Users/GetUsersSearchRequestV1Tests.swift b/Tests/TwitterAPIKitTests/APIv1/Users/GetUsersSearchRequestV1Tests.swift index 98fd7a43..4e6b3c15 100644 --- a/Tests/TwitterAPIKitTests/APIv1/Users/GetUsersSearchRequestV1Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv1/Users/GetUsersSearchRequestV1Tests.swift @@ -12,7 +12,7 @@ import XCTest internal class GetUsersSearchRequestV1Tests: XCTestCase { public func test() throws { let req = GetUsersSearchRequestV1( - q: "_q_", + query: "_q_", page: 11, count: 100, includeEntities: true @@ -35,7 +35,7 @@ internal class GetUsersSearchRequestV1Tests: XCTestCase { public func testDefaultArg() throws { let req = GetUsersSearchRequestV1( - q: "qq" + query: "qq" ) AssertEqualAnyDict( diff --git a/Tests/TwitterAPIKitTests/APIv2/FieldsV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/FieldsV2Tests.swift index 6710c37b..9f809bc2 100644 --- a/Tests/TwitterAPIKitTests/APIv2/FieldsV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/FieldsV2Tests.swift @@ -11,6 +11,7 @@ import XCTest @testable import TwitterAPIKit internal class FieldsV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func testTwitterTweetFieldsV2() throws { let allCases: [TwitterTweetFieldsV2] = [ .attachments, diff --git a/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchAllRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchAllRequestV2Tests.swift index b919cfc3..7d4f4ca5 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchAllRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchAllRequestV2Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class GetTweetsSearchAllRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = GetTweetsSearchAllRequestV2( query: "_q_", diff --git a/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchRecentRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchRecentRequestV2Tests.swift index eb948855..14925af7 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchRecentRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Search/GetTweetsSearchRecentRequestV2Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class GetTweetsSearchRecentRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = GetTweetsSearchRecentRequestV2( query: "Q", diff --git a/Tests/TwitterAPIKitTests/APIv2/Stream/PostTweetsSearchStreamRulesRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Stream/PostTweetsSearchStreamRulesRequestV2Tests.swift index 60f592da..52624a99 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Stream/PostTweetsSearchStreamRulesRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Stream/PostTweetsSearchStreamRulesRequestV2Tests.swift @@ -10,52 +10,47 @@ import TwitterAPIKit import XCTest internal class PostTweetsSearchStreamRulesRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { - XCTContext.runActivity(named: "add") { _ in - - let add = PostTweetsSearchStreamRulesRequestV2( - operation: .add([ - .init(value: "value", tag: "tag"), - .init(value: "hoge"), - ]) - ) - - XCTAssertEqual(add.method, .post) - XCTAssertEqual(add.path, "/2/tweets/search/stream/rules") - XCTAssertEqual(add.bodyContentType, .json) + let add = PostTweetsSearchStreamRulesRequestV2( + operation: .add([ + .init(value: "value", tag: "tag"), + .init(value: "hoge"), + ]) + ) - AssertEqualAnyDict(add.parameters, [:]) - AssertEqualAnyDict( - add.bodyParameters, - [ - "add": [ - ["value": "value", "tag": "tag"], - ["value": "hoge"], - ], - ] - ) - AssertEqualAnyDict(add.queryParameters, [:]) - } + XCTAssertEqual(add.method, .post) + XCTAssertEqual(add.path, "/2/tweets/search/stream/rules") + XCTAssertEqual(add.bodyContentType, .json) - XCTContext.runActivity(named: "delete") { _ in + AssertEqualAnyDict(add.parameters, [:]) + AssertEqualAnyDict( + add.bodyParameters, + [ + "add": [ + ["value": "value", "tag": "tag"], + ["value": "hoge"], + ], + ] + ) + AssertEqualAnyDict(add.queryParameters, [:]) - let delete = PostTweetsSearchStreamRulesRequestV2(operation: .delete(["1", "20"])) + let delete = PostTweetsSearchStreamRulesRequestV2(operation: .delete(["1", "20"])) - XCTAssertEqual(delete.method, .post) - XCTAssertEqual(delete.path, "/2/tweets/search/stream/rules") - XCTAssertEqual(delete.bodyContentType, .json) + XCTAssertEqual(delete.method, .post) + XCTAssertEqual(delete.path, "/2/tweets/search/stream/rules") + XCTAssertEqual(delete.bodyContentType, .json) - AssertEqualAnyDict(delete.parameters, [:]) - AssertEqualAnyDict( - delete.bodyParameters, - [ - "delete": [ - "ids": ["1", "20"], - ], - ] - ) - AssertEqualAnyDict(delete.queryParameters, [:]) - } + AssertEqualAnyDict(delete.parameters, [:]) + AssertEqualAnyDict( + delete.bodyParameters, + [ + "delete": [ + "ids": ["1", "20"], + ], + ] + ) + AssertEqualAnyDict(delete.queryParameters, [:]) } public func testDryRun() throws { diff --git a/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersMentionsRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersMentionsRequestV2Tests.swift index 3e54e90c..e289f72a 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersMentionsRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersMentionsRequestV2Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class GetUsersMentionsRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = GetUsersMentionsRequestV2( id: "_i_", diff --git a/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTimelinesReverseChronologicalRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTimelinesReverseChronologicalRequestV2Tests.swift index 9017cddd..328f3c19 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTimelinesReverseChronologicalRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTimelinesReverseChronologicalRequestV2Tests.swift @@ -11,6 +11,7 @@ import XCTest // swiftlint:disable:next type_name internal class GetUsersTimelinesReverseChronologicalRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = GetUsersTimelinesReverseChronologicalRequestV2( id: "_i_", diff --git a/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTweetsRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTweetsRequestV2Tests.swift index 65092695..91855a2a 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTweetsRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Timeline/GetUsersTweetsRequestV2Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class GetUsersTweetsRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let req = GetUsersTweetsRequestV2( id: "_i_", diff --git a/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetRequestV2Tests.swift index 22669fef..5f1c9e9e 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetRequestV2Tests.swift @@ -11,39 +11,33 @@ import XCTest internal class GetTweetRequestV2Tests: XCTestCase { public func test() throws { - XCTContext.runActivity(named: "with only required parameters") { _ in - - let tweet = GetTweetRequestV2(id: "123") - - XCTAssertEqual(tweet.method, .get) - XCTAssertEqual(tweet.path, "/2/tweets/123") - AssertEqualAnyDict(tweet.parameters, [:]) - } - - XCTContext.runActivity(named: "with all parameters") { _ in - - let tweet = GetTweetRequestV2( - id: "1234", - expansions: [.authorID], - mediaFields: [.url, .altText], - placeFields: [.name, .id], - pollFields: [.id], - tweetFields: [.text, .id], - userFields: [.entities] - ) - - AssertEqualAnyDict( - tweet.parameters, - [ - "expansions": "author_id", - "media.fields": "alt_text,url", - "place.fields": "id,name", - "poll.fields": "id", - "tweet.fields": "id,text", - "user.fields": "entities", - ] - ) - } + let tweet = GetTweetRequestV2(id: "123") + + XCTAssertEqual(tweet.method, .get) + XCTAssertEqual(tweet.path, "/2/tweets/123") + AssertEqualAnyDict(tweet.parameters, [:]) + + let tweet2 = GetTweetRequestV2( + id: "1234", + expansions: [.authorID], + mediaFields: [.url, .altText], + placeFields: [.name, .id], + pollFields: [.id], + tweetFields: [.text, .id], + userFields: [.entities] + ) + + AssertEqualAnyDict( + tweet2.parameters, + [ + "expansions": "author_id", + "media.fields": "alt_text,url", + "place.fields": "id,name", + "poll.fields": "id", + "tweet.fields": "id,text", + "user.fields": "entities", + ] + ) } deinit { diff --git a/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetsRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetsRequestV2Tests.swift index 3e57300c..36d1f11e 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetsRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Tweet/GetTweetsRequestV2Tests.swift @@ -11,40 +11,34 @@ import XCTest internal class GetTweetsRequestV2Tests: XCTestCase { public func test() throws { - XCTContext.runActivity(named: "with only required parameters") { _ in - - let tweet = GetTweetsRequestV2(ids: ["123", "abc"]) - - XCTAssertEqual(tweet.method, .get) - XCTAssertEqual(tweet.path, "/2/tweets") - AssertEqualAnyDict(tweet.parameters, ["ids": "123,abc"]) - } - - XCTContext.runActivity(named: "with all parameters") { _ in - - let tweet = GetTweetsRequestV2( - ids: ["1234"], - expansions: [.attachmentsMediaKeys], - mediaFields: [.url, .altText], - placeFields: [.name, .id], - pollFields: [.id], - tweetFields: [.text, .id], - userFields: [.entities] - ) - - AssertEqualAnyDict( - tweet.parameters, - [ - "ids": "1234", - "expansions": "attachments.media_keys", - "media.fields": "alt_text,url", - "place.fields": "id,name", - "poll.fields": "id", - "tweet.fields": "id,text", - "user.fields": "entities", - ] - ) - } + let tweet = GetTweetsRequestV2(ids: ["123", "abc"]) + + XCTAssertEqual(tweet.method, .get) + XCTAssertEqual(tweet.path, "/2/tweets") + AssertEqualAnyDict(tweet.parameters, ["ids": "123,abc"]) + + let tweet2 = GetTweetsRequestV2( + ids: ["1234"], + expansions: [.attachmentsMediaKeys], + mediaFields: [.url, .altText], + placeFields: [.name, .id], + pollFields: [.id], + tweetFields: [.text, .id], + userFields: [.entities] + ) + + AssertEqualAnyDict( + tweet2.parameters, + [ + "ids": "1234", + "expansions": "attachments.media_keys", + "media.fields": "alt_text,url", + "place.fields": "id,name", + "poll.fields": "id", + "tweet.fields": "id,text", + "user.fields": "entities", + ] + ) } deinit { diff --git a/Tests/TwitterAPIKitTests/APIv2/Tweet/PostTweetsRequestV2Tests.swift b/Tests/TwitterAPIKitTests/APIv2/Tweet/PostTweetsRequestV2Tests.swift index 3926484f..00136249 100644 --- a/Tests/TwitterAPIKitTests/APIv2/Tweet/PostTweetsRequestV2Tests.swift +++ b/Tests/TwitterAPIKitTests/APIv2/Tweet/PostTweetsRequestV2Tests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class PostTweetsRequestV2Tests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let request = PostTweetsRequestV2( directMessageDeepLink: "deep_link", diff --git a/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuth2AccessTokenTests.swift b/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuth2AccessTokenTests.swift index 7e0481bb..cf1383ec 100644 --- a/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuth2AccessTokenTests.swift +++ b/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuth2AccessTokenTests.swift @@ -11,74 +11,65 @@ import XCTest @testable import TwitterAPIKit internal class TwitterOAuth2AccessTokenTests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { - try XCTContext.runActivity(named: "without refresh_token") { _ in - - let data = Data( - #""" - { - "scope" : "tweet.write tweet.read", - "token_type" : "bearer", - "expires_in" : 7200, - "access_token" : "" - } - """#.utf8 - ) - guard let token = try TwitterOAuth2AccessToken(jsonData: data) else { - XCTFail("Failed to create test token") - return + let data = Data( + #""" + { + "scope" : "tweet.write tweet.read", + "token_type" : "bearer", + "expires_in" : 7200, + "access_token" : "" } - XCTAssertEqual(token.scope, ["tweet.write", "tweet.read"]) - XCTAssertEqual(token.tokenType, "bearer") - XCTAssertEqual(token.expiresIn, 7_200) - XCTAssertEqual(token.accessToken, "") - XCTAssertNil(token.refreshToken) + """#.utf8 + ) + guard let token = try TwitterOAuth2AccessToken(jsonData: data) else { + XCTFail("Failed to create test token") + return } + XCTAssertEqual(token.scope, ["tweet.write", "tweet.read"]) + XCTAssertEqual(token.tokenType, "bearer") + XCTAssertEqual(token.expiresIn, 7_200) + XCTAssertEqual(token.accessToken, "") + XCTAssertNil(token.refreshToken) - try XCTContext.runActivity(named: "with refresh_token") { _ in - - let data = Data( - #""" - { - "scope" : "tweet.write tweet.read offline.access", - "token_type" : "bearer", - "expires_in" : 7200, - "access_token" : "", - "refresh_token" : "" - } - """#.utf8 - ) - guard let token = try TwitterOAuth2AccessToken(jsonData: data) else { - XCTFail("Failed to create test token") - return + let data2 = Data( + #""" + { + "scope" : "tweet.write tweet.read offline.access", + "token_type" : "bearer", + "expires_in" : 7200, + "access_token" : "", + "refresh_token" : "" } - XCTAssertEqual(token.scope, ["tweet.write", "tweet.read", "offline.access"]) - XCTAssertEqual(token.tokenType, "bearer") - XCTAssertEqual(token.expiresIn, 7_200) - XCTAssertEqual(token.accessToken, "") - XCTAssertEqual(token.refreshToken, "") + """#.utf8 + ) + guard let token2 = try TwitterOAuth2AccessToken(jsonData: data2) else { + XCTFail("Failed to create test token") + return } + XCTAssertEqual(token2.scope, ["tweet.write", "tweet.read", "offline.access"]) + XCTAssertEqual(token2.tokenType, "bearer") + XCTAssertEqual(token2.expiresIn, 7_200) + XCTAssertEqual(token2.accessToken, "") + XCTAssertEqual(token2.refreshToken, "") } public func testError() throws { - try XCTContext.runActivity(named: "Not json") { _ in - XCTAssertThrowsError(try TwitterOAuth2AccessToken.fromResponse(data: Data("aa".utf8))) { error in - guard error is TwitterAPIKitError else { - XCTFail("Expected TwitterAPIKitError") - return - } - XCTAssertTrue(error.isResponseSerializeFailed) + XCTAssertThrowsError(try TwitterOAuth2AccessToken.fromResponse(data: Data("aa".utf8))) { error in + guard let error = error as? TwitterAPIKitError else { + XCTFail("Expected TwitterAPIKitError") + return } + XCTAssertTrue(error.isResponseSerializeFailed) } - try XCTContext.runActivity(named: "valid json but invalid object") { _ in - XCTAssertThrowsError(try TwitterOAuth2AccessToken.fromResponse(data: Data("{}".utf8))) { error in - guard error is TwitterAPIKitError else { - XCTFail("Expected TwitterAPIKitError") - return - } - XCTAssertTrue(error.isResponseSerializeFailed) + XCTAssertThrowsError(try TwitterOAuth2AccessToken.fromResponse(data: Data("{}".utf8))) { error in + guard let error = error as? TwitterAPIKitError else { + XCTFail("Expected TwitterAPIKitError") + return } + XCTAssertTrue(error.isResponseSerializeFailed) } } diff --git a/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuthAccessTokenV1Tests.swift b/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuthAccessTokenV1Tests.swift index 3c28b236..f8786fcb 100644 --- a/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuthAccessTokenV1Tests.swift +++ b/Tests/TwitterAPIKitTests/AuthAPI/TwitterOAuthAccessTokenV1Tests.swift @@ -27,6 +27,7 @@ internal class TwitterOAuthAccessTokenV1Tests: XCTestCase { guard let token = TwitterOAuthAccessTokenV1(queryStringData: data) else { XCTFail("Failed to decode token Response") + return } XCTAssertEqual(token.oauthToken, "token") diff --git a/Tests/TwitterAPIKitTests/Extensions/ConcurrencyTests.swift b/Tests/TwitterAPIKitTests/Extensions/ConcurrencyTests.swift index ea11de9c..3e45f1a4 100644 --- a/Tests/TwitterAPIKitTests/Extensions/ConcurrencyTests.swift +++ b/Tests/TwitterAPIKitTests/Extensions/ConcurrencyTests.swift @@ -14,6 +14,7 @@ import XCTest @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) internal class ConcurrencyTests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() async throws { let mockTask = MockTwitterAPISessionTask(taskIdentifier: 1) @@ -25,8 +26,13 @@ import XCTest task.append(chunk: Data("{\"key\"".utf8)) task.append(chunk: Data(":\"value\"}".utf8)) + guard let url = URL(string: "http://example.com") else { + XCTFail("Invalid Url") + return + } + mockTask.httpResponse = .init( - url: URL(string: "http://example.com"), + url: url, statusCode: 200, httpVersion: "1.1", headerFields: [:] @@ -61,6 +67,7 @@ import XCTest } } + // swiftlint:disable:next function_body_length public func testCancel() async throws { let mockTask = MockTwitterAPISessionTask(taskIdentifier: 1) @@ -84,22 +91,22 @@ import XCTest do { let error = await response.error - XCTAssertTrue(error ? error.isCancelled : false) + XCTAssertTrue(error?.isCancelled ?? false) } do { let error = await responseObj.error - XCTAssertTrue(error ? error.isCancelled : false) + XCTAssertTrue(error?.isCancelled ?? false) } do { let error = await responseDecodable.error - XCTAssertTrue(error ? error.isCancelled : false) + XCTAssertTrue(error?.isCancelled ?? false) } do { let error = await aResponse.error - XCTAssertTrue(error ? error.isCancelled : false) + XCTAssertTrue(error?.isCancelled ?? false) } XCTAssertTrue(mockTask.cancelled) @@ -133,17 +140,28 @@ import XCTest XCTAssertTrue(asyncTask.isCancelled) XCTAssertEqual(rss.count, 4) for res in rss { - XCTAssertTrue(r.error.isCancelled) + guard let error = res.error else { + XCTFail("No Response") + return + } + + XCTAssertTrue(error.isCancelled) } } + // swiftlint:disable:next function_body_length public func testStream() async throws { + guard let url = URL(string: "http://example.com") else { + XCTFail("Invalid Url") + return + } + let mockTask = MockTwitterAPISessionTask( taskIdentifier: 1, currentRequest: nil, originalRequest: nil, httpResponse: .init( - url: URL(string: "http://example.com"), + url: url, statusCode: 200, httpVersion: "1.1", headerFields: [:] @@ -207,13 +225,19 @@ import XCTest XCTAssertTrue(mockTask.cancelled) } - public func testStreamError() async throws { + // swiftlint:disable:next function_body_length + public func testStreamError() async { + guard let exampleUrl = URL(string: "https://example.com") else { + XCTFail("Invalid Example Url") + return + } + let mockTask = MockTwitterAPISessionTask( taskIdentifier: 1, currentRequest: nil, originalRequest: nil, httpResponse: .init( - url: URL(string: "http://example.com"), + url: exampleUrl, statusCode: 200, httpVersion: "1.1", headerFields: [:] @@ -225,7 +249,7 @@ import XCTest .streamResponse( queue: .main ) - .map { resp in resp.compactMap { String(data: $0, encoding: .utf8) } } + .map { resp in resp.map { String(data: $0, encoding: .utf8) } } let asyncTask = Task { var count = 0 for await resp in stream { diff --git a/Tests/TwitterAPIKitTests/Extensions/DataTests.swift b/Tests/TwitterAPIKitTests/Extensions/DataTests.swift index 71df9627..830d17de 100644 --- a/Tests/TwitterAPIKitTests/Extensions/DataTests.swift +++ b/Tests/TwitterAPIKitTests/Extensions/DataTests.swift @@ -12,42 +12,34 @@ import XCTest internal class DataTests: XCTestCase { public func testSerialize() throws { - XCTContext.runActivity(named: "success") { _ in - let data = Data("{\"a\":1}".utf8) - let serialized = data.serialize() - XCTAssertEqual(serialized.success as? [String: Int], ["a": 1]) - } + let data = Data("{\"a\":1}".utf8) + let serialized = data.serialize() + XCTAssertEqual(serialized.success as? [String: Int], ["a": 1]) - XCTContext.runActivity(named: "failure") { _ in - let data = Data() - let serialized = data.serialize() - guard let error = serialized.error else { - XCTFail("Expected error but got nil") - return - } - XCTAssertTrue(error.isResponseSerializeFailed) + let data2 = Data() + let serialized2 = data2.serialize() + guard let error = serialized2.error else { + XCTFail("Expected error but got nil") + return } + XCTAssertTrue(error.isResponseSerializeFailed) } public func testDecode() throws { struct Obj: Decodable { let abc: Int } - XCTContext.runActivity(named: "success") { _ in - let data = Data("{\"abc\":1}".utf8) - let serialized = data.decode(Obj.self, decoder: JSONDecoder()) - XCTAssertEqual(serialized.success?.abc, 1) - } + let data = Data("{\"abc\":1}".utf8) + let serialized = data.decode(Obj.self, decoder: JSONDecoder()) + XCTAssertEqual(serialized.success?.abc, 1) - XCTContext.runActivity(named: "failure") { _ in - let data = Data() - let serialized = data.decode(Obj.self, decoder: JSONDecoder()) - guard let error = serialized.error else { - XCTFail("Expected error but got nil") - return - } - XCTAssertTrue(error.isResponseSerializeFailed) + let data2 = Data() + let serialized2 = data2.decode(Obj.self, decoder: JSONDecoder()) + guard let error = serialized2.error else { + XCTFail("Expected error but got nil") + return } + XCTAssertTrue(error.isResponseSerializeFailed) } deinit { diff --git a/Tests/TwitterAPIKitTests/Helper/CombinationsSequence.swift b/Tests/TwitterAPIKitTests/Helper/CombinationsSequence.swift index f9ab6fac..ccf27258 100644 --- a/Tests/TwitterAPIKitTests/Helper/CombinationsSequence.swift +++ b/Tests/TwitterAPIKitTests/Helper/CombinationsSequence.swift @@ -59,7 +59,7 @@ public struct CombinationsSequence { return 1 << total } - internal func binomial(total: Int, size: Int) -> Int { + func binomial(total: Int, size: Int) -> Int { switch size { case total, 0: 1 case total...: 0 @@ -124,7 +124,7 @@ extension CombinationsSequence: Sequence { internal mutating func advance() { // Advances `kRange` by incrementing its `lowerBound` until the range is // empty, when iteration is finished. - internal func advanceKRange() { + func advanceKRange() { if kRange.lowerBound < kRange.upperBound { let advancedLowerBound = kRange.lowerBound + 1 kRange = advancedLowerBound ..< kRange.upperBound diff --git a/Tests/TwitterAPIKitTests/Mock/MockURLProtocol.swift b/Tests/TwitterAPIKitTests/Mock/MockURLProtocol.swift index d5bbbbb0..bc0b31a2 100644 --- a/Tests/TwitterAPIKitTests/Mock/MockURLProtocol.swift +++ b/Tests/TwitterAPIKitTests/Mock/MockURLProtocol.swift @@ -8,6 +8,17 @@ import Foundation +#if canImport(FoundationNetworking) +import FoundationNetworking +#endif + +internal func convertOptionalHttpUrlResponseToHttpUrlResponse( + _ response: HTTPURLResponse? +) -> HTTPURLResponse { + // swiftlint:disable:next force_unwrapping + return response! +} + internal class MockURLProtocol: URLProtocol { public static var requestHandler: ((URLRequest) throws -> (HTTPURLResponse, Data?))? public static var requestAssert: ((URLRequest) throws -> Void)? @@ -26,7 +37,7 @@ internal class MockURLProtocol: URLProtocol { } override public func startLoading() { - guard let url = request.url else { + guard request.url != nil else { client?.urlProtocol(self, didFailWithError: URLError(.badURL)) return } @@ -36,12 +47,12 @@ internal class MockURLProtocol: URLProtocol { throw URLError(.badURL) } return ( - HTTPURLResponse( + convertOptionalHttpUrlResponseToHttpUrlResponse(HTTPURLResponse( url: requestURL, statusCode: 200, httpVersion: "2.0", headerFields: nil - ) ?? HTTPURLResponse(), + )), Data() ) } diff --git a/Tests/TwitterAPIKitTests/OAuthHelperTests.swift b/Tests/TwitterAPIKitTests/OAuthHelperTests.swift index 123cd03b..8578ac47 100644 --- a/Tests/TwitterAPIKitTests/OAuthHelperTests.swift +++ b/Tests/TwitterAPIKitTests/OAuthHelperTests.swift @@ -34,15 +34,13 @@ internal class OAuthHelperTests: XCTestCase { oauthTimestamp: "1318622958", oauthNonce: "kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg" ) - let expectedHeader = #""" - OAuth oauth_consumer_key="xvz1evFS4wEEPTGEFPHBog", \ - oauth_nonce="kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg", \ - oauth_signature="hCtSmYh%2BiHYCEqBWrE7C7hYmtUk%3D", \ - oauth_signature_method="HMAC-SHA1", \ - oauth_timestamp="1318622958", \ - oauth_token="370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb", \ - oauth_version="1.0" - """# + let expectedHeader = "OAuth oauth_consumer_key=\"xvz1evFS4wEEPTGEFPHBog\", " + + "oauth_nonce=\"kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg\", " + + "oauth_signature=\"hCtSmYh%2BiHYCEqBWrE7C7hYmtUk%3D\", " + + "oauth_signature_method=\"HMAC-SHA1\", " + + "oauth_timestamp=\"1318622958\", " + + "oauth_token=\"370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb\", " + + "oauth_version=\"1.0\"" XCTAssertEqual(header, expectedHeader) } diff --git a/Tests/TwitterAPIKitTests/SessionTask/TwitterAPIFailedTaskTests.swift b/Tests/TwitterAPIKitTests/SessionTask/TwitterAPIFailedTaskTests.swift index 560336a7..cfee0c2c 100644 --- a/Tests/TwitterAPIKitTests/SessionTask/TwitterAPIFailedTaskTests.swift +++ b/Tests/TwitterAPIKitTests/SessionTask/TwitterAPIFailedTaskTests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class TwitterAPIFailedTaskTests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let task = TwitterAPIFailedTask(.responseFailed(reason: .invalidResponse(error: nil))) diff --git a/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedJSONTaskTests.swift b/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedJSONTaskTests.swift index e48e664c..7bef60ec 100644 --- a/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedJSONTaskTests.swift +++ b/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedJSONTaskTests.swift @@ -18,6 +18,7 @@ internal class TwitterAPISessionDelegatedJSONTaskTests: XCTestCase { // swiftlint:disable:next force_unwrapping internal let testURL = URL(string: "http://example.com")! + // swiftlint:disable:next function_body_length public func testSuccess() throws { let mockTask = MockTwitterAPISessionTask(taskIdentifier: 1) @@ -89,6 +90,7 @@ internal class TwitterAPISessionDelegatedJSONTaskTests: XCTestCase { wait(for: [exp], timeout: 10) } + // swiftlint:disable:next function_body_length public func testInvalidStatusCode() throws { let mockTask = MockTwitterAPISessionTask(taskIdentifier: 1) @@ -140,6 +142,7 @@ internal class TwitterAPISessionDelegatedJSONTaskTests: XCTestCase { wait(for: [exp], timeout: 10) } + // swiftlint:disable:next function_body_length public func testCompleteWithError() throws { let mockTask = MockTwitterAPISessionTask(taskIdentifier: 1) @@ -183,6 +186,7 @@ internal class TwitterAPISessionDelegatedJSONTaskTests: XCTestCase { wait(for: [exp], timeout: 10) } + // swiftlint:disable:next function_body_length public func testCancel() throws { let mockTask = MockTwitterAPISessionTask(taskIdentifier: 1) diff --git a/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedStreamTaskTests.swift b/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedStreamTaskTests.swift index 98e1cd4b..f67ecb8b 100644 --- a/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedStreamTaskTests.swift +++ b/Tests/TwitterAPIKitTests/SessionTask/TwitterAPISessionDelegatedStreamTaskTests.swift @@ -50,6 +50,7 @@ internal class TwitterAPISessionDelegatedStreamTaskTests: XCTestCase { XCTAssertEqual(task.httpResponse, resp) } + // swiftlint:disable:next function_body_length public func test() throws { guard let responseURL = URL(string: "https://example.com"), let response = HTTPURLResponse( @@ -124,6 +125,7 @@ internal class TwitterAPISessionDelegatedStreamTaskTests: XCTestCase { XCTAssertEqual(count, 4) } + // swiftlint:disable:next function_body_length public func testInvalidStatusCode() throws { guard let responseURL = URL(string: "https://example.com"), let response = HTTPURLResponse( @@ -153,11 +155,12 @@ internal class TwitterAPISessionDelegatedStreamTaskTests: XCTestCase { DispatchQueue.main.async { task.append( chunk: Data( + ( "{\"detail\":\"Authenticating with OAuth 1.0a User Context is forbidden for this endpoint. " + "Supported authentication types are [OAuth 2.0 Application-Only].\",\"title\":\"Unsupported " + "Authentication\",\"status\":403,\"type\":\"https://api.twitter.com/2/problems/unsupported-" + "authentication\"}" - .utf8 + ).utf8 ) ) task.complete(error: nil) @@ -208,6 +211,7 @@ internal class TwitterAPISessionDelegatedStreamTaskTests: XCTestCase { XCTAssertEqual(count, 1) } + // swiftlint:disable:next function_body_length public func testNilResponse() throws { let mockTask = MockTwitterAPISessionTask( taskIdentifier: 1, @@ -254,6 +258,7 @@ internal class TwitterAPISessionDelegatedStreamTaskTests: XCTestCase { XCTAssertEqual(count, 1) } + // swiftlint:disable:next function_body_length public func testError() throws { let mockTask = MockTwitterAPISessionTask( taskIdentifier: 1, diff --git a/Tests/TwitterAPIKitTests/TwitterAPIClientTests.swift b/Tests/TwitterAPIKitTests/TwitterAPIClientTests.swift index 783442ae..51d0ab78 100644 --- a/Tests/TwitterAPIKitTests/TwitterAPIClientTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAPIClientTests.swift @@ -22,6 +22,7 @@ internal class TwitterAPIClientTests: XCTestCase { XCTAssertEqual(dateV1, dateV2) } + // swiftlint:disable:next function_body_length public func testRefreshToken() throws { let config = URLSessionConfiguration.default config.protocolClasses = [MockURLProtocol.self] @@ -92,6 +93,7 @@ internal class TwitterAPIClientTests: XCTestCase { } } + // swiftlint:disable:next function_body_length public func testRefreshTokenForceRefresh() throws { let config = URLSessionConfiguration.default config.protocolClasses = [MockURLProtocol.self] @@ -230,8 +232,10 @@ internal class TwitterAPIClientTests: XCTestCase { #if compiler(>=5.5.2) && canImport(_Concurrency) + // swiftlint:disable function_body_length @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) public func testRefreshTokenAsync() async throws { + // swiftlint:enable function_body_length let config = URLSessionConfiguration.default config.protocolClasses = [MockURLProtocol.self] diff --git a/Tests/TwitterAPIKitTests/TwitterAPIErrorResponseTests.swift b/Tests/TwitterAPIKitTests/TwitterAPIErrorResponseTests.swift index 022cdf56..b339a65a 100644 --- a/Tests/TwitterAPIKitTests/TwitterAPIErrorResponseTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAPIErrorResponseTests.swift @@ -10,188 +10,165 @@ import TwitterAPIKit import XCTest internal class TwitterAPIErrorResponseTests: XCTestCase { + // swiftlint:disable:next function_body_length public func testTwitterAPIErrorResponseV1() throws { - XCTContext.runActivity(named: "") { _ in - - let v1Response = TwitterAPIErrorResponseV1(message: "_message_", code: 100, errors: []) - XCTAssertEqual(v1Response.message, "_message_") - XCTAssertEqual(v1Response.code, 100) - XCTAssertEqual(v1Response.errors, [TwitterAPIErrorResponseV1]()) - XCTAssertTrue(v1Response.contains(code: 100)) - XCTAssertFalse(v1Response.contains(code: 1)) - } - - XCTContext.runActivity(named: "from obj") { _ in - - let obj: [String: Any] = [ - "errors": [ - [ - "message": "message1", - "code": 1, - ], - [ - "message": "message2", - "code": 2, - ], + let v1Response = TwitterAPIErrorResponseV1(message: "_message_", code: 100, errors: []) + XCTAssertEqual(v1Response.message, "_message_") + XCTAssertEqual(v1Response.code, 100) + XCTAssertEqual(v1Response.errors, [TwitterAPIErrorResponseV1]()) + XCTAssertTrue(v1Response.contains(code: 100)) + XCTAssertFalse(v1Response.contains(code: 1)) + + let obj: [String: Any] = [ + "errors": [ + [ + "message": "message1", + "code": 1, ], - ] + [ + "message": "message2", + "code": 2, + ], + ], + ] - guard let v1Response = TwitterAPIErrorResponseV1(obj: obj) else { - return XCTFail("Failed to parse response") - } + guard let v1Response2 = TwitterAPIErrorResponseV1(obj: obj) else { + XCTFail("Failed to parse response") + return + } - XCTAssertEqual(v1Response.message, "message1") - XCTAssertEqual(v1Response.code, 1) - XCTAssertEqual( - v1Response.errors, - [ + XCTAssertEqual(v1Response2.message, "message1") + XCTAssertEqual(v1Response2.code, 1) + XCTAssertEqual( + v1Response2.errors, + [ + .init(message: "message1", code: 1, errors: []), + .init(message: "message2", code: 2, errors: []), + ] + ) + XCTAssertTrue(v1Response2.contains(code: 1)) + XCTAssertFalse(v1Response2.contains(code: 100)) + + XCTAssertEqual( + v1Response2, + .init( + message: "message1", + code: 1, + errors: [ .init(message: "message1", code: 1, errors: []), .init(message: "message2", code: 2, errors: []), ] ) - XCTAssertTrue(v1Response.contains(code: 1)) - XCTAssertFalse(v1Response.contains(code: 100)) - - XCTAssertEqual( - v1Response, - .init( - message: "message1", - code: 1, - errors: [ - .init(message: "message1", code: 1, errors: []), - .init(message: "message2", code: 2, errors: []), - ] - ) - ) - } + ) - XCTContext.runActivity(named: "Invalid") { _ in - XCTAssertNil(TwitterAPIErrorResponseV1(obj: [:])) - } + XCTAssertNil(TwitterAPIErrorResponseV1(obj: [:])) } + // swiftlint:disable:next function_body_length public func testTwitterAPIErrorResponseV2() throws { - XCTContext.runActivity(named: "") { _ in - - let v2Response = TwitterAPIErrorResponseV2(title: "t", detail: "d", type: "ty", errors: []) - XCTAssertEqual(v2Response.title, "t") - XCTAssertEqual(v2Response.detail, "d") - XCTAssertEqual(v2Response.type, "ty") - XCTAssertEqual(v2Response.errors, []) + let v2Response = TwitterAPIErrorResponseV2(title: "t", detail: "d", type: "ty", errors: []) + XCTAssertEqual(v2Response.title, "t") + XCTAssertEqual(v2Response.detail, "d") + XCTAssertEqual(v2Response.type, "ty") + XCTAssertEqual(v2Response.errors, []) + + let obj: [String: Any] = [ + "title": "_title_", + "detail": "_detail_", + "type": "_type_", + "errors": [ + ["message": "_message_", "parameters": ["param": ["b"]]], + ], + ] + guard let v2Response2 = TwitterAPIErrorResponseV2(obj: obj) else { + XCTFail("Failed to parse response") + return } - XCTContext.runActivity(named: "from obj") { _ in - let obj: [String: Any] = [ - "title": "_title_", - "detail": "_detail_", - "type": "_type_", - "errors": [ - ["message": "_message_", "parameters": ["param": ["b"]]], - - ], - ] - guard let v2Response = TwitterAPIErrorResponseV2(obj: obj) else { - return XCTFail("Failed to parse response") - } - - XCTAssertEqual(v2Response.title, "_title_") - XCTAssertEqual(v2Response.detail, "_detail_") - XCTAssertEqual(v2Response.type, "_type_") - XCTAssertEqual(v2Response.errors.first?.message, "_message_") - XCTAssertEqual(v2Response.errors.first?.parameters["param"], ["b"]) - - XCTAssertEqual( - v2Response, - TwitterAPIErrorResponseV2( - title: "_title_", - detail: "_detail_", - type: "_type_", - errors: [.init(message: "_message_", parameters: ["param": ["b"]])] - ) + XCTAssertEqual(v2Response2.title, "_title_") + XCTAssertEqual(v2Response2.detail, "_detail_") + XCTAssertEqual(v2Response2.type, "_type_") + XCTAssertEqual(v2Response2.errors.first?.message, "_message_") + XCTAssertEqual(v2Response2.errors.first?.parameters["param"], ["b"]) + + XCTAssertEqual( + v2Response2, + TwitterAPIErrorResponseV2( + title: "_title_", + detail: "_detail_", + type: "_type_", + errors: [.init(message: "_message_", parameters: ["param": ["b"]])] ) - } + ) - XCTContext.runActivity(named: "Invalid") { _ in - XCTAssertNil(TwitterAPIErrorResponseV2(obj: [:])) - } + XCTAssertNil(TwitterAPIErrorResponseV2(obj: [:])) } + // swiftlint:disable:next function_body_length public func testTwitterAPIErrorResponse() throws { - try XCTContext.runActivity(named: "V1") { _ in - let obj: [String: Any] = [ - "errors": [ - [ - "message": "message1", - "code": 1, - ], - [ - "message": "message2", - "code": 2, - ], + let obj: [String: Any] = [ + "errors": [ + [ + "message": "message1", + "code": 1, ], - ] - - let data = try JSONSerialization.data(withJSONObject: obj, options: []) - let error = TwitterAPIErrorResponse(data: data) - - XCTAssertTrue(error.isV1) - XCTAssertNotNil(error.v1) - - XCTAssertFalse(error.isV2) - XCTAssertNil(error.v2) - - XCTAssertFalse(error.isUnknown) - XCTAssertNil(error.unknownData) - - XCTAssertEqual(error.message, "message1") - XCTAssertEqual(error.code, 1) - } - - try XCTContext.runActivity(named: "v2") { _ in - let obj: [String: Any] = [ - "title": "_title_", - "detail": "_detail_", - "type": "_type_", - "errors": [ - ["message": "_message_", "parameters": ["param": ["b"]]], - + [ + "message": "message2", + "code": 2, ], - ] - let data = try JSONSerialization.data(withJSONObject: obj, options: []) - let error = TwitterAPIErrorResponse(data: data) - - XCTAssertFalse(error.isV1) - XCTAssertNil(error.v1) - - XCTAssertTrue(error.isV2) - XCTAssertNotNil(error.v2) - - XCTAssertFalse(error.isUnknown) - XCTAssertNil(error.unknownData) - - XCTAssertEqual(error.message, "_detail_") - XCTAssertNil(error.code) - } - - XCTContext.runActivity(named: "unknown") { _ in - - XCTContext.runActivity(named: "empty") { _ in - let error = TwitterAPIErrorResponse(data: Data()) - XCTAssertEqual(error, .unknown(Data())) - XCTAssertTrue(error.isUnknown) - XCTAssertEqual(error.message, "") - XCTAssertNil(error.code) - } - - XCTContext.runActivity(named: "invalid") { _ in - let data = Data("{}") - let error = TwitterAPIErrorResponse(data: data) - XCTAssertEqual(error, .unknown(data)) - XCTAssertTrue(error.isUnknown) - XCTAssertEqual(error.unknownData, data) - XCTAssertEqual(error.message, "{}") - } - } + ], + ] + + let data = try JSONSerialization.data(withJSONObject: obj, options: []) + let error = TwitterAPIErrorResponse(data: data) + + XCTAssertTrue(error.isVersion1) + XCTAssertNotNil(error.version1) + + XCTAssertFalse(error.isVersion2) + XCTAssertNil(error.version2) + + XCTAssertFalse(error.isUnknown) + XCTAssertNil(error.unknownData) + + XCTAssertEqual(error.message, "message1") + XCTAssertEqual(error.code, 1) + + let obj2: [String: Any] = [ + "title": "_title_", + "detail": "_detail_", + "type": "_type_", + "errors": [ + ["message": "_message_", "parameters": ["param": ["b"]]], + ], + ] + let data2 = try JSONSerialization.data(withJSONObject: obj2, options: []) + let error2 = TwitterAPIErrorResponse(data: data2) + + XCTAssertFalse(error2.isVersion1) + XCTAssertNil(error2.version1) + + XCTAssertTrue(error2.isVersion2) + XCTAssertNotNil(error2.version2) + + XCTAssertFalse(error2.isUnknown) + XCTAssertNil(error2.unknownData) + + XCTAssertEqual(error2.message, "_detail_") + XCTAssertNil(error2.code) + + let error3 = TwitterAPIErrorResponse(data: Data()) + XCTAssertEqual(error3, .unknown(Data())) + XCTAssertTrue(error3.isUnknown) + XCTAssertEqual(error3.message, "") + XCTAssertNil(error3.code) + + let data4 = Data("{}".utf8) + let error4 = TwitterAPIErrorResponse(data: data4) + XCTAssertEqual(error4, .unknown(data4)) + XCTAssertTrue(error4.isUnknown) + XCTAssertEqual(error4.unknownData, data4) + XCTAssertEqual(error4.message, "{}") } deinit { diff --git a/Tests/TwitterAPIKitTests/TwitterAPIKitErrorTests.swift b/Tests/TwitterAPIKitTests/TwitterAPIKitErrorTests.swift index 53b31ba3..713ded6b 100644 --- a/Tests/TwitterAPIKitTests/TwitterAPIKitErrorTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAPIKitErrorTests.swift @@ -11,18 +11,14 @@ import XCTest internal class TwitterAPIKitErrorTests: XCTestCase { public func testInit() throws { - XCTContext.runActivity(named: "unknown") { _ in + let error = TwitterAPIKitError(error: NSError(domain: "", code: 0, userInfo: nil)) + XCTAssertTrue(error.isUnkonwn) - let error = TwitterAPIKitError(error: NSError(domain: "", code: 0, userInfo: nil)) - XCTAssertTrue(error.isUnkonwn) - } - XCTContext.runActivity(named: "TwitterAPIKitError") { _ in - let error = TwitterAPIKitError( - error: TwitterAPIKitError.responseFailed(reason: .invalidResponse(error: nil)) - ) - XCTAssertFalse(error.isUnkonwn) - XCTAssertTrue(error.isResponseFailed) - } + let error2 = TwitterAPIKitError( + error: TwitterAPIKitError.responseFailed(reason: .invalidResponse(error: nil)) + ) + XCTAssertFalse(error2.isUnkonwn) + XCTAssertTrue(error2.isResponseFailed) } public func testRequestFailed() throws { diff --git a/Tests/TwitterAPIKitTests/TwitterAPIRequestTests.swift b/Tests/TwitterAPIKitTests/TwitterAPIRequestTests.swift index 6b0edaab..f7c70795 100644 --- a/Tests/TwitterAPIKitTests/TwitterAPIRequestTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAPIRequestTests.swift @@ -10,7 +10,9 @@ import XCTest @testable import TwitterAPIKit +// swiftlint:disable force_cast force_unwrapping internal class TwitterAPIRequestTests: XCTestCase { + private struct MockTwitterAPIRequest: TwitterAPIRequest { var method: HTTPMethod = .get var path: String = "/mock" @@ -28,124 +30,93 @@ internal class TwitterAPIRequestTests: XCTestCase { var bodyContentType: BodyContentType = .wwwFormUrlEncoded } - private var env: TwitterAPIEnvironment - - override public init() { - let apiUrl = URL(string: "https://api.example.com") - let uploadUrl = URL(string: "https://upload.example.com") - - guard let apiUrl, let uploadUrl else { - XCTFail("apiUrl / uploadUrl isn't valid") - } - - env = .init( - apiURL: apiUrl, - uploadURL: uploadUrl - ) - } + private let env = TwitterAPIEnvironment( + apiURL: .init(string: "https://api.example.com")!, + uploadURL: .init(string: "https://upload.example.com")! + ) public func testRequestURL() throws { - XCTContext.runActivity(named: "api") { _ in - let req = MockTwitterAPIRequest(parameters: ["key": "value"], baseURLType: .api) - XCTAssertEqual(req.requestURL(for: env).absoluteString, "https://api.example.com/mock") - } + let req = MockTwitterAPIRequest(parameters: ["key": "value"], baseURLType: .api) + XCTAssertEqual(req.requestURL(for: env).absoluteString, "https://api.example.com/mock") - XCTContext.runActivity(named: "upload") { _ in - let req = MockTwitterAPIRequest(parameters: ["key": "value"], baseURLType: .upload) - XCTAssertEqual(req.requestURL(for: env).absoluteString, "https://upload.example.com/mock") - } + let req2 = MockTwitterAPIRequest(parameters: ["key": "value"], baseURLType: .upload) + XCTAssertEqual(req2.requestURL(for: env).absoluteString, "https://upload.example.com/mock") } public func testParameterForOAuth() throws { - XCTContext.runActivity(named: "wwwFormUrlEncoded") { _ in - let req = MockTwitterAPIRequest(parameters: ["key": "value"], bodyContentType: .wwwFormUrlEncoded) - XCTAssertEqual(req.parameterForOAuth as? [String: String], ["key": "value"]) - } + let req = MockTwitterAPIRequest(parameters: ["key": "value"], bodyContentType: .wwwFormUrlEncoded) + XCTAssertEqual(req.parameterForOAuth as? [String: String], ["key": "value"]) - XCTContext.runActivity(named: "json") { _ in - let req = MockTwitterAPIRequest(parameters: ["key": "value"], bodyContentType: .json) - XCTAssertEqual(req.parameterForOAuth as? [String: String], [:]) - } + let req2 = MockTwitterAPIRequest(parameters: ["key": "value"], bodyContentType: .json) + XCTAssertEqual(req2.parameterForOAuth as? [String: String], [:]) - XCTContext.runActivity(named: "multipartFormData") { _ in - let req = MockTwitterAPIRequest(parameters: ["key": "value"], bodyContentType: .multipartFormData) - XCTAssertEqual(req.parameterForOAuth as? [String: String], [:]) - } + let req3 = MockTwitterAPIRequest(parameters: ["key": "value"], bodyContentType: .multipartFormData) + XCTAssertEqual(req3.parameterForOAuth as? [String: String], [:]) } + // swiftlint:disable:next function_body_length public func testParameterByMethods() throws { // 🥓 = F0 9F A5 93 - try XCTContext.runActivity(named: "GET") { _ in - let req = MockTwitterAPIRequest( - method: .get, - parameters: ["key": "value,🥓"] - ) + let req = MockTwitterAPIRequest( + method: .get, + parameters: ["key": "value,🥓"] + ) - XCTAssertEqual(req.queryParameters as? [String: String], ["key": "value,🥓"]) - XCTAssertEqual(req.bodyParameters as? [String: String], [:]) + XCTAssertEqual(req.queryParameters as? [String: String], ["key": "value,🥓"]) + XCTAssertEqual(req.bodyParameters as? [String: String], [:]) - let urlReq = try req.buildRequest(environment: env) + let urlReq = try req.buildRequest(environment: env) - XCTAssertEqual(urlReq.httpMethod, "GET") - XCTAssertEqual(urlReq.url?.query, "key=value%2C%F0%9F%A5%93") - XCTAssertNil(urlReq.httpBody) - } + XCTAssertEqual(urlReq.httpMethod, "GET") + XCTAssertEqual(urlReq.url?.query, "key=value%2C%F0%9F%A5%93") + XCTAssertNil(urlReq.httpBody) - try XCTContext.runActivity(named: "POST") { _ in - let req = MockTwitterAPIRequest( - method: .post, - parameters: ["key": "value,🥓"] - ) + let req2 = MockTwitterAPIRequest( + method: .post, + parameters: ["key": "value,🥓"] + ) - XCTAssertEqual(req.queryParameters as? [String: String], [:]) - XCTAssertEqual(req.bodyParameters as? [String: String], ["key": "value,🥓"]) + XCTAssertEqual(req2.queryParameters as! [String: String], [:]) + XCTAssertEqual(req2.bodyParameters as! [String: String], ["key": "value,🥓"]) - let urlReq = try req.buildRequest(environment: env) + let urlReq2 = try req2.buildRequest(environment: env) - XCTAssertEqual(urlReq.httpMethod, "POST") - XCTAssertNil(urlReq.url?.query) - let httpBody = try XCTUnwrap(urlReq.httpBody) - let bodyString = try XCTUnwrap(String(data: httpBody, encoding: .utf8)) - XCTAssertEqual(bodyString, "key=value%2C%F0%9F%A5%93") - } + XCTAssertEqual(urlReq2.httpMethod, "POST") + XCTAssertNil(urlReq2.url?.query) + XCTAssertEqual(String(data: urlReq2.httpBody!, encoding: .utf8)!, "key=value%2C%F0%9F%A5%93") - try XCTContext.runActivity(named: "PUT") { _ in - let req = MockTwitterAPIRequest( - method: .put, - parameters: ["key": "value,🥓"] - ) + let req3 = MockTwitterAPIRequest( + method: .put, + parameters: ["key": "value,🥓"] + ) - XCTAssertEqual(req.queryParameters as? [String: String], [:]) - XCTAssertEqual(req.bodyParameters as? [String: String], ["key": "value,🥓"]) + XCTAssertEqual(req3.queryParameters as! [String: String], [:]) + XCTAssertEqual(req3.bodyParameters as! [String: String], ["key": "value,🥓"]) - let urlReq = try req.buildRequest(environment: env) + let urlReq3 = try req3.buildRequest(environment: env) - XCTAssertEqual(urlReq.httpMethod, "PUT") - XCTAssertNil(urlReq.url?.query) - let httpBody = try XCTUnwrap(urlReq.httpBody) - let bodyString = try XCTUnwrap(String(data: httpBody, encoding: .utf8)) - XCTAssertEqual(bodyString, "key=value%2C%F0%9F%A5%93") - } + XCTAssertEqual(urlReq3.httpMethod, "PUT") + XCTAssertNil(urlReq3.url?.query) + XCTAssertEqual(String(data: urlReq3.httpBody!, encoding: .utf8)!, "key=value%2C%F0%9F%A5%93") - try XCTContext.runActivity(named: "DELETE") { _ in - let req = MockTwitterAPIRequest( - method: .delete, - parameters: ["key": "value,🥓"] - ) + let req4 = MockTwitterAPIRequest( + method: .delete, + parameters: ["key": "value,🥓"] + ) - XCTAssertEqual(req.queryParameters as? [String: String], ["key": "value,🥓"]) - XCTAssertEqual(req.bodyParameters as? [String: String], [:]) + XCTAssertEqual(req4.queryParameters as! [String: String], ["key": "value,🥓"]) + XCTAssertEqual(req4.bodyParameters as! [String: String], [:]) - let urlReq = try req.buildRequest(environment: env) + let urlReq4 = try req4.buildRequest(environment: env) - XCTAssertEqual(urlReq.httpMethod, "DELETE") - XCTAssertEqual(urlReq.url?.query, "key=value%2C%F0%9F%A5%93") - XCTAssertNil(urlReq.httpBody) - } + XCTAssertEqual(urlReq4.httpMethod, "DELETE") + XCTAssertEqual(urlReq4.url?.query, "key=value%2C%F0%9F%A5%93") + XCTAssertNil(urlReq4.httpBody) } public func testURLQueryPercentEncode() throws { + let req = MockTwitterAPIRequest( method: .get, parameters: [ @@ -169,170 +140,131 @@ internal class TwitterAPIRequestTests: XCTestCase { bodyParameters: ["body": "あ"] ) - XCTAssertEqual(req.parameters as? [String: String], [:]) - XCTAssertEqual(req.queryParameters as? [String: String], ["key": "value,🥓"]) - XCTAssertEqual(req.bodyParameters as? [String: String], ["body": "あ"]) + XCTAssertEqual(req.parameters as! [String: String], [:]) + XCTAssertEqual(req.queryParameters as! [String: String], ["key": "value,🥓"]) + XCTAssertEqual(req.bodyParameters as! [String: String], ["body": "あ"]) let urlReq = try req.buildRequest(environment: env) XCTAssertEqual(urlReq.httpMethod, "POST") XCTAssertEqual(urlReq.url?.query, "key=value%2C%F0%9F%A5%93") - let httpBody = try XCTUnwrap(urlReq.httpBody) - let bodyString = try XCTUnwrap(String(data: httpBody, encoding: .utf8)) - XCTAssertEqual(bodyString, "body=%E3%81%82") - } - - public func testBodyContentType() throws { - try testWWWFormUrlEncoded() - try testMultipartFormData() - try testJSON() + XCTAssertEqual(String(data: urlReq.httpBody!, encoding: .utf8)!, "body=%E3%81%82") } - public func testWWWFormUrlEncoded() throws { - try XCTContext.runActivity(named: "wwwFormUrlEncoded") { _ in - let req = try MockTwitterAPIRequest( - method: .post, - parameters: ["key": "value,🥓"], - bodyContentType: .wwwFormUrlEncoded - ).buildRequest(environment: env) - - let httpBody = try XCTUnwrap(req.httpBody) - let body = try XCTUnwrap(String(data: httpBody, encoding: .utf8)) - XCTAssertEqual(body, "key=value%2C%F0%9F%A5%93") + public func testFormUrlEncodedBodyContentType() throws { + let req = try MockTwitterAPIRequest( + method: .post, + parameters: ["key": "value,🥓"], + bodyContentType: .wwwFormUrlEncoded + ).buildRequest(environment: env) + + guard let httpBody = req.httpBody, + let body = String(data: httpBody, encoding: .utf8) else { + XCTFail("Failed to get HTTP body") + return } - } - public func testMultipartFormData() throws { - try XCTContext.runActivity(named: "multipartFormData") { _ in - let req = try MockTwitterAPIRequest( - method: .post, - parameters: [ - "a-value": MultipartFormDataPart.value(name: "a", value: "value"), - "b-data": MultipartFormDataPart.data( - name: "b", - value: Data("ab".utf8), - filename: "hoge.txt", - mimeType: "plain/text" - ), - ], - bodyContentType: .multipartFormData - ).buildRequest(environment: env) - - guard let contentType = req.allHTTPHeaderFields?["Content-Type"] else { - XCTFail("Content-Type header not found") - return - } - XCTAssertTrue(contentType.hasPrefix("multipart/form-data; boundary=TwitterAPIKit-")) + XCTAssertEqual(body, "key=value%2C%F0%9F%A5%93") + } - let boundary = contentType.replacingOccurrences( - of: "multipart/form-data; boundary=", with: "" - ) + // swiftlint:disable:next function_body_length + public func testMultipartFormDataBodyContentType() throws { + let req = try MockTwitterAPIRequest( + method: .post, + parameters: [ + "a-value": MultipartFormDataPart.value(name: "a", value: "value"), + "b-data": MultipartFormDataPart.data( + name: "b", + value: Data("ab".utf8), + filename: "test.txt", + mimeType: "plain/text" + ), + ], + bodyContentType: .multipartFormData + ).buildRequest(environment: env) + + guard let contentType = req.allHTTPHeaderFields?["Content-Type"], + contentType.hasPrefix("multipart/form-data; boundary=TwitterAPIKit-"), + let httpBody = req.httpBody, + let body = String(data: httpBody, encoding: .utf8) else { + XCTFail("Failed to get content type or body") + return + } - guard let httpBody = req.httpBody, - let body = String(data: httpBody, encoding: .utf8) - else { - XCTFail("Failed to get HTTP body or decode as UTF-8") - return - } + let boundary = contentType.replacingOccurrences( + of: "multipart/form-data; boundary=", + with: "" + ) - let expect = """ - --\(boundary)\r\n - Content-Disposition: form-data; name="a"\r\n - \r\n - value\r\n - --\(boundary)\r\n - Content-Disposition: form-data; name="b"; filename="hoge.txt"\r\n - Content-Type: plain/text\r\n - \r\n - ab\r\n - --\(boundary)--\r\n - """ - - XCTAssertEqual(body, expect) - try testInvalidMultipartFormData() - } + let expect = "--\(boundary)\r\n" + + "Content-Disposition: form-data; name=\"a\"\r\n" + + "\r\n" + + "value\r\n" + + "--\(boundary)\r\n" + + "Content-Disposition: form-data; name=\"b\"; filename=\"test.txt\"\r\n" + + "Content-Type: plain/text\r\n" + + "\r\n" + + "ab\r\n" + + "--\(boundary)--\r\n" + + XCTAssertEqual(body, expect) } - public func testInvalidMultipartFormData() throws { - try XCTContext.runActivity(named: "Invalid parameter") { _ in - XCTAssertThrowsError( - try MockTwitterAPIRequest( - method: .post, - parameters: ["key": "value,🥓"], - bodyContentType: .multipartFormData - ).buildRequest(environment: env) - ) { error in - XCTAssertTrue(error is TwitterAPIKitError) - } - } - } - public func testJSON() throws { - try XCTContext.runActivity(named: "json") { _ in - let req = try MockTwitterAPIRequest( + public func testInvalidMultipartFormData() throws { + XCTAssertThrowsError( + try MockTwitterAPIRequest( method: .post, parameters: ["key": "value,🥓"], - bodyContentType: .json + bodyContentType: .multipartFormData ).buildRequest(environment: env) + ) { error in + XCTAssertTrue(error is TwitterAPIKitError, "Error should be TwitterAPIKitError") + } + } - let httpBody = try XCTUnwrap(req.httpBody) - let body = try JSONSerialization.jsonObject(with: httpBody, options: []) - XCTAssertEqual(body as? [String: String], ["key": "value,🥓"]) + public func testJsonBodyContentType() throws { + let req = try MockTwitterAPIRequest( + method: .post, + parameters: ["key": "value,🥓"], + bodyContentType: .json + ).buildRequest(environment: env) - try testInvalidJSON() - try testInvalidJSONValue() + guard let httpBody = req.httpBody else { + XCTFail("HTTP body should not be nil") + return } - } - public func testInvalidJSON() throws { - try XCTContext.runActivity(named: "Invalid") { _ in - XCTAssertThrowsError( - try MockTwitterAPIRequest( - method: .post, - parameters: ["key": Data()], - bodyContentType: .json - ).buildRequest(environment: env) - ) { error in - if - let error = error as? TwitterAPIKitError, - case .jsonSerializationFailed = error.requestFailureReason - { - } else { - XCTFail("Unknown Error") - } - } + let body = try JSONSerialization.jsonObject(with: httpBody, options: []) + guard let bodyDict = body as? [String: String] else { + XCTFail("Body should be [String: String]") + return } - } - public func testInvalidJSONValue() throws { - try XCTContext.runActivity(named: "Invalid value") { _ in - // Create invalid UTF-16 string bytes - let invalidBytes: [UInt8] = [0xD8, 0x00] + XCTAssertEqual(bodyDict, ["key": "value,🥓"]) + } - guard let invalidString = String(bytes: invalidBytes, encoding: .utf16BigEndian) else { - XCTFail("Failed to create test string") + public func testInvalidJsonSerialization() throws { + XCTAssertThrowsError( + try MockTwitterAPIRequest( + method: .post, + parameters: ["key": Data()], + bodyContentType: .json + ).buildRequest(environment: env) + ) { error in + guard let apiError = error as? TwitterAPIKitError else { + XCTFail("Error should be TwitterAPIKitError") return } - - XCTAssertThrowsError( - try MockTwitterAPIRequest( - method: .post, - parameters: [invalidString: invalidString], - bodyContentType: .json - ).buildRequest(environment: env) - ) { error in - if - let error = error as? TwitterAPIKitError, - case .jsonSerializationFailed = error.requestFailureReason - { - } else { - XCTFail("Unknown Error") - } + guard case .jsonSerializationFailed = apiError.requestFailureReason else { + XCTFail("Error should be jsonSerializationFailed") + return } } } deinit { - // De-init Logic Here + // De-init logic here } } +// swiftlint:enable force_cast force_unwrapping diff --git a/Tests/TwitterAPIKitTests/TwitterAPIResponseTests.swift b/Tests/TwitterAPIKitTests/TwitterAPIResponseTests.swift index 795134b7..fc46f3fd 100644 --- a/Tests/TwitterAPIKitTests/TwitterAPIResponseTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAPIResponseTests.swift @@ -10,6 +10,7 @@ import TwitterAPIKit import XCTest internal class TwitterAPIResponseTests: XCTestCase { + // swiftlint:disable:next function_body_length public func test() throws { let rateLimit = TwitterRateLimit(header: [ "x-rate-limit-limit": "10", @@ -19,6 +20,7 @@ internal class TwitterAPIResponseTests: XCTestCase { let data = Data("{}".utf8) guard let url = URL(string: "https://example.com") else { XCTFail("Failed to decode url Response") + return } let response: TwitterAPIResponse = TwitterAPIResponse( @@ -37,45 +39,38 @@ internal class TwitterAPIResponseTests: XCTestCase { XCTAssertFalse(response.isError) XCTAssertTrue(response.prettyString.hasPrefix("-- Request success --")) - XCTContext.runActivity(named: "map") { _ in - let mapped = response.compactMap { data in - try? JSONSerialization.jsonObject(with: data, options: []) - } - XCTAssertEqual(mapped.success as? [String: String], [:]) + let mapped = response.map { data in + try? JSONSerialization.jsonObject(with: data, options: []) } + XCTAssertEqual(mapped.success as? [String: String], [:]) - XCTContext.runActivity(named: "tryMap") { _ in - let mapped = response.tryMap { data in - try JSONSerialization.jsonObject(with: data, options: []) - } - XCTAssertEqual(mapped.success as? [String: String], [:]) + let mapped2 = response.tryMap { data in + try JSONSerialization.jsonObject(with: data, options: []) } + XCTAssertEqual(mapped2.success as? [String: String], [:]) - XCTContext.runActivity(named: "tryMapWithError") { _ in - let mapped = response.tryMap { _ in - throw NSError(domain: "", code: 0, userInfo: nil) - } - XCTAssertTrue(mapped.isError) - XCTAssertTrue(mapped.error.isMockURLProtocolUnkonwn) - XCTAssertTrue(mapped.prettyString.hasPrefix("-- Request failure --")) - - XCTContext.runActivity(named: "mapError") { _ in - let errored = mapped.mapError { _ in - .responseFailed(reason: .invalidResponse(error: nil)) - } + let mapped3 = response.tryMap { _ in + throw NSError(domain: "", code: 0, userInfo: nil) + } + XCTAssertTrue(mapped3.isError) + XCTAssertTrue(mapped3.prettyString.hasPrefix("-- Request failure --")) - XCTAssertTrue(errored.error.isResponseFailed) - } + let errored = mapped3.mapError { _ in + .responseFailed(reason: .invalidResponse(error: nil)) } - XCTContext.runActivity(named: "mapError") { _ in - let mapped = response.mapError { _ in - XCTFail("do not call") - fatalError() - } + guard let error = errored.error else { + XCTFail("No Response") + return + } + XCTAssertTrue(error.isResponseFailed) - XCTAssertNotNil(mapped.success) + let mapped4 = response.mapError { _ in + XCTFail("do not call") + fatalError() } + + XCTAssertNotNil(mapped4.success) } deinit { diff --git a/Tests/TwitterAPIKitTests/TwitterAPISessionTests.swift b/Tests/TwitterAPIKitTests/TwitterAPISessionTests.swift index e9952787..f41a7ea1 100644 --- a/Tests/TwitterAPIKitTests/TwitterAPISessionTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAPISessionTests.swift @@ -90,36 +90,6 @@ internal class TwitterAPISessionTests: XCTestCase { wait(for: [exp], timeout: 10) } - public func testPOST() throws { - MockURLProtocol.requestAssert = { request in - XCTAssertEqual(request.httpMethod, "POST") - XCTAssertEqual(request.url?.absoluteString, "https://api.example.com/post.json") - XCTAssertNil(request.httpBody) - - guard let bodyStream = request.httpBodyStream else { - XCTFail("HTTP body stream is nil") - return - } - - do { - let data = try Data(reading: bodyStream) - guard let body = String(data: data, encoding: .utf8) else { - XCTFail("Failed to decode body data as UTF-8") - return - } - XCTAssertEqual(body, "hoge=%F0%9F%98%80") - } catch { - XCTFail("Failed to read HTTP body stream: \(error)") - } - } - - let exp = expectation(description: "") - session.send(PostTwitterReqeust()).responseData(queue: .main) { _ in - exp.fulfill() - } - wait(for: [exp], timeout: 10) - } - public func testEmpty() throws { MockURLProtocol.requestAssert = { request in XCTAssertEqual(request.httpMethod, "GET") @@ -134,6 +104,7 @@ internal class TwitterAPISessionTests: XCTestCase { wait(for: [exp], timeout: 10) } + // swiftlint:disable:next function_body_length public func testStream() throws { let config = URLSessionConfiguration.default config.protocolClasses = [MockURLProtocol.self] diff --git a/Tests/TwitterAPIKitTests/TwitterAuthenticationMethodTests.swift b/Tests/TwitterAPIKitTests/TwitterAuthenticationMethodTests.swift index d98abc8d..ead69090 100644 --- a/Tests/TwitterAPIKitTests/TwitterAuthenticationMethodTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterAuthenticationMethodTests.swift @@ -27,7 +27,7 @@ internal final class TwitterAuthenticationMethodTests: XCTestCase { } // MARK: - OAuth20 - + // swiftlint:disable:next function_body_length public func testOAuth20Init() throws { do { let createdAt = Date(timeIntervalSince1970: 2) @@ -66,6 +66,7 @@ internal final class TwitterAuthenticationMethodTests: XCTestCase { ) guard let token = try TwitterOAuth2AccessToken(jsonData: tokenJSON) else { XCTFail("Failed to decode token Response") + return } let oauth20 = TwitterAuthenticationMethod.OAuth20( clientID: "_client_id_", @@ -83,6 +84,7 @@ internal final class TwitterAuthenticationMethodTests: XCTestCase { } } + // swiftlint:disable:next function_body_length public func testOAuth20Refresh() throws { let createdAt = Date(timeIntervalSince1970: 2) @@ -113,6 +115,7 @@ internal final class TwitterAuthenticationMethodTests: XCTestCase { ) guard let token = try TwitterOAuth2AccessToken(jsonData: tokenJSON) else { XCTFail("Failed to decode token Response") + return } oauth20.refresh(token: token, refreshedAt: refreshedAt) diff --git a/Tests/TwitterAPIKitTests/TwitterRateLimitTests.swift b/Tests/TwitterAPIKitTests/TwitterRateLimitTests.swift index bdf7fa6b..f0a32879 100644 --- a/Tests/TwitterAPIKitTests/TwitterRateLimitTests.swift +++ b/Tests/TwitterAPIKitTests/TwitterRateLimitTests.swift @@ -11,66 +11,59 @@ import XCTest internal class TwitterRateLimitTests: XCTestCase { public func test() throws { - XCTContext.runActivity(named: "from int") { _ in - let header = [ - "x-rate-limit-limit": 15, - "x-rate-limit-remaining": 13, - "x-rate-limit-reset": 1_644_417_523, - ] + let header = [ + "x-rate-limit-limit": 15, + "x-rate-limit-remaining": 13, + "x-rate-limit-reset": 1_644_417_523, + ] - guard let rateLimit = TwitterRateLimit(header: header) else { - XCTFail("Failed to decode rateLimit Response") - } - - XCTAssertEqual(rateLimit.limit, 15) - XCTAssertEqual(rateLimit.remaining, 13) - XCTAssertEqual(rateLimit.reset, 1_644_417_523) - XCTAssertEqual(rateLimit.resetDate.timeIntervalSince1970, 1_644_417_523) + guard let rateLimit = TwitterRateLimit(header: header) else { + XCTFail("Failed to decode rateLimit Response") + return } - XCTContext.runActivity(named: "from string") { _ in - let header = [ - "x-rate-limit-limit": "15", - "x-rate-limit-remaining": "3", - "x-rate-limit-reset": "1644417524", - ] + XCTAssertEqual(rateLimit.limit, 15) + XCTAssertEqual(rateLimit.remaining, 13) + XCTAssertEqual(rateLimit.reset, 1_644_417_523) + XCTAssertEqual(rateLimit.resetDate.timeIntervalSince1970, 1_644_417_523) - guard let rateLimit = TwitterRateLimit(header: header) else { - XCTFail("Failed to decode rateLimit Response") - } + let header2 = [ + "x-rate-limit-limit": "15", + "x-rate-limit-remaining": "3", + "x-rate-limit-reset": "1644417524", + ] - XCTAssertEqual(rateLimit.limit, 15) - XCTAssertEqual(rateLimit.remaining, 3) - XCTAssertEqual(rateLimit.reset, 1_644_417_524) + guard let rateLimit2 = TwitterRateLimit(header: header2) else { + XCTFail("Failed to decode rateLimit Response") + return } + + XCTAssertEqual(rateLimit2.limit, 15) + XCTAssertEqual(rateLimit2.remaining, 3) + XCTAssertEqual(rateLimit2.reset, 1_644_417_524) } public func testNil() throws { - XCTContext.runActivity(named: "limit") { _ in - let header = [ - "x-rate-limit-remaining": "3", - "x-rate-limit-reset": "1644417524", - ] + let header = [ + "x-rate-limit-remaining": "3", + "x-rate-limit-reset": "1644417524", + ] - XCTAssertNil(TwitterRateLimit(header: header)) - } - XCTContext.runActivity(named: "remaining") { _ in - let header = [ - "x-rate-limit-limit": "15", - "x-rate-limit-reset": "1644417524", - ] + XCTAssertNil(TwitterRateLimit(header: header)) - XCTAssertNil(TwitterRateLimit(header: header)) - } + let header2 = [ + "x-rate-limit-limit": "15", + "x-rate-limit-reset": "1644417524", + ] - XCTContext.runActivity(named: "reset") { _ in - let header = [ - "x-rate-limit-limit": "15", - "x-rate-limit-remaining": "3", - ] + XCTAssertNil(TwitterRateLimit(header: header2)) - XCTAssertNil(TwitterRateLimit(header: header)) - } + let header3 = [ + "x-rate-limit-limit": "15", + "x-rate-limit-remaining": "3", + ] + + XCTAssertNil(TwitterRateLimit(header: header3)) } deinit { diff --git a/lint.txt b/lint.txt deleted file mode 100644 index 2c89f460..00000000 --- a/lint.txt +++ /dev/null @@ -1,4 +0,0 @@ - -> twitterapikit@1.0.0 lint -> swiftlint --config=.swiftlint.yml . -