diff --git a/BraintreeCore/BTAPIClient.m b/BraintreeCore/BTAPIClient.m
index 5f370e0ec2..04a9d57258 100644
--- a/BraintreeCore/BTAPIClient.m
+++ b/BraintreeCore/BTAPIClient.m
@@ -67,10 +67,12 @@ - (instancetype)copyWithSource:(BTClientMetadataSourceType)source
// IMPORTANT: Copy http so that tests using FakeHTTP will work.
copiedClient.http = self.http;
- BTMutableClientMetadata *mutableMetadata = [self.metadata mutableCopy];
- mutableMetadata.source = source;
- mutableMetadata.integration = integration;
- copiedClient->_metadata = [mutableMetadata copy];
+ if (copiedClient) {
+ BTMutableClientMetadata *mutableMetadata = [self.metadata mutableCopy];
+ mutableMetadata.source = source;
+ mutableMetadata.integration = integration;
+ copiedClient->_metadata = [mutableMetadata copy];
+ }
return copiedClient;
}
diff --git a/Specs/Braintree-3D-Secure-Specs/Supporting Files/Braintree-3D-Secure-Specs-Info.plist b/Specs/Braintree-3D-Secure-Specs/Supporting Files/Braintree-3D-Secure-Specs-Info.plist
deleted file mode 100644
index 169b6f710e..0000000000
--- a/Specs/Braintree-3D-Secure-Specs/Supporting Files/Braintree-3D-Secure-Specs-Info.plist
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- ${EXECUTABLE_NAME}
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundlePackageType
- BNDL
- CFBundleShortVersionString
- 1.0
- CFBundleSignature
- ????
- CFBundleVersion
- 1
-
-
diff --git a/Specs/Braintree-3D-Secure-Specs/Supporting Files/Braintree-3D-Secure-Specs-Prefix.pch b/Specs/Braintree-3D-Secure-Specs/Supporting Files/Braintree-3D-Secure-Specs-Prefix.pch
deleted file mode 100644
index a87c9cd1a4..0000000000
--- a/Specs/Braintree-3D-Secure-Specs/Supporting Files/Braintree-3D-Secure-Specs-Prefix.pch
+++ /dev/null
@@ -1,16 +0,0 @@
-#import
-#import
-#import
-
-#define SPT_SHORTHAND
-#import
-
-#define EXP_SHORTHAND
-#import
-
-#import
-
-#define HC_SHORTHAND
-#import
-
-#import "KIFSystemTestActor+ViewControllerActions.h"
diff --git a/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpec.m b/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpec.m
deleted file mode 100644
index c22a55935e..0000000000
--- a/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpec.m
+++ /dev/null
@@ -1,115 +0,0 @@
-#import "BTClient+Testing.h"
-#import "BTCoinbaseAcceptanceSpecViewController.h"
-
-SpecBegin(BTCoinbaseAcceptance)
-
-beforeAll(^{
- XCTestExpectation *updateCoinbaseMerchantOptionsExpectation = [self expectationWithDescription:@"update merchant options for coinbase"];
- [BTClient testClientWithConfiguration:@{ BTClientTestConfigurationKeyMerchantIdentifier:@"integration_merchant_id",
- BTClientTestConfigurationKeyPublicKey:@"integration_public_key",
- BTClientTestConfigurationKeyCustomer:@YES,
- BTClientTestConfigurationKeyClientTokenVersion: @2 }
- async:YES
- completion:^(BTClient *client) {
- [client updateCoinbaseMerchantOptions:@{ @"enabled": @YES }
- success:^{
- [updateCoinbaseMerchantOptionsExpectation fulfill];
- }
- failure:^(NSError *error) {
- XCTFail(@"Should not call failure block of updateCoinbaseMerchantOptions:success:failure:");
- }];
- }];
- [self waitForExpectationsWithTimeout:10 handler:nil];
-});
-
-afterAll(^{
- XCTestExpectation *updateCoinbaseMerchantOptionsExpectation = [self expectationWithDescription:@"update merchant options for coinbase"];
- [BTClient testClientWithConfiguration:@{ BTClientTestConfigurationKeyMerchantIdentifier:@"integration_merchant_id",
- BTClientTestConfigurationKeyPublicKey:@"integration_public_key",
- BTClientTestConfigurationKeyCustomer:@YES,
- BTClientTestConfigurationKeyClientTokenVersion: @2 }
- async:YES
- completion:^(BTClient *client) {
- [client updateCoinbaseMerchantOptions:@{ @"enabled": @NO }
- success:^{
- [updateCoinbaseMerchantOptionsExpectation fulfill];
- }
- failure:^(NSError *error) {
- XCTFail(@"Should not call failure block of updateCoinbaseMerchantOptions:success:failure:");
- }];
- }];
- [self waitForExpectationsWithTimeout:10 handler:nil];
-});
-
-describe(@"Coinbase authorization", ^{
- beforeEach(^{
- BTCoinbaseAcceptanceSpecViewController *vc = [[BTCoinbaseAcceptanceSpecViewController alloc] init];
- [system presentViewController:vc
-withinNavigationControllerWithNavigationBarClass:nil
- toolbarClass:nil
- configurationBlock:nil];
- [tester waitForTimeInterval:2]; // Wait for preparePayPalMobile to finish
- [tester waitForViewWithAccessibilityLabel:vc.title];
- });
-
- it(@"authorizes the user in the coinbase app and returns a nonce when the app is available", ^{
- [system waitForApplicationToOpenURLWithScheme:BTCoinbaseAcceptanceSpecCoinbaseScheme
- whileExecutingBlock:^{
- [tester tapViewWithAccessibilityLabel:@"Coinbase"];
- } returning:YES];
-
- // Simulate Response: Success
- NSURL *returnURL = [NSURL URLWithString:@"com.braintreepayments.Braintree-Demo.payments://x-callback-url/vzero/auth/coinbase/redirect?code=fake-coinbase-auth-code"];
- [[UIApplication sharedApplication] openURL:returnURL];
-
- [tester waitForViewWithAccessibilityLabel:@"Got a ฿ nonce! satoshi@example.com"];
- });
-
- it(@"shows the error when the coinbase flow results in an error", ^{
- [system waitForApplicationToOpenURLWithScheme:BTCoinbaseAcceptanceSpecCoinbaseScheme
- whileExecutingBlock:^{
- [tester tapViewWithAccessibilityLabel:@"Coinbase"];
- } returning:YES];
-
- // Simulate Response: Error
- NSURL *returnURL = [NSURL URLWithString:@"com.braintreepayments.Braintree-Demo.payments://x-callback-url/vzero/auth/coinbase/redirect?error=some_error&error_description=The+error."];
- [[UIApplication sharedApplication] openURL:returnURL];
-
- [tester waitForViewWithAccessibilityLabel:@"Failed with error. The error."];
- });
-
- it(@"distinguishes the canceled/denied flow from other errors flows", ^{
- [system waitForApplicationToOpenURLWithScheme:BTCoinbaseAcceptanceSpecCoinbaseScheme
- whileExecutingBlock:^{
- [tester tapViewWithAccessibilityLabel:@"Coinbase"];
- } returning:YES];
-
- // Simulate Response: Error
- NSURL *returnURL = [NSURL URLWithString:@"com.braintreepayments.Braintree-Demo.payments://x-callback-url/vzero/auth/coinbase/redirect?error=access_denied&error_description=The+resource+owner+or+authorization+server+denied+the+request."];
- [[UIApplication sharedApplication] openURL:returnURL];
-
- [tester waitForViewWithAccessibilityLabel:@"Canceled"];
- });
-
- it(@"authorizes the user in the browser and returns a nonce when the app is not available", ^{
- [system waitForApplicationToOpenURLWithScheme:@"https"
- whileExecutingBlock:^{
- // Inside of `executionBlock` to avoid unintended interactions with KIF's Swizzling
- OCMockObject *applicationPartialStub = [OCMockObject partialMockForObject:[UIApplication sharedApplication]];
- [[[applicationPartialStub expect] andReturnValue:@NO] canOpenURL:HC_hasProperty(@"scheme", BTCoinbaseAcceptanceSpecCoinbaseScheme)];
-
- [tester tapViewWithAccessibilityLabel:@"Coinbase"];
-
- [applicationPartialStub verify];
- [applicationPartialStub stopMocking];
- } returning:YES];
-
- // Simulate Response: Success
- NSURL *returnURL = [NSURL URLWithString:@"com.braintreepayments.Braintree-Demo.payments://x-callback-url/vzero/auth/coinbase/redirect?code=fake-coinbase-auth-code"];
- [[UIApplication sharedApplication] openURL:returnURL];
-
- [tester waitForViewWithAccessibilityLabel:@"Got a ฿ nonce! satoshi@example.com"];
- });
-});
-
-SpecEnd
diff --git a/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpecViewController.h b/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpecViewController.h
deleted file mode 100644
index 28aff46a31..0000000000
--- a/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpecViewController.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#import
-#import "BTPaymentProvider.h"
-
-extern NSString *const BTCoinbaseAcceptanceSpecCoinbaseScheme;
-
-/// A view controller for testing out coinbase app switching, intended to be used only in
-/// BTCoinbaseAcceptanceSpec
-@interface BTCoinbaseAcceptanceSpecViewController : UIViewController
-@property (nonatomic, strong) BTPaymentProvider *provider;
-@property (nonatomic, strong) UILabel *statusLabel;
-@end
-
diff --git a/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpecViewController.m b/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpecViewController.m
deleted file mode 100644
index 685fad08e2..0000000000
--- a/Specs/Braintree-Acceptance-Specs/BTCoinbaseAcceptanceSpecViewController.m
+++ /dev/null
@@ -1,78 +0,0 @@
-#import "BTClient+Testing.h"
-#import
-
-#import "BTCoinbaseAcceptanceSpecViewController.h"
-
-NSString *const BTCoinbaseAcceptanceSpecCoinbaseScheme = @"com.coinbase.oauth-authorize";
-
-@implementation BTCoinbaseAcceptanceSpecViewController
-
-- (void)viewDidLoad {
- [super viewDidLoad];
- self.title = NSStringFromClass([self class]);
- self.view.backgroundColor = [UIColor whiteColor];
- [BTClient testClientWithConfiguration:@{ BTClientTestConfigurationKeyMerchantIdentifier:@"integration_merchant_id",
- BTClientTestConfigurationKeyPublicKey:@"integration_public_key",
- BTClientTestConfigurationKeyCustomer:@YES,
- BTClientTestConfigurationKeyClientTokenVersion: @2 }
- async:YES
- completion:^(BTClient *client) {
- id mockApplication = [OCMockObject partialMockForObject:[UIApplication sharedApplication]];
- [[mockApplication stub] openURL:[OCMArg isNotEqual:BTCoinbaseAcceptanceSpecCoinbaseScheme]];
- [[mockApplication stub] canOpenURL:[OCMArg isNotEqual:BTCoinbaseAcceptanceSpecCoinbaseScheme]];
- self.provider = [[BTPaymentProvider alloc] initWithClient:client];
- self.provider.delegate = self;
- UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
- button.translatesAutoresizingMaskIntoConstraints = NO;
- [button setTitle:@"Coinbase" forState:UIControlStateNormal];
- [button addTarget:self action:@selector(tappedCoinbase) forControlEvents:UIControlEventTouchUpInside];
- [self.view addSubview:button];
- [button autoCenterInSuperviewMargins];
-
- [mockApplication stopMocking];
- }];
-
- self.statusLabel = [[UILabel alloc] initForAutoLayout];
- self.statusLabel.text = @"Uninitialized";
- [self.view addSubview:self.statusLabel];
- [self.statusLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:8];
- [self.statusLabel autoAlignAxisToSuperviewMarginAxis:ALAxisVertical];
-}
-
-- (void)tappedCoinbase {
- [self.provider createPaymentMethod:BTPaymentProviderTypeCoinbase];
-}
-
-#pragma mark BTPaymentMethodCreateDelegate
-
-- (void)paymentMethodCreatorWillProcess:(id)sender {
- self.statusLabel.text = @"Processing...";
-}
-
-- (void)paymentMethodCreatorDidCancel:(id)sender {
- self.statusLabel.text = @"Canceled";
-}
-
-- (void)paymentMethodCreator:(id)sender didFailWithError:(NSError *)error {
- self.statusLabel.text = [NSString stringWithFormat:@"Failed with error. %@", error.localizedDescription];
-}
-
-- (void)paymentMethodCreatorWillPerformAppSwitch:(id)sender {
- self.statusLabel.text = @"Performing app switch";
-}
-
-- (void)paymentMethodCreator:(id)sender didCreatePaymentMethod:(BTPaymentMethod *)paymentMethod {
- if ([paymentMethod isKindOfClass:[BTCoinbasePaymentMethod class]]) {
- self.statusLabel.text = [NSString stringWithFormat:@"Got a ฿ nonce! %@", paymentMethod];
- }
-}
-
-- (void)paymentMethodCreator:(id)sender requestsPresentationOfViewController:(UIViewController *)viewController {
- [self presentViewController:viewController animated:YES completion:nil];
-}
-
-- (void)paymentMethodCreator:(id)sender requestsDismissalOfViewController:(UIViewController *)viewController {
- [self dismissViewControllerAnimated:YES completion:nil];
-}
-
-@end