parent
63cbf39a8a
commit
e21e11b022
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Fixed
|
||||
|
||||
- Platform purchasers cannot upgrade to full version. [#464](https://github.com/passepartoutvpn/passepartout-apple/issues/464)
|
||||
|
||||
## 2.3.2 (2024-01-11)
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -194,29 +194,8 @@ private extension PaywallView.PurchaseView {
|
|||
}
|
||||
|
||||
private extension PaywallView.PurchaseView {
|
||||
|
||||
// hide full version if already bought the other platform version
|
||||
var skFullVersion: InAppProduct? {
|
||||
guard !productManager.isFullVersion() else {
|
||||
return nil
|
||||
}
|
||||
#if targetEnvironment(macCatalyst)
|
||||
guard !productManager.hasPurchased(.fullVersion_iOS) else {
|
||||
return nil
|
||||
}
|
||||
#else
|
||||
guard !productManager.hasPurchased(.fullVersion_macOS) else {
|
||||
return nil
|
||||
}
|
||||
#endif
|
||||
return productManager.product(withIdentifier: .fullVersion)
|
||||
}
|
||||
|
||||
var skAppleTV: InAppProduct? {
|
||||
guard feature == .appleTV else {
|
||||
return nil
|
||||
}
|
||||
return productManager.product(withIdentifier: .appleTV)
|
||||
productManager.product(withIdentifier: .fullVersion)
|
||||
}
|
||||
|
||||
var fullFeatures: [FeatureModel] {
|
||||
|
@ -230,8 +209,9 @@ private extension PaywallView.PurchaseView {
|
|||
}
|
||||
|
||||
var productRowModels: [InAppProduct] {
|
||||
[skFullVersion, skAppleTV]
|
||||
.compactMap { $0 }
|
||||
productManager
|
||||
.purchasableProducts(withFeature: feature)
|
||||
.compactMap { productManager.product(withIdentifier: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -293,6 +293,44 @@ extension ProductManager {
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: Purchasable products
|
||||
|
||||
extension ProductManager {
|
||||
|
||||
// no purchase -> full version or platform version
|
||||
// purchased platform -> may only purchase other platform
|
||||
|
||||
public func purchasableProducts(withFeature feature: LocalProduct?) -> [LocalProduct] {
|
||||
var products: [LocalProduct] = {
|
||||
if hasPurchased(.fullVersion) {
|
||||
return []
|
||||
}
|
||||
#if targetEnvironment(macCatalyst)
|
||||
if hasPurchased(.fullVersion_macOS) {
|
||||
return []
|
||||
}
|
||||
if hasPurchased(.fullVersion_iOS) {
|
||||
return [.fullVersion_macOS]
|
||||
}
|
||||
return [.fullVersion, .fullVersion_macOS]
|
||||
#else
|
||||
if hasPurchased(.fullVersion_iOS) {
|
||||
return []
|
||||
}
|
||||
if hasPurchased(.fullVersion_macOS) {
|
||||
return [.fullVersion_iOS]
|
||||
}
|
||||
return [.fullVersion, .fullVersion_iOS]
|
||||
#endif
|
||||
}()
|
||||
if feature == .appleTV && !hasPurchased(.appleTV) {
|
||||
products.append(.appleTV)
|
||||
}
|
||||
return products
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Helpers
|
||||
|
||||
private extension ProductManager {
|
||||
|
|
|
@ -33,6 +33,8 @@ final class ProductManagerTests: XCTestCase {
|
|||
|
||||
private let noBuildProducts = BuildProducts { _ in [] }
|
||||
|
||||
// MARK: Build products
|
||||
|
||||
func test_givenBuildProducts_whenOlder_thenFullVersion() {
|
||||
let reader = MockReceiptReader()
|
||||
reader.setReceipt(withBuild: 500, products: [])
|
||||
|
@ -57,6 +59,8 @@ final class ProductManagerTests: XCTestCase {
|
|||
XCTAssertFalse(sut.isEligible(forFeature: .fullVersion))
|
||||
}
|
||||
|
||||
// MARK: Eligibility
|
||||
|
||||
func test_givenPurchase_whenReload_thenCredited() {
|
||||
let reader = MockReceiptReader()
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
|
@ -163,4 +167,70 @@ final class ProductManagerTests: XCTestCase {
|
|||
|
||||
XCTAssertTrue(sut.isEligible(forFeature: .appleTV))
|
||||
}
|
||||
|
||||
// MARK: Purchasable
|
||||
|
||||
func test_givenNoPurchase_thenCanBuyFullAndPlatformVersion() {
|
||||
let reader = MockReceiptReader()
|
||||
reader.setReceipt(withBuild: 1500, products: [])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
|
||||
#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: 1500, products: [.fullVersion])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [])
|
||||
}
|
||||
|
||||
func test_givenPlatformVersion_thenCannotPurchaseSamePlatform() {
|
||||
let reader = MockReceiptReader()
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
reader.setReceipt(withBuild: 1500, products: [.fullVersion_macOS])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [])
|
||||
#else
|
||||
reader.setReceipt(withBuild: 1500, products: [.fullVersion_iOS])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [])
|
||||
#endif
|
||||
}
|
||||
|
||||
func test_givenOtherPlatformVersion_thenCanOnlyPurchaseMissingPlatform() {
|
||||
let reader = MockReceiptReader()
|
||||
|
||||
#if targetEnvironment(macCatalyst)
|
||||
reader.setReceipt(withBuild: 1500, products: [.fullVersion_iOS])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [.fullVersion_macOS])
|
||||
#else
|
||||
reader.setReceipt(withBuild: 1500, products: [.fullVersion_macOS])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
XCTAssertEqual(sut.purchasableProducts(withFeature: nil), [.fullVersion_iOS])
|
||||
#endif
|
||||
}
|
||||
|
||||
func test_givenAppleTV_whenDidNotPurchase_thenCanPurchase() {
|
||||
let reader = MockReceiptReader()
|
||||
reader.setReceipt(withBuild: 1500, products: [])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
|
||||
XCTAssertTrue(sut.purchasableProducts(withFeature: .appleTV).contains(.appleTV))
|
||||
}
|
||||
|
||||
func test_givenAppleTV_whenDidPurchase_thenCannotPurchase() {
|
||||
let reader = MockReceiptReader()
|
||||
reader.setReceipt(withBuild: 1500, products: [.appleTV])
|
||||
let sut = ProductManager(inApp: inApp, receiptReader: reader, buildProducts: noBuildProducts)
|
||||
|
||||
XCTAssertFalse(sut.purchasableProducts(withFeature: .appleTV).contains(.appleTV))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue