Browse Source

Additional PaymentQueueController tests

Andrea Bizzotto 8 years ago
parent
commit
e9d8f2dc81

+ 2 - 1
SwiftyStoreKit/PaymentQueueController.swift

@@ -130,7 +130,8 @@ public class PaymentQueueController: NSObject, SKPaymentTransactionObserver {
          * SKPaymentQueue rejects multiple restore purchases calls.
          * SKPaymentQueue rejects multiple restore purchases calls.
          * Having one payment queue observer for each request causes extra processing
          * Having one payment queue observer for each request causes extra processing
          * Failed translations only ever belong to queued payment request.
          * Failed translations only ever belong to queued payment request.
-         * restoreCompletedTransactionsFailedWithError is called when a restore payments request fails.
+         * restoreCompletedTransactionsFailedWithError is always called when a restore purchases request fails.
+         * paymentQueueRestoreCompletedTransactionsFinished is always called following 0 or more update transactions when a restore purchases request succeeds.
          * A complete transactions handler is require to catch any transactions that are updated when the app is not running.
          * A complete transactions handler is require to catch any transactions that are updated when the app is not running.
          * Registering a complete transactions handler when the app launches ensures that any pending transactions can be cleared.
          * Registering a complete transactions handler when the app launches ensures that any pending transactions can be cleared.
          * If a complete transactions handler is missing, pending transactions can be mis-attributed to any new incoming payments or restore purchases.
          * If a complete transactions handler is missing, pending transactions can be mis-attributed to any new incoming payments or restore purchases.

+ 111 - 1
SwiftyStoreKitTests/PaymentQueueControllerTests.swift

@@ -72,7 +72,7 @@ class PaymentQueueControllerTests: XCTestCase {
     }
     }
     
     
     // MARK: SKPaymentTransactionObserver callbacks
     // MARK: SKPaymentTransactionObserver callbacks
-    func testPaymentQueue_when_oneTransactionForEachState_then_correctCallbacksCalled() {
+    func testPaymentQueue_when_oneTransactionForEachState_onePayment_oneRestorePurchases_oneCompleteTransactions_then_correctCallbacksCalled() {
 
 
         // setup
         // setup
         let spy = PaymentQueueSpy()
         let spy = PaymentQueueSpy()
@@ -142,6 +142,116 @@ class PaymentQueueControllerTests: XCTestCase {
         XCTAssertTrue(completeTransactionsCallbackCalled)
         XCTAssertTrue(completeTransactionsCallbackCalled)
     }
     }
     
     
+    func testPaymentQueue_when_oneTransactionForEachState_onePayment_noRestorePurchases_oneCompleteTransactions_then_correctCallbacksCalled() {
+        
+        // setup
+        let spy = PaymentQueueSpy()
+        
+        let paymentQueueController = PaymentQueueController(paymentQueue: spy)
+        
+        let purchasedProductIdentifier = "com.SwiftyStoreKit.product1"
+        let failedProductIdentifier = "com.SwiftyStoreKit.product2"
+        let restoredProductIdentifier = "com.SwiftyStoreKit.product3"
+        let deferredProductIdentifier = "com.SwiftyStoreKit.product4"
+        let purchasingProductIdentifier = "com.SwiftyStoreKit.product5"
+        
+        let transactions = [
+            makeTestPaymentTransaction(productIdentifier: purchasedProductIdentifier, transactionState: .purchased),
+            makeTestPaymentTransaction(productIdentifier: failedProductIdentifier, transactionState: .failed),
+            makeTestPaymentTransaction(productIdentifier: restoredProductIdentifier, transactionState: .restored),
+            makeTestPaymentTransaction(productIdentifier: deferredProductIdentifier, transactionState: .deferred),
+            makeTestPaymentTransaction(productIdentifier: purchasingProductIdentifier, transactionState: .purchasing),
+            ]
+        
+        
+        var paymentCallbackCalled = false
+        let testPayment = makeTestPayment(productIdentifier: purchasedProductIdentifier) { result in
+            paymentCallbackCalled = true
+            if case .purchased(let product) = result {
+                XCTAssertEqual(product.productId, purchasedProductIdentifier)
+            }
+            else {
+                XCTFail("expected purchased callback with product id")
+            }
+        }
+        
+        var completeTransactionsCallbackCalled = false
+        let completeTransactions = CompleteTransactions(atomically: true) { products in
+            completeTransactionsCallbackCalled = true
+            XCTAssertEqual(products.count, 3)
+            XCTAssertEqual(products[0].productId, failedProductIdentifier)
+            XCTAssertEqual(products[1].productId, restoredProductIdentifier)
+            XCTAssertEqual(products[2].productId, deferredProductIdentifier)
+        }
+        
+        // run
+        paymentQueueController.startPayment(testPayment)
+        
+        paymentQueueController.completeTransactions(completeTransactions)
+        
+        paymentQueueController.paymentQueue(SKPaymentQueue(), updatedTransactions: transactions)
+        paymentQueueController.paymentQueueRestoreCompletedTransactionsFinished(SKPaymentQueue())
+        
+        // verify
+        XCTAssertTrue(paymentCallbackCalled)
+        XCTAssertTrue(completeTransactionsCallbackCalled)
+    }
+
+    func testPaymentQueue_when_oneTransactionForEachState_noPayments_oneRestorePurchases_oneCompleteTransactions_then_correctCallbacksCalled() {
+        
+        // setup
+        let spy = PaymentQueueSpy()
+        
+        let paymentQueueController = PaymentQueueController(paymentQueue: spy)
+        
+        let purchasedProductIdentifier = "com.SwiftyStoreKit.product1"
+        let failedProductIdentifier = "com.SwiftyStoreKit.product2"
+        let restoredProductIdentifier = "com.SwiftyStoreKit.product3"
+        let deferredProductIdentifier = "com.SwiftyStoreKit.product4"
+        let purchasingProductIdentifier = "com.SwiftyStoreKit.product5"
+        
+        let transactions = [
+            makeTestPaymentTransaction(productIdentifier: purchasedProductIdentifier, transactionState: .purchased),
+            makeTestPaymentTransaction(productIdentifier: failedProductIdentifier, transactionState: .failed),
+            makeTestPaymentTransaction(productIdentifier: restoredProductIdentifier, transactionState: .restored),
+            makeTestPaymentTransaction(productIdentifier: deferredProductIdentifier, transactionState: .deferred),
+            makeTestPaymentTransaction(productIdentifier: purchasingProductIdentifier, transactionState: .purchasing),
+            ]
+        
+        var restorePurchasesCallbackCalled = false
+        let restorePurchases = RestorePurchases(atomically: true) { results in
+            restorePurchasesCallbackCalled = true
+            XCTAssertEqual(results.count, 1)
+            let first = results.first!
+            if case .restored(let restoredProduct) = first {
+                XCTAssertEqual(restoredProduct.productId, restoredProductIdentifier)
+            }
+            else {
+                XCTFail("expected restored callback with product")
+            }
+        }
+        
+        var completeTransactionsCallbackCalled = false
+        let completeTransactions = CompleteTransactions(atomically: true) { products in
+            completeTransactionsCallbackCalled = true
+            XCTAssertEqual(products.count, 3)
+            XCTAssertEqual(products[0].productId, purchasedProductIdentifier)
+            XCTAssertEqual(products[1].productId, failedProductIdentifier)
+            XCTAssertEqual(products[2].productId, deferredProductIdentifier)
+        }
+        
+        // run
+        paymentQueueController.restorePurchases(restorePurchases)
+        
+        paymentQueueController.completeTransactions(completeTransactions)
+        
+        paymentQueueController.paymentQueue(SKPaymentQueue(), updatedTransactions: transactions)
+        paymentQueueController.paymentQueueRestoreCompletedTransactionsFinished(SKPaymentQueue())
+        
+        // verify
+        XCTAssertTrue(restorePurchasesCallbackCalled)
+        XCTAssertTrue(completeTransactionsCallbackCalled)
+    }
     
     
     // MARK: Helpers
     // MARK: Helpers
     func makeTestPaymentTransaction(productIdentifier: String, transactionState: SKPaymentTransactionState) -> TestPaymentTransaction {
     func makeTestPaymentTransaction(productIdentifier: String, transactionState: SKPaymentTransactionState) -> TestPaymentTransaction {