Skip to content

Commit

Permalink
Fixed tvOS tests (#1928)
Browse files Browse the repository at this point in the history
Turns out we hadn't been running tests on `tvOS` for a while:
> [19:08:22]: Couldn't find any matching simulators for '["Apple TV
(15.2)"]' - falling back to default simulator
> [19:08:22]: Found simulator "iPhone 13 Pro (15.5)"

I found this went I went to dig into [this
failure](#1926 (comment)).
Turns out that wasn't running on `tvOS` anyway.

This turns them back on, fixes the compilation issues on `tvOS` tests,
and ensures that we don't run into this issue again.

### Changes:
- Renamed device in lane `test_tvos`
- Enabled `ensure_devices_found` on `iOS` and `tvOS` lanes. This will
also ensure that we don't stop running tests on iOS XX because it
doesn't find that simulator.
- Removed `UnitTestHostApp` storyboards and scene, since those aren't
supported in `tvOS`, and aren't needed because there's no UI.
- Made `StoreKitUnitTests` and `UnitTestHostApp` targets universal
- No longer linking `AdServices` on `tvOS` in test targets
- Disabled attribution tests on `tvOS`. Those methods weren't being
compiled, but we were testing that a message was being sent, even though
it no longer was.
- Changed iOS 14 tests to use Xcode 13 due to
xcpretty/xcode-install#466 (same as #1918).
  • Loading branch information
NachoSoto authored Sep 23, 2022
1 parent 6d176f0 commit e3c0dfe
Show file tree
Hide file tree
Showing 16 changed files with 48 additions and 180 deletions.
9 changes: 6 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ commands:
command: gem install xcode-install
- run:
name: Install simulator
command: xcversion simulators --install="<< parameters.install-name >>"
command: | # Print all available simulators and install required one
xcversion simulators
xcversion simulators --install="<< parameters.install-name >>"
- run:
name: Create simulator
command: xcrun simctl create '<< parameters.sim-name >>' com.apple.CoreSimulator.SimDeviceType.<< parameters.sim-device-type >> com.apple.CoreSimulator.SimRuntime.<< parameters.sim-device-runtime >>
Expand Down Expand Up @@ -235,7 +237,7 @@ jobs:
command: bundle exec fastlane test_ios
no_output_timeout: 30m
environment:
SCAN_DEVICE: iPhone 13 (16.0)
SCAN_DEVICE: iPhone 14 (16.0)
- compress_result_bundle:
directory: fastlane/test_output/xctest/ios
bundle_name: RevenueCat
Expand Down Expand Up @@ -571,7 +573,8 @@ workflows:
- run-test-tvos:
xcode_version: '14.0.0'
- run-test-ios-14:
xcode_version: '14.0.0'
# Simulator fails to install on Xcode 14
xcode_version: '13.4.1'
- run-test-ios-13:
# Simulator fails to install on Xcode 14
xcode_version: '13.4.1'
Expand Down
39 changes: 8 additions & 31 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@
2DE61A84264190830021CEA0 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE61A83264190830021CEA0 /* Constants.swift */; };
2DEAC2DD26EFE46E006914ED /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DEAC2DC26EFE46E006914ED /* AppDelegate.swift */; };
2DEAC2E126EFE46E006914ED /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DEAC2E026EFE46E006914ED /* ViewController.swift */; };
2DEAC2E426EFE46E006914ED /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2DEAC2E226EFE46E006914ED /* Main.storyboard */; };
2DEAC2E626EFE470006914ED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2DEAC2E526EFE470006914ED /* Assets.xcassets */; };
2DEAC2E926EFE470006914ED /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2DEAC2E726EFE470006914ED /* LaunchScreen.storyboard */; };
2DFF6C56270CA28800ECAFAB /* MockRequestFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 351B517926D44FF000BD2BD7 /* MockRequestFetcher.swift */; };
351B513D26D4491E00BD2BD7 /* MockDeviceCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 351B513C26D4491E00BD2BD7 /* MockDeviceCache.swift */; };
351B513F26D4496000BD2BD7 /* MockIdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 351B513E26D4496000BD2BD7 /* MockIdentityManager.swift */; };
Expand Down Expand Up @@ -616,9 +614,7 @@
2DEAC2DA26EFE46E006914ED /* UnitTestsHostApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UnitTestsHostApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
2DEAC2DC26EFE46E006914ED /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
2DEAC2E026EFE46E006914ED /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
2DEAC2E326EFE46E006914ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
2DEAC2E526EFE470006914ED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
2DEAC2E826EFE470006914ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
2DEAC2EA26EFE470006914ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2DEC0CFB24A2A1B100B0E5BB /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
33FFC8744F2BAE7BD8889A4C /* Pods_RevenueCat.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RevenueCat.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -1434,9 +1430,7 @@
children = (
2DEAC2DC26EFE46E006914ED /* AppDelegate.swift */,
2DEAC2E026EFE46E006914ED /* ViewController.swift */,
2DEAC2E226EFE46E006914ED /* Main.storyboard */,
2DEAC2E526EFE470006914ED /* Assets.xcassets */,
2DEAC2E726EFE470006914ED /* LaunchScreen.storyboard */,
2DEAC2EA26EFE470006914ED /* Info.plist */,
);
path = UnitTestsHostApp;
Expand Down Expand Up @@ -2242,10 +2236,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2DEAC2E926EFE470006914ED /* LaunchScreen.storyboard in Resources */,
2D735F7E26EFF198004E82A7 /* UnitTestsConfiguration.storekit in Resources */,
2DEAC2E626EFE470006914ED /* Assets.xcassets in Resources */,
2DEAC2E426EFE46E006914ED /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -2787,25 +2779,6 @@
};
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
2DEAC2E226EFE46E006914ED /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
2DEAC2E326EFE46E006914ED /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
2DEAC2E726EFE470006914ED /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
2DEAC2E826EFE470006914ED /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
2DAC5F7926F13C9800C5258F /* Debug */ = {
isa = XCBuildConfiguration;
Expand All @@ -2827,11 +2800,12 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.revenuecat.StoreKitUnitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos watchsimulator watchos appletvsimulator appletvos";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_TREAT_WARNINGS_AS_ERRORS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = "1,2,3,4,6";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UnitTestsHostApp.app/UnitTestsHostApp";
};
name = Debug;
Expand All @@ -2855,10 +2829,11 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.revenuecat.StoreKitUnitTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos watchsimulator watchos appletvsimulator appletvos";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_TREAT_WARNINGS_AS_ERRORS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = "1,2,3,4,6";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UnitTestsHostApp.app/UnitTestsHostApp";
};
name = Release;
Expand Down Expand Up @@ -3118,9 +3093,10 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.revenuecat.StoreKitUnitTestsHostApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos watchsimulator watchos appletvsimulator appletvos";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = "1,2,3,4,6";
};
name = Debug;
};
Expand All @@ -3140,8 +3116,9 @@
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.revenuecat.StoreKitUnitTestsHostApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos watchsimulator watchos appletvsimulator appletvos";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TARGETED_DEVICE_FAMILY = "1,2,3,4,6";
};
name = Release;
};
Expand Down
3 changes: 0 additions & 3 deletions Sources/Logging/Strings/PurchaseStrings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ enum PurchaseStrings {
case product_unpurchased_or_missing
case transaction_unverified(productID: String, errorMessage: String)
case unknown_purchase_result(result: String)
case begin_refund_request_unsupported
case begin_refund_no_entitlement_found(entitlementID: String?)
case begin_refund_no_active_entitlement
case begin_refund_multiple_active_entitlements
Expand Down Expand Up @@ -220,8 +219,6 @@ extension PurchaseStrings: CustomStringConvertible {
"Verification error: \(errorMessage)"
case let .unknown_purchase_result(result):
return "Received unknown purchase result: \(result)"
case .begin_refund_request_unsupported:
return "Tried to call beginRefundRequest in a platform that doesn't support it!"
case .begin_refund_no_entitlement_found(let entitlementID):
return "Could not find \(entitlementID.flatMap { "entitlement with ID " + $0 } ?? "active entitlement")" +
" for refund."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 55;
objects = {

/* Begin PBXBuildFile section */
2C396F5E281C64B700669657 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C396F5D281C64B700669657 /* AdServices.framework */; };
2C396F5E281C64B700669657 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C396F5D281C64B700669657 /* AdServices.framework */; platformFilters = (ios, maccatalyst, macos, ); };
2DD77909270E23870079CBD4 /* RCAttributionNetworkAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = A5D614EC26EBE84F007DDB75 /* RCAttributionNetworkAPI.m */; };
2DD7790B270E23870079CBD4 /* RCCustomerInfoAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = A5D614F026EBE84F007DDB75 /* RCCustomerInfoAPI.m */; };
2DD7790C270E23870079CBD4 /* RCPurchasesErrorCodeAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = A5D614EE26EBE84F007DDB75 /* RCPurchasesErrorCodeAPI.m */; };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objectVersion = 55;
objects = {

/* Begin PBXBuildFile section */
2C396F5C281C64AF00669657 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C396F5B281C64AF00669657 /* AdServices.framework */; };
2C396F5C281C64AF00669657 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C396F5B281C64AF00669657 /* AdServices.framework */; platformFilters = (ios, maccatalyst, macos, ); };
2DD778E4270E23460079CBD4 /* AttributionNetworkAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D614CA26EBE7EA007DDB75 /* AttributionNetworkAPI.swift */; };
2DD778E5270E23460079CBD4 /* IntroEligibilityAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D614CD26EBE7EA007DDB75 /* IntroEligibilityAPI.swift */; };
2DD778E6270E23460079CBD4 /* PurchasesAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5D614CE26EBE7EA007DDB75 /* PurchasesAPI.swift */; };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,7 @@ func checkAttributionAPI() {

attribution.collectDeviceIdentifiers()

#if !os(tvOS)
attribution.enableAdServicesAttributionTokenCollection()
#endif
}
36 changes: 4 additions & 32 deletions Tests/StoreKitUnitTests/BeginRefundRequestHelperTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import XCTest

@testable import RevenueCat

#if os(iOS) || targetEnvironment(macCatalyst)

class BeginRefundRequestHelperTests: TestCase {

private var systemInfo: MockSystemInfo!
Expand Down Expand Up @@ -60,37 +62,6 @@ class BeginRefundRequestHelperTests: TestCase {
}
}

func testBeginRefundRequestForProductFatalErrorIfNotIosOrCatalyst() throws {
#if os(watchOS) || os(macOS) || os(tvOS)
expectFatalError(expectedMessage: Strings.purchase.begin_refund_request_unsupported.description) {
_ = try await helper.beginRefundRequest(forProduct: mockProductID)
}
#else
throw XCTSkip("beginRefundRequestForProduct is not available for this test.")
#endif
}

func testBeginRefundRequestForEntitlementFatalErrorIfNotIosOrCatalyst() throws {
#if os(watchOS) || os(macOS) || os(tvOS)
expectFatalError(expectedMessage: Strings.purchase.begin_refund_request_unsupported.description) {
_ = try await helper.beginRefundRequest(forEntitlement: mockEntitlementID)
}
#else
throw XCTSkip("beginRefundRequestForEntitlement is not available for this test.")
#endif
}

func testBeginRefundRequestForActiveEntitlementFatalErrorIfNotIosOrCatalyst() throws {
#if os(watchOS) || os(macOS) || os(tvOS)
expectFatalError(expectedMessage: Strings.purchase.begin_refund_request_unsupported.description) {
_ = try await helper.beginRefundRequestforActiveEntitlement()
}
#else
throw XCTSkip("beginRefundRequestForEntitlement is not available for this test.")
#endif
}

#if os(iOS)
@available(iOS 15.0, macCatalyst 15.0, *)
func testBeginRefundRequestFailsAndPassesErrorThroughIfPurchasesUnverified() async throws {
try AvailabilityChecks.iOS15APIAvailableOrSkipTest()
Expand Down Expand Up @@ -250,7 +221,6 @@ class BeginRefundRequestHelperTests: TestCase {
expect(error.localizedDescription) == expectedError.localizedDescription
}
}
#endif

}

Expand Down Expand Up @@ -347,3 +317,5 @@ private extension BeginRefundRequestHelperTests {
}

}

#endif
6 changes: 6 additions & 0 deletions Tests/StoreKitUnitTests/PurchasesOrchestratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,10 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(transactionListener.invokedListenForTransactionsCount) == 1
}

#if os(iOS) || targetEnvironment(macCatalyst)

@available(watchOS, unavailable)
@available(tvOS, unavailable)
func testShowManageSubscriptionsCallsCompletionWithErrorIfThereIsAFailure() {
let message = "Failed to get managementURL from CustomerInfo. Details: customerInfo is nil."
mockManageSubsHelper.mockError = ErrorUtils.customerInfoError(withMessage: message)
Expand Down Expand Up @@ -646,6 +650,8 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
}
}

#endif

func testRestorePurchasesDoesNotLogWarningIfAllowSharingAppStoreAccountIsNotDefined() async throws {
let logger = TestLogHandler()

Expand Down
4 changes: 4 additions & 0 deletions Tests/UnitTests/Mocks/MockSK2BeginRefundRequestHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import Foundation
@testable import RevenueCat
import StoreKit

#if os(iOS) || targetEnvironment(macCatalyst)

@available(iOS 15.0, macCatalyst 15.0, *)
@available(watchOS, unavailable)
@available(tvOS, unavailable)
Expand Down Expand Up @@ -63,3 +65,5 @@ class MockSK2BeginRefundRequestHelper: SK2BeginRefundRequestHelper {
}

}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ class PurchasesAttributionDataTests: BasePurchasesTests {
expect(invokedMethodParams.appUserID) == identityManager.currentAppUserID
}

#if !os(tvOS)

@available(*, deprecated)
func testAdClientAttributionDataIsAutomaticallyCollected() throws {
self.setupPurchases(automaticCollection: true)
Expand All @@ -132,11 +134,6 @@ class PurchasesAttributionDataTests: BasePurchasesTests {
expect(obtainedVersionData["iad-campaign-id"]).toNot(beNil())
}

func testAdClientAttributionDataIsNotAutomaticallyCollectedIfDisabled() {
self.setupPurchases(automaticCollection: false)
expect(self.backend.invokedPostAttributionDataParameters).to(beNil())
}

func testAttributionDataPostponesMultiple() {
let data = ["yo": "dog", "what": 45, "is": ["up"]] as [String: Any]

Expand All @@ -148,4 +145,11 @@ class PurchasesAttributionDataTests: BasePurchasesTests {
expect(self.subscriberAttributesManager.invokedConvertAttributionDataAndSetParametersList).to(haveCount(1))
}

#endif

func testAdClientAttributionDataIsNotAutomaticallyCollectedIfDisabled() {
self.setupPurchases(automaticCollection: false)
expect(self.backend.invokedPostAttributionDataParameters).to(beNil())
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class SubscriptionPeriodTests: TestCase {

/// Necessary since SKProductSubscriptionPeriod.debugDescription & SKProductSubscriptionPeriod.description
/// return the object's address in memory.
@available(iOS 11.2, *)
@available(iOS 11.2, macOS 10.13.2, tvOS 11.2, watchOS 6.2, *)
private func description(for skProductSubscriptionPeriod: SKProductSubscriptionPeriod) -> String {

let periodUnit: String
Expand Down
29 changes: 1 addition & 28 deletions Tests/UnitTestsHostApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,4 @@
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

// MARK: UISceneSession Lifecycle

@available(iOS 13.0, *)
func application(_ application: UIApplication,
configurationForConnecting connectingSceneSession: UISceneSession,
options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after
// application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

}
class AppDelegate: UIResponder, UIApplicationDelegate {}
25 changes: 0 additions & 25 deletions Tests/UnitTestsHostApp/Base.lproj/LaunchScreen.storyboard

This file was deleted.

Loading

0 comments on commit e3c0dfe

Please sign in to comment.