2022-04-05 16:18:06 -03:00
|
|
|
//
|
|
|
|
|
// Copyright RevenueCat Inc. All Rights Reserved.
|
|
|
|
|
//
|
|
|
|
|
// Licensed under the MIT License (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
|
//
|
|
|
|
|
// LocalReceiptParserStoreKitTests.swift
|
|
|
|
|
//
|
|
|
|
|
// Created by Andrés Boedo on 4/4/22.
|
|
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
import Nimble
|
|
|
|
|
@testable import RevenueCat
|
2022-04-06 15:44:00 -03:00
|
|
|
import StoreKit
|
2022-04-05 16:18:06 -03:00
|
|
|
import XCTest
|
|
|
|
|
|
2023-03-16 13:11:24 -07:00
|
|
|
@available(iOS 14.0, tvOS 14.0, macOS 11.0, watchOS 7.0, *)
|
2022-04-05 16:18:06 -03:00
|
|
|
class LocalReceiptParserStoreKitTests: StoreKitConfigTestCase {
|
|
|
|
|
|
2022-08-31 13:30:38 -07:00
|
|
|
private let operationDispatcher: OperationDispatcher = .default
|
|
|
|
|
private let receiptRefreshRequestFactory = ReceiptRefreshRequestFactory()
|
|
|
|
|
private var requestFetcher: StoreKitRequestFetcher!
|
|
|
|
|
private var systemInfo: SystemInfo!
|
|
|
|
|
private var receiptFetcher: ReceiptFetcher!
|
2022-12-22 10:09:12 -08:00
|
|
|
private var parser: PurchasesReceiptParser!
|
2022-04-05 16:18:06 -03:00
|
|
|
|
2022-04-06 15:43:26 -03:00
|
|
|
override func setUpWithError() throws {
|
|
|
|
|
try super.setUpWithError()
|
2022-08-31 13:30:38 -07:00
|
|
|
self.requestFetcher = StoreKitRequestFetcher(requestFactory: receiptRefreshRequestFactory,
|
|
|
|
|
operationDispatcher: operationDispatcher)
|
2022-04-05 16:18:06 -03:00
|
|
|
|
2023-07-13 08:24:51 -07:00
|
|
|
self.systemInfo = SystemInfo(platformInfo: Purchases.platformInfo,
|
|
|
|
|
finishTransactions: true,
|
|
|
|
|
operationDispatcher: operationDispatcher,
|
2024-07-01 12:37:21 -07:00
|
|
|
storeKitVersion: .storeKit1)
|
2022-08-31 13:30:38 -07:00
|
|
|
self.receiptFetcher = ReceiptFetcher(requestFetcher: self.requestFetcher, systemInfo: systemInfo)
|
2022-09-27 12:50:34 -07:00
|
|
|
self.parser = .default
|
2022-04-06 15:43:26 -03:00
|
|
|
}
|
|
|
|
|
|
2022-08-31 13:30:38 -07:00
|
|
|
@MainActor
|
2022-04-06 15:43:26 -03:00
|
|
|
func testReceiptParserParsesEmptyReceipt() async throws {
|
2024-03-05 05:30:49 -06:00
|
|
|
let data = try await XCTAsyncUnwrap(await self.receiptFetcher.receiptData(refreshPolicy: .always))
|
2022-04-06 15:43:26 -03:00
|
|
|
|
|
|
|
|
let receipt = try self.parser.parse(from: data)
|
2022-04-05 16:18:06 -03:00
|
|
|
|
2022-04-06 15:44:00 -03:00
|
|
|
expect(receipt.bundleId) == "com.revenuecat.StoreKitUnitTestsHostApp"
|
2024-01-09 18:07:05 -08:00
|
|
|
#if os(macOS)
|
|
|
|
|
expect(receipt.applicationVersion) == SystemInfo.frameworkVersion.replacingOccurrences(
|
|
|
|
|
of: "-SNAPSHOT",
|
|
|
|
|
with: ""
|
|
|
|
|
)
|
|
|
|
|
#else
|
2022-04-05 16:18:06 -03:00
|
|
|
expect(receipt.applicationVersion) == "1"
|
2024-01-09 18:07:05 -08:00
|
|
|
#endif
|
2022-04-06 15:44:00 -03:00
|
|
|
expect(receipt.originalApplicationVersion).to(beNil())
|
|
|
|
|
expect(receipt.opaqueValue).toNot(beNil())
|
|
|
|
|
expect(receipt.sha1Hash).toNot(beNil())
|
2023-05-17 12:43:14 -04:00
|
|
|
expect(receipt.creationDate).to(beCloseToNow())
|
2022-04-06 15:44:00 -03:00
|
|
|
expect(receipt.expirationDate).toNot(beNil())
|
2023-05-17 12:43:14 -04:00
|
|
|
expect(receipt.expirationDate).toNot(beCloseToNow())
|
2022-04-06 15:44:00 -03:00
|
|
|
expect(receipt.inAppPurchases).to(beEmpty())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *)
|
|
|
|
|
func testReceiptParserParsesReceiptWithSingleIAP() async throws {
|
2024-07-01 12:37:21 -07:00
|
|
|
try AvailabilityChecks.iOS16APIAvailableOrSkipTest()
|
2022-04-06 15:44:00 -03:00
|
|
|
let product = try await fetchSk2Product()
|
2023-07-12 06:05:53 -07:00
|
|
|
let purchaseTime = Date()
|
|
|
|
|
|
2022-04-06 15:44:00 -03:00
|
|
|
_ = try await product.purchase()
|
|
|
|
|
|
2022-08-31 13:30:38 -07:00
|
|
|
let receiptData = await self.receiptFetcher.receiptData(refreshPolicy: .always)
|
|
|
|
|
let data = try XCTUnwrap(receiptData)
|
2022-04-06 15:44:00 -03:00
|
|
|
|
|
|
|
|
let receipt = try self.parser.parse(from: data)
|
|
|
|
|
|
2022-08-22 16:00:39 -07:00
|
|
|
let firstPurchase = try XCTUnwrap(receipt.inAppPurchases.onlyElement)
|
2022-04-06 15:44:00 -03:00
|
|
|
|
|
|
|
|
expect(firstPurchase.quantity) == 1
|
|
|
|
|
expect(firstPurchase.productId) == product.id
|
|
|
|
|
expect(firstPurchase.transactionId).toNot(beNil())
|
|
|
|
|
expect(firstPurchase.originalTransactionId).to(beNil())
|
2022-11-09 11:18:52 -08:00
|
|
|
expect(firstPurchase.productType) == .unknown
|
2022-04-06 15:44:00 -03:00
|
|
|
|
2023-07-12 06:05:53 -07:00
|
|
|
expect(firstPurchase.purchaseDate).to(beCloseTo(purchaseTime, within: 5))
|
2022-04-06 15:44:00 -03:00
|
|
|
expect(firstPurchase.originalPurchaseDate).to(beNil())
|
|
|
|
|
|
|
|
|
|
expect(firstPurchase.expiresDate).toNot(beNil())
|
2023-05-17 12:43:14 -04:00
|
|
|
expect(firstPurchase.expiresDate).toNot(beCloseToNow())
|
2022-04-06 15:44:00 -03:00
|
|
|
|
2022-11-09 11:18:52 -08:00
|
|
|
expect(firstPurchase.isSubscription) == true
|
|
|
|
|
|
2022-04-06 15:44:00 -03:00
|
|
|
expect(firstPurchase.cancellationDate).to(beNil())
|
|
|
|
|
expect(firstPurchase.isInTrialPeriod).to(beNil())
|
|
|
|
|
expect(firstPurchase.isInIntroOfferPeriod) == true
|
|
|
|
|
expect(firstPurchase.webOrderLineItemId).to(beNil())
|
|
|
|
|
expect(firstPurchase.promotionalOfferIdentifier).to(beNil())
|
|
|
|
|
|
2022-04-05 16:18:06 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|