passepartout-apple/PassepartoutLibrary/Tests/PassepartoutFrontendTests/ProductManagerTests.swift

282 lines
11 KiB
Swift

//
// ProductManagerTests.swift
// Passepartout
//
// Created by Davide De Rosa on 12/19/23.
// 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
@testable import PassepartoutFrontend
import XCTest
@MainActor
final class ProductManagerTests: XCTestCase {
private let inApp = MockInApp()
private let olderBuildNumber = 500
private let defaultBuildNumber = 1000
private let newerBuildNumber = 1500
// MARK: Build products
func test_givenBuildProducts_whenOlder_thenFullVersion() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: olderBuildNumber, products: [])
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: BuildProducts { build in
if build <= self.defaultBuildNumber {
return [.fullVersion]
}
return []
})
XCTAssertTrue(sut.isEligible(forFeature: .fullVersion))
}
func test_givenBuildProducts_whenNewer_thenFreeVersion() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: newerBuildNumber, products: [])
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: BuildProducts { build in
if build <= self.defaultBuildNumber {
return [.fullVersion]
}
return []
})
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion))
}
// MARK: Eligibility
func test_givenPurchasedFeature_whenReloadReceipt_thenIsEligible() {
let reader = MockReceiptReader()
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion))
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion])
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion))
sut.reloadReceipt()
XCTAssertTrue(sut.isEligible(forFeature: .fullVersion))
}
func test_givenPurchasedFeatures_thenIsOnlyEligibleForFeatures() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.siriShortcuts, .networkSettings])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertTrue(sut.isEligible(forFeature: .siriShortcuts))
XCTAssertTrue(sut.isEligible(forFeature: .networkSettings))
XCTAssertFalse(sut.isEligible(forFeature: .trustedNetworks))
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion))
XCTAssertFalse(sut.isFullVersion())
}
func test_givenPurchasedAndCancelledFeature_thenIsNotEligible() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion], cancelledProducts: [.fullVersion])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion))
}
func test_givenFreeVersion_thenIsNotEligibleForAnyFeature() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertFalse(sut.isFullVersion())
XCTAssertTrue(LocalProduct
.allFeatures
.allSatisfy { !sut.isEligible(forFeature: $0) }
)
}
func test_givenFreeVersion_thenIsNotEligibleForAppleTV() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertFalse(sut.isEligible(forFeature: .appleTV))
}
func test_givenFullVersion_thenIsEligibleForAnyFeatureExceptAppleTV() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertTrue(sut.isFullVersion())
LocalProduct
.allFeatures
.forEach {
guard $0 != .appleTV && !$0.isLegacyPlatformVersion else {
XCTAssertFalse(sut.isEligible(forFeature: $0), $0.rawValue)
return
}
XCTAssertTrue(sut.isEligible(forFeature: $0), $0.rawValue)
}
}
func test_givenFullVersion_thenIsNotEligibleForAppleTV() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertFalse(sut.isEligible(forFeature: .appleTV))
}
func test_givenAppleTV_thenIsEligibleForAppleTV() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.appleTV])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertTrue(sut.isEligible(forFeature: .appleTV))
}
func test_givenPlatformVersion_thenIsFullVersionForPlatform() {
let reader = MockReceiptReader()
let sut = ProductManager(inApp: inApp, receiptReader: reader)
#if targetEnvironment(macCatalyst)
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion_macOS, .networkSettings])
sut.reloadReceipt()
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion_iOS))
XCTAssertTrue(sut.isEligible(forFeature: .fullVersion_macOS))
#else
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion_iOS, .networkSettings])
sut.reloadReceipt()
XCTAssertTrue(sut.isEligible(forFeature: .fullVersion_iOS))
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion_macOS))
#endif
XCTAssertTrue(sut.isCurrentPlatformVersion())
XCTAssertTrue(sut.isFullVersion())
XCTAssertTrue(sut.isEligible(forFeature: .fullVersion))
}
// MARK: Purchasable
func test_givenNoPurchase_thenCanBuyFullAndPlatformVersion() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
#if targetEnvironment(macCatalyst)
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [.fullVersion, .fullVersion_macOS])
#else
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [.fullVersion, .fullVersion_iOS])
#endif
}
func test_givenFullVersion_thenCannotPurchase() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [])
}
func test_givenPlatformVersion_thenCannotPurchaseSamePlatform() {
let reader = MockReceiptReader()
#if targetEnvironment(macCatalyst)
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion_macOS])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [])
#else
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion_iOS])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [])
#endif
}
func test_givenOtherPlatformVersion_thenCanOnlyPurchaseMissingPlatform() {
let reader = MockReceiptReader()
#if targetEnvironment(macCatalyst)
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion_iOS])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [.fullVersion_macOS])
#else
reader.setReceipt(withBuild: defaultBuildNumber, products: [.fullVersion_macOS])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [.fullVersion_iOS])
#endif
}
func test_givenAppleTV_whenDidNotPurchase_thenCanPurchase() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: .appleTV), [.appleTV])
}
func test_givenAppleTV_whenDidPurchase_thenCannotPurchase() {
let reader = MockReceiptReader()
reader.setReceipt(withBuild: defaultBuildNumber, products: [.appleTV])
let sut = ProductManager(inApp: inApp, receiptReader: reader)
XCTAssertEqual(sut.purchasableProducts(withFeature: .appleTV), [])
}
// MARK: App type
func test_givenBetaApp_thenIsNotEligibleForAnyFeature() {
let reader = MockReceiptReader()
let sut = ProductManager(inApp: inApp, receiptReader: reader, overriddenAppType: .beta)
XCTAssertTrue(LocalProduct
.allFeatures
.allSatisfy { !sut.isEligible(forFeature: $0) }
)
}
func test_givenFullApp_thenIsEligibleForAnyFeatureExceptAppleTV() {
let reader = MockReceiptReader()
let sut = ProductManager(inApp: inApp, receiptReader: reader, overriddenAppType: .fullVersion)
LocalProduct
.allFeatures
.forEach {
guard !$0.isLegacyPlatformVersion, $0 != .appleTV else {
XCTAssertFalse(sut.isEligible(forFeature: $0), $0.rawValue)
return
}
XCTAssertTrue(sut.isEligible(forFeature: $0), $0.rawValue)
}
}
func test_givenFullPlusTVApp_thenIsEligibleForAnyFeature() {
let reader = MockReceiptReader()
let sut = ProductManager(inApp: inApp, receiptReader: reader, overriddenAppType: .fullVersionPlusTV)
LocalProduct
.allFeatures
.forEach {
guard !$0.isLegacyPlatformVersion else {
XCTAssertFalse(sut.isEligible(forFeature: $0), $0.rawValue)
return
}
XCTAssertTrue(sut.isEligible(forFeature: $0), $0.rawValue)
}
}
}