2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ #import < OCMock/OCMock.h>
5
6
#import < XCTest/XCTest.h>
6
7
#import " Stubs.h"
7
8
@@ -59,10 +60,11 @@ - (void)testTransactionPurchased {
59
60
shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
60
61
return YES ;
61
62
}
62
- updatedDownloads: nil ];
63
- [queue addTransactionObserver: handler ];
63
+ updatedDownloads: nil
64
+ transactionCache: OCMClassMock (FIATransactionCache.class) ];
64
65
SKPayment *payment =
65
66
[SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
67
+ [handler startObservingPaymentQueue ];
66
68
[handler addPayment: payment];
67
69
[self waitForExpectations: @[ expectation ] timeout: 5 ];
68
70
XCTAssertEqual (tran.transactionState , SKPaymentTransactionStatePurchased);
@@ -87,10 +89,12 @@ - (void)testTransactionFailed {
87
89
shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
88
90
return YES ;
89
91
}
90
- updatedDownloads: nil ];
91
- [queue addTransactionObserver: handler];
92
+ updatedDownloads: nil
93
+ transactionCache: OCMClassMock (FIATransactionCache.class)];
94
+
92
95
SKPayment *payment =
93
96
[SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
97
+ [handler startObservingPaymentQueue ];
94
98
[handler addPayment: payment];
95
99
[self waitForExpectations: @[ expectation ] timeout: 5 ];
96
100
XCTAssertEqual (tran.transactionState , SKPaymentTransactionStateFailed);
@@ -115,10 +119,12 @@ - (void)testTransactionRestored {
115
119
shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
116
120
return YES ;
117
121
}
118
- updatedDownloads: nil ];
119
- [queue addTransactionObserver: handler];
122
+ updatedDownloads: nil
123
+ transactionCache: OCMClassMock (FIATransactionCache.class)];
124
+
120
125
SKPayment *payment =
121
126
[SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
127
+ [handler startObservingPaymentQueue ];
122
128
[handler addPayment: payment];
123
129
[self waitForExpectations: @[ expectation ] timeout: 5 ];
124
130
XCTAssertEqual (tran.transactionState , SKPaymentTransactionStateRestored);
@@ -143,10 +149,12 @@ - (void)testTransactionPurchasing {
143
149
shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
144
150
return YES ;
145
151
}
146
- updatedDownloads: nil ];
147
- [queue addTransactionObserver: handler];
152
+ updatedDownloads: nil
153
+ transactionCache: OCMClassMock (FIATransactionCache.class)];
154
+
148
155
SKPayment *payment =
149
156
[SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
157
+ [handler startObservingPaymentQueue ];
150
158
[handler addPayment: payment];
151
159
[self waitForExpectations: @[ expectation ] timeout: 5 ];
152
160
XCTAssertEqual (tran.transactionState , SKPaymentTransactionStatePurchasing);
@@ -171,10 +179,11 @@ - (void)testTransactionDeferred {
171
179
shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
172
180
return YES ;
173
181
}
174
- updatedDownloads: nil ];
175
- [queue addTransactionObserver: handler ];
182
+ updatedDownloads: nil
183
+ transactionCache: OCMClassMock (FIATransactionCache.class) ];
176
184
SKPayment *payment =
177
185
[SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
186
+ [handler startObservingPaymentQueue ];
178
187
[handler addPayment: payment];
179
188
[self waitForExpectations: @[ expectation ] timeout: 5 ];
180
189
XCTAssertEqual (tran.transactionState , SKPaymentTransactionStateDeferred);
@@ -201,12 +210,178 @@ - (void)testFinishTransaction {
201
210
shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
202
211
return YES ;
203
212
}
204
- updatedDownloads: nil ];
205
- [queue addTransactionObserver: handler ];
213
+ updatedDownloads: nil
214
+ transactionCache: OCMClassMock (FIATransactionCache.class) ];
206
215
SKPayment *payment =
207
216
[SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
217
+ [handler startObservingPaymentQueue ];
208
218
[handler addPayment: payment];
209
219
[self waitForExpectations: @[ expectation ] timeout: 5 ];
210
220
}
211
221
222
+ - (void )testStartObservingPaymentQueueShouldNotProcessTransactionsWhenCacheIsEmpty {
223
+ FIATransactionCache *mockCache = OCMClassMock (FIATransactionCache.class );
224
+ FIAPaymentQueueHandler *handler =
225
+ [[FIAPaymentQueueHandler alloc ] initWithQueue: [[SKPaymentQueueStub alloc ] init ]
226
+ transactionsUpdated: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
227
+ XCTFail (" transactionsUpdated callback should not be called when cache is empty." );
228
+ }
229
+ transactionRemoved: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
230
+ XCTFail (" transactionRemoved callback should not be called when cache is empty." );
231
+ }
232
+ restoreTransactionFailed: nil
233
+ restoreCompletedTransactionsFinished: nil
234
+ shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
235
+ return YES ;
236
+ }
237
+ updatedDownloads: ^(NSArray <SKDownload *> *_Nonnull downloads) {
238
+ XCTFail (" updatedDownloads callback should not be called when cache is empty." );
239
+ }
240
+ transactionCache: mockCache];
241
+
242
+ [handler startObservingPaymentQueue ];
243
+
244
+ OCMVerify (times (1 ), [mockCache getObjectsForKey: TransactionCacheKeyUpdatedTransactions]);
245
+ OCMVerify (times (1 ), [mockCache getObjectsForKey: TransactionCacheKeyUpdatedDownloads]);
246
+ OCMVerify (times (1 ), [mockCache getObjectsForKey: TransactionCacheKeyRemovedTransactions]);
247
+ }
248
+
249
+ - (void )testStartObservingPaymentQueueShouldProcessTransactionsForItemsInCache {
250
+ XCTestExpectation *updateTransactionsExpectation =
251
+ [self expectationWithDescription:
252
+ @" transactionsUpdated callback should be called with one transaction." ];
253
+ XCTestExpectation *removeTransactionsExpectation =
254
+ [self expectationWithDescription:
255
+ @" transactionsRemoved callback should be called with one transaction." ];
256
+ XCTestExpectation *updateDownloadsExpectation =
257
+ [self expectationWithDescription:
258
+ @" downloadsUpdated callback should be called with one transaction." ];
259
+ SKPaymentTransaction *mockTransaction = OCMClassMock (SKPaymentTransaction.class );
260
+ SKDownload *mockDownload = OCMClassMock (SKDownload.class );
261
+ FIATransactionCache *mockCache = OCMClassMock (FIATransactionCache.class );
262
+ FIAPaymentQueueHandler *handler =
263
+ [[FIAPaymentQueueHandler alloc ] initWithQueue: [[SKPaymentQueueStub alloc ] init ]
264
+ transactionsUpdated: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
265
+ XCTAssertEqualObjects (transactions, @[ mockTransaction ]);
266
+ [updateTransactionsExpectation fulfill ];
267
+ }
268
+ transactionRemoved: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
269
+ XCTAssertEqualObjects (transactions, @[ mockTransaction ]);
270
+ [removeTransactionsExpectation fulfill ];
271
+ }
272
+ restoreTransactionFailed: nil
273
+ restoreCompletedTransactionsFinished: nil
274
+ shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
275
+ return YES ;
276
+ }
277
+ updatedDownloads: ^(NSArray <SKDownload *> *_Nonnull downloads) {
278
+ XCTAssertEqualObjects (downloads, @[ mockDownload ]);
279
+ [updateDownloadsExpectation fulfill ];
280
+ }
281
+ transactionCache: mockCache];
282
+
283
+ OCMStub ([mockCache getObjectsForKey: TransactionCacheKeyUpdatedTransactions]).andReturn (@[
284
+ mockTransaction
285
+ ]);
286
+ OCMStub ([mockCache getObjectsForKey: TransactionCacheKeyUpdatedDownloads]).andReturn (@[
287
+ mockDownload
288
+ ]);
289
+ OCMStub ([mockCache getObjectsForKey: TransactionCacheKeyRemovedTransactions]).andReturn (@[
290
+ mockTransaction
291
+ ]);
292
+
293
+ [handler startObservingPaymentQueue ];
294
+
295
+ [self waitForExpectations: @[
296
+ updateTransactionsExpectation, removeTransactionsExpectation, updateDownloadsExpectation
297
+ ]
298
+ timeout: 5 ];
299
+ OCMVerify (times (1 ), [mockCache getObjectsForKey: TransactionCacheKeyUpdatedTransactions]);
300
+ OCMVerify (times (1 ), [mockCache getObjectsForKey: TransactionCacheKeyUpdatedDownloads]);
301
+ OCMVerify (times (1 ), [mockCache getObjectsForKey: TransactionCacheKeyRemovedTransactions]);
302
+ }
303
+
304
+ - (void )testTransactionsShouldBeCachedWhenNotObserving {
305
+ SKPaymentQueueStub *queue = [[SKPaymentQueueStub alloc ] init ];
306
+ FIATransactionCache *mockCache = OCMClassMock (FIATransactionCache.class );
307
+ FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc ] initWithQueue: queue
308
+ transactionsUpdated: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
309
+ XCTFail (" transactionsUpdated callback should not be called when cache is empty." );
310
+ }
311
+ transactionRemoved: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
312
+ XCTFail (" transactionRemoved callback should not be called when cache is empty." );
313
+ }
314
+ restoreTransactionFailed: nil
315
+ restoreCompletedTransactionsFinished: nil
316
+ shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
317
+ return YES ;
318
+ }
319
+ updatedDownloads: ^(NSArray <SKDownload *> *_Nonnull downloads) {
320
+ XCTFail (" updatedDownloads callback should not be called when cache is empty." );
321
+ }
322
+ transactionCache: mockCache];
323
+
324
+ SKPayment *payment =
325
+ [SKPayment paymentWithProduct: [[SKProductStub alloc ] initWithMap: self .productResponseMap]];
326
+ [handler addPayment: payment];
327
+
328
+ OCMVerify (times (1 ), [mockCache addObjects: [OCMArg any ]
329
+ forKey: TransactionCacheKeyUpdatedTransactions]);
330
+ OCMVerify (never (), [mockCache addObjects: [OCMArg any ]
331
+ forKey: TransactionCacheKeyUpdatedDownloads]);
332
+ OCMVerify (never (), [mockCache addObjects: [OCMArg any ]
333
+ forKey: TransactionCacheKeyRemovedTransactions]);
334
+ }
335
+
336
+ - (void )testTransactionsShouldNotBeCachedWhenNotObserving {
337
+ XCTestExpectation *updateTransactionsExpectation =
338
+ [self expectationWithDescription:
339
+ @" transactionsUpdated callback should be called with one transaction." ];
340
+ XCTestExpectation *removeTransactionsExpectation =
341
+ [self expectationWithDescription:
342
+ @" transactionsRemoved callback should be called with one transaction." ];
343
+ XCTestExpectation *updateDownloadsExpectation =
344
+ [self expectationWithDescription:
345
+ @" downloadsUpdated callback should be called with one transaction." ];
346
+ SKPaymentTransaction *mockTransaction = OCMClassMock (SKPaymentTransaction.class );
347
+ SKDownload *mockDownload = OCMClassMock (SKDownload.class );
348
+ SKPaymentQueueStub *queue = [[SKPaymentQueueStub alloc ] init ];
349
+ queue.testState = SKPaymentTransactionStatePurchased;
350
+ FIATransactionCache *mockCache = OCMClassMock (FIATransactionCache.class );
351
+ FIAPaymentQueueHandler *handler = [[FIAPaymentQueueHandler alloc ] initWithQueue: queue
352
+ transactionsUpdated: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
353
+ XCTAssertEqualObjects (transactions, @[ mockTransaction ]);
354
+ [updateTransactionsExpectation fulfill ];
355
+ }
356
+ transactionRemoved: ^(NSArray <SKPaymentTransaction *> *_Nonnull transactions) {
357
+ XCTAssertEqualObjects (transactions, @[ mockTransaction ]);
358
+ [removeTransactionsExpectation fulfill ];
359
+ }
360
+ restoreTransactionFailed: nil
361
+ restoreCompletedTransactionsFinished: nil
362
+ shouldAddStorePayment: ^BOOL (SKPayment *_Nonnull payment, SKProduct *_Nonnull product) {
363
+ return YES ;
364
+ }
365
+ updatedDownloads: ^(NSArray <SKDownload *> *_Nonnull downloads) {
366
+ XCTAssertEqualObjects (downloads, @[ mockDownload ]);
367
+ [updateDownloadsExpectation fulfill ];
368
+ }
369
+ transactionCache: mockCache];
370
+
371
+ [handler startObservingPaymentQueue ];
372
+ [handler paymentQueue: queue updatedTransactions: @[ mockTransaction ]];
373
+ [handler paymentQueue: queue removedTransactions: @[ mockTransaction ]];
374
+ [handler paymentQueue: queue updatedDownloads: @[ mockDownload ]];
375
+
376
+ [self waitForExpectations: @[
377
+ updateTransactionsExpectation, removeTransactionsExpectation, updateDownloadsExpectation
378
+ ]
379
+ timeout: 5 ];
380
+ OCMVerify (never (), [mockCache addObjects: [OCMArg any ]
381
+ forKey: TransactionCacheKeyUpdatedTransactions]);
382
+ OCMVerify (never (), [mockCache addObjects: [OCMArg any ]
383
+ forKey: TransactionCacheKeyUpdatedDownloads]);
384
+ OCMVerify (never (), [mockCache addObjects: [OCMArg any ]
385
+ forKey: TransactionCacheKeyRemovedTransactions]);
386
+ }
212
387
@end
0 commit comments