// // BUYPaymentProviderTests.m // Mobile Buy SDK // // Created by David Muzi on 2015-12-15. // Copyright © 2015 Shopify Inc. All rights reserved. // @import XCTest; #import <Buy/Buy.h> #import "BUYApplePayPaymentProvider.h" #import "BUYWebCheckoutPaymentProvider.h" #import "BUYClientTestBase.h" #import "BUYPaymentController.h" #import <OHHTTPStubs/OHHTTPStubs.h> @interface BUYPaymentController () - (id <BUYPaymentProvider>)providerForType:(NSString *)type; @end @interface BUYPaymentProviderTests : XCTestCase <BUYPaymentProviderDelegate> @property (nonatomic) NSMutableDictionary <NSString *, XCTestExpectation *> *expectations; @property (nonatomic) BUYModelManager *modelManager; @end @implementation BUYPaymentProviderTests - (void)setUp { [super setUp]; self.modelManager = [BUYModelManager modelManager]; self.expectations = [@{} mutableCopy]; } - (void)tearDown { [super tearDown]; [OHHTTPStubs removeAllStubs]; } - (BUYClient *)client { return [[BUYClient alloc] initWithShopDomain:BUYShopDomain_Placeholder apiKey:BUYAPIKey_Placeholder appId:BUYAppId_Placeholder]; } - (BUYCheckout *)checkout { return [self.modelManager insertCheckoutWithJSONDictionary:nil]; } - (void)mockRequests { // This mocks a getShop, and createCheckout request [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) { return YES; } withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) { return [BUYPaymentProviderTests responseForRequest:request]; }]; } + (OHHTTPStubsResponse *)responseForRequest:(NSURLRequest *)request { NSURLComponents *components = [NSURLComponents componentsWithURL:request.URL resolvingAgainstBaseURL:NO]; if ([components.path isEqualToString:@"/meta.json"]) { return [OHHTTPStubsResponse responseWithJSONObject:@{@"id": @"123", @"country": @"US", @"currency": @"USD"} statusCode:200 headers:nil]; } else if ([components.path isEqualToString:@"/api/checkouts.json"]) { return [OHHTTPStubsResponse responseWithJSONObject:@{@"checkout":@{@"payment_due": @(99), @"web_checkout_url": @"https://example.com"}} statusCode:200 headers:nil]; } return nil; } #pragma mark - Apple Pay - (void)testAppleAvailability { BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"]; XCTAssertTrue(applePay.isAvailable); BUYApplePayPaymentProvider *applePay2 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@""]; XCTAssertFalse(applePay2.isAvailable); } - (void)testApplePayPresentationCallbacks { [self mockRequests]; BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"]; applePay.delegate = self; self.expectations[@"presentController"] = [self expectationWithDescription:NSStringFromSelector(_cmd)]; [applePay startCheckout:self.checkout]; [self waitForExpectationsWithTimeout:1 handler:^(NSError *error) { XCTAssertNil(error); }]; } - (void)testApplePayProvider { BUYApplePayPaymentProvider *applePay1 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"]; XCTAssertEqualObjects(applePay1.merchantID, @"merchant.id.1"); // 4 default networks should be configured XCTAssertEqual(applePay1.supportedNetworks.count, 4); applePay1.supportedNetworks = @[PKPaymentNetworkMasterCard]; XCTAssertEqual(applePay1.supportedNetworks.count, 1); XCTAssertEqualObjects(applePay1.supportedNetworks[0], PKPaymentNetworkMasterCard); } - (void)testCanShowApplePaySetup { BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"]; XCTAssertTrue(applePay.canShowApplePaySetup); BUYApplePayPaymentProvider *applePay2 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@""]; XCTAssertFalse(applePay2.canShowApplePaySetup); } - (void)testFailedApplePayCallbacks { [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) { return YES; } withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) { return [OHHTTPStubsResponse responseWithJSONObject:@{} statusCode:400 headers:nil]; }]; BUYApplePayPaymentProvider *applePay = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"]; applePay.delegate = self; self.expectations[@"failedCheckout"] = [self expectationWithDescription:NSStringFromSelector(_cmd)]; self.expectations[@"failedShop"] = [self expectationWithDescription:NSStringFromSelector(_cmd)]; [applePay startCheckout:self.checkout]; [self waitForExpectationsWithTimeout:1 handler:^(NSError *error) { XCTAssertNil(error); }]; } #pragma mark - Web - (void)testWebAvailability { BUYWebCheckoutPaymentProvider *webProvider = [[BUYWebCheckoutPaymentProvider alloc] initWithClient:self.client]; XCTAssertTrue(webProvider.isAvailable); } - (void)testWebPresentationCallbacks { [self mockRequests]; BUYWebCheckoutPaymentProvider *webProvider = [[BUYWebCheckoutPaymentProvider alloc] initWithClient:self.client]; webProvider.delegate = self; self.expectations[@"presentController"] = [self expectationWithDescription:NSStringFromSelector(_cmd)]; [webProvider startCheckout:self.checkout]; [self waitForExpectationsWithTimeout:1 handler:^(NSError *error) { XCTAssertNil(error); }]; } #pragma mark - Payment Controller - (void)testPaymentController { BUYPaymentController *controller = [[BUYPaymentController alloc] init]; BUYApplePayPaymentProvider *applePay1 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.1"]; [controller addPaymentProvider:applePay1]; XCTAssertEqual(controller.providers.count, 1); id <BUYPaymentProvider> provider = [controller providerForType:BUYApplePayPaymentProviderId]; XCTAssertEqualObjects(provider, applePay1); BUYWebCheckoutPaymentProvider *webProvider = [[BUYWebCheckoutPaymentProvider alloc] initWithClient:self.client]; [controller addPaymentProvider:webProvider]; XCTAssertEqual(controller.providers.count, 2); provider = [controller providerForType:BUYWebPaymentProviderId]; XCTAssertEqualObjects(provider, webProvider); // Attempt to add an alternate Apple Pay provider BUYApplePayPaymentProvider *applePay2 = [[BUYApplePayPaymentProvider alloc] initWithClient:self.client merchantID:@"merchant.id.2"]; [controller addPaymentProvider:applePay2]; XCTAssertEqual(controller.providers.count, 2); } - (void)testStartingPaymentWithPaymentController { [self mockRequests]; BUYPaymentController *controller = [[BUYPaymentController alloc] init]; BUYWebCheckoutPaymentProvider *webProvider = [[BUYWebCheckoutPaymentProvider alloc] initWithClient:self.client]; webProvider.delegate = self; [controller addPaymentProvider:webProvider]; self.expectations[@"presentController"] = [self expectationWithDescription:NSStringFromSelector(_cmd)]; [controller startCheckout:self.checkout withProviderType:BUYWebPaymentProviderId]; [self waitForExpectationsWithTimeout:1 handler:^(NSError *error) { XCTAssertNil(error); }]; } #pragma mark - Payment Provider delegate - (void)paymentProvider:(id <BUYPaymentProvider>)provider wantsControllerPresented:(UIViewController *)controller { [self.expectations[@"presentController"] fulfill]; } - (void)paymentProviderWantsControllerDismissed:(id <BUYPaymentProvider>)provider { } - (void)paymentProviderWillStartCheckout:(id <BUYPaymentProvider>)provider { } - (void)paymentProviderDidDismissCheckout:(id <BUYPaymentProvider>)provider { } - (void)paymentProvider:(id <BUYPaymentProvider>)provider didFailToUpdateCheckoutWithError:(NSError *)error { } - (void)paymentProvider:(id <BUYPaymentProvider>)provider didFailCheckoutWithError:(NSError *)error; { if (self.expectations[@"failedCheckout"]) { [self.expectations[@"failedCheckout"] fulfill]; [self.expectations removeObjectForKey:@"failedCheckout"]; } if (self.expectations[@"failedShop"]) { [self.expectations[@"failedShop"] fulfill]; [self.expectations removeObjectForKey:@"failedShop"]; } } - (void)paymentProvider:(id <BUYPaymentProvider>)provider didCompleteCheckout:(BUYCheckout *)checkout withStatus:(BUYStatus)status { } @end