-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Implement testing on different OS versions - Temporarily drop testing on watchOS
- Loading branch information
1 parent
7bb4a64
commit f3da71a
Showing
10 changed files
with
358 additions
and
221 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,54 +24,129 @@ jobs: | |
args: --strict | ||
env: | ||
DIFF_BASE: ${{ github.base_ref }} | ||
Latest: | ||
name: Test Latest (iOS, macOS, tvOS, watchOS) | ||
runs-on: macOS-12 | ||
macOS: | ||
name: ${{ matrix.name }} | ||
runs-on: ${{ matrix.runsOn }} | ||
env: | ||
DEVELOPER_DIR: "/Applications/Xcode_14.1.app/Contents/Developer" | ||
DEVELOPER_DIR: "/Applications/${{ matrix.xcode }}.app/Contents/Developer" | ||
timeout-minutes: 10 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- destination: "OS=16.1,name=iPhone 14 Pro" | ||
name: "iOS" | ||
scheme: "Flare" | ||
sdk: iphonesimulator | ||
- destination: "OS=16.1,name=Apple TV" | ||
name: "tvOS" | ||
scheme: "Flare" | ||
sdk: appletvsimulator | ||
# - destination: "OS=9.1,name=Apple Watch Series 8 (45mm)" | ||
# name: "watchOS" | ||
# scheme: "Flare" | ||
# sdk: watchsimulator | ||
- destination: "platform=macOS" | ||
name: "macOS" | ||
scheme: "Flare" | ||
sdk: macosx | ||
- xcode: "Xcode_15.0" | ||
runsOn: macos-13 | ||
name: "macOS 13, Xcode 15.0, Swift 5.9.0" | ||
- xcode: "Xcode_14.3.1" | ||
runsOn: macos-13 | ||
name: "macOS 13, Xcode 14.3.1, Swift 5.8.0" | ||
- xcode: "Xcode_14.2" | ||
runsOn: macOS-12 | ||
name: "macOS 12, Xcode 14.2, Swift 5.7.2" | ||
- xcode: "Xcode_14.1" | ||
runsOn: macOS-12 | ||
name: "macOS 12, Xcode 14.1, Swift 5.7.1" | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Install Dependencies | ||
run: make setup_build_tools | ||
- name: Generate project | ||
run: make generate | ||
- name: ${{ matrix.name }} | ||
run: xcodebuild test CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -scheme "Flare" -destination "platform=macOS" clean -enableCodeCoverage YES -resultBundlePath "./macos.xcresult" || exit 1 | ||
- name: Upload coverage reports to Codecov | ||
uses: codecov/[email protected] | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} | ||
xcode: true | ||
xcode_archive_path: "./macos.xcresult" | ||
|
||
iOS: | ||
name: ${{ matrix.name }} | ||
runs-on: ${{ matrix.runsOn }} | ||
env: | ||
DEVELOPER_DIR: "/Applications/${{ matrix.xcode }}.app/Contents/Developer" | ||
timeout-minutes: 10 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- destination: "OS=17.0,name=iPhone 14 Pro" | ||
name: "iOS 17.0" | ||
xcode: "Xcode_15.0" | ||
runsOn: macos-13 | ||
- destination: "OS=16.4,name=iPhone 14 Pro" | ||
name: "iOS 16.4" | ||
xcode: "Xcode_14.3.1" | ||
runsOn: macos-13 | ||
- destination: "OS=15.5,name=iPhone 13 Pro" | ||
name: "iOS 15.5" | ||
xcode: "Xcode_14.3.1" | ||
runsOn: macOS-13 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Install Dependencies | ||
run: make setup_build_tools | ||
- name: Generate project | ||
run: make generate | ||
- name: ${{ matrix.name }} | ||
run: xcodebuild test -scheme "${{ matrix.scheme }}" -destination "${{ matrix.destination }}" clean -enableCodeCoverage YES -resultBundlePath "./${{ matrix.sdk }}.xcresult" || exit 1 | ||
run: xcodebuild test CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -scheme "Flare" -destination "${{ matrix.destination }}" clean -enableCodeCoverage YES -resultBundlePath "./iphonesimulator.xcresult" || exit 1 | ||
- name: Upload coverage reports to Codecov | ||
uses: codecov/[email protected] | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} | ||
xcode: true | ||
xcode_archive_path: "./${{ matrix.sdk }}.xcresult" | ||
xcode_archive_path: "./iphonesimulator.xcresult" | ||
|
||
tvOS: | ||
name: ${{ matrix.name }} | ||
runs-on: ${{ matrix.runsOn }} | ||
env: | ||
DEVELOPER_DIR: "/Applications/${{ matrix.xcode }}.app/Contents/Developer" | ||
timeout-minutes: 10 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- destination: "OS=17.0,name=Apple TV" | ||
name: "tvOS 17.0" | ||
xcode: "Xcode_15.0" | ||
runsOn: macos-13 | ||
- destination: "OS=16.4,name=Apple TV" | ||
name: "tvOS 16.4" | ||
xcode: "Xcode_14.3.1" | ||
runsOn: macos-13 | ||
- destination: "OS=15.4,name=Apple TV" | ||
name: "tvOS 15.4" | ||
xcode: "Xcode_14.3.1" | ||
runsOn: macos-13 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Install Dependencies | ||
run: make setup_build_tools | ||
- name: Generate project | ||
run: make generate | ||
- name: ${{ matrix.name }} | ||
run: xcodebuild test -scheme "Flare" -destination "${{ matrix.destination }}" clean -enableCodeCoverage YES -resultBundlePath "./appletvsimulator.xcresult" || exit 1 | ||
- name: Upload coverage reports to Codecov | ||
uses: codecov/[email protected] | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} | ||
xcode: true | ||
xcode_archive_path: "./appletvsimulator.xcresult" | ||
|
||
Beta: | ||
name: "Test Betas" | ||
name: ${{ matrix.name }} | ||
runs-on: macos-13 | ||
env: | ||
DEVELOPER_DIR: "/Applications/Xcode_15.0.app/Contents/Developer" | ||
DEVELOPER_DIR: "/Applications/Xcode_15.1.app/Contents/Developer" | ||
timeout-minutes: 10 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- destination: "OS=1.0,name=Apple Vision Pro" | ||
name: "visionOS" | ||
name: "visionOS 1.0" | ||
scheme: "Flare" | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// | ||
// Flare | ||
// Copyright © 2023 Space Code. All rights reserved. | ||
// | ||
|
||
@testable import Flare | ||
import XCTest | ||
|
||
// MARK: - FlareStoreKit2Tests | ||
|
||
@available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) | ||
final class FlareStoreKit2Tests: StoreSessionTestCase { | ||
// MARK: - Properties | ||
|
||
private var iapProviderMock: IAPProviderMock! | ||
|
||
private var sut: Flare! | ||
|
||
// MARK: - XCTestCase | ||
|
||
override func setUp() { | ||
super.setUp() | ||
iapProviderMock = IAPProviderMock() | ||
sut = Flare(iapProvider: iapProviderMock) | ||
} | ||
|
||
override func tearDown() { | ||
iapProviderMock = nil | ||
sut = nil | ||
super.tearDown() | ||
} | ||
|
||
#if os(iOS) || VISION_OS | ||
func test_thatFlareRefundsPurchase() async throws { | ||
// given | ||
iapProviderMock.stubbedBeginRefundRequest = .success | ||
|
||
// when | ||
let state = try await sut.beginRefundRequest(productID: .productID) | ||
|
||
// then | ||
if case .success = state {} | ||
else { XCTFail("state must be `success`") } | ||
} | ||
|
||
func test_thatFlareRefundRequestThrowsAnError_whenBeginRefundRequestFailed() async throws { | ||
// given | ||
iapProviderMock.stubbedBeginRefundRequest = .failed(error: IAPError.unknown) | ||
|
||
// when | ||
let state = try await sut.beginRefundRequest(productID: .productID) | ||
|
||
// then | ||
if case let .failed(error) = state { XCTAssertEqual(error as NSError, IAPError.unknown as NSError) } | ||
else { XCTFail("state must be `failed`") } | ||
} | ||
#endif | ||
|
||
func test_thatFlarePurchasesAProductWithOptions_whenPurchaseCompleted() async throws { | ||
let transaction = StoreTransactionStub() | ||
try await test_purchaseWithOptionsAndCompletion( | ||
transaction: transaction, | ||
canMakePayments: true, | ||
expectedResult: .success(StoreTransaction(storeTransaction: transaction)) | ||
) | ||
} | ||
|
||
func test_thatFlarePurchaseThrowsAnError_whenPaymentNotAllowed() async throws { | ||
try await test_purchaseWithOptionsAndCompletion( | ||
canMakePayments: false, | ||
expectedResult: .failure(IAPError.paymentNotAllowed) | ||
) | ||
} | ||
|
||
func test_thatFlarePurchasesAsyncAProductWithOptionsAndCompletionHandler_whenPurchaseCompleted() async throws { | ||
let transaction = StoreTransactionStub() | ||
try await test_purchaseWithOptions( | ||
canMakePayments: true, | ||
expectedResult: .success(StoreTransaction(storeTransaction: transaction)) | ||
) | ||
} | ||
|
||
func test_thatFlarePurchaseAsyncThrowsAnError_whenPaymentNotAllowed() async throws { | ||
try await test_purchaseWithOptions( | ||
canMakePayments: false, | ||
expectedResult: .failure(IAPError.paymentNotAllowed) | ||
) | ||
} | ||
|
||
// MARK: Private | ||
|
||
private func test_purchaseWithOptionsAndCompletion( | ||
transaction: StoreTransactionStub? = nil, | ||
canMakePayments: Bool, | ||
expectedResult: Result<StoreTransaction, IAPError> | ||
) async throws { | ||
// given | ||
let product = try await ProductProviderHelper.purchases.randomElement() | ||
let storeTransactionStub = transaction ?? StoreTransactionStub() | ||
storeTransactionStub.stubbedProductIdentifier = product?.id | ||
|
||
iapProviderMock.stubbedCanMakePayments = canMakePayments | ||
iapProviderMock.stubbedAsyncPurchaseWithOptions = StoreTransaction( | ||
storeTransaction: storeTransactionStub | ||
) | ||
|
||
// when | ||
let result: Result<StoreTransaction, IAPError> = await result(for: { | ||
try await sut.purchase( | ||
product: StoreProduct(product: product!), | ||
options: [.simulatesAskToBuyInSandbox(false)] | ||
) | ||
}) | ||
|
||
// then | ||
XCTAssertEqual(result, expectedResult) | ||
} | ||
|
||
private func test_purchaseWithOptions( | ||
transaction: StoreTransactionStub? = nil, | ||
canMakePayments: Bool, | ||
expectedResult: Result<StoreTransaction, IAPError> | ||
) async throws { | ||
// given | ||
let expectation = XCTestExpectation(description: "Purchase a product") | ||
|
||
let product = try await ProductProviderHelper.purchases.randomElement() | ||
let storeTransactionStub = transaction ?? StoreTransactionStub() | ||
storeTransactionStub.stubbedProductIdentifier = product?.id | ||
|
||
iapProviderMock.stubbedCanMakePayments = canMakePayments | ||
iapProviderMock.stubbedPurchaseWithOptionsResult = .success(StoreTransaction(storeTransaction: storeTransactionStub)) | ||
|
||
// when | ||
sut.purchase( | ||
product: StoreProduct(product: product!), | ||
options: [.simulatesAskToBuyInSandbox(false)] | ||
) { result in | ||
XCTAssertEqual(result, expectedResult) | ||
expectation.fulfill() | ||
} | ||
|
||
// then | ||
wait(for: [expectation], timeout: .second) | ||
} | ||
} | ||
|
||
// MARK: - Constants | ||
|
||
private extension TimeInterval { | ||
static let second: CGFloat = 1.0 | ||
} | ||
|
||
private extension String { | ||
static let productID = "com.flare.test_purchase_2" | ||
} |
Oops, something went wrong.