| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "Stubs.h" |
| |
| @implementation SKProductSubscriptionPeriodStub |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| self = [super init]; |
| if (self) { |
| [self setValue:map[@"numberOfUnits"] ?: @(0) forKey:@"numberOfUnits"]; |
| [self setValue:map[@"unit"] ?: @(0) forKey:@"unit"]; |
| } |
| return self; |
| } |
| |
| @end |
| |
| @implementation SKProductDiscountStub |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| self = [super init]; |
| if (self) { |
| [self setValue:[[NSDecimalNumber alloc] initWithString:map[@"price"]] ?: [NSNull null] |
| forKey:@"price"]; |
| NSLocale *locale = NSLocale.systemLocale; |
| [self setValue:locale ?: [NSNull null] forKey:@"priceLocale"]; |
| [self setValue:map[@"numberOfPeriods"] ?: @(0) forKey:@"numberOfPeriods"]; |
| SKProductSubscriptionPeriodStub *subscriptionPeriodSub = |
| [[SKProductSubscriptionPeriodStub alloc] initWithMap:map[@"subscriptionPeriod"]]; |
| [self setValue:subscriptionPeriodSub forKey:@"subscriptionPeriod"]; |
| [self setValue:map[@"paymentMode"] ?: @(0) forKey:@"paymentMode"]; |
| if (@available(iOS 12.2, *)) { |
| [self setValue:map[@"identifier"] ?: [NSNull null] forKey:@"identifier"]; |
| [self setValue:map[@"type"] ?: @(0) forKey:@"type"]; |
| } |
| } |
| return self; |
| } |
| |
| @end |
| |
| @implementation SKProductStub |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| self = [super init]; |
| if (self) { |
| [self setValue:map[@"productIdentifier"] ?: [NSNull null] forKey:@"productIdentifier"]; |
| [self setValue:map[@"localizedDescription"] ?: [NSNull null] forKey:@"localizedDescription"]; |
| [self setValue:map[@"localizedTitle"] ?: [NSNull null] forKey:@"localizedTitle"]; |
| [self setValue:map[@"downloadable"] ?: @NO forKey:@"downloadable"]; |
| [self setValue:[[NSDecimalNumber alloc] initWithString:map[@"price"]] ?: [NSNull null] |
| forKey:@"price"]; |
| NSLocale *locale = NSLocale.systemLocale; |
| [self setValue:locale ?: [NSNull null] forKey:@"priceLocale"]; |
| [self setValue:map[@"downloadContentLengths"] ?: @(0) forKey:@"downloadContentLengths"]; |
| if (@available(iOS 11.2, *)) { |
| SKProductSubscriptionPeriodStub *period = |
| [[SKProductSubscriptionPeriodStub alloc] initWithMap:map[@"subscriptionPeriod"]]; |
| [self setValue:period ?: [NSNull null] forKey:@"subscriptionPeriod"]; |
| SKProductDiscountStub *discount = |
| [[SKProductDiscountStub alloc] initWithMap:map[@"introductoryPrice"]]; |
| [self setValue:discount ?: [NSNull null] forKey:@"introductoryPrice"]; |
| [self setValue:map[@"subscriptionGroupIdentifier"] ?: [NSNull null] |
| forKey:@"subscriptionGroupIdentifier"]; |
| } |
| if (@available(iOS 12.2, *)) { |
| NSMutableArray *discounts = [[NSMutableArray alloc] init]; |
| for (NSDictionary *discountMap in map[@"discounts"]) { |
| [discounts addObject:[[SKProductDiscountStub alloc] initWithMap:discountMap]]; |
| } |
| |
| [self setValue:discounts forKey:@"discounts"]; |
| } |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithProductID:(NSString *)productIdentifier { |
| self = [super init]; |
| if (self) { |
| [self setValue:productIdentifier forKey:@"productIdentifier"]; |
| } |
| return self; |
| } |
| |
| @end |
| |
| @interface SKProductRequestStub () |
| |
| @property(strong, nonatomic) NSSet *identifers; |
| @property(strong, nonatomic) NSError *error; |
| |
| @end |
| |
| @implementation SKProductRequestStub |
| |
| - (instancetype)initWithProductIdentifiers:(NSSet<NSString *> *)productIdentifiers { |
| self = [super initWithProductIdentifiers:productIdentifiers]; |
| self.identifers = productIdentifiers; |
| return self; |
| } |
| |
| - (instancetype)initWithFailureError:(NSError *)error { |
| self = [super init]; |
| self.error = error; |
| return self; |
| } |
| |
| - (void)start { |
| NSMutableArray *productArray = [NSMutableArray new]; |
| for (NSString *identifier in self.identifers) { |
| [productArray addObject:@{@"productIdentifier" : identifier}]; |
| } |
| SKProductsResponseStub *response = |
| [[SKProductsResponseStub alloc] initWithMap:@{@"products" : productArray}]; |
| if (self.error) { |
| [self.delegate request:self didFailWithError:self.error]; |
| } else { |
| [self.delegate productsRequest:self didReceiveResponse:response]; |
| } |
| } |
| |
| @end |
| |
| @implementation SKProductsResponseStub |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| self = [super init]; |
| if (self) { |
| NSMutableArray *products = [NSMutableArray new]; |
| for (NSDictionary *productMap in map[@"products"]) { |
| SKProductStub *product = [[SKProductStub alloc] initWithMap:productMap]; |
| [products addObject:product]; |
| } |
| [self setValue:products forKey:@"products"]; |
| } |
| return self; |
| } |
| |
| @end |
| |
| @interface InAppPurchasePluginStub () |
| |
| @end |
| |
| @implementation InAppPurchasePluginStub |
| |
| - (SKProductRequestStub *)getProductRequestWithIdentifiers:(NSSet *)identifiers { |
| return [[SKProductRequestStub alloc] initWithProductIdentifiers:identifiers]; |
| } |
| |
| - (SKProduct *)getProduct:(NSString *)productID { |
| return [[SKProductStub alloc] initWithProductID:productID]; |
| } |
| |
| - (SKReceiptRefreshRequestStub *)getRefreshReceiptRequest:(NSDictionary *)properties { |
| return [[SKReceiptRefreshRequestStub alloc] initWithReceiptProperties:properties]; |
| } |
| |
| @end |
| |
| @interface SKPaymentQueueStub () |
| |
| @end |
| |
| @implementation SKPaymentQueueStub |
| |
| - (void)addTransactionObserver:(id<SKPaymentTransactionObserver>)observer { |
| self.observer = observer; |
| } |
| |
| - (void)removeTransactionObserver:(id<SKPaymentTransactionObserver>)observer { |
| self.observer = nil; |
| } |
| |
| - (void)addPayment:(SKPayment *)payment { |
| SKPaymentTransactionStub *transaction = |
| [[SKPaymentTransactionStub alloc] initWithState:self.testState payment:payment]; |
| [self.observer paymentQueue:self updatedTransactions:@[ transaction ]]; |
| } |
| |
| - (void)restoreCompletedTransactions { |
| if ([self.observer |
| respondsToSelector:@selector(paymentQueueRestoreCompletedTransactionsFinished:)]) { |
| [self.observer paymentQueueRestoreCompletedTransactionsFinished:self]; |
| } |
| } |
| |
| - (void)finishTransaction:(SKPaymentTransaction *)transaction { |
| if ([self.observer respondsToSelector:@selector(paymentQueue:removedTransactions:)]) { |
| [self.observer paymentQueue:self removedTransactions:@[ transaction ]]; |
| } |
| } |
| |
| @end |
| |
| @implementation SKPaymentTransactionStub { |
| SKPayment *_payment; |
| } |
| |
| - (instancetype)initWithID:(NSString *)identifier { |
| self = [super init]; |
| if (self) { |
| [self setValue:identifier forKey:@"transactionIdentifier"]; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| self = [super init]; |
| if (self) { |
| [self setValue:map[@"transactionIdentifier"] forKey:@"transactionIdentifier"]; |
| [self setValue:map[@"transactionState"] forKey:@"transactionState"]; |
| if (![map[@"originalTransaction"] isKindOfClass:[NSNull class]] && |
| map[@"originalTransaction"]) { |
| [self setValue:[[SKPaymentTransactionStub alloc] initWithMap:map[@"originalTransaction"]] |
| forKey:@"originalTransaction"]; |
| } |
| [self setValue:map[@"error"] ? [[NSErrorStub alloc] initWithMap:map[@"error"]] : [NSNull null] |
| forKey:@"error"]; |
| [self setValue:[NSDate dateWithTimeIntervalSince1970:[map[@"transactionTimeStamp"] doubleValue]] |
| forKey:@"transactionDate"]; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithState:(SKPaymentTransactionState)state { |
| self = [super init]; |
| if (self) { |
| // Only purchased and restored transactions have transactionIdentifier: |
| // https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411288-transactionidentifier?language=objc |
| if (state == SKPaymentTransactionStatePurchased || state == SKPaymentTransactionStateRestored) { |
| [self setValue:@"fakeID" forKey:@"transactionIdentifier"]; |
| } |
| [self setValue:@(state) forKey:@"transactionState"]; |
| } |
| return self; |
| } |
| |
| - (instancetype)initWithState:(SKPaymentTransactionState)state payment:(SKPayment *)payment { |
| self = [super init]; |
| if (self) { |
| // Only purchased and restored transactions have transactionIdentifier: |
| // https://developer.apple.com/documentation/storekit/skpaymenttransaction/1411288-transactionidentifier?language=objc |
| if (state == SKPaymentTransactionStatePurchased || state == SKPaymentTransactionStateRestored) { |
| [self setValue:@"fakeID" forKey:@"transactionIdentifier"]; |
| } |
| [self setValue:@(state) forKey:@"transactionState"]; |
| _payment = payment; |
| } |
| return self; |
| } |
| |
| - (SKPayment *)payment { |
| return _payment; |
| } |
| |
| @end |
| |
| @implementation NSErrorStub |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| return [self initWithDomain:[map objectForKey:@"domain"] |
| code:[[map objectForKey:@"code"] integerValue] |
| userInfo:[map objectForKey:@"userInfo"]]; |
| } |
| |
| @end |
| |
| @implementation FIAPReceiptManagerStub : FIAPReceiptManager |
| |
| - (NSData *)getReceiptData:(NSURL *)url error:(NSError **)error { |
| if (self.returnError) { |
| *error = [NSError errorWithDomain:@"test" |
| code:1 |
| userInfo:@{ |
| @"name" : @"test", |
| @"houseNr" : @5, |
| @"error" : [[NSError alloc] initWithDomain:@"internalTestDomain" |
| code:99 |
| userInfo:nil] |
| }]; |
| return nil; |
| } |
| NSString *originalString = [NSString stringWithFormat:@"test"]; |
| return [[NSData alloc] initWithBase64EncodedString:originalString options:kNilOptions]; |
| } |
| |
| @end |
| |
| @implementation SKReceiptRefreshRequestStub { |
| NSError *_error; |
| } |
| |
| - (instancetype)initWithReceiptProperties:(NSDictionary<NSString *, id> *)properties { |
| self = [super initWithReceiptProperties:properties]; |
| return self; |
| } |
| |
| - (instancetype)initWithFailureError:(NSError *)error { |
| self = [super init]; |
| _error = error; |
| return self; |
| } |
| |
| - (void)start { |
| if (_error) { |
| [self.delegate request:self didFailWithError:_error]; |
| } else { |
| [self.delegate requestDidFinish:self]; |
| } |
| } |
| |
| @end |
| |
| @implementation SKStorefrontStub |
| |
| - (instancetype)initWithMap:(NSDictionary *)map { |
| self = [super init]; |
| if (self) { |
| // Set stub values |
| [self setValue:map[@"countryCode"] forKey:@"countryCode"]; |
| [self setValue:map[@"identifier"] forKey:@"identifier"]; |
| } |
| return self; |
| } |
| |
| @end |