diff --git a/Library/Sources/CommonIAP/Domain/AppProduct+Features.swift b/Library/Sources/CommonIAP/Domain/AppProduct+Features.swift index 7c6bc38c..ce51c609 100644 --- a/Library/Sources/CommonIAP/Domain/AppProduct+Features.swift +++ b/Library/Sources/CommonIAP/Domain/AppProduct+Features.swift @@ -37,11 +37,11 @@ extension AppProduct { public enum Full { static let all: [AppProduct] = [ - .Full.OneTime.full, - .Full.OneTime.fullTV, + .Full.OneTime.allFeatures, .Full.Recurring.monthly, .Full.Recurring.yearly, // + .Full.OneTime.iOS_macOS, .Full.OneTime.iOS, .Full.OneTime.macOS ] @@ -66,12 +66,7 @@ extension AppProduct.Features { extension AppProduct.Full { public enum OneTime { - - // iOS/macOS - public static let full = AppProduct(featureId: "full_multi_version") - - // iOS/macOS + tvOS - public static let fullTV = AppProduct(featureId: "full.lifetime") + public static let allFeatures = AppProduct(featureId: "full.lifetime") } public enum Recurring { @@ -84,7 +79,10 @@ extension AppProduct.Full { extension AppProduct { public var isFullVersion: Bool { switch self { - case .Full.OneTime.full, .Full.OneTime.fullTV, .Full.Recurring.monthly, .Full.Recurring.yearly: + case .Full.Recurring.yearly, + .Full.Recurring.monthly, + .Full.OneTime.allFeatures, + .Full.OneTime.iOS_macOS: return true default: return false @@ -113,6 +111,9 @@ extension AppProduct.Features { extension AppProduct.Full.OneTime { + @available(*, deprecated) + public static let iOS_macOS = AppProduct(featureId: "full_multi_version") + @available(*, deprecated) public static let iOS = AppProduct(featureId: "full_version") diff --git a/Library/Sources/CommonIAP/Domain/AppUserLevel.swift b/Library/Sources/CommonIAP/Domain/AppUserLevel.swift index 58817423..a73e99e1 100644 --- a/Library/Sources/CommonIAP/Domain/AppUserLevel.swift +++ b/Library/Sources/CommonIAP/Domain/AppUserLevel.swift @@ -32,9 +32,9 @@ public enum AppUserLevel: Int, Sendable { case beta = 1 - case full = 2 + case fullV2 = 2 // without .appleTV - case fullTV = 3 + case fullV3 = 3 } extension AppUserLevel { diff --git a/Library/Sources/CommonLibrary/IAP/AppFeature+Full.swift b/Library/Sources/CommonLibrary/IAP/AppFeature+Full.swift deleted file mode 100644 index 073e6ad5..00000000 --- a/Library/Sources/CommonLibrary/IAP/AppFeature+Full.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// AppFeature+Full.swift -// Passepartout -// -// Created by Davide De Rosa on 11/20/24. -// Copyright (c) 2024 Davide De Rosa. All rights reserved. -// -// https://github.com/passepartoutvpn -// -// This file is part of Passepartout. -// -// Passepartout is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Passepartout is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Passepartout. If not, see . -// - -import Foundation - -extension AppFeature { - public static let fullFeatures = AppFeature.allCases.filter { - $0 != .appleTV - } - - public static let fullTVFeatures = AppFeature.allCases -} diff --git a/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Levels.swift b/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Levels.swift index e8ae88b4..39db11a6 100644 --- a/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Levels.swift +++ b/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Levels.swift @@ -35,11 +35,11 @@ extension AppUserLevel: AppFeatureProviding { .sharing ] - case .full: - return AppFeature.fullFeatures + case .fullV2: + return AppProduct.Full.OneTime.iOS_macOS.features - case .fullTV: - return AppFeature.fullTVFeatures + case .fullV3: + return AppProduct.Full.OneTime.allFeatures.features default: return [] diff --git a/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Products.swift b/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Products.swift index a943b074..d641d0dc 100644 --- a/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Products.swift +++ b/Library/Sources/CommonLibrary/IAP/AppFeatureProviding+Products.swift @@ -31,27 +31,29 @@ extension AppProduct: AppFeatureProviding { // MARK: Current - case .Full.OneTime.full: - return AppFeature.fullFeatures - - case .Full.OneTime.fullTV, .Full.Recurring.monthly, .Full.Recurring.yearly: - return AppFeature.fullTVFeatures + case .Full.OneTime.allFeatures, .Full.Recurring.monthly, .Full.Recurring.yearly: + return AppFeature.allCases case .Features.appleTV: return [.appleTV, .sharing] // MARK: Discontinued + case .Full.OneTime.iOS_macOS: + return AppFeature.allCases.filter { + $0 != .appleTV + } + case .Full.OneTime.iOS: #if os(iOS) - return AppFeature.fullFeatures + return AppProduct.Full.OneTime.iOS_macOS.features #else return [] #endif case .Full.OneTime.macOS: #if os(macOS) - return AppFeature.fullFeatures + return AppProduct.Full.OneTime.iOS_macOS.features #else return [] #endif diff --git a/Library/Sources/CommonLibrary/IAP/IAPManager+Suggestions.swift b/Library/Sources/CommonLibrary/IAP/IAPManager+Suggestions.swift index fd8530cc..c4b8c3c5 100644 --- a/Library/Sources/CommonLibrary/IAP/IAPManager+Suggestions.swift +++ b/Library/Sources/CommonLibrary/IAP/IAPManager+Suggestions.swift @@ -30,7 +30,7 @@ import PassepartoutKit extension IAPManager { public var isFullVersionPurchaser: Bool { - purchasedProducts.contains(.Full.OneTime.full) || purchasedProducts.contains(.Full.OneTime.fullTV) || (purchasedProducts.contains(.Full.OneTime.iOS) && purchasedProducts.contains(.Full.OneTime.macOS)) + purchasedProducts.contains(where: \.isFullVersion) || (purchasedProducts.contains(.Full.OneTime.iOS) && purchasedProducts.contains(.Full.OneTime.macOS)) } public func suggestedProducts(for requiredFeatures: Set, withRecurring: Bool = true) -> Set? { @@ -51,20 +51,14 @@ extension IAPManager { assertionFailure("Full version purchaser requiring other than [.appleTV]") } } else { // !isFullVersionPurchaser - if ineligibleFeatures == [.appleTV] { - products.insert(.Features.appleTV) - products.insert(.Full.OneTime.fullTV) - } else if ineligibleFeatures.contains(.appleTV) { - products.insert(.Full.OneTime.fullTV) + if eligibleFeatures.contains(.appleTV) { + products.insert(.Full.OneTime.iOS_macOS) } else { - if !eligibleFeatures.contains(.appleTV) { - products.insert(.Full.OneTime.fullTV) - } - products.insert(.Full.OneTime.full) + products.insert(.Full.OneTime.allFeatures) } } - if withRecurring && products.contains(.Full.OneTime.fullTV) { + if withRecurring && products.contains(.Full.OneTime.allFeatures) { products.insert(.Full.Recurring.monthly) products.insert(.Full.Recurring.yearly) } diff --git a/Library/Sources/UILibrary/Previews/AppContext+Previews.swift b/Library/Sources/UILibrary/Previews/AppContext+Previews.swift index 11063a86..79fc9900 100644 --- a/Library/Sources/UILibrary/Previews/AppContext+Previews.swift +++ b/Library/Sources/UILibrary/Previews/AppContext+Previews.swift @@ -31,7 +31,7 @@ import PassepartoutKit extension AppContext { public static let forPreviews: AppContext = { let iapManager = IAPManager( - customUserLevel: .fullTV, + customUserLevel: .fullV3, inAppHelper: FakeAppProductHelper(), receiptReader: FakeAppReceiptReader(), betaChecker: TestFlightChecker(), diff --git a/Library/Sources/UILibrary/Views/Paywall/PaywallView.swift b/Library/Sources/UILibrary/Views/Paywall/PaywallView.swift index 8b91c61b..b3492133 100644 --- a/Library/Sources/UILibrary/Views/Paywall/PaywallView.swift +++ b/Library/Sources/UILibrary/Views/Paywall/PaywallView.swift @@ -90,7 +90,7 @@ private extension PaywallView { featureProductsView fullProductsView if !iapManager.isFullVersionPurchaser { - fullVersionFeaturesView + allFeaturesView } restoreView } @@ -142,11 +142,11 @@ private extension PaywallView { } } - var fullVersionFeaturesView: some View { + var allFeaturesView: some View { FeatureListView( style: allFeaturesStyle, header: Strings.Views.Paywall.Sections.AllFeatures.header, - features: fullVersionFeatures, + features: allFeatures, content: featureView(for:) ) } @@ -197,8 +197,8 @@ private extension PaywallView { // MARK: - private extension PaywallView { - var fullVersionFeatures: [AppFeature] { - AppFeature.fullFeatures + var allFeatures: [AppFeature] { + AppProduct.Full.OneTime.allFeatures.features } func fetchAvailableProducts() async { @@ -285,9 +285,9 @@ private extension AppProduct { return .min case .Full.Recurring.monthly: return 1 - case .Full.OneTime.fullTV: + case .Full.OneTime.allFeatures: return 2 - case .Full.OneTime.full: + case .Full.OneTime.iOS_macOS: return 3 default: return .max diff --git a/Library/Tests/CommonLibraryTests/Business/IAPManagerTests.swift b/Library/Tests/CommonLibraryTests/Business/IAPManagerTests.swift index 193a49a7..7bad677f 100644 --- a/Library/Tests/CommonLibraryTests/Business/IAPManagerTests.swift +++ b/Library/Tests/CommonLibraryTests/Business/IAPManagerTests.swift @@ -49,7 +49,7 @@ extension IAPManagerTests { let sut = IAPManager(receiptReader: reader) let appProducts: [AppProduct] = [ - .Full.OneTime.full, + .Full.OneTime.iOS_macOS, .Donations.huge ] let inAppProducts = try await sut.purchasableProducts(for: appProducts) @@ -88,12 +88,12 @@ extension IAPManagerTests { await reader.setReceipt(withBuild: olderBuildNumber, identifiers: []) let sut = IAPManager(receiptReader: reader) { build in if build <= self.defaultBuildNumber { - return [.Full.OneTime.full] + return [.Full.OneTime.iOS_macOS] } return [] } await sut.reloadReceipt() - XCTAssertTrue(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertTrue(sut.isEligible(for: AppFeature.fullV2Features)) } func test_givenBuildProducts_whenNewer_thenFreeVersion() async { @@ -101,12 +101,12 @@ extension IAPManagerTests { await reader.setReceipt(withBuild: newerBuildNumber, products: []) let sut = IAPManager(receiptReader: reader) { build in if build <= self.defaultBuildNumber { - return [.Full.OneTime.full] + return [.Full.OneTime.iOS_macOS] } return [] } await sut.reloadReceipt() - XCTAssertFalse(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertFalse(sut.isEligible(for: AppFeature.fullV2Features)) } } @@ -117,13 +117,13 @@ extension IAPManagerTests { let reader = FakeAppReceiptReader() let sut = IAPManager(receiptReader: reader) - XCTAssertFalse(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertFalse(sut.isEligible(for: AppFeature.fullV2Features)) - await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.full]) - XCTAssertFalse(sut.isEligible(for: AppFeature.fullFeatures)) + await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.iOS_macOS]) + XCTAssertFalse(sut.isEligible(for: AppFeature.fullV2Features)) await sut.reloadReceipt() - XCTAssertTrue(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertTrue(sut.isEligible(for: AppFeature.fullV2Features)) } func test_givenPurchasedFeatures_thenIsOnlyEligibleForFeatures() async { @@ -139,20 +139,20 @@ extension IAPManagerTests { XCTAssertFalse(sut.isEligible(for: .onDemand)) XCTAssertTrue(sut.isEligible(for: .routing)) XCTAssertFalse(sut.isEligible(for: .sharing)) - XCTAssertFalse(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertFalse(sut.isEligible(for: AppFeature.fullV2Features)) } func test_givenPurchasedAndCancelledFeature_thenIsNotEligible() async { let reader = FakeAppReceiptReader() await reader.setReceipt( withBuild: defaultBuildNumber, - products: [.Full.OneTime.full], - cancelledProducts: [.Full.OneTime.full] + products: [.Full.OneTime.iOS_macOS], + cancelledProducts: [.Full.OneTime.iOS_macOS] ) let sut = IAPManager(receiptReader: reader) await sut.reloadReceipt() - XCTAssertFalse(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertFalse(sut.isEligible(for: AppFeature.fullV2Features)) } func test_givenFreeVersion_thenIsNotEligibleForAnyFeature() async { @@ -161,7 +161,7 @@ extension IAPManagerTests { let sut = IAPManager(receiptReader: reader) await sut.reloadReceipt() - AppFeature.fullFeatures.forEach { + AppFeature.fullV2Features.forEach { XCTAssertFalse(sut.isEligible(for: $0)) } } @@ -177,7 +177,7 @@ extension IAPManagerTests { func test_givenFullV2Version_thenIsEligibleForAnyFeatureExceptExcluded() async { let reader = FakeAppReceiptReader() - await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.full]) + await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.iOS_macOS]) let sut = IAPManager(receiptReader: reader) await sut.reloadReceipt() @@ -186,7 +186,7 @@ extension IAPManagerTests { .interactiveLogin ] AppFeature.allCases.forEach { - if AppFeature.fullFeatures.contains($0) { + if AppFeature.fullV2Features.contains($0) { XCTAssertTrue(sut.isEligible(for: $0)) } else { XCTAssertTrue(excluded.contains($0)) @@ -212,7 +212,7 @@ extension IAPManagerTests { #if os(macOS) await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.macOS, .Features.networkSettings]) await sut.reloadReceipt() - XCTAssertTrue(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertTrue(sut.isEligible(for: AppFeature.fullV2Features)) #else await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.iOS, .Features.networkSettings]) await sut.reloadReceipt() @@ -227,7 +227,7 @@ extension IAPManagerTests { #if os(macOS) await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.iOS, .Features.networkSettings]) await sut.reloadReceipt() - XCTAssertFalse(sut.isEligible(for: AppFeature.fullFeatures)) + XCTAssertFalse(sut.isEligible(for: AppFeature.fullV2Features)) #else await reader.setReceipt(withBuild: defaultBuildNumber, products: [.Full.OneTime.macOS, .Features.networkSettings]) await sut.reloadReceipt() @@ -266,23 +266,21 @@ extension IAPManagerTests { XCTAssertNil(sut.suggestedProducts(for: [])) } - func test_givenFree_whenRequireFeature_thenSuggestsFullAndFullTV() async { + func test_givenFree_whenRequireFeature_thenSuggestsFullTV() async { let sut = await IAPManager(products: []) XCTAssertEqual(sut.suggestedProducts(for: [.dns]), [ .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.full, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } - func test_givenFree_whenRequireAppleTV_thenSuggestsAppleTVAndFullTV() async { + func test_givenFree_whenRequireAppleTV_thenSuggestsFullTV() async { let sut = await IAPManager(products: []) XCTAssertEqual(sut.suggestedProducts(for: [.appleTV]), [ - .Features.appleTV, .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } @@ -291,7 +289,7 @@ extension IAPManagerTests { XCTAssertEqual(sut.suggestedProducts(for: [.appleTV, .providers]), [ .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } @@ -300,43 +298,39 @@ extension IAPManagerTests { XCTAssertNil(sut.suggestedProducts(for: [.dns])) } - func test_givenCurrentPlatform_whenRequireAppleTV_thenSuggestsAppleTVAndFullTV() async { + func test_givenCurrentPlatform_whenRequireAppleTV_thenSuggestsFullTV() async { let sut = await IAPManager.withFullCurrentPlatform() XCTAssertEqual(sut.suggestedProducts(for: [.appleTV]), [ - .Features.appleTV, .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } - func test_givenCurrentPlatform_whenRequireFeatureAndAppleTV_thenSuggestsAppleTVAndFullTV() async { + func test_givenCurrentPlatform_whenRequireFeatureAndAppleTV_thenSuggestsFullTV() async { let sut = await IAPManager.withFullCurrentPlatform() XCTAssertEqual(sut.suggestedProducts(for: [.appleTV, .providers]), [ - .Features.appleTV, .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } - func test_givenOtherPlatform_whenRequireFeature_thenSuggestsFullAndFullTV() async { + func test_givenOtherPlatform_whenRequireFeature_thenSuggestsFullTV() async { let sut = await IAPManager.withFullOtherPlatform() XCTAssertEqual(sut.suggestedProducts(for: [.dns]), [ .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV, - .Full.OneTime.full + .Full.OneTime.allFeatures ]) } - func test_givenOtherPlatform_whenRequireAppleTV_thenSuggestsAppleTVAndFullTV() async { + func test_givenOtherPlatform_whenRequireAppleTV_thenSuggestsFullTV() async { let sut = await IAPManager.withFullOtherPlatform() XCTAssertEqual(sut.suggestedProducts(for: [.appleTV]), [ - .Features.appleTV, .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } @@ -345,24 +339,24 @@ extension IAPManagerTests { XCTAssertEqual(sut.suggestedProducts(for: [.appleTV, .providers]), [ .Full.Recurring.yearly, .Full.Recurring.monthly, - .Full.OneTime.fullTV + .Full.OneTime.allFeatures ]) } func test_givenFull_whenRequireFeature_thenSuggestsNothing() async { - let sut = await IAPManager(products: [.Full.OneTime.full]) + let sut = await IAPManager(products: [.Full.OneTime.iOS_macOS]) XCTAssertNil(sut.suggestedProducts(for: [.dns])) } func test_givenFull_whenRequireAppleTV_thenSuggestsAppleTV() async { - let sut = await IAPManager(products: [.Full.OneTime.full]) + let sut = await IAPManager(products: [.Full.OneTime.iOS_macOS]) XCTAssertEqual(sut.suggestedProducts(for: [.appleTV]), [ .Features.appleTV ]) } func test_givenFull_whenRequireFeatureAndAppleTV_thenSuggestsAppleTV() async { - let sut = await IAPManager(products: [.Full.OneTime.full]) + let sut = await IAPManager(products: [.Full.OneTime.iOS_macOS]) XCTAssertEqual(sut.suggestedProducts(for: [.appleTV, .providers]), [ .Features.appleTV ]) @@ -371,7 +365,7 @@ extension IAPManagerTests { func test_givenAppleTV_whenRequireFeature_thenSuggestsFull() async { let sut = await IAPManager(products: [.Features.appleTV]) XCTAssertEqual(sut.suggestedProducts(for: [.dns]), [ - .Full.OneTime.full + .Full.OneTime.iOS_macOS ]) } @@ -383,22 +377,22 @@ extension IAPManagerTests { func test_givenAppleTV_whenRequireFeatureAndAppleTV_thenSuggestsFull() async { let sut = await IAPManager(products: [.Features.appleTV]) XCTAssertEqual(sut.suggestedProducts(for: [.appleTV, .providers]), [ - .Full.OneTime.full + .Full.OneTime.iOS_macOS ]) } - func test_givenAll_whenRequireFeature_thenSuggestsNothing() async { - let sut = await IAPManager(products: [.Full.OneTime.fullTV]) + func test_givenFullTV_whenRequireFeature_thenSuggestsNothing() async { + let sut = await IAPManager(products: [.Full.OneTime.allFeatures]) XCTAssertNil(sut.suggestedProducts(for: [.dns])) } - func test_givenAll_whenRequireAppleTV_thenSuggestsNothing() async { - let sut = await IAPManager(products: [.Full.OneTime.fullTV]) + func test_givenFullTV_whenRequireAppleTV_thenSuggestsNothing() async { + let sut = await IAPManager(products: [.Full.OneTime.allFeatures]) XCTAssertNil(sut.suggestedProducts(for: [.appleTV])) } - func test_givenAll_whenRequireFeatureAndAppleTV_thenSuggestsNothing() async { - let sut = await IAPManager(products: [.Full.OneTime.fullTV]) + func test_givenFullTV_whenRequireFeatureAndAppleTV_thenSuggestsNothing() async { + let sut = await IAPManager(products: [.Full.OneTime.allFeatures]) XCTAssertNil(sut.suggestedProducts(for: [.appleTV, .providers])) } } @@ -446,7 +440,7 @@ extension IAPManagerTests { func test_givenFullV2App_thenIsEligibleForAnyFeatureExceptExcluded() async { let reader = FakeAppReceiptReader() - let sut = IAPManager(customUserLevel: .full, receiptReader: reader) + let sut = IAPManager(customUserLevel: .fullV2, receiptReader: reader) await sut.reloadReceipt() let excluded: Set = [ @@ -454,7 +448,7 @@ extension IAPManagerTests { .interactiveLogin ] AppFeature.allCases.forEach { - if AppFeature.fullFeatures.contains($0) { + if AppFeature.fullV2Features.contains($0) { XCTAssertTrue(sut.isEligible(for: $0)) } else { XCTAssertTrue(excluded.contains($0)) @@ -465,10 +459,10 @@ extension IAPManagerTests { func test_givenSubscriberApp_thenIsEligibleForAnyFeature() async { let reader = FakeAppReceiptReader() - let sut = IAPManager(customUserLevel: .fullTV, receiptReader: reader) + let sut = IAPManager(customUserLevel: .fullV3, receiptReader: reader) await sut.reloadReceipt() - AppFeature.fullFeatures.forEach { + AppFeature.fullV2Features.forEach { XCTAssertTrue(sut.isEligible(for: $0)) } XCTAssertTrue(sut.isEligible(for: .appleTV)) @@ -545,7 +539,7 @@ extension IAPManagerTests { extension IAPManagerTests { func test_givenManager_whenObserveObjects_thenReloadsReceipt() async { let reader = FakeAppReceiptReader() - await reader.setReceipt(withBuild: .max, products: [.Full.OneTime.full]) + await reader.setReceipt(withBuild: .max, products: [.Full.OneTime.iOS_macOS]) let sut = IAPManager(receiptReader: reader) XCTAssertEqual(sut.userLevel, .undefined) @@ -620,3 +614,7 @@ private extension IAPManager { #endif } } + +private extension AppFeature { + static let fullV2Features = AppProduct.Full.OneTime.iOS_macOS.features +} diff --git a/Passepartout/App/Context/AppContext+Testing.swift b/Passepartout/App/Context/AppContext+Testing.swift index bc0cda1e..5dc4cd01 100644 --- a/Passepartout/App/Context/AppContext+Testing.swift +++ b/Passepartout/App/Context/AppContext+Testing.swift @@ -33,7 +33,7 @@ extension AppContext { static func forUITesting(withRegistry registry: Registry) -> AppContext { let dependencies: Dependencies = .shared let iapManager = IAPManager( - customUserLevel: .fullTV, + customUserLevel: .fullV3, inAppHelper: dependencies.appProductHelper(), receiptReader: FakeAppReceiptReader(), betaChecker: TestFlightChecker(),