mirror of
https://github.com/passepartoutvpn/passepartout-apple.git
synced 2025-02-22 07:42:07 +00:00
Simplify products (#1024)
Only offer compensations to former purchasers: - .appleTV to .full purchasers - .full to .appleTV purchasers Always suggest .fullTV to new purchasers. Finally rename: - .full to .iOS_macOS - .fullTV to .allFeatures (lifetime)
This commit is contained in:
parent
2eca757dc6
commit
c527171957
@ -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")
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension AppFeature {
|
||||
public static let fullFeatures = AppFeature.allCases.filter {
|
||||
$0 != .appleTV
|
||||
}
|
||||
|
||||
public static let fullTVFeatures = AppFeature.allCases
|
||||
}
|
@ -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 []
|
||||
|
@ -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
|
||||
|
@ -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<AppFeature>, withRecurring: Bool = true) -> Set<AppProduct>? {
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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<AppFeature> = [
|
||||
@ -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
|
||||
}
|
||||
|
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user