From 02fd09b6de32db3765e23d3a4dfd21bbc9567574 Mon Sep 17 00:00:00 2001 From: "zunda.dev@gmail.com" Date: Sat, 30 Nov 2024 13:10:08 +0900 Subject: [PATCH] fix Test --- Sources/TestHelpers/HTTPClientMock.swift | 28 ++-- .../AuthClientMultipleInstancesTests.swift | 3 +- Tests/AuthTests/AuthClientTests.swift | 126 ++++++++---------- Tests/AuthTests/AuthErrorTests.swift | 14 +- Tests/AuthTests/ExtractParamsTests.swift | 3 +- Tests/AuthTests/RequestsTests.swift | 44 +++--- Tests/AuthTests/SessionManagerTests.swift | 8 +- Tests/AuthTests/StoredSessionTests.swift | 11 +- .../FunctionInvokeOptionsTests.swift | 4 +- .../FunctionsTests/FunctionsClientTests.swift | 90 ++++++------- Tests/FunctionsTests/RequestTests.swift | 23 +++- .../HelpersTests/ObservationTokenTests.swift | 3 +- .../AuthClientIntegrationTests.swift | 7 +- .../PostgrestIntegrationTests.swift | 2 +- .../Potsgrest/PostgresTransformsTests.swift | 2 +- .../Potsgrest/PostgrestBasicTests.swift | 2 +- .../Potsgrest/PostgrestFilterTests.swift | 2 +- .../PostgrestResourceEmbeddingTests.swift | 2 +- .../RealtimeIntegrationTests.swift | 15 ++- .../StorageClientIntegrationTests.swift | 7 +- .../StorageFileIntegrationTests.swift | 15 ++- .../PostgRESTTests/BuildURLRequestTests.swift | 33 ++--- Tests/PostgRESTTests/JSONTests.swift | 11 +- .../PostgrestBuilderTests.swift | 14 +- .../PostgrestResponseTests.swift | 21 ++- Tests/RealtimeTests/MockWebSocketClient.swift | 3 +- .../PostgresJoinConfigTests.swift | 3 +- Tests/RealtimeTests/RealtimeTests.swift | 25 ++-- Tests/RealtimeTests/_PushTests.swift | 5 +- .../SupabaseStorageClient+Test.swift | 6 +- Tests/StorageTests/SupabaseStorageTests.swift | 85 ++++++------ Tests/SupabaseTests/SupabaseClientTests.swift | 15 ++- 32 files changed, 323 insertions(+), 309 deletions(-) diff --git a/Sources/TestHelpers/HTTPClientMock.swift b/Sources/TestHelpers/HTTPClientMock.swift index 3de790de..aa09ecc9 100644 --- a/Sources/TestHelpers/HTTPClientMock.swift +++ b/Sources/TestHelpers/HTTPClientMock.swift @@ -9,14 +9,16 @@ import ConcurrencyExtras import Foundation import Helpers import XCTestDynamicOverlay +import HTTPTypes package actor HTTPClientMock: HTTPClientType { + package struct MockNotFound: Error {} - private var mocks = [@Sendable (HTTPRequest) async throws -> HTTPResponse?]() + private var mocks = [@Sendable (HTTPRequest, Data?) async throws -> (Data, HTTPResponse)?]() /// Requests received by this client in order. - package var receivedRequests: [HTTPRequest] = [] + package var receivedRequests: [(HTTPRequest, Data?)] = [] /// Responses returned by this client in order. package var returnedResponses: [Result] = [] @@ -25,12 +27,12 @@ package actor HTTPClientMock: HTTPClientType { @discardableResult package func when( - _ request: @escaping @Sendable (HTTPRequest) -> Bool, - return response: @escaping @Sendable (HTTPRequest) async throws -> HTTPResponse + _ request: @escaping @Sendable (HTTPRequest, Data?) -> Bool, + return response: @escaping @Sendable (HTTPRequest, Data?) async throws -> (Data, HTTPResponse) ) -> Self { - mocks.append { r in - if request(r) { - return try await response(r) + mocks.append { r, b in + if request(r, b) { + return try await response(r, b) } return nil } @@ -39,19 +41,19 @@ package actor HTTPClientMock: HTTPClientType { @discardableResult package func any( - _ response: @escaping @Sendable (HTTPRequest) async throws -> HTTPResponse + _ response: @escaping @Sendable (HTTPRequest, Data?) async throws -> (Data, HTTPResponse) ) -> Self { - when({ _ in true }, return: response) + when({ _, _ in true }, return: response) } - package func send(_ request: HTTPRequest) async throws -> HTTPResponse { - receivedRequests.append(request) + package func send(_ request: HTTPRequest, _ bodyData: Data?) async throws -> (Data, HTTPResponse) { + receivedRequests.append((request, bodyData)) for mock in mocks { do { - if let response = try await mock(request) { + if let (data, response) = try await mock(request, bodyData) { returnedResponses.append(.success(response)) - return response + return (data, response) } } catch { returnedResponses.append(.failure(error)) diff --git a/Tests/AuthTests/AuthClientMultipleInstancesTests.swift b/Tests/AuthTests/AuthClientMultipleInstancesTests.swift index 26998388..fe4c3231 100644 --- a/Tests/AuthTests/AuthClientMultipleInstancesTests.swift +++ b/Tests/AuthTests/AuthClientMultipleInstancesTests.swift @@ -5,10 +5,11 @@ // Created by Guilherme Souza on 05/07/24. // -@testable import Auth import TestHelpers import XCTest +@testable import Auth + final class AuthClientMultipleInstancesTests: XCTestCase { func testMultipleAuthClientInstances() { let url = URL(string: "http://localhost:54321/auth")! diff --git a/Tests/AuthTests/AuthClientTests.swift b/Tests/AuthTests/AuthClientTests.swift index 17905696..9c4fd989 100644 --- a/Tests/AuthTests/AuthClientTests.swift +++ b/Tests/AuthTests/AuthClientTests.swift @@ -7,6 +7,7 @@ import ConcurrencyExtras import CustomDump +import HTTPTypes import InlineSnapshotTesting import TestHelpers import XCTest @@ -80,8 +81,8 @@ final class AuthClientTests: XCTestCase { } func testSignOut() async throws { - sut = makeSUT { _ in - .stub() + sut = makeSUT { _, _ in + TestStub.stub() } Dependencies[sut.clientID].sessionStorage.store(.validSession) @@ -109,8 +110,8 @@ final class AuthClientTests: XCTestCase { } func testSignOutWithOthersScopeShouldNotRemoveLocalSession() async throws { - sut = makeSUT { _ in - .stub() + sut = makeSUT { _, _ in + TestStub.stub() } Dependencies[sut.clientID].sessionStorage.store(.validSession) @@ -122,14 +123,12 @@ final class AuthClientTests: XCTestCase { } func testSignOutShouldRemoveSessionIfUserIsNotFound() async throws { - sut = makeSUT { _ in + sut = makeSUT { _, _ in throw AuthError.api( message: "", errorCode: .unknown, - underlyingData: Data(), - underlyingResponse: HTTPURLResponse( - url: URL(string: "http://localhost")!, statusCode: 404, httpVersion: nil, - headerFields: nil)! + data: Data(), + response: HTTPResponse(status: .init(code: 404)) ) } @@ -155,14 +154,12 @@ final class AuthClientTests: XCTestCase { } func testSignOutShouldRemoveSessionIfJWTIsInvalid() async throws { - sut = makeSUT { _ in + sut = makeSUT { _, _ in throw AuthError.api( message: "", errorCode: .invalidCredentials, - underlyingData: Data(), - underlyingResponse: HTTPURLResponse( - url: URL(string: "http://localhost")!, statusCode: 401, httpVersion: nil, - headerFields: nil)! + data: Data(), + response: HTTPResponse(status: .init(code: 401)) ) } @@ -188,14 +185,12 @@ final class AuthClientTests: XCTestCase { } func testSignOutShouldRemoveSessionIf403Returned() async throws { - sut = makeSUT { _ in + sut = makeSUT { _, _ in throw AuthError.api( message: "", errorCode: .invalidCredentials, - underlyingData: Data(), - underlyingResponse: HTTPURLResponse( - url: URL(string: "http://localhost")!, statusCode: 403, httpVersion: nil, - headerFields: nil)! + data: Data(), + response: HTTPResponse(status: .init(code: 403)) ) } @@ -223,8 +218,8 @@ final class AuthClientTests: XCTestCase { func testSignInAnonymously() async throws { let session = Session(fromMockNamed: "anonymous-sign-in-response") - let sut = makeSUT { _ in - .stub(fromFileName: "anonymous-sign-in-response") + let sut = makeSUT { _, _ in + TestStub.stub(fromFileName: "anonymous-sign-in-response") } let eventsTask = Task { @@ -243,8 +238,8 @@ final class AuthClientTests: XCTestCase { } func testSignInWithOAuth() async throws { - let sut = makeSUT { _ in - .stub(fromFileName: "session") + let sut = makeSUT { _, _ in + TestStub.stub(fromFileName: "session") } let eventsTask = Task { @@ -266,8 +261,8 @@ final class AuthClientTests: XCTestCase { } func testGetLinkIdentityURL() async throws { - let sut = makeSUT { _ in - .stub( + let sut = makeSUT { _, _ in + TestStub.stub( """ { "url" : "https://github.com/login/oauth/authorize?client_id=1234&redirect_to=com.supabase.swift-examples://&redirect_uri=http://127.0.0.1:54321/auth/v1/callback&response_type=code&scope=user:email&skip_http_redirect=true&state=jwt" @@ -295,8 +290,8 @@ final class AuthClientTests: XCTestCase { func testLinkIdentity() async throws { let url = "https://github.com/login/oauth/authorize?client_id=1234&redirect_to=com.supabase.swift-examples://&redirect_uri=http://127.0.0.1:54321/auth/v1/callback&response_type=code&scope=user:email&skip_http_redirect=true&state=jwt" - let sut = makeSUT { _ in - .stub( + let sut = makeSUT { _, _ in + TestStub.stub( """ { "url" : "\(url)" @@ -318,12 +313,12 @@ final class AuthClientTests: XCTestCase { } func testAdminListUsers() async throws { - let sut = makeSUT { _ in - .stub( + let sut = makeSUT { _, _ in + TestStub.stub( fromFileName: "list-users-response", headers: [ - "X-Total-Count": "669", - "Link": + .xTotalCount: "669", + .link: "; rel=\"next\", ; rel=\"last\"", ] ) @@ -336,12 +331,12 @@ final class AuthClientTests: XCTestCase { } func testAdminListUsers_noNextPage() async throws { - let sut = makeSUT { _ in - .stub( + let sut = makeSUT { _, _ in + TestStub.stub( fromFileName: "list-users-response", headers: [ - "X-Total-Count": "669", - "Link": "; rel=\"last\"", + .xTotalCount: "669", + .link: "; rel=\"last\"", ] ) } @@ -378,20 +373,20 @@ final class AuthClientTests: XCTestCase { } private func makeSUT( - fetch: ((URLRequest) async throws -> HTTPResponse)? = nil + fetch: ((HTTPRequest, Data?) async throws -> (Data, HTTPResponse))? = nil ) -> AuthClient { let configuration = AuthClient.Configuration( url: clientURL, - headers: ["Apikey": "dummy.api.key"], + headers: [.apiKey: "dummy.api.key"], localStorage: storage, logger: nil, - fetch: { request in + fetch: { request, body in guard let fetch else { throw UnimplementedError() } - let response = try await fetch(request) - return (response.data, response.underlyingResponse) + let (data, response) = try await fetch(request, body) + return (data, response) } ) @@ -401,52 +396,47 @@ final class AuthClientTests: XCTestCase { } } -extension HTTPResponse { +struct TestStub { static func stub( _ body: String = "", code: Int = 200, - headers: [String: String]? = nil - ) -> HTTPResponse { - HTTPResponse( - data: body.data(using: .utf8)!, - response: HTTPURLResponse( - url: clientURL, - statusCode: code, - httpVersion: nil, + headers: HTTPFields = [:] + ) -> (Data, HTTPResponse) { + ( + Data(body.utf8), + HTTPResponse( + status: .init(code: code), headerFields: headers - )! + ) ) } static func stub( fromFileName fileName: String, code: Int = 200, - headers: [String: String]? = nil - ) -> HTTPResponse { - HTTPResponse( - data: json(named: fileName), - response: HTTPURLResponse( - url: clientURL, - statusCode: code, - httpVersion: nil, + headers: HTTPFields = [:] + ) -> (Data, HTTPResponse) { + ( + json(named: fileName), + HTTPResponse( + status: .init(code: code), headerFields: headers - )! + ) ) } static func stub( _ value: some Encodable, code: Int = 200, - headers: [String: String]? = nil - ) -> HTTPResponse { - HTTPResponse( - data: try! AuthClient.Configuration.jsonEncoder.encode(value), - response: HTTPURLResponse( - url: clientURL, - statusCode: code, - httpVersion: nil, + headers: HTTPFields = [:] + ) -> (Data, HTTPResponse) { + ( + try! AuthClient.Configuration.jsonEncoder.encode(value), + HTTPResponse( + status: .init(code: code), headerFields: headers - )! + ) ) + } } diff --git a/Tests/AuthTests/AuthErrorTests.swift b/Tests/AuthTests/AuthErrorTests.swift index 66695263..782de4d4 100644 --- a/Tests/AuthTests/AuthErrorTests.swift +++ b/Tests/AuthTests/AuthErrorTests.swift @@ -5,9 +5,11 @@ // Created by Guilherme Souza on 29/08/24. // -@testable import Auth +import HTTPTypes import XCTest +@testable import Auth + #if canImport(FoundationNetworking) import FoundationNetworking #endif @@ -25,13 +27,17 @@ final class AuthErrorTests: XCTestCase { let api = AuthError.api( message: "API Error", errorCode: .emailConflictIdentityNotDeletable, - underlyingData: Data(), - underlyingResponse: HTTPURLResponse(url: URL(string: "http://localhost")!, statusCode: 400, httpVersion: nil, headerFields: nil)! + data: Data(), + response: HTTPResponse(status: .init(code: 400)) ) XCTAssertEqual(api.errorCode, .emailConflictIdentityNotDeletable) XCTAssertEqual(api.message, "API Error") - let pkceGrantCodeExchange = AuthError.pkceGrantCodeExchange(message: "PKCE failure", error: nil, code: nil) + let pkceGrantCodeExchange = AuthError.pkceGrantCodeExchange( + message: "PKCE failure", + error: nil, + code: nil + ) XCTAssertEqual(pkceGrantCodeExchange.errorCode, .unknown) XCTAssertEqual(pkceGrantCodeExchange.message, "PKCE failure") diff --git a/Tests/AuthTests/ExtractParamsTests.swift b/Tests/AuthTests/ExtractParamsTests.swift index 4ced833e..daacb291 100644 --- a/Tests/AuthTests/ExtractParamsTests.swift +++ b/Tests/AuthTests/ExtractParamsTests.swift @@ -5,9 +5,10 @@ // Created by Guilherme Souza on 23/12/23. // -@testable import Auth import XCTest +@testable import Auth + final class ExtractParamsTests: XCTestCase { func testExtractParamsInQuery() { let code = UUID().uuidString diff --git a/Tests/AuthTests/RequestsTests.swift b/Tests/AuthTests/RequestsTests.swift index a2b36c79..da3e66d0 100644 --- a/Tests/AuthTests/RequestsTests.swift +++ b/Tests/AuthTests/RequestsTests.swift @@ -5,13 +5,15 @@ // Created by Guilherme Souza on 07/10/23. // -@testable import Auth +import HTTPTypes import Helpers import InlineSnapshotTesting import SnapshotTesting import TestHelpers import XCTest +@testable import Auth + #if canImport(FoundationNetworking) import FoundationNetworking #endif @@ -140,10 +142,10 @@ final class RequestsTests: XCTestCase { #if !os(Linux) && !os(Windows) func testSessionFromURL() async throws { - let sut = makeSUT(fetch: { request in - let authorizationHeader = request.allHTTPHeaderFields?["Authorization"] + let sut = makeSUT(fetch: { request, bodyData in + let authorizationHeader = request.headerFields[.authorization] XCTAssertEqual(authorizationHeader, "bearer accesstoken") - return (json(named: "user"), HTTPURLResponse.stub()) + return (json(named: "user"), HTTPResponse(status: .ok)) }) let currentDate = Date() @@ -430,7 +432,12 @@ final class RequestsTests: XCTestCase { Dependencies[sut.clientID].sessionStorage.store(.validSession) await assert { - _ = try await sut.mfa.enroll(params: MFAEnrollParams(issuer: "supabase.com", friendlyName: "test")) + _ = try await sut.mfa.enroll( + params: MFAEnrollParams( + issuer: "supabase.com", + friendlyName: "test" + ) + ) } } @@ -480,7 +487,13 @@ final class RequestsTests: XCTestCase { Dependencies[sut.clientID].sessionStorage.store(.validSession) await assert { - _ = try await sut.mfa.verify(params: .init(factorId: "123", challengeId: "123", code: "123456")) + _ = try await sut.mfa.verify( + params: .init( + factorId: "123", + challengeId: "123", + code: "123456" + ) + ) } } @@ -516,20 +529,22 @@ final class RequestsTests: XCTestCase { let configuration = AuthClient.Configuration( url: clientURL, - headers: ["Apikey": "dummy.api.key", "X-Client-Info": "gotrue-swift/x.y.z"], + headers: [.apiKey: "dummy.api.key", .xClientInfo: "gotrue-swift/x.y.z"], flowType: flowType, localStorage: InMemoryLocalStorage(), logger: nil, encoder: encoder, - fetch: { request in + fetch: { request, bodyData in DispatchQueue.main.sync { + var request = URLRequest(httpRequest: request)! + request.httpBody = bodyData assertSnapshot( of: request, as: .curl, record: record, file: file, testName: testName, line: line ) } if let fetch { - return try await fetch(request) + return try await fetch(request, bodyData) } throw UnimplementedError() @@ -539,14 +554,3 @@ final class RequestsTests: XCTestCase { return AuthClient(configuration: configuration) } } - -extension HTTPURLResponse { - fileprivate static func stub(code: Int = 200) -> HTTPURLResponse { - HTTPURLResponse( - url: clientURL, - statusCode: code, - httpVersion: nil, - headerFields: nil - )! - } -} diff --git a/Tests/AuthTests/SessionManagerTests.swift b/Tests/AuthTests/SessionManagerTests.swift index 3d866055..36c6cb3b 100644 --- a/Tests/AuthTests/SessionManagerTests.swift +++ b/Tests/AuthTests/SessionManagerTests.swift @@ -82,11 +82,13 @@ final class SessionManagerTests: XCTestCase { let (refreshSessionStream, refreshSessionContinuation) = AsyncStream.makeStream() await http.when( - { $0.url.path.contains("/token") }, - return: { _ in + { request, bodyData in + request.url!.path.contains("/token") + }, + return: { _, _ in refreshSessionCallCount.withValue { $0 += 1 } let session = await refreshSessionStream.first(where: { _ in true })! - return .stub(session) + return TestStub.stub(session) } ) diff --git a/Tests/AuthTests/StoredSessionTests.swift b/Tests/AuthTests/StoredSessionTests.swift index 9e466ec2..47a3592d 100644 --- a/Tests/AuthTests/StoredSessionTests.swift +++ b/Tests/AuthTests/StoredSessionTests.swift @@ -1,9 +1,10 @@ -@testable import Auth import ConcurrencyExtras import SnapshotTesting import TestHelpers import XCTest +@testable import Auth + final class StoredSessionTests: XCTestCase { let clientID = AuthClientID() @@ -37,11 +38,11 @@ final class StoredSessionTests: XCTestCase { appMetadata: [ "provider": "email", "providers": [ - "email", + "email" ], ], userMetadata: [ - "referrer_id": nil, + "referrer_id": nil ], aud: "authenticated", confirmationSentAt: ISO8601DateFormatter().date(from: "2022-04-09T11:57:01Z")!, @@ -65,13 +66,13 @@ final class StoredSessionTests: XCTestCase { identityId: UUID(uuidString: "859F402D-B3DE-4105-A1B9-932836D9193B")!, userId: UUID(uuidString: "859F402D-B3DE-4105-A1B9-932836D9193B")!, identityData: [ - "sub": "859f402d-b3de-4105-a1b9-932836d9193b", + "sub": "859f402d-b3de-4105-a1b9-932836d9193b" ], provider: "email", createdAt: ISO8601DateFormatter().date(from: "2022-04-09T11:57:01Z")!, lastSignInAt: ISO8601DateFormatter().date(from: "2022-04-09T11:57:01Z")!, updatedAt: ISO8601DateFormatter().date(from: "2022-04-09T11:57:01Z")! - ), + ) ], factors: nil ) diff --git a/Tests/FunctionsTests/FunctionInvokeOptionsTests.swift b/Tests/FunctionsTests/FunctionInvokeOptionsTests.swift index 4a781007..ed9ffba5 100644 --- a/Tests/FunctionsTests/FunctionInvokeOptionsTests.swift +++ b/Tests/FunctionsTests/FunctionInvokeOptionsTests.swift @@ -28,8 +28,8 @@ final class FunctionInvokeOptionsTests: XCTestCase { let boundary = "Boundary-\(UUID().uuidString)" let contentType = "multipart/form-data; boundary=\(boundary)" let options = FunctionInvokeOptions( - headers: ["Content-Type": contentType], - body: "binary value".data(using: .utf8)! + headers: [.contentType: contentType], + body: Data("binary value".utf8) ) XCTAssertEqual(options.headers[.contentType], contentType) XCTAssertNotNil(options.body) diff --git a/Tests/FunctionsTests/FunctionsClientTests.swift b/Tests/FunctionsTests/FunctionsClientTests.swift index e4972dce..38b29745 100644 --- a/Tests/FunctionsTests/FunctionsClientTests.swift +++ b/Tests/FunctionsTests/FunctionsClientTests.swift @@ -1,10 +1,11 @@ import ConcurrencyExtras -@testable import Functions -import Helpers import HTTPTypes +import Helpers import TestHelpers import XCTest +@testable import Functions + #if canImport(FoundationNetworking) import FoundationNetworking #endif @@ -13,32 +14,32 @@ final class FunctionsClientTests: XCTestCase { let url = URL(string: "http://localhost:5432/functions/v1")! let apiKey = "supabase.anon.key" - lazy var sut = FunctionsClient(url: url, headers: ["Apikey": apiKey]) + lazy var sut = FunctionsClient(url: url, headers: [.apiKey: apiKey]) func testInit() async { let client = FunctionsClient( url: url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: .saEast1 ) XCTAssertEqual(client.region, "sa-east-1") - XCTAssertEqual(client.headers[.init("Apikey")!], apiKey) - XCTAssertNotNil(client.headers[.init("X-Client-Info")!]) + XCTAssertEqual(client.headers[.apiKey], apiKey) + XCTAssertNotNil(client.headers[.xClientInfo]) } func testInvoke() async throws { let url = URL(string: "http://localhost:5432/functions/v1/hello_world")! let http = await HTTPClientMock() - .when { - $0.url.pathComponents.contains("hello_world") - } return: { _ in - try .stub(body: Empty()) + .when { request, bodyData in + return request.url!.pathComponents.contains("hello_world") + } return: { _, _ in + try TestStub.stub(body: Empty()) } let sut = FunctionsClient( url: self.url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: nil, http: http ) @@ -47,24 +48,24 @@ final class FunctionsClientTests: XCTestCase { try await sut.invoke( "hello_world", - options: .init(headers: ["X-Custom-Key": "value"], body: body) + options: .init(headers: [.init("X-Custom-Key")!: "value"], body: body) ) let request = await http.receivedRequests.last - XCTAssertEqual(request?.url, url) - XCTAssertEqual(request?.method, .post) - XCTAssertEqual(request?.headers[.init("Apikey")!], apiKey) - XCTAssertEqual(request?.headers[.init("X-Custom-Key")!], "value") - XCTAssertEqual(request?.headers[.init("X-Client-Info")!], "functions-swift/\(Functions.version)") + XCTAssertEqual(request?.0.url, url) + XCTAssertEqual(request?.0.method, .post) + XCTAssertEqual(request?.0.headerFields[.apiKey], apiKey) + XCTAssertEqual(request?.0.headerFields[.init("X-Custom-Key")!], "value") + XCTAssertEqual(request?.0.headerFields[.xClientInfo], "functions-swift/\(Functions.version)") } func testInvokeWithCustomMethod() async throws { - let http = await HTTPClientMock().any { _ in try .stub(body: Empty()) } + let http = await HTTPClientMock().any { _, _ in try TestStub.stub(body: Empty()) } let sut = FunctionsClient( url: url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: nil, http: http ) @@ -72,15 +73,15 @@ final class FunctionsClientTests: XCTestCase { try await sut.invoke("hello-world", options: .init(method: .delete)) let request = await http.receivedRequests.last - XCTAssertEqual(request?.method, .delete) + XCTAssertEqual(request?.0.method, .delete) } func testInvokeWithQuery() async throws { - let http = await HTTPClientMock().any { _ in try .stub(body: Empty()) } + let http = await HTTPClientMock().any { _, _ in try TestStub.stub(body: Empty()) } let sut = FunctionsClient( url: url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: nil, http: http ) @@ -93,12 +94,12 @@ final class FunctionsClientTests: XCTestCase { ) let request = await http.receivedRequests.last - XCTAssertEqual(request?.urlRequest.url?.query, "key=value") + XCTAssertEqual(request?.0.url?.query, "key=value") } func testInvokeWithRegionDefinedInClient() async throws { let http = await HTTPClientMock() - .any { _ in try .stub(body: Empty()) } + .any { _, _ in try TestStub.stub(body: Empty()) } let sut = FunctionsClient( url: url, @@ -110,12 +111,12 @@ final class FunctionsClientTests: XCTestCase { try await sut.invoke("hello-world") let request = await http.receivedRequests.last - XCTAssertEqual(request?.headers[.xRegion], "ca-central-1") + XCTAssertEqual(request?.0.headerFields[.xRegion], "ca-central-1") } func testInvokeWithRegion() async throws { let http = await HTTPClientMock() - .any { _ in try .stub(body: Empty()) } + .any { _, _ in try TestStub.stub(body: Empty()) } let sut = FunctionsClient( url: url, @@ -127,12 +128,12 @@ final class FunctionsClientTests: XCTestCase { try await sut.invoke("hello-world", options: .init(region: .caCentral1)) let request = await http.receivedRequests.last - XCTAssertEqual(request?.headers[.xRegion], "ca-central-1") + XCTAssertEqual(request?.0.headerFields[.xRegion], "ca-central-1") } func testInvokeWithoutRegion() async throws { let http = await HTTPClientMock() - .any { _ in try .stub(body: Empty()) } + .any { _, _ in try TestStub.stub(body: Empty()) } let sut = FunctionsClient( url: url, @@ -144,16 +145,16 @@ final class FunctionsClientTests: XCTestCase { try await sut.invoke("hello-world") let request = await http.receivedRequests.last - XCTAssertNil(request?.headers[.xRegion]) + XCTAssertNil(request?.0.headerFields[.xRegion]) } func testInvoke_shouldThrow_URLError_badServerResponse() async { let sut = await FunctionsClient( url: url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: nil, http: HTTPClientMock() - .any { _ in throw URLError(.badServerResponse) } + .any { _, _ in throw URLError(.badServerResponse) } ) do { @@ -168,10 +169,10 @@ final class FunctionsClientTests: XCTestCase { func testInvoke_shouldThrow_FunctionsError_httpError() async { let sut = await FunctionsClient( url: url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: nil, http: HTTPClientMock() - .any { _ in try .stub(body: Empty(), statusCode: 300) } + .any { _, _ in try TestStub.stub(body: Empty(), statusCode: 300) } ) do { try await sut.invoke("hello_world") @@ -186,10 +187,10 @@ final class FunctionsClientTests: XCTestCase { func testInvoke_shouldThrow_FunctionsError_relayError() async { let sut = await FunctionsClient( url: url, - headers: ["Apikey": apiKey], + headers: [.apiKey: apiKey], region: nil, - http: HTTPClientMock().any { _ in - try .stub( + http: HTTPClientMock().any { _, _ in + try TestStub.stub( body: Empty(), headers: [.xRelayError: "true"] ) @@ -211,23 +212,18 @@ final class FunctionsClientTests: XCTestCase { } } -extension Helpers.HTTPResponse { +struct TestStub { static func stub( body: any Encodable, statusCode: Int = 200, headers: HTTPFields = .init() - ) throws -> Helpers.HTTPResponse { + ) throws -> (Data, HTTPResponse) { let data = try JSONEncoder().encode(body) - let response = HTTPURLResponse( - url: URL(string: "http://127.0.0.1")!, - statusCode: statusCode, - httpVersion: nil, - headerFields: headers.dictionary - )! - return HTTPResponse( - data: data, - response: response + let response = HTTPResponse( + status: .init(code: statusCode), + headerFields: headers ) + return (data, response) } } diff --git a/Tests/FunctionsTests/RequestTests.swift b/Tests/FunctionsTests/RequestTests.swift index 30d8bab1..556f971b 100644 --- a/Tests/FunctionsTests/RequestTests.swift +++ b/Tests/FunctionsTests/RequestTests.swift @@ -5,10 +5,11 @@ // Created by Guilherme Souza on 23/04/24. // -@testable import Functions import SnapshotTesting import XCTest +@testable import Functions + final class RequestTests: XCTestCase { let url = URL(string: "http://localhost:5432/functions/v1")! let apiKey = "supabase.anon.key" @@ -33,7 +34,10 @@ final class RequestTests: XCTestCase { func testInvokeWithCustomHeader() async { await snapshot { - try await $0.invoke("hello-world", options: .init(headers: ["x-custom-key": "custom value"])) + try await $0.invoke( + "hello-world", + options: .init(headers: [.init("x-custom-key")!: "custom value"]) + ) } } @@ -52,10 +56,19 @@ final class RequestTests: XCTestCase { ) async { let sut = FunctionsClient( url: url, - headers: ["apikey": apiKey, "x-client-info": "functions-swift/x.y.z"] - ) { request in + headers: [.apiKey: apiKey, .xClientInfo: "functions-swift/x.y.z"] + ) { request, bodyData in await MainActor.run { - assertSnapshot(of: request, as: .curl, record: record, file: file, testName: testName, line: line) + var request = URLRequest(httpRequest: request)! + request.httpBody = bodyData + assertSnapshot( + of: request, + as: .curl, + record: record, + file: file, + testName: testName, + line: line + ) } throw NSError(domain: "Error", code: 0, userInfo: nil) } diff --git a/Tests/HelpersTests/ObservationTokenTests.swift b/Tests/HelpersTests/ObservationTokenTests.swift index 16eec655..6deb021e 100644 --- a/Tests/HelpersTests/ObservationTokenTests.swift +++ b/Tests/HelpersTests/ObservationTokenTests.swift @@ -7,9 +7,10 @@ import ConcurrencyExtras import Foundation -@testable import Helpers import XCTest +@testable import Helpers + final class ObservationTokenTests: XCTestCase { func testRemove() { let handle = ObservationToken() diff --git a/Tests/IntegrationTests/AuthClientIntegrationTests.swift b/Tests/IntegrationTests/AuthClientIntegrationTests.swift index d72637c8..fd64b382 100644 --- a/Tests/IntegrationTests/AuthClientIntegrationTests.swift +++ b/Tests/IntegrationTests/AuthClientIntegrationTests.swift @@ -5,12 +5,13 @@ // Created by Guilherme Souza on 27/03/24. // -@testable import Auth import ConcurrencyExtras import CustomDump import TestHelpers import XCTest +@testable import Auth + #if canImport(FoundationNetworking) import FoundationNetworking #endif @@ -24,8 +25,8 @@ final class AuthClientIntegrationTests: XCTestCase { configuration: AuthClient.Configuration( url: URL(string: "\(DotEnv.SUPABASE_URL)/auth/v1")!, headers: [ - "apikey": key, - "Authorization": "Bearer \(key)", + .apiKey: key, + .authorization: "Bearer \(key)", ], localStorage: InMemoryLocalStorage(), logger: nil diff --git a/Tests/IntegrationTests/PostgrestIntegrationTests.swift b/Tests/IntegrationTests/PostgrestIntegrationTests.swift index 6336fcfc..a8398ebf 100644 --- a/Tests/IntegrationTests/PostgrestIntegrationTests.swift +++ b/Tests/IntegrationTests/PostgrestIntegrationTests.swift @@ -38,7 +38,7 @@ final class IntegrationTests: XCTestCase { let client = PostgrestClient( url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1")!, headers: [ - "Apikey": DotEnv.SUPABASE_ANON_KEY, + .apiKey: DotEnv.SUPABASE_ANON_KEY ], logger: nil ) diff --git a/Tests/IntegrationTests/Potsgrest/PostgresTransformsTests.swift b/Tests/IntegrationTests/Potsgrest/PostgresTransformsTests.swift index a0c5925e..99278637 100644 --- a/Tests/IntegrationTests/Potsgrest/PostgresTransformsTests.swift +++ b/Tests/IntegrationTests/Potsgrest/PostgresTransformsTests.swift @@ -14,7 +14,7 @@ final class PostgrestTransformsTests: XCTestCase { configuration: PostgrestClient.Configuration( url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1")!, headers: [ - "apikey": DotEnv.SUPABASE_ANON_KEY + .apiKey: DotEnv.SUPABASE_ANON_KEY ], logger: nil ) diff --git a/Tests/IntegrationTests/Potsgrest/PostgrestBasicTests.swift b/Tests/IntegrationTests/Potsgrest/PostgrestBasicTests.swift index 9912b4d1..ee86afb9 100644 --- a/Tests/IntegrationTests/Potsgrest/PostgrestBasicTests.swift +++ b/Tests/IntegrationTests/Potsgrest/PostgrestBasicTests.swift @@ -14,7 +14,7 @@ final class PostgrestBasicTests: XCTestCase { configuration: PostgrestClient.Configuration( url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1")!, headers: [ - "apikey": DotEnv.SUPABASE_ANON_KEY, + .apiKey: DotEnv.SUPABASE_ANON_KEY ], logger: nil ) diff --git a/Tests/IntegrationTests/Potsgrest/PostgrestFilterTests.swift b/Tests/IntegrationTests/Potsgrest/PostgrestFilterTests.swift index 9ec7e3b1..b6fa13be 100644 --- a/Tests/IntegrationTests/Potsgrest/PostgrestFilterTests.swift +++ b/Tests/IntegrationTests/Potsgrest/PostgrestFilterTests.swift @@ -14,7 +14,7 @@ final class PostgrestFilterTests: XCTestCase { configuration: PostgrestClient.Configuration( url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1")!, headers: [ - "apikey": DotEnv.SUPABASE_ANON_KEY, + .apiKey: DotEnv.SUPABASE_ANON_KEY ], logger: nil ) diff --git a/Tests/IntegrationTests/Potsgrest/PostgrestResourceEmbeddingTests.swift b/Tests/IntegrationTests/Potsgrest/PostgrestResourceEmbeddingTests.swift index c4acfbda..3f9d7af1 100644 --- a/Tests/IntegrationTests/Potsgrest/PostgrestResourceEmbeddingTests.swift +++ b/Tests/IntegrationTests/Potsgrest/PostgrestResourceEmbeddingTests.swift @@ -14,7 +14,7 @@ final class PostgrestResourceEmbeddingTests: XCTestCase { configuration: PostgrestClient.Configuration( url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1")!, headers: [ - "apikey": DotEnv.SUPABASE_ANON_KEY, + .apiKey: DotEnv.SUPABASE_ANON_KEY ], logger: nil ) diff --git a/Tests/IntegrationTests/RealtimeIntegrationTests.swift b/Tests/IntegrationTests/RealtimeIntegrationTests.swift index 4b2b543a..000640ca 100644 --- a/Tests/IntegrationTests/RealtimeIntegrationTests.swift +++ b/Tests/IntegrationTests/RealtimeIntegrationTests.swift @@ -8,23 +8,24 @@ import ConcurrencyExtras import CustomDump import PostgREST -@testable import Realtime import Supabase import TestHelpers import XCTest +@testable import Realtime + final class RealtimeIntegrationTests: XCTestCase { let realtime = RealtimeClientV2( url: URL(string: "\(DotEnv.SUPABASE_URL)/realtime/v1")!, options: RealtimeClientOptions( - headers: ["apikey": DotEnv.SUPABASE_ANON_KEY] + headers: [.apiKey: DotEnv.SUPABASE_ANON_KEY] ) ) let db = PostgrestClient( url: URL(string: "\(DotEnv.SUPABASE_URL)/rest/v1")!, headers: [ - "apikey": DotEnv.SUPABASE_ANON_KEY, + .apiKey: DotEnv.SUPABASE_ANON_KEY ] ) @@ -73,14 +74,14 @@ final class RealtimeIntegrationTests: XCTestCase { [ "event": "test", "payload": [ - "value": 1, + "value": 1 ], "type": "broadcast", ], [ "event": "test", "payload": [ - "value": 2, + "value": 2 ], "type": "broadcast", ], @@ -151,7 +152,7 @@ final class RealtimeIntegrationTests: XCTestCase { expectNoDifference( joins, [ - [], // This is the first PRESENCE_STATE event. + [], // This is the first PRESENCE_STATE event. [UserState(email: "test@supabase.com")], [UserState(email: "test2@supabase.com")], [], @@ -161,7 +162,7 @@ final class RealtimeIntegrationTests: XCTestCase { expectNoDifference( leaves, [ - [], // This is the first PRESENCE_STATE event. + [], // This is the first PRESENCE_STATE event. [], [UserState(email: "test@supabase.com")], [UserState(email: "test2@supabase.com")], diff --git a/Tests/IntegrationTests/StorageClientIntegrationTests.swift b/Tests/IntegrationTests/StorageClientIntegrationTests.swift index 2d073eab..df32ed7f 100644 --- a/Tests/IntegrationTests/StorageClientIntegrationTests.swift +++ b/Tests/IntegrationTests/StorageClientIntegrationTests.swift @@ -14,7 +14,7 @@ final class StorageClientIntegrationTests: XCTestCase { configuration: StorageClientConfiguration( url: URL(string: "\(DotEnv.SUPABASE_URL)/storage/v1")!, headers: [ - "Authorization": "Bearer \(DotEnv.SUPABASE_SERVICE_ROLE_KEY)", + .authorization: "Bearer \(DotEnv.SUPABASE_SERVICE_ROLE_KEY)" ], logger: nil ) @@ -36,7 +36,10 @@ final class StorageClientIntegrationTests: XCTestCase { buckets = try await storage.listBuckets() XCTAssertTrue(buckets.contains { $0.id == bucket.id }) - try await storage.updateBucket(bucketName, options: BucketOptions(allowedMimeTypes: ["image/jpeg"])) + try await storage.updateBucket( + bucketName, + options: BucketOptions(allowedMimeTypes: ["image/jpeg"]) + ) bucket = try await storage.getBucket(bucketName) XCTAssertEqual(bucket.allowedMimeTypes, ["image/jpeg"]) diff --git a/Tests/IntegrationTests/StorageFileIntegrationTests.swift b/Tests/IntegrationTests/StorageFileIntegrationTests.swift index 188090a9..02f5a912 100644 --- a/Tests/IntegrationTests/StorageFileIntegrationTests.swift +++ b/Tests/IntegrationTests/StorageFileIntegrationTests.swift @@ -5,10 +5,11 @@ // Created by Guilherme Souza on 07/05/24. // +import HTTPTypes +import Helpers import InlineSnapshotTesting import Storage import XCTest -import Helpers #if canImport(FoundationNetworking) import FoundationNetworking @@ -19,7 +20,7 @@ final class StorageFileIntegrationTests: XCTestCase { configuration: StorageClientConfiguration( url: URL(string: "\(DotEnv.SUPABASE_URL)/storage/v1")!, headers: [ - "Authorization": "Bearer \(DotEnv.SUPABASE_SERVICE_ROLE_KEY)" + .authorization: "Bearer \(DotEnv.SUPABASE_SERVICE_ROLE_KEY)" ], logger: nil ) @@ -378,9 +379,13 @@ final class StorageFileIntegrationTests: XCTestCase { let publicURL = try storage.from(bucketName).getPublicURL(path: uploadPath) - let (_, response) = try await URLSession.shared.data(from: publicURL) - let httpResponse = try XCTUnwrap(response as? HTTPURLResponse) - let cacheControl = try XCTUnwrap(httpResponse.value(forHTTPHeaderField: "cache-control")) + let request = HTTPRequest( + method: .get, + url: publicURL + ) + + let (_, response) = try await URLSession.shared.data(for: request) + let cacheControl = try XCTUnwrap(response.headerFields[.cacheControl]) XCTAssertEqual(cacheControl, "public, max-age=14400") } diff --git a/Tests/PostgRESTTests/BuildURLRequestTests.swift b/Tests/PostgRESTTests/BuildURLRequestTests.swift index c4ba68d1..f909f4b5 100644 --- a/Tests/PostgRESTTests/BuildURLRequestTests.swift +++ b/Tests/PostgRESTTests/BuildURLRequestTests.swift @@ -1,5 +1,6 @@ import ConcurrencyExtras import Foundation +import HTTPTypes import Helpers import SnapshotTesting import XCTest @@ -49,15 +50,18 @@ final class BuildURLRequestTests: XCTestCase { let client = PostgrestClient( url: url, schema: nil, - headers: ["X-Client-Info": "postgrest-swift/x.y.z"], + headers: [.xClientInfo: "postgrest-swift/x.y.z"], logger: nil, - fetch: { request in + fetch: { request, bodyData in guard let runningTestCase = await runningTestCase.value else { XCTFail("execute called without a runningTestCase set.") - return (Data(), URLResponse.empty()) + return (Data(), HTTPResponse(status: .ok)) } await MainActor.run { [runningTestCase] in + var request = URLRequest(httpRequest: request)! + request.httpBody = bodyData + assertSnapshot( of: request, as: .curl, @@ -69,7 +73,7 @@ final class BuildURLRequestTests: XCTestCase { ) } - return (Data(), URLResponse.empty()) + return (Data(), HTTPResponse(status: .ok)) }, encoder: encoder ) @@ -251,26 +255,7 @@ final class BuildURLRequestTests: XCTestCase { func testSessionConfiguration() { let client = PostgrestClient(url: url, schema: nil, logger: nil) - let clientInfoHeader = client.configuration.headers["X-Client-Info"] + let clientInfoHeader = client.configuration.headers[.xClientInfo] XCTAssertNotNil(clientInfoHeader) } } - -extension URLResponse { - // Windows and Linux don't have the ability to empty initialize a URLResponse like `URLResponse()` - // so - // We provide a function that can give us the right value on an platform. - // See https://github.com/apple/swift-corelibs-foundation/pull/4778 - fileprivate static func empty() -> URLResponse { - #if os(Windows) || os(Linux) - URLResponse( - url: .init(string: "https://supabase.com")!, - mimeType: nil, - expectedContentLength: 0, - textEncodingName: nil - ) - #else - URLResponse() - #endif - } -} diff --git a/Tests/PostgRESTTests/JSONTests.swift b/Tests/PostgRESTTests/JSONTests.swift index dabf2d97..5b339933 100644 --- a/Tests/PostgRESTTests/JSONTests.swift +++ b/Tests/PostgRESTTests/JSONTests.swift @@ -5,16 +5,17 @@ // Created by Guilherme Souza on 01/07/24. // -@testable import PostgREST import XCTest +@testable import PostgREST + final class JSONTests: XCTestCase { func testDecodeJSON() throws { let json = """ - { - "created_at": "2024-06-15T18:12:04+00:00" - } - """.data(using: .utf8)! + { + "created_at": "2024-06-15T18:12:04+00:00" + } + """.data(using: .utf8)! struct Value: Decodable { var createdAt: Date diff --git a/Tests/PostgRESTTests/PostgrestBuilderTests.swift b/Tests/PostgRESTTests/PostgrestBuilderTests.swift index 1fa049a4..41466c28 100644 --- a/Tests/PostgRESTTests/PostgrestBuilderTests.swift +++ b/Tests/PostgRESTTests/PostgrestBuilderTests.swift @@ -5,19 +5,23 @@ // Created by Guilherme Souza on 20/08/24. // -@testable import PostgREST import XCTest +@testable import PostgREST + final class PostgrestBuilderTests: XCTestCase { let url = URL(string: "http://localhost:54321/rest/v1")! func testCustomHeaderOnAPerCallBasis() throws { - let postgrest1 = PostgrestClient(url: url, headers: ["apikey": "foo"], logger: nil) - let postgrest2 = try postgrest1.rpc("void_func").setHeader(name: .init("apikey")!, value: "bar") + let postgrest1 = PostgrestClient(url: url, headers: [.apiKey: "foo"], logger: nil) + let postgrest2 = try postgrest1.rpc("void_func").setHeader(name: .apiKey, value: "bar") // Original client object isn't affected - XCTAssertEqual(postgrest1.from("users").select().mutableState.request.headers[.init("apikey")!], "foo") + XCTAssertEqual( + postgrest1.from("users").select().mutableState.request.headerFields[.apiKey], + "foo" + ) // Derived client object uses new header value - XCTAssertEqual(postgrest2.mutableState.request.headers[.init("apikey")!], "bar") + XCTAssertEqual(postgrest2.mutableState.request.headerFields[.apiKey], "bar") } } diff --git a/Tests/PostgRESTTests/PostgrestResponseTests.swift b/Tests/PostgRESTTests/PostgrestResponseTests.swift index 09637818..9c65311e 100644 --- a/Tests/PostgRESTTests/PostgrestResponseTests.swift +++ b/Tests/PostgRESTTests/PostgrestResponseTests.swift @@ -1,3 +1,4 @@ +import HTTPTypes import XCTest @testable import PostgREST @@ -10,12 +11,10 @@ class PostgrestResponseTests: XCTestCase { func testInit() { // Prepare data and response let data = Data() - let response = HTTPURLResponse( - url: URL(string: "http://example.com")!, - statusCode: 200, - httpVersion: nil, - headerFields: ["Content-Range": "bytes 0-100/200"] - )! + let response = HTTPResponse( + status: .init(code: 200), + headerFields: [.contentRange: "bytes 0-100/200"] + ) let value = "Test Value" // Create the PostgrestResponse instance @@ -32,12 +31,10 @@ class PostgrestResponseTests: XCTestCase { func testInitWithNoCount() { // Prepare data and response let data = Data() - let response = HTTPURLResponse( - url: URL(string: "http://example.com")!, - statusCode: 200, - httpVersion: nil, - headerFields: ["Content-Range": "*"] - )! + let response = HTTPResponse( + status: .init(code: 200), + headerFields: [.contentRange: "*"] + ) let value = "Test Value" // Create the PostgrestResponse instance diff --git a/Tests/RealtimeTests/MockWebSocketClient.swift b/Tests/RealtimeTests/MockWebSocketClient.swift index bcabc958..5580b122 100644 --- a/Tests/RealtimeTests/MockWebSocketClient.swift +++ b/Tests/RealtimeTests/MockWebSocketClient.swift @@ -7,9 +7,10 @@ import ConcurrencyExtras import Foundation -@testable import Realtime import XCTestDynamicOverlay +@testable import Realtime + #if canImport(FoundationNetworking) import FoundationNetworking #endif diff --git a/Tests/RealtimeTests/PostgresJoinConfigTests.swift b/Tests/RealtimeTests/PostgresJoinConfigTests.swift index bb695d18..64db6c56 100644 --- a/Tests/RealtimeTests/PostgresJoinConfigTests.swift +++ b/Tests/RealtimeTests/PostgresJoinConfigTests.swift @@ -5,9 +5,10 @@ // Created by Guilherme Souza on 26/12/23. // -@testable import Realtime import XCTest +@testable import Realtime + final class PostgresJoinConfigTests: XCTestCase { func testSameConfigButDifferentIdAreEqual() { let config1 = PostgresJoinConfig( diff --git a/Tests/RealtimeTests/RealtimeTests.swift b/Tests/RealtimeTests/RealtimeTests.swift index 35a318cc..b7956208 100644 --- a/Tests/RealtimeTests/RealtimeTests.swift +++ b/Tests/RealtimeTests/RealtimeTests.swift @@ -1,5 +1,6 @@ import ConcurrencyExtras import CustomDump +import HTTPTypes import Helpers import InlineSnapshotTesting import TestHelpers @@ -33,7 +34,7 @@ final class RealtimeTests: XCTestCase { sut = RealtimeClientV2( url: url, options: RealtimeClientOptions( - headers: ["apikey": apiKey], + headers: [.apiKey: apiKey], heartbeatInterval: 1, reconnectDelay: 1, timeoutInterval: 2 @@ -298,17 +299,12 @@ final class RealtimeTests: XCTestCase { } func testBroadcastWithHTTP() async throws { - await http.when { - $0.url.path.hasSuffix("broadcast") - } return: { _ in - HTTPResponse( - data: "{}".data(using: .utf8)!, - response: HTTPURLResponse( - url: self.sut.broadcastURL, - statusCode: 200, - httpVersion: nil, - headerFields: nil - )! + await http.when { request, bodyData in + request.url!.path.hasSuffix("broadcast") + } return: { _, _ in + ( + Data("{}".utf8), + HTTPResponse(status: .init(code: 200)) ) } @@ -319,7 +315,10 @@ final class RealtimeTests: XCTestCase { try await channel.broadcast(event: "test", message: ["value": 42]) let request = await http.receivedRequests.last - assertInlineSnapshot(of: request?.urlRequest, as: .raw(pretty: true)) { + var urlRequest = request.map { URLRequest(httpRequest: $0.0) } + urlRequest??.httpBody = request?.1 + + assertInlineSnapshot(of: urlRequest as? URLRequest, as: .raw(pretty: true)) { """ POST https://localhost:54321/realtime/v1/api/broadcast Authorization: Bearer anon.api.key diff --git a/Tests/RealtimeTests/_PushTests.swift b/Tests/RealtimeTests/_PushTests.swift index 67efc7a1..871c0bed 100644 --- a/Tests/RealtimeTests/_PushTests.swift +++ b/Tests/RealtimeTests/_PushTests.swift @@ -6,10 +6,11 @@ // import ConcurrencyExtras -@testable import Realtime import TestHelpers import XCTest +@testable import Realtime + final class _PushTests: XCTestCase { var ws: MockWebSocketClient! var socket: RealtimeClientV2! @@ -27,7 +28,7 @@ final class _PushTests: XCTestCase { socket = RealtimeClientV2( url: URL(string: "https://localhost:54321/v1/realtime")!, options: RealtimeClientOptions( - headers: ["apiKey": "apikey"] + headers: [.apiKey: "apikey"] ), ws: ws, http: HTTPClientMock() diff --git a/Tests/StorageTests/SupabaseStorageClient+Test.swift b/Tests/StorageTests/SupabaseStorageClient+Test.swift index ac10137f..bb9dace9 100644 --- a/Tests/StorageTests/SupabaseStorageClient+Test.swift +++ b/Tests/StorageTests/SupabaseStorageClient+Test.swift @@ -18,9 +18,9 @@ extension SupabaseStorageClient { configuration: StorageClientConfiguration( url: URL(string: supabaseURL)!, headers: [ - "Authorization": "Bearer \(apiKey)", - "Apikey": apiKey, - "X-Client-Info": "storage-swift/x.y.z", + .authorization: "Bearer \(apiKey)", + .apiKey: apiKey, + .xClientInfo: "storage-swift/x.y.z", ], session: session, logger: nil diff --git a/Tests/StorageTests/SupabaseStorageTests.swift b/Tests/StorageTests/SupabaseStorageTests.swift index 5742538d..9482d916 100644 --- a/Tests/StorageTests/SupabaseStorageTests.swift +++ b/Tests/StorageTests/SupabaseStorageTests.swift @@ -1,5 +1,6 @@ import CustomDump import Foundation +import HTTPTypes import InlineSnapshotTesting import XCTest import XCTestDynamicOverlay @@ -15,8 +16,7 @@ final class SupabaseStorageTests: XCTestCase { let bucketId = "tests" var sessionMock = StorageHTTPSession( - fetch: unimplemented("StorageHTTPSession.fetch"), - upload: unimplemented("StorageHTTPSession.upload") + fetch: unimplemented("StorageHTTPSession.fetch") ) func testGetPublicURL() throws { @@ -58,24 +58,20 @@ final class SupabaseStorageTests: XCTestCase { } func testCreateSignedURLs() async throws { - sessionMock.fetch = { _ in + sessionMock.fetch = { _, _ in ( - """ - [ - { - "signedURL": "/sign/file1.txt?token=abc.def.ghi" - }, - { - "signedURL": "/sign/file2.txt?token=abc.def.ghi" - }, - ] - """.data(using: .utf8)!, - HTTPURLResponse( - url: self.supabaseURL, - statusCode: 200, - httpVersion: nil, - headerFields: nil - )! + Data( + """ + [ + { + "signedURL": "/sign/file1.txt?token=abc.def.ghi" + }, + { + "signedURL": "/sign/file2.txt?token=abc.def.ghi" + }, + ] + """.utf8), + HTTPResponse(status: .init(code: 200)) ) } @@ -96,7 +92,10 @@ final class SupabaseStorageTests: XCTestCase { func testUploadData() async throws { testingBoundary.setValue("alamofire.boundary.c21f947c1c7b0c57") - sessionMock.fetch = { request in + sessionMock.fetch = { request, bodyData in + var request = URLRequest(httpRequest: request)! + request.httpBody = bodyData + assertInlineSnapshot(of: request, as: .curl) { #""" curl \ @@ -126,18 +125,16 @@ final class SupabaseStorageTests: XCTestCase { """# } return ( - """ - { - "Id": "tests/file1.txt", - "Key": "tests/file1.txt" - } - """.data(using: .utf8)!, - HTTPURLResponse( - url: self.supabaseURL, - statusCode: 200, - httpVersion: nil, - headerFields: nil - )! + Data( + """ + { + "Id": "tests/file1.txt", + "Key": "tests/file1.txt" + } + """.utf8), + HTTPResponse( + status: .init(code: 200) + ) ) } @@ -157,7 +154,9 @@ final class SupabaseStorageTests: XCTestCase { func testUploadFileURL() async throws { testingBoundary.setValue("alamofire.boundary.c21f947c1c7b0c57") - sessionMock.fetch = { request in + sessionMock.fetch = { request, bodyData in + var request = URLRequest(httpRequest: request)! + request.httpBody = bodyData assertInlineSnapshot(of: request, as: .curl) { #""" curl \ @@ -172,18 +171,14 @@ final class SupabaseStorageTests: XCTestCase { """# } return ( - """ - { - "Id": "tests/file1.txt", - "Key": "tests/file1.txt" - } - """.data(using: .utf8)!, - HTTPURLResponse( - url: self.supabaseURL, - statusCode: 200, - httpVersion: nil, - headerFields: nil - )! + Data( + """ + { + "Id": "tests/file1.txt", + "Key": "tests/file1.txt" + } + """.utf8), + HTTPResponse(status: .init(code: 200)) ) } diff --git a/Tests/SupabaseTests/SupabaseClientTests.swift b/Tests/SupabaseTests/SupabaseClientTests.swift index c487177d..c459786d 100644 --- a/Tests/SupabaseTests/SupabaseClientTests.swift +++ b/Tests/SupabaseTests/SupabaseClientTests.swift @@ -1,10 +1,12 @@ -@testable import Auth import CustomDump -@testable import Functions +import HTTPTypes import IssueReporting +import XCTest + +@testable import Auth +@testable import Functions @testable import Realtime @testable import Supabase -import XCTest final class AuthLocalStorageMock: AuthLocalStorage { func store(key _: String, value _: Data) throws {} @@ -27,7 +29,7 @@ final class SupabaseClientTests: XCTestCase { let logger = Logger() let customSchema = "custom_schema" let localStorage = AuthLocalStorageMock() - let customHeaders = ["header_field": "header_value"] + let customHeaders: HTTPFields = [.init("header_field")!: "header_value"] let client = SupabaseClient( supabaseURL: URL(string: "https://project-ref.supabase.co")!, @@ -47,7 +49,7 @@ final class SupabaseClientTests: XCTestCase { region: .apNortheast1 ), realtime: RealtimeClientOptions( - headers: ["custom_realtime_header_key": "custom_realtime_header_value"] + headers: [.init("custom_realtime_header_key")!: "custom_realtime_header_value"] ) ) ) @@ -79,7 +81,8 @@ final class SupabaseClientTests: XCTestCase { let realtimeOptions = client.realtimeV2.options let expectedRealtimeHeader = client._headers.merging(with: [ - .init("custom_realtime_header_key")!: "custom_realtime_header_value"] + .init("custom_realtime_header_key")!: "custom_realtime_header_value" + ] ) expectNoDifference(realtimeOptions.headers, expectedRealtimeHeader) XCTAssertIdentical(realtimeOptions.logger as? Logger, logger)