From 08ea213879d3f7fbd1f4b56cfcf7d60544af1968 Mon Sep 17 00:00:00 2001 From: Tony Li Date: Fri, 14 Jun 2024 13:15:03 +1200 Subject: [PATCH 1/2] Split unit test code into separate filees --- .../Tests/wordpress-api/Endpoints/Users.swift | 50 +++++++ .../Tests/wordpress-api/HTTPErrorTests.swift | 33 +++++ .../wordpress-api/Support/HTTPStubs.swift | 55 ++++++++ .../wordpress-api/WordPressAPITests.swift | 125 ------------------ 4 files changed, 138 insertions(+), 125 deletions(-) create mode 100644 native/swift/Tests/wordpress-api/Endpoints/Users.swift create mode 100644 native/swift/Tests/wordpress-api/HTTPErrorTests.swift create mode 100644 native/swift/Tests/wordpress-api/Support/HTTPStubs.swift delete mode 100644 native/swift/Tests/wordpress-api/WordPressAPITests.swift diff --git a/native/swift/Tests/wordpress-api/Endpoints/Users.swift b/native/swift/Tests/wordpress-api/Endpoints/Users.swift new file mode 100644 index 000000000..b53ba3081 --- /dev/null +++ b/native/swift/Tests/wordpress-api/Endpoints/Users.swift @@ -0,0 +1,50 @@ +import Foundation +import XCTest + +@testable import WordPressAPI + +final class UsersTest: XCTestCase { + + func testRetrieveUser() async throws { + let response = """ + { + "id": 1, + "name": "User Name", + "url": "", + "description": "", + "link": "https://profiles.wordpress.org/user/", + "slug": "poliuk", + "avatar_urls": { + "24": "https://secure.gravatar.com/avatar/uuid?s=24&d=mm&r=g", + "48": "https://secure.gravatar.com/avatar/uuid?s=48&d=mm&r=g", + "96": "https://secure.gravatar.com/avatar/uuid?s=96&d=mm&r=g" + }, + "meta": [], + "_links": { + "self": [ + { + "href": "https://wordpress.org/wp-json/wp/v2/users/1" + } + ], + "collection": [ + { + "href": "https://wordpress.org/wp-json/wp/v2/users" + } + ] + } + } + """ + let stubs = HTTPStubs() + stubs.stub(path: "/wp-json/wp/v2/users/1", with: .json(response)) + + let api = try WordPressAPI( + urlSession: .shared, + baseUrl: URL(string: "https://wordpress.org")!, + authenticationStategy: .none, + executor: stubs + ) + let user = try await api.users.retrieveWithViewContext(userId: 1) + XCTAssertEqual(user.name, "User Name") + } + +} diff --git a/native/swift/Tests/wordpress-api/HTTPErrorTests.swift b/native/swift/Tests/wordpress-api/HTTPErrorTests.swift new file mode 100644 index 000000000..f63a844d1 --- /dev/null +++ b/native/swift/Tests/wordpress-api/HTTPErrorTests.swift @@ -0,0 +1,33 @@ +import Foundation +import XCTest + +@testable import WordPressAPI + +class HTTPErrorTests: XCTestCase { + +#if !os(Linux) + // Skip on Linux, because `XCTExpectFailure` is unavailable on Linux + func testTimeout() async throws { + let stubs = HTTPStubs() + stubs.missingStub = .failure(URLError(.timedOut)) + + let api = try WordPressAPI( + urlSession: .shared, + baseUrl: URL(string: "https://wordpress.org")!, + authenticationStategy: .none, + executor: stubs + ) + + do { + _ = try await api.users.retrieveWithViewContext(userId: 1) + XCTFail("Unexpected response") + } catch let error as URLError { + XCTAssertEqual(error.code, .timedOut) + } catch { + XCTExpectFailure("URLError can't not be passed to Rust") + XCTAssertFalse(true, "Unexpected error: \(error)") + } + } +#endif + +} diff --git a/native/swift/Tests/wordpress-api/Support/HTTPStubs.swift b/native/swift/Tests/wordpress-api/Support/HTTPStubs.swift new file mode 100644 index 000000000..38a4e1273 --- /dev/null +++ b/native/swift/Tests/wordpress-api/Support/HTTPStubs.swift @@ -0,0 +1,55 @@ +import Foundation +import WordPressAPI + +#if canImport(WordPressAPIInternal) +import WordPressAPIInternal +#endif + +class HTTPStubs: SafeRequestExecutor { + + var stubs: [(condition: (WpNetworkRequest) -> Bool, response: WpNetworkResponse)] = [] + + var missingStub: Result? + + public func execute(_ request: WpNetworkRequest) async -> Result { + if let response = stub(for: request) { + return .success(response) + } + + switch missingStub { + case let .success(response): + return .success(response) + case .failure: + // TODO: Translate error into the Rust type + return .failure(.RequestExecutionFailed(statusCode: nil, reason: "")) + default: + // TODO: Translate error into the Rust type + return .failure(.RequestExecutionFailed(statusCode: nil, reason: "")) + } + } + + func stub(for request: WpNetworkRequest) -> WpNetworkResponse? { + stubs.first { stub in stub.condition(request) }? + .response + } + + func stub(path: String, with response: WpNetworkResponse) { + stubs.append(( + condition: { URL(string: $0.url)?.path == path }, + response: response + )) + } + +} + +extension WpNetworkResponse { + + static func json(_ content: String) -> WpNetworkResponse { + WpNetworkResponse( + body: content.data(using: .utf8)!, + statusCode: 200, + headerMap: ["Content-Type": "application/json"] + ) + } + +} diff --git a/native/swift/Tests/wordpress-api/WordPressAPITests.swift b/native/swift/Tests/wordpress-api/WordPressAPITests.swift deleted file mode 100644 index 168e13d87..000000000 --- a/native/swift/Tests/wordpress-api/WordPressAPITests.swift +++ /dev/null @@ -1,125 +0,0 @@ -import XCTest -import Foundation -@testable import WordPressAPI - -#if canImport(WordPressAPIInternal) -import WordPressAPIInternal -#endif - -final class WordPressAPITests: XCTestCase { - - func testExample() async throws { - let response = """ - { - "id": 1, - "name": "User Name", - "url": "", - "description": "", - "link": "https://profiles.wordpress.org/user/", - "slug": "poliuk", - "avatar_urls": { - "24": "https://secure.gravatar.com/avatar/uuid?s=24&d=mm&r=g", - "48": "https://secure.gravatar.com/avatar/uuid?s=48&d=mm&r=g", - "96": "https://secure.gravatar.com/avatar/uuid?s=96&d=mm&r=g" - }, - "meta": [], - "_links": { - "self": [ - { - "href": "https://wordpress.org/wp-json/wp/v2/users/1" - } - ], - "collection": [ - { - "href": "https://wordpress.org/wp-json/wp/v2/users" - } - ] - } - } - """ - let stubs = HTTPStubs() - stubs.stub(path: "/wp-json/wp/v2/users/1", with: .json(response)) - - let api = try WordPressAPI( - urlSession: .shared, - baseUrl: URL(string: "https://wordpress.org")!, - authenticationStategy: .none, - executor: stubs - ) - let user = try await api.users.retrieveWithViewContext(userId: 1) - XCTAssertEqual(user.name, "User Name") - } - -#if !os(Linux) - // Skip on Linux, because `XCTExpectFailure` is unavailable on Linux - func testTimeout() async throws { - let stubs = HTTPStubs() - stubs.missingStub = .failure(URLError(.timedOut)) - - let api = try WordPressAPI( - urlSession: .shared, - baseUrl: URL(string: "https://wordpress.org")!, - authenticationStategy: .none, - executor: stubs - ) - - do { - _ = try await api.users.retrieveWithViewContext(userId: 1) - XCTFail("Unexpected response") - } catch let error as URLError { - XCTAssertEqual(error.code, .timedOut) - } catch { - XCTExpectFailure("URLError can't not be passed to Rust") - XCTAssertFalse(true, "Unexpected error: \(error)") - } - } -#endif - -} - -extension WpNetworkResponse { - static func json(_ content: String) -> WpNetworkResponse { - WpNetworkResponse( - body: content.data(using: .utf8)!, - statusCode: 200, - headerMap: ["Content-Type": "application/json"] - ) - } -} - -class HTTPStubs: SafeRequestExecutor { - - var stubs: [(condition: (WpNetworkRequest) -> Bool, response: WpNetworkResponse)] = [] - - var missingStub: Result? - - public func execute(_ request: WpNetworkRequest) async -> Result { - if let response = stub(for: request) { - return .success(response) - } - - switch missingStub { - case let .success(response): - return .success(response) - case .failure: - // TODO: Translate error into the Rust type - return .failure(.RequestExecutionFailed(statusCode: nil, reason: "")) - default: - // TODO: Translate error into the Rust type - return .failure(.RequestExecutionFailed(statusCode: nil, reason: "")) - } - } - - func stub(for request: WpNetworkRequest) -> WpNetworkResponse? { - stubs.first { stub in stub.condition(request) }? - .response - } - - func stub(path: String, with response: WpNetworkResponse) { - stubs.append(( - condition: { URL(string: $0.url)?.path == path }, - response: response - )) - } - -} From 72a60697e02fe474e878eb01d97711ad95ecd687 Mon Sep 17 00:00:00 2001 From: Jeremy Massel <1123407+jkmassel@users.noreply.github.com> Date: Tue, 25 Jun 2024 21:39:22 -0600 Subject: [PATCH 2/2] Fix test --- native/swift/Tests/wordpress-api/HTTPErrorTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native/swift/Tests/wordpress-api/HTTPErrorTests.swift b/native/swift/Tests/wordpress-api/HTTPErrorTests.swift index f63a844d1..7215bc7f5 100644 --- a/native/swift/Tests/wordpress-api/HTTPErrorTests.swift +++ b/native/swift/Tests/wordpress-api/HTTPErrorTests.swift @@ -2,6 +2,7 @@ import Foundation import XCTest @testable import WordPressAPI +import WordPressAPIInternal class HTTPErrorTests: XCTestCase { @@ -24,8 +25,7 @@ class HTTPErrorTests: XCTestCase { } catch let error as URLError { XCTAssertEqual(error.code, .timedOut) } catch { - XCTExpectFailure("URLError can't not be passed to Rust") - XCTAssertFalse(true, "Unexpected error: \(error)") + XCTAssertTrue(error is WordPressAPIInternal.WpApiError) } } #endif