Skip to content

Commit

Permalink
bump baselines to iOS 16, macOS 13, etc (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronsky authored Aug 31, 2024
1 parent a1f0ef0 commit 38f26e6
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 16 deletions.
8 changes: 4 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import PackageDescription
let package = Package(
name: "AppStoreConnect",
platforms: [
.iOS(.v15),
.macOS(.v12),
.tvOS(.v15),
.watchOS(.v8),
.iOS(.v16),
.macOS(.v13),
.tvOS(.v16),
.watchOS(.v9),
],
products: [
.library(
Expand Down
8 changes: 4 additions & 4 deletions Package@swift-6.0.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import PackageDescription
let package = Package(
name: "AppStoreConnect",
platforms: [
.iOS(.v15),
.macOS(.v12),
.tvOS(.v15),
.watchOS(.v8),
.iOS(.v16),
.macOS(.v13),
.tvOS(.v16),
.watchOS(.v9),
],
products: [
.library(
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ print(apps)

## Installation

This project supports Swift 5.9 and higher, and has minimum requirements of iOS 15, macOS 12, tvOS 15, and watchOS 8. It strives to be fully supported for deployment on all other platforms outlined by Swift.org [Platform Support page](https://www.swift.org/platform-support/#deployment-only), such as the various Linux flavors and Windows. App Store Connect API version 3.5 and Enterprise Program 1.0 are supported.
This project supports Swift 5.9 and higher, and has minimum requirements of iOS 16, macOS 13, tvOS 16, and watchOS 9. It strives to be fully supported for deployment on all other platforms outlined by Swift.org [Platform Support page](https://www.swift.org/platform-support/#deployment-only), such as the various Linux flavors and Windows. App Store Connect API version 3.5 and Enterprise Program 1.0 are supported.

The package defines two products: `AppStoreConnect` and `EnterpriseProgram`. Each product provides the `AppStoreConnect` module, which contains the client and authentication logic, and either the `AppStoreAPI` or `EnterpriseAPI` modules, respectively. To integrate with App Store Connect, you would add a dependency on the `"AppStoreConnect"` product. To use the Enterprise Program API, add the `"EnterpriseProgram"` product as a target dependency instead. Finally, both products can be made dependencies of the same target without significant conflict. See the [invite_user](/Examples/invite_user/InviteUser.swift) sample for a rough example of this.

Expand Down
6 changes: 4 additions & 2 deletions Sources/AppStoreConnect/AppStoreConnectClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ public actor AppStoreConnectClient {
/// - currentPage: The API object representing the current page.
/// - Returns: The response from the App Store Connect API.
/// - Throws: An error describing the manner in which the request failed to complete.
public func send<Response>(_ request: Request<Response>, pageAfter currentPage: Response) async throws -> Response?
where Response: Decodable {
public func send<Response>(
_ request: Request<Response>,
pageAfter currentPage: Response
) async throws -> Response? where Response: Decodable {
guard let nextPage = pagedDocumentLinks(currentPage)?.next else {
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import XCTest
import FoundationNetworking
#endif

final class AppStoreConnectTests: XCTestCase {
final class AppStoreConnectClientTests: XCTestCase {
private struct TestData {
enum Case {
case success
Expand Down
172 changes: 171 additions & 1 deletion Tests/AppStoreConnectTests/TransportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,174 @@ import XCTest
import FoundationNetworking
#endif

class TransportTests: XCTestCase {}
class TransportTests: XCTestCase {
private func createSession() -> URLSession {
let config = URLSessionConfiguration.ephemeral
config.protocolClasses = [MockURLProtocol.self]

return URLSession(configuration: config)
}

private class MockURLProtocol: URLProtocol {
typealias ResponseMaker = @Sendable (URLRequest) throws -> Response<Data>

static let knownRequests: [URLRequest: ResponseMaker] = [
URLRequest(url: URL(string: "https://example.com/test-send-async")!): MockData.mockingSuccessNoContent(

Check warning on line 23 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 23 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
for:),
URLRequest(url: URL(string: "https://example.com/test-send-async-error")!): MockData.mockingError(for:),

Check warning on line 25 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 25 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
URLRequest(url: URL(string: "https://example.com/test-send-closure")!): MockData.mockingSuccessNoContent(

Check warning on line 26 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 26 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
for:),
URLRequest(url: URL(string: "https://example.com/test-send-closure-error")!): MockData.mockingError(for:),

Check warning on line 28 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 28 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
URLRequest(url: URL(string: "https://example.com/test-download-async")!): MockData.mockingSuccessNoContent(

Check warning on line 29 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 29 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
for:),
URLRequest(url: URL(string: "https://example.com/test-download-async-error")!): MockData.mockingError(for:),

Check warning on line 31 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 31 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
URLRequest(url: URL(string: "https://example.com/test-download-closure")!): MockData
.mockingSuccessNoContent(for:),

Check warning on line 33 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 33 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
URLRequest(url: URL(string: "https://example.com/test-download-closure-error")!): MockData.mockingError(

Check warning on line 34 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 34 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
for:),
URLRequest(url: URL(string: "https://example.com/test-upload-async")!): MockData.mockingSuccessNoContent(

Check warning on line 36 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 36 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
for:),
URLRequest(url: URL(string: "https://example.com/test-upload-async-error")!): MockData.mockingError(for:),

Check warning on line 38 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=macOS)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races

Check warning on line 38 in Tests/AppStoreConnectTests/TransportTests.swift

View workflow job for this annotation

GitHub Actions / xcodebuild (15.4, platform=iOS Simulator,name=iPhone 15 Pro Max)

converting non-sendable function value to '@sendable (URLRequest) throws -> Response<Data>' may introduce data races
URLRequest(url: URL(string: "https://example.com/test-upload-closure")!): MockData.mockingSuccessNoContent(
for:),
URLRequest(url: URL(string: "https://example.com/test-upload-closure-error")!): MockData.mockingError(for:),
]

override class func canInit(with request: URLRequest) -> Bool {
knownRequests.keys.contains(request)
}

override class func canonicalRequest(for request: URLRequest) -> URLRequest {
return request
}

override func startLoading() {
do {
let response = try MockURLProtocol.knownRequests[request]!(request)
let (data, urlResponse) = (response.data ?? Data(), response.response)

self.client?.urlProtocol(self, didReceive: urlResponse, cacheStoragePolicy: .notAllowed)
self.client?.urlProtocol(self, didLoad: data)
self.client?.urlProtocolDidFinishLoading(self)
} catch {
self.client?.urlProtocol(self, didFailWithError: error)
}
}

override func stopLoading() {}
}

func testURLSessionSendRequest() async throws {
let request = URLRequest(url: URL(string: "https://example.com/test-send-async")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
_ = try await createSession()
.send(request: request, decoder: decoder)
}

func testURLSessionSendRequestFailure() async throws {
let request = URLRequest(url: URL(string: "https://example.com/test-send-async-error")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
try await XCTAssertThrowsError(
await createSession()
.send(request: request, decoder: decoder)
)
}

func testURLSessionSendRequestCompletion() {
let request = URLRequest(url: URL(string: "https://example.com/test-send-closure")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
let expectation = XCTestExpectation(description: "test-send-closure")
createSession()
.send(request: request, decoder: decoder) { result in
XCTAssertNoThrow({ try result.get() })
expectation.fulfill()
}
}

func testURLSessionSendRequestCompletionFailure() {
let request = URLRequest(url: URL(string: "https://example.com/test-send-closure-error")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
let expectation = XCTestExpectation(description: "test-send-closure-error")
createSession()
.send(request: request, decoder: decoder) { result in
expectation.fulfill()
}
}

func testURLSessionDownloadRequest() async throws {
let request = URLRequest(url: URL(string: "https://example.com/test-download-async")!)
_ = try await createSession()
.download(request: request)
}

func testURLSessionDownloadRequestFailure() async throws {
let request = URLRequest(url: URL(string: "https://example.com/test-download-async-error")!)
try await XCTAssertThrowsError(
await createSession().download(request: request)
)
}

func testURLSessionDownloadRequestCompletion() {
let request = URLRequest(url: URL(string: "https://example.com/test-download-closure")!)
let expectation = XCTestExpectation(description: "test-download-closure")
createSession()
.download(request: request) { result in
XCTAssertNoThrow({ try result.get() })
expectation.fulfill()
}
}

func testURLSessionDownloadRequestCompletionFailure() {
let request = URLRequest(url: URL(string: "https://example.com/test-download-closure-error")!)
let expectation = XCTestExpectation(description: "test-download-closure-error")
createSession()
.download(request: request) { result in
expectation.fulfill()
}
}

func testURLSessionUploadRequest() async throws {
let request = URLRequest(url: URL(string: "https://example.com/test-upload-async")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
_ = try await createSession()
.upload(request: request, data: Data(), decoder: decoder)
}

func testURLSessionUploadRequestFailure() async throws {
let request = URLRequest(url: URL(string: "https://example.com/test-upload-async-error")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
try await XCTAssertThrowsError(
await createSession()
.upload(request: request, data: Data(), decoder: decoder)
)
}

func testURLSessionUploadRequestCompletion() {
let request = URLRequest(url: URL(string: "https://example.com/test-upload-closure")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
let expectation = XCTestExpectation(description: "test-upload-closure")
createSession()
.upload(request: request, data: Data(), decoder: decoder) { result in
XCTAssertNoThrow({ try result.get() })
expectation.fulfill()
}
}

func testURLSessionUploadRequestCompletionFailure() {
let request = URLRequest(url: URL(string: "https://example.com/test-upload-closure-error")!)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom(decodeISO8601Date(with:))
let expectation = XCTestExpectation(description: "test-upload-closure-error")
createSession()
.upload(request: request, data: Data(), decoder: decoder) { result in
expectation.fulfill()
}
}
}
7 changes: 4 additions & 3 deletions Tests/Mocks/MockData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,10 @@ public enum MockData {
}

extension MockData {
public static func mockingSuccess<Content: Codable>(with content: Content, url: URL = URL()) throws -> Response<
Data
> {
public static func mockingSuccess<Content: Codable>(
with content: Content,
url: URL = URL()
) throws -> Response<Data> {
let data = try MockData.encoder.encode(content)
return .init(data: data, response: urlResponse(for: url, statusCode: 200), statusCode: 200, rate: nil)
}
Expand Down

0 comments on commit 38f26e6

Please sign in to comment.