Skip to content

Commit c66b01f

Browse files
committed
Use URLSession
1 parent d740b00 commit c66b01f

File tree

5 files changed

+99
-40
lines changed

5 files changed

+99
-40
lines changed

Package.resolved

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version: 5.7
1+
// swift-tools-version: 5.8
22

33
import PackageDescription
44

@@ -14,15 +14,20 @@ let package = Package(
1414
products: [
1515
.library(name: "Functions", targets: ["Functions"])
1616
],
17-
dependencies: [],
17+
dependencies: [
18+
.package(url: "https://github.com/WeTransfer/Mocker", from: "3.0.1")
19+
],
1820
targets: [
1921
.target(
2022
name: "Functions",
2123
dependencies: []
2224
),
2325
.testTarget(
2426
name: "FunctionsTests",
25-
dependencies: ["Functions"]
27+
dependencies: [
28+
"Functions",
29+
"Mocker",
30+
]
2631
),
2732
]
2833
)

Sources/Functions/FunctionsClient.swift

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
import Foundation
22

3-
public final class FunctionsClient {
4-
public typealias FetchHandler = (URLRequest) async throws -> (Data, URLResponse)
5-
3+
public actor FunctionsClient {
64
let url: URL
75
var headers: [String: String]
8-
9-
private let fetch: FetchHandler
6+
let session: URLSession
107

118
public init(
129
url: URL,
1310
headers: [String: String] = [:],
14-
fetch: @escaping FetchHandler = URLSession.shared.data(for:)
11+
session: URLSession = .shared
1512
) {
1613
self.url = url
1714
self.headers = headers
1815
self.headers["X-Client-Info"] = "functions-swift/\(version)"
19-
self.fetch = fetch
16+
self.session = session
2017
}
2118

2219
/// Updates the authorization header.
@@ -80,7 +77,7 @@ public final class FunctionsClient {
8077
urlRequest.httpMethod = "POST"
8178
urlRequest.httpBody = invokeOptions.body
8279

83-
let (data, response) = try await fetch(urlRequest)
80+
let (data, response) = try await session.data(for: urlRequest)
8481

8582
guard let httpResponse = response as? HTTPURLResponse else {
8683
throw URLError(.badServerResponse)
Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Mocker
12
import XCTest
23

34
@testable import Functions
@@ -6,12 +7,15 @@ final class FunctionsClientTests: XCTestCase {
67
let url = URL(string: "http://localhost:5432/functions/v1")!
78
let apiKey = "supabase.anon.key"
89

10+
lazy var sut = FunctionsClient(url: url, headers: ["apikey": apiKey])
11+
912
func testInvoke() async throws {
13+
let url = URL(string: "http://localhost:5432/functions/v1/hello_world")!
1014
var _request: URLRequest?
11-
let sut = FunctionsClient(url: url, headers: ["apikey": apiKey]) {
12-
_request = $0
13-
return (Data(), HTTPURLResponse.mock(url: self.url))
14-
}
15+
16+
var mock = Mock(url: url, dataType: .json, statusCode: 200, data: [.post: Data()])
17+
mock.onRequestHandler = .init { _request = $0 }
18+
mock.register()
1519

1620
let body = ["name": "Supabase"]
1721

@@ -22,18 +26,22 @@ final class FunctionsClientTests: XCTestCase {
2226

2327
let request = try XCTUnwrap(_request)
2428

25-
XCTAssertEqual(request.url, URL(string: "http://localhost:5432/functions/v1/hello_world"))
29+
XCTAssertEqual(request.url, url)
2630
XCTAssertEqual(request.httpMethod, "POST")
2731
XCTAssertEqual(request.value(forHTTPHeaderField: "apikey"), apiKey)
2832
XCTAssertEqual(request.value(forHTTPHeaderField: "X-Custom-Key"), "value")
2933
XCTAssertEqual(
30-
request.value(forHTTPHeaderField: "X-Client-Info"), "functions-swift/\(Functions.version)")
34+
request.value(forHTTPHeaderField: "X-Client-Info"),
35+
"functions-swift/\(Functions.version)"
36+
)
3137
}
3238

3339
func testInvoke_shouldThrow_URLError_badServerResponse() async {
34-
let sut = FunctionsClient(url: url) { _ in
35-
(Data(), URLResponse())
36-
}
40+
let url = URL(string: "http://localhost:5432/functions/v1/hello_world")!
41+
let mock = Mock(
42+
url: url, dataType: .json, statusCode: 200, data: [.post: Data()],
43+
requestError: URLError(.badServerResponse))
44+
mock.register()
3745

3846
do {
3947
try await sut.invoke(functionName: "hello_world")
@@ -45,12 +53,10 @@ final class FunctionsClientTests: XCTestCase {
4553
}
4654

4755
func testInvoke_shouldThrow_FunctionsError_httpError() async {
48-
let sut = FunctionsClient(url: url) { _ in
49-
(
50-
"error".data(using: .utf8)!,
51-
HTTPURLResponse.mock(url: self.url, statusCode: 300)
52-
)
53-
}
56+
let url = URL(string: "http://localhost:5432/functions/v1/hello_world")!
57+
let mock = Mock(
58+
url: url, dataType: .json, statusCode: 300, data: [.post: "error".data(using: .utf8)!])
59+
mock.register()
5460

5561
do {
5662
try await sut.invoke(functionName: "hello_world")
@@ -64,12 +70,11 @@ final class FunctionsClientTests: XCTestCase {
6470
}
6571

6672
func testInvoke_shouldThrow_FunctionsError_relayError() async {
67-
let sut = FunctionsClient(url: url) { _ in
68-
(
69-
Data(),
70-
HTTPURLResponse.mock(url: self.url, headerFields: ["x-relay-error": "true"])
71-
)
72-
}
73+
let url = URL(string: "http://localhost:5432/functions/v1/hello_world")!
74+
let mock = Mock(
75+
url: url, dataType: .json, statusCode: 200, data: [.post: Data()],
76+
additionalHeaders: ["x-relay-error": "true"])
77+
mock.register()
7378

7479
do {
7580
try await sut.invoke(functionName: "hello_world")
@@ -79,14 +84,10 @@ final class FunctionsClientTests: XCTestCase {
7984
XCTFail("Unexpected error thrown \(error)")
8085
}
8186
}
82-
}
8387

84-
extension HTTPURLResponse {
85-
static func mock(
86-
url: URL,
87-
statusCode: Int = 200,
88-
headerFields: [String: String]? = nil
89-
) -> HTTPURLResponse {
90-
HTTPURLResponse(url: url, statusCode: statusCode, httpVersion: nil, headerFields: headerFields)!
88+
func test_setAuth() async {
89+
await sut.setAuth(token: "access.token")
90+
let headers = await sut.headers
91+
XCTAssertEqual(headers["Authorization"], "Bearer access.token")
9192
}
9293
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env bash
2+
##===----------------------------------------------------------------------===##
3+
##
4+
## This source file is part of the SwiftOpenAPIGenerator open source project
5+
##
6+
## Copyright (c) 2023 Apple Inc. and the SwiftOpenAPIGenerator project authors
7+
## Licensed under Apache License v2.0
8+
##
9+
## See LICENSE.txt for license information
10+
## See CONTRIBUTORS.txt for the list of SwiftOpenAPIGenerator project authors
11+
##
12+
## SPDX-License-Identifier: Apache-2.0
13+
##
14+
##===----------------------------------------------------------------------===##
15+
16+
set -euo pipefail
17+
18+
log() { printf -- "** %s\n" "$*" >&2; }
19+
error() { printf -- "** ERROR: %s\n" "$*" >&2; }
20+
fatal() { error "$@"; exit 1; }
21+
22+
CURRENT_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
23+
REPO_ROOT="$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel)"
24+
25+
log "Checking required environment variables..."
26+
test -n "${BASELINE_REPO_URL:-}" || fatal "BASELINE_REPO_URL unset"
27+
test -n "${BASELINE_TREEISH:-}" || fatal "BASELINE_TREEISH unset"
28+
29+
log "Fetching baseline: ${BASELINE_REPO_URL}#${BASELINE_TREEISH}..."
30+
git -C "${REPO_ROOT}" fetch "${BASELINE_REPO_URL}" "${BASELINE_TREEISH}"
31+
BASELINE_COMMIT=$(git -C "${REPO_ROOT}" rev-parse FETCH_HEAD)
32+
33+
log "Checking for API changes since ${BASELINE_REPO_URL}#${BASELINE_TREEISH} (${BASELINE_COMMIT})..."
34+
swift package --package-path "${REPO_ROOT}" diagnose-api-breaking-changes \
35+
"${BASELINE_COMMIT}" \
36+
&& RC=$? || RC=$?
37+
38+
if [ "${RC}" -ne 0 ]; then
39+
fatal "❌ Breaking API changes detected."
40+
exit "${RC}"
41+
fi
42+
log "✅ No breaking API changes detected."

0 commit comments

Comments
 (0)