Commit d4a6e276 by Dima Bart

Merge pull request #202 from Shopify/feature/customer-addresses

Add customer address API
parents bcd3a4c0 55464d5e
......@@ -118,6 +118,14 @@
@"https://_DOMAIN_/api/customers/orders.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersToken].absoluteString,
@"https://_DOMAIN_/api/customers/customer_token.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersPasswordRecovery].absoluteString,
@"https://_DOMAIN_/api/customers/recover.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersWithID:identifier].absoluteString,
@"https://_DOMAIN_/api/customers/_ID_.json"
);
......@@ -126,10 +134,6 @@
@"https://_DOMAIN_/api/customers/_ID_/activate.json?param=value"
);
XCTAssertEqualObjects(
[self.client urlForCustomersToken].absoluteString,
@"https://_DOMAIN_/api/customers/customer_token.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersTokenWithID:identifier].absoluteString,
@"https://_DOMAIN_/api/customers/_ID_/customer_token.json"
);
......@@ -138,13 +142,18 @@
@"https://_DOMAIN_/api/customers/_ID_/customer_token/renew.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersPasswordRecovery].absoluteString,
@"https://_DOMAIN_/api/customers/recover.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersPasswordResetWithID:identifier parameters:parameters].absoluteString,
@"https://_DOMAIN_/api/customers/_ID_/reset.json?param=value"
);
XCTAssertEqualObjects(
[self.client urlForCustomersAddressesWithID:identifier].absoluteString,
@"https://_DOMAIN_/api/customers/_ID_/addresses.json"
);
XCTAssertEqualObjects(
[self.client urlForCustomersAddressWithID:identifier addressID:@999].absoluteString,
@"https://_DOMAIN_/api/customers/_ID_/addresses/999.json"
);
}
@end
......@@ -151,18 +151,6 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg";
);
}
- (void)testMerchantId
{
NSString *merchantId = @"com.merchant.id";
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
[self.client enableApplePayWithMerchantId:merchantId];
XCTAssertEqualObjects(merchantId, self.client.merchantId);
#pragma GCC diagnostic pop
}
- (void)testStatusCodeConversions
{
BUYStatus status = [self.client statusForStatusCode:412 error:nil];
......
......@@ -32,15 +32,22 @@
#import <OHHTTPStubs/OHHTTPStubs.h>
#import "OHHTTPStubsResponse+Helpers.h"
// Remove this macro entirely when test shop has customer api enabled
//#define CUSTOMER_API_AVAILABLE
@interface BUYClientTest_Customer : BUYClientTestBase
@property (strong, nonatomic) BUYCustomer *customer;
@property (strong, nonatomic) BUYAddress *createdAddress;
@end
@implementation BUYClientTest_Customer
#pragma mark - Tear Down -
#pragma mark - Lifecycle -
- (void)setUp
{
[super setUp];
[self loginDefaultCustomer];
}
- (void)tearDown
{
......@@ -48,6 +55,31 @@
[OHHTTPStubs removeAllStubs];
}
- (void)loginDefaultCustomer
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return [self shouldUseMocks];
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithKey:@"testCustomerLogin"];
}];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[self.client loginCustomerWithCredentials:[self credentialsForLogin] callback:^(BUYCustomer *customer, NSString *token, NSError *error) {
XCTAssertNil(error);
XCTAssertNotNil(customer);
XCTAssertEqualObjects(customer.email, self.customerEmail);
self.customer = customer;
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:^(NSError * _Nullable error) {
XCTAssertNil(error);
}];
}
#pragma mark - Creation -
- (void)testCustomerDuplicateEmail
......@@ -113,21 +145,7 @@
- (void)testCustomerLogin
{
[OHHTTPStubs stubUsingResponseWithKey:@"testCustomerLogin" useMocks:[self shouldUseMocks]];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[self.client loginCustomerWithCredentials:[self credentialsForLogin] callback:^(BUYCustomer *customer, NSString *token, NSError *error) {
XCTAssertNil(error);
XCTAssertNotNil(customer);
XCTAssertEqualObjects(customer.email, self.customerEmail);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:^(NSError * _Nullable error) {
XCTAssertNil(error);
}];
[self loginDefaultCustomer];
}
- (void)testCustomerLogout
......@@ -162,23 +180,193 @@
BUYAccountCredentialItem *email = [BUYAccountCredentialItem itemWithEmail:self.customerEmail];
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[email]];
[self.client loginCustomerWithCredentials:[self credentialsForLogin] callback:^(BUYCustomer * _Nullable customer, NSString * _Nullable token, NSError * _Nullable error) {
[self.client updateCustomerWithCredentials:credentials customerID:self.customer.identifier.stringValue callback:^(BUYCustomer *customer, NSError *error) {
XCTAssertNil(error);
XCTAssertNotNil(customer);
XCTAssertEqualObjects(customer.email, self.customerEmail);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
#pragma mark - Address -
- (void)testGetAddresses
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return [self shouldUseMocks];
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithKey:@"testCustomerAddresses"];
}];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[self.client getAddressesForCustomerID:self.customer.identifier.stringValue callback:^(NSArray<BUYAddress *> * _Nullable addresses, NSError * _Nullable error) {
XCTAssertNotNil(addresses);
XCTAssertTrue(addresses.count > 0);
XCTAssertTrue([addresses.firstObject isKindOfClass:[BUYAddress class]]);
XCTAssertNil(error);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
- (void)testAddressCRUD
{
[self createAddress];
[self getAddress];
[self updateAddress];
[self deleteAddress];
}
- (void)createAddress
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return [self shouldUseMocks];
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithKey:@"testCustomerAddress1"];
}];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
BUYAddress *address = [self address];
[self.client createAddress:address forCustomerID:self.customer.identifier.stringValue callback:^(BUYAddress * _Nullable returnedAddress, NSError * _Nullable error) {
[OHHTTPStubs stubUsingResponseWithKey:@"testCustomerLogin" useMocks:[self shouldUseMocks]];
[self.client updateCustomerWithCredentials:credentials customerID:customer.identifier.stringValue callback:^(BUYCustomer *customer, NSError *error) {
XCTAssertNotNil(returnedAddress);
XCTAssertNil(error);
XCTAssertNotNil(returnedAddress.identifier);
XCTAssertEqualObjects(address.address1, returnedAddress.address1);
XCTAssertEqualObjects(address.city, returnedAddress.city);
XCTAssertEqualObjects(address.province, returnedAddress.province);
XCTAssertEqualObjects(address.provinceCode, returnedAddress.provinceCode);
XCTAssertEqualObjects(address.country, returnedAddress.country);
XCTAssertEqualObjects(address.countryCode, returnedAddress.countryCode);
XCTAssertEqualObjects(address.zip, returnedAddress.zip);
self.createdAddress = returnedAddress;
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
- (void)getAddress
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return [self shouldUseMocks];
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithKey:@"testCustomerAddress1"];
}];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[self.client getAddressWithID:self.createdAddress.identifier forCustomerID:self.customer.identifier.stringValue callback:^(BUYAddress * _Nullable address, NSError * _Nullable error) {
XCTAssertNotNil(address);
XCTAssertNil(error);
XCTAssertNotNil(customer);
XCTAssertEqualObjects(customer.email, self.customerEmail);
XCTAssertEqualObjects(address.identifier, self.createdAddress.identifier);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
- (void)updateAddress
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return [self shouldUseMocks];
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithKey:@"testCustomerAddress2"];
}];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
BUYAddress *modifiedAddress = [self addressByModyfyingAddress:self.createdAddress];
[self.client updateAddress:modifiedAddress forCustomerID:self.customer.identifier.stringValue callback:^(BUYAddress * _Nullable returnedAddress, NSError * _Nullable error) {
XCTAssertNotNil(returnedAddress);
XCTAssertNil(error);
XCTAssertEqualObjects(modifiedAddress.address1, returnedAddress.address1);
XCTAssertEqualObjects(modifiedAddress.city, returnedAddress.city);
XCTAssertEqualObjects(modifiedAddress.province, returnedAddress.province);
XCTAssertEqualObjects(modifiedAddress.provinceCode, returnedAddress.provinceCode);
XCTAssertEqualObjects(modifiedAddress.country, returnedAddress.country);
XCTAssertEqualObjects(modifiedAddress.countryCode, returnedAddress.countryCode);
XCTAssertEqualObjects(modifiedAddress.zip, returnedAddress.zip);
self.createdAddress = returnedAddress;
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
- (void)deleteAddress
{
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest * _Nonnull request) {
return [self shouldUseMocks];
} withStubResponse:^OHHTTPStubsResponse * _Nonnull(NSURLRequest * _Nonnull request) {
return [OHHTTPStubsResponse responseWithKey:@"testCustomerAddressDelete"];
}];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[self.client deleteAddress:self.createdAddress forCustomerID:self.customer.identifier.stringValue callback:^(BUYStatus status, NSError * _Nullable error) {
XCTAssertEqual(status, 204);
XCTAssertNil(error);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:10 handler:nil];
}
#pragma mark - Address -
- (BUYAddress *)address
{
BUYAddress *address = [[BUYAddress alloc] initWithModelManager:self.client.modelManager JSONDictionary:nil];
address.address1 = @"3892 Streewell Rd.";
address.city = @"Toronto";
address.province = @"Ontario";
address.provinceCode = @"ON";
address.country = @"Canada";
address.countryCode = @"CA";
address.zip = @"L8S 2W2";
return address;
}
- (BUYAddress *)addressByModyfyingAddress:(BUYAddress *)oldAddress;
{
BUYAddress *address = [[BUYAddress alloc] initWithModelManager:self.client.modelManager JSONDictionary:nil];
address.identifier = oldAddress.identifier;
address.address1 = @"8493 Southwest St.";
address.city = @"Vancouver";
address.province = @"British Columbia";
address.provinceCode = @"BC";
address.country = @"Canada";
address.countryCode = @"CA";
address.zip = @"T3G 4D9";
return address;
}
#pragma mark - Credentials -
- (BUYAccountCredentials *)credentialsForLogin
......
......@@ -124,5 +124,9 @@
"testCustomerDuplicateEmail":{"body":"{\"errors\":{\"customer\":{\"email\":[{\"code\":\"taken\",\"message\":\"has already been taken\",\"options\":{\"rescue_from_duplicate\":true,\"value\":\"asd@asd.com\"}}]}}}"},
"testCustomerInvalidEmailPassword":{"body":"{\"errors\":{\"customer\":{\"password\":[{\"code\":\"too_short\",\"message\":\"is too short (minimum is 5 characters)\",\"options\":{\"count\":5}}],\"password_confirmation\":[{\"code\":\"confirmation\",\"message\":\"doesn't match Password\",\"options\":{\"attribute\":\"Password\"}}],\"email\":[{\"code\":\"invalid\",\"message\":\"is invalid\",\"options\":{}}]}}}"},
"testCustomerLogout":{"body":"{}","code":204,"message":"OK"},
"testCustomerLogin":{"body":"{\"customer\":{\"id\":2529265094,\"email\":\"asd@asd.com\",\"default_address\":{\"id\":2839567814,\"first_name\":\"Fast\",\"last_name\":\"Add\",\"company\":\"Adidas\",\"address1\":\"Sass\",\"address2\":\"12\",\"city\":\"Qsdasd\",\"province\":null,\"country\":\"Bouvet Island\",\"zip\":\"24124124\",\"phone\":\"123124124\",\"name\":\"Fast Add\",\"province_code\":null,\"country_code\":\"BV\",\"country_name\":\"Bouvet Island\",\"default\":true},\"verified_email\":true,\"accepts_marketing\":false,\"first_name\":\"Fast\",\"last_name\":\"Add\",\"orders_count\":9,\"total_spent\":\"375.00\",\"created_at\":\"2016-02-16T14:42:24-05:00\",\"updated_at\":\"2016-03-10T16:34:04-05:00\",\"state\":\"enabled\",\"last_order_id\":2566266118,\"last_order_name\":\"#1137\",\"addresses\":[{\"id\":2785988486,\"first_name\":\"AA\",\"last_name\":\"A\",\"phone\":\"\",\"company\":\"\",\"address1\":\"Assiniboine Road\",\"address2\":\"\",\"city\":\"Toronto\",\"province\":\"Ontario\",\"province_code\":\"ON\",\"country\":\"Canada\",\"country_code\":\"CA\",\"zip\":\"M3J1E1\"},{\"id\":2839567814,\"first_name\":\"Fast\",\"last_name\":\"Add\",\"phone\":\"123124124\",\"company\":\"Adidas\",\"address1\":\"Sass\",\"address2\":\"12\",\"city\":\"Qsdasd\",\"province\":null,\"province_code\":null,\"country\":\"Bouvet Island\",\"country_code\":\"BV\",\"zip\":\"24124124\"}],\"multipass_identifier\":null,\"tax_exempt\":false}}","code":200,"message":"OK"}
"testCustomerLogin":{"body":"{\"customer\":{\"id\":2529265094,\"email\":\"asd@asd.com\",\"default_address\":{\"id\":2839567814,\"first_name\":\"Fast\",\"last_name\":\"Add\",\"company\":\"Shopify Inc.\",\"address1\":\"Sass\",\"address2\":\"12\",\"city\":\"Qsdasd\",\"province\":null,\"country\":\"Bouvet Island\",\"zip\":\"24124124\",\"phone\":\"123124124\",\"name\":\"Fast Add\",\"province_code\":null,\"country_code\":\"BV\",\"country_name\":\"Bouvet Island\",\"default\":true},\"verified_email\":true,\"accepts_marketing\":false,\"first_name\":\"Fast\",\"last_name\":\"Add\",\"orders_count\":9,\"total_spent\":\"375.00\",\"created_at\":\"2016-02-16T14:42:24-05:00\",\"updated_at\":\"2016-03-10T16:34:04-05:00\",\"state\":\"enabled\",\"last_order_id\":2566266118,\"last_order_name\":\"#1137\",\"addresses\":[{\"id\":2785988486,\"first_name\":\"AA\",\"last_name\":\"A\",\"phone\":\"\",\"company\":\"\",\"address1\":\"Assiniboine Road\",\"address2\":\"\",\"city\":\"Toronto\",\"province\":\"Ontario\",\"province_code\":\"ON\",\"country\":\"Canada\",\"country_code\":\"CA\",\"zip\":\"M3J1E1\"},{\"id\":2839567814,\"first_name\":\"Fast\",\"last_name\":\"Add\",\"phone\":\"123124124\",\"company\":\"Shopify Inc.\",\"address1\":\"Sass\",\"address2\":\"12\",\"city\":\"Qsdasd\",\"province\":null,\"province_code\":null,\"country\":\"Bouvet Island\",\"country_code\":\"BV\",\"zip\":\"24124124\"}],\"multipass_identifier\":null,\"tax_exempt\":false}}","code":200,"message":"OK"},
"testCustomerAddresses":{"code":200,"message":"OK","body":"{\"addresses\":[{\"id\":3228337350,\"first_name\":\"MobileBuy\",\"last_name\":\"TestBot\",\"phone\":\"1-555-555-5555\",\"company\":\"Shopify Inc.\",\"address1\":\"150 Elgin Street\",\"address2\":\"8th Floor\",\"city\":\"Toledo\",\"province\":null,\"province_code\":null,\"country\":null,\"country_code\":null,\"zip\":\"K1N5T5\"},{\"id\":3228402182,\"first_name\":\"MobileBuy\",\"last_name\":\"TestBot\",\"phone\":\"1-555-555-5555\",\"company\":\"Shopify Inc.\",\"address1\":\"150 Elgin Street\",\"address2\":\"8th Floor\",\"city\":\"Ottawa\",\"province\":null,\"province_code\":null,\"country\":null,\"country_code\":null,\"zip\":\"K1N5T5\"},{\"id\":3228535430,\"first_name\":\"Testy\",\"last_name\":\"McTesterson\",\"phone\":\"1-555-555-5555\",\"company\":\"Shopify Inc.\",\"address1\":\"150 Elgin Street\",\"address2\":\"8th Floor\",\"city\":\"Ottawa\",\"province\":null,\"province_code\":null,\"country\":null,\"country_code\":null,\"zip\":\"K1N5T5\"},{\"id\":3279871622,\"first_name\":\"MobileBuy\",\"last_name\":\"asfas\",\"phone\":null,\"company\":null,\"address1\":\"150 Elgin Street\",\"address2\":\"8th Floor\",\"city\":\"Toledo\",\"province\":\"Ciudad Autónoma de Buenos Aires\",\"province_code\":\"C\",\"country\":\"Argentina\",\"country_code\":\"AR\",\"zip\":\"124124\"}]}"},
"testCustomerAddress1":{"code":200,"message":"OK","body":"{\"address\":{\"id\":3541821574,\"first_name\":\"MobileBuy\",\"last_name\":\"asfas\",\"phone\":null,\"company\":null,\"address1\":\"3892 Streewell Rd.\",\"address2\":null,\"city\":\"Toronto\",\"province\":\"Ontario\",\"province_code\":\"ON\",\"country\":\"Canada\",\"country_code\":\"CA\",\"zip\":\"L8S 2W2\"}}"},
"testCustomerAddress2":{"code":200,"message":"OK","body":"{\"address\":{\"id\":3541821574,\"first_name\":\"MobileBuy\",\"last_name\":\"asfas\",\"phone\":null,\"company\":null,\"address1\":\"8493 Southwest St.\",\"address2\":null,\"city\":\"Vancouver\",\"province\":\"British Columbia\",\"province_code\":\"BC\",\"country\":\"Canada\",\"country_code\":\"CA\",\"zip\":\"T3G 4D9\"}}"},
"testCustomerAddressDelete":{"code":204,"message":"OK","body":"{}"}
}
......@@ -386,6 +386,10 @@
9A585C0D1CE6440B001F20F0 /* BUYOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A585C051CE6440B001F20F0 /* BUYOperation.m */; };
9A6B03791CDA5D4F0054C26E /* BUYAccountCredentialsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A6B03781CDA5D4F0054C26E /* BUYAccountCredentialsTests.m */; };
9A7652C31CF487BD00220E4B /* BUYOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A7652C21CF487BD00220E4B /* BUYOperationTests.m */; };
9A807E831CF74EBE00023160 /* BUYClient+Address.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A807E811CF74EBE00023160 /* BUYClient+Address.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A807E841CF74EBE00023160 /* BUYClient+Address.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A807E811CF74EBE00023160 /* BUYClient+Address.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A807E851CF74EBE00023160 /* BUYClient+Address.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A807E821CF74EBE00023160 /* BUYClient+Address.m */; };
9A807E861CF74EBE00023160 /* BUYClient+Address.m in Sources */ = {isa = PBXBuildFile; fileRef = 9A807E821CF74EBE00023160 /* BUYClient+Address.m */; };
9ABBCCA11CF5C9D10075B0C5 /* BUYFakeSafariController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9ABBCCA01CF5C9D10075B0C5 /* BUYFakeSafariController.m */; };
B2653EC31CEF55CC0012D57D /* BUYModelManager+ApplePay.h in Headers */ = {isa = PBXBuildFile; fileRef = B2653EC11CEF55CC0012D57D /* BUYModelManager+ApplePay.h */; };
B2653EC41CEF55CC0012D57D /* BUYModelManager+ApplePay.h in Headers */ = {isa = PBXBuildFile; fileRef = B2653EC11CEF55CC0012D57D /* BUYModelManager+ApplePay.h */; };
......@@ -676,6 +680,8 @@
9A585C121CE65811001F20F0 /* BUYRequestOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYRequestOperation.m; sourceTree = "<group>"; };
9A6B03781CDA5D4F0054C26E /* BUYAccountCredentialsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYAccountCredentialsTests.m; sourceTree = "<group>"; };
9A7652C21CF487BD00220E4B /* BUYOperationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYOperationTests.m; sourceTree = "<group>"; };
9A807E811CF74EBE00023160 /* BUYClient+Address.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BUYClient+Address.h"; sourceTree = "<group>"; };
9A807E821CF74EBE00023160 /* BUYClient+Address.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BUYClient+Address.m"; sourceTree = "<group>"; };
9ABBCC9F1CF5C9D10075B0C5 /* BUYFakeSafariController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BUYFakeSafariController.h; sourceTree = "<group>"; };
9ABBCCA01CF5C9D10075B0C5 /* BUYFakeSafariController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BUYFakeSafariController.m; sourceTree = "<group>"; };
B2653EC11CEF55CC0012D57D /* BUYModelManager+ApplePay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "BUYModelManager+ApplePay.h"; sourceTree = "<group>"; };
......@@ -1203,6 +1209,8 @@
9A0B0C711CEB52B90037D68F /* BUYClient+Checkout.m */,
8498DCB11CDD1B4A00BD12A8 /* BUYClient+Customers.h */,
8498DCB21CDD1B4A00BD12A8 /* BUYClient+Customers.m */,
9A807E811CF74EBE00023160 /* BUYClient+Address.h */,
9A807E821CF74EBE00023160 /* BUYClient+Address.m */,
);
path = Data;
sourceTree = "<group>";
......@@ -1260,6 +1268,7 @@
9019313C1BC5B9BC00D1134E /* BUYShop.h in Headers */,
9019313D1BC5B9BC00D1134E /* BUYShippingRate.h in Headers */,
9019313E1BC5B9BC00D1134E /* BUYApplePayAdditions.h in Headers */,
9A807E841CF74EBE00023160 /* BUYClient+Address.h in Headers */,
84980F531CB7616900CFAB58 /* BUYDecimalNumberTransformer.h in Headers */,
901931421BC5B9BC00D1134E /* BUYMaskedCreditCard.h in Headers */,
8498DCB61CDD1B5400BD12A8 /* BUYClient+Internal.h in Headers */,
......@@ -1388,6 +1397,7 @@
84DD12CD1CC6401400A2442D /* BUYCustomer.h in Headers */,
BE9A645D1B503CE30033E558 /* BUYObject.h in Headers */,
9A0B0CA71CED0A860037D68F /* BUYCheckoutOperation.h in Headers */,
9A807E831CF74EBE00023160 /* BUYClient+Address.h in Headers */,
BE9A646E1B503D1E0033E558 /* BUYRuntime.h in Headers */,
BEB74A901B55A3D00005A300 /* BUYCollection.h in Headers */,
84D915431CC0359700D334FB /* BUYObserver.h in Headers */,
......@@ -1678,6 +1688,7 @@
84980F391CB75C2900CFAB58 /* NSPropertyDescription+BUYAdditions.m in Sources */,
9A585C0D1CE6440B001F20F0 /* BUYOperation.m in Sources */,
841ADE221CB6C942000004B0 /* NSURL+BUYAdditions.m in Sources */,
9A807E861CF74EBE00023160 /* BUYClient+Address.m in Sources */,
901931161BC5B9BC00D1134E /* BUYShippingRate.m in Sources */,
841ADE061CB6C942000004B0 /* NSDate+BUYAdditions.m in Sources */,
84B0A7431CE10F8100253EB0 /* BUYClient+CheckoutHelpers.m in Sources */,
......@@ -1820,6 +1831,7 @@
84980F381CB75C2900CFAB58 /* NSPropertyDescription+BUYAdditions.m in Sources */,
9A585C0C1CE6440B001F20F0 /* BUYOperation.m in Sources */,
841ADE211CB6C942000004B0 /* NSURL+BUYAdditions.m in Sources */,
9A807E851CF74EBE00023160 /* BUYClient+Address.m in Sources */,
BE9A644E1B503CA60033E558 /* BUYShippingRate.m in Sources */,
841ADE051CB6C942000004B0 /* NSDate+BUYAdditions.m in Sources */,
84B0A7421CE10F8100253EB0 /* BUYClient+CheckoutHelpers.m in Sources */,
......
......@@ -63,6 +63,7 @@ FOUNDATION_EXPORT const unsigned char BuyVersionString[];
#import <Buy/BUYWebCheckoutPaymentProvider.h>
#import <Buy/BUYClient.h>
#import <Buy/BUYClient+Address.h>
#import <Buy/BUYClient+Customers.h>
#import <Buy/BUYClient+Checkout.h>
#import <Buy/BUYClient+Storefront.h>
......
//
// BUYClient+Address.h
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYClient+Customers.h"
NS_ASSUME_NONNULL_BEGIN
@class BUYAddress;
/**
* Return block containing an array of BUYAddress objects for an existing customer of the shop
*
* @param addresses An array containing BUYAddress objects
* @param error An optional NSError
*/
typedef void (^BUYDataAddressesBlock)(NSArray<BUYAddress *> * _Nullable addresses, NSError * _Nullable error);
/**
* Return block containing a BUYAddress object for an existing customer of the shop
*
* @param address A BUYAddress
* @param error An optional NSError
*/
typedef void (^BUYDataAddressBlock)(BUYAddress * _Nullable address, NSError * _Nullable error);
@interface BUYClient (Address)
/**
* GET /api/customers/:customer_id/addresses
* Fetch all customer addresses
*
* @param customerID Customer ID for which to fetch all address
* @param block (NSArray<BUYAddress *> *addresses, NSError *error)
*
* @return The associated BUYRequestOperation
*/
- (BUYRequestOperation *)getAddressesForCustomerID:(NSString *)customerID callback:(BUYDataAddressesBlock)block;
/**
* GET /api/customers/:customer_id/addresses/:id
* Fetch a customer address by ID
*
* @param addressID Identifier of the address to fetch
* @param customerID Customer ID for which to fetch the address
* @param block (BUYAddress *address, NSError *error)
*
* @return The associated BUYRequestOperation
*/
- (BUYRequestOperation *)getAddressWithID:(NSNumber *)addressID forCustomerID:(NSString *)customerID callback:(BUYDataAddressBlock)block;
/**
* POST /api/customers/:customer_id/addresses
* Creates a new customer address
*
* @param address Address to create
* @param customer Customer ID for which to create the address
* @param block (BUYAddress *address, NSError *error)
*
* @return The associated BUYRequestOperation
*/
- (BUYRequestOperation *)createAddress:(BUYAddress *)address forCustomerID:(NSString *)customerID callback:(BUYDataAddressBlock)block;
/**
* PUT /api/customers/:customer_id/addresses/:id
* Updates the customer address
*
* @param address Address to update, containing updated values
* @param customerID Customer ID for which to update the address
* @param block (BUYAddress *address, NSError *error)
*
* @return The associated BUYRequestOperation
*/
- (BUYRequestOperation *)updateAddress:(BUYAddress *)address forCustomerID:(NSString *)customerID callback:(BUYDataAddressBlock)block;
/**
* DELETE /api/customers/:customer_id/addresses/:id
* Delete the customer address
*
* @param address Address to delete
* @param customerID Customer ID for which to delete the address
* @param block (BUYStatus status, NSError *error)
*
* @return The associated BUYRequestOperation
*/
- (BUYRequestOperation *)deleteAddress:(BUYAddress *)address forCustomerID:(NSString *)customerID callback:(BUYDataStatusBlock)block;
@end
NS_ASSUME_NONNULL_END
//
// BUYClient+Address.m
// Mobile Buy SDK
//
// Created by Shopify.
// Copyright (c) 2015 Shopify Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BUYClient+Address.h"
#import "BUYClient+Routing.h"
#import "BUYClient+Internal.h"
#import "BUYCustomer.h"
#import "BUYAddress.h"
#import "BUYAssert.h"
@implementation BUYClient (Address)
- (BUYRequestOperation *)getAddressesForCustomerID:(NSString *)customerID callback:(BUYDataAddressesBlock)block
{
NSURL *route = [self urlForCustomersAddressesWithID:customerID];
return [self getRequestForURL:route completionHandler:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
NSArray<BUYAddress *> *addresses = nil;
if (json && !error) {
addresses = [self.modelManager insertAddresssWithJSONArray:json[@"addresses"]];
}
block(addresses, error);
}];
}
- (BUYRequestOperation *)getAddressWithID:(NSNumber *)addressID forCustomerID:(NSString *)customerID callback:(BUYDataAddressBlock)block
{
NSURL *route = [self urlForCustomersAddressWithID:customerID addressID:addressID];
return [self getRequestForURL:route completionHandler:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
BUYAddress *address = nil;
if (json && !error) {
address = [self.modelManager insertAddressWithJSONDictionary:json[@"address"]];
}
block(address, error);
}];
}
- (BUYRequestOperation *)createAddress:(BUYAddress *)address forCustomerID:(NSString *)customerID callback:(BUYDataAddressBlock)block
{
NSURL *route = [self urlForCustomersAddressesWithID:customerID];
return [self postRequestForURL:route object:@{ @"address" : address.JSONDictionary } completionHandler:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
BUYAddress *address = nil;
if (json && !error) {
address = [self.modelManager insertAddressWithJSONDictionary:json[@"address"]];
}
block(address, error);
}];
}
- (BUYRequestOperation *)updateAddress:(BUYAddress *)address forCustomerID:(NSString *)customerID callback:(BUYDataAddressBlock)block
{
BUYAssert(address.identifier, @"Failed to update address. Address must have a valid identifier.");
NSURL *route = [self urlForCustomersAddressWithID:customerID addressID:address.identifier];
return [self putRequestForURL:route object:@{ @"address" : address.JSONDictionary } completionHandler:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
BUYAddress *address = nil;
if (json && !error) {
address = [self.modelManager insertAddressWithJSONDictionary:json[@"address"]];
}
block(address, error);
}];
}
- (BUYRequestOperation *)deleteAddress:(BUYAddress *)address forCustomerID:(NSString *)customerID callback:(BUYDataStatusBlock)block
{
BUYAssert(address.identifier, @"Failed to update address. Address must have a valid identifier.");
NSURL *route = [self urlForCustomersAddressWithID:customerID addressID:address.identifier];
return [self deleteRequestForURL:route completionHandler:^(NSDictionary *json, NSHTTPURLResponse *response, NSError *error) {
block(response.statusCode, error);
}];
}
@end
......@@ -47,12 +47,16 @@
- (NSURL *)urlForCustomers;
- (NSURL *)urlForCustomersOrders;
- (NSURL *)urlForCustomersToken;
- (NSURL *)urlForCustomersPasswordRecovery;
- (NSURL *)urlForCustomersWithID:(NSString *)identifier;
- (NSURL *)urlForCustomersActivationWithID:(NSString *)identifier parameters:(NSDictionary *)parameters;
- (NSURL *)urlForCustomersToken;
- (NSURL *)urlForCustomersTokenWithID:(NSString *)customerID;
- (NSURL *)urlForCustomersTokenRenewalWithID:(NSString *)customerID;
- (NSURL *)urlForCustomersPasswordRecovery;
- (NSURL *)urlForCustomersPasswordResetWithID:(NSString *)identifier parameters:(NSDictionary *)parameters;
- (NSURL *)urlForCustomersAddressesWithID:(NSString *)customerID;
- (NSURL *)urlForCustomersAddressWithID:(NSString *)customerID addressID:(NSNumber *)addressID;
@end
......@@ -178,6 +178,18 @@
return [[[self urlForCustomers] appendPath:@"/orders"] appendExtension];
}
- (NSURL *)urlForCustomersToken
{
return [[[self urlForCustomers] appendPath:@"/customer_token"] appendExtension];
}
- (NSURL *)urlForCustomersPasswordRecovery
{
return [[[self urlForCustomers] appendPath:@"/recover"] appendExtension];
}
#pragma mark - Customer With ID -
- (NSURL *)urlForCustomersWithID:(NSString *)identifier
{
return [[[self urlForCustomers] appendPath:identifier] appendExtension];
......@@ -188,11 +200,6 @@
return [[[[self urlForCustomersWithID:identifier] appendPath:@"/activate"] appendParameters:parameters] appendExtension];
}
- (NSURL *)urlForCustomersToken
{
return [[[self urlForCustomers] appendPath:@"/customer_token"] appendExtension];
}
- (NSURL *)urlForCustomersTokenWithID:(NSString *)customerID
{
return [[[self urlForCustomersWithID:customerID] appendPath:@"/customer_token"] appendExtension];
......@@ -203,14 +210,21 @@
return [[[self urlForCustomersWithID:customerID] appendPath:@"/customer_token/renew"] appendExtension];
}
- (NSURL *)urlForCustomersPasswordRecovery
- (NSURL *)urlForCustomersPasswordResetWithID:(NSString *)identifier parameters:(NSDictionary *)parameters
{
return [[[self urlForCustomers] appendPath:@"/recover"] appendExtension];
return [[[[self urlForCustomersWithID:identifier] appendPath:@"/reset"] appendExtension] appendParameters:parameters];
}
- (NSURL *)urlForCustomersPasswordResetWithID:(NSString *)identifier parameters:(NSDictionary *)parameters
#pragma mark - Customer Addresses -
- (NSURL *)urlForCustomersAddressesWithID:(NSString *)customerID
{
return [[[[self urlForCustomersWithID:identifier] appendPath:@"/reset"] appendExtension] appendParameters:parameters];
return [[[self urlForCustomersWithID:customerID] appendPath:@"/addresses"] appendExtension];
}
- (NSURL *)urlForCustomersAddressWithID:(NSString *)customerID addressID:(NSNumber *)addressID
{
return [[[[self urlForCustomersWithID:customerID] appendPath:@"/addresses"] appendIdentifier:addressID] appendExtension];
}
#pragma mark - Utilities -
......
......@@ -121,11 +121,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong, readonly, nonnull) NSString *appId;
/**
* The Merchant ID is used for Apple Pay and set using `enableApplePayWithMerchantId:`
*/
@property (nonatomic, strong, readonly, nullable) NSString *merchantId NS_DEPRECATED_IOS(8_0, 9_0, "Set the `merchantId` on a BUYViewController subclass instead");
/**
* Application name to attribute orders to. Defaults to app bundle name (CFBundleName)
*/
@property (nonatomic, strong, nonnull) NSString *applicationName;
......@@ -142,15 +137,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (strong, nonatomic, nullable) NSString *customerToken;
#pragma mark - Deprecated methods
/**
* Enable Apple Pay by calling this method with the Merchant ID provided via Apple Pay setup in the Mobile SDK Channel on Shopify Admin
*
* @param merchantId The Merchant ID generated on Shopify Admin
*/
- (void)enableApplePayWithMerchantId:(NSString *)merchantId NS_DEPRECATED_IOS(8_0, 9_0, "Set the merchantId on a `BUYViewController` subclass instead");
@end
NS_ASSUME_NONNULL_END
......@@ -251,11 +251,4 @@ static NSString * const BUYClientJSONMimeType = @"application/json";
}
}
#pragma mark - Deprecations
- (void)enableApplePayWithMerchantId:(NSString *)merchantId
{
_merchantId = merchantId;
}
@end
......@@ -36,6 +36,11 @@
<entry key="documentation" value="The first name of the person associated with the payment method."/>
</userInfo>
</attribute>
<attribute name="identifier" optional="YES" attributeType="Integer 64" defaultValueString="0" syncable="YES">
<userInfo>
<entry key="documentation" value="Unique identifier for the address"/>
</userInfo>
</attribute>
<attribute name="lastName" optional="YES" attributeType="String" syncable="YES">
<userInfo>
<entry key="documentation" value="The last name of the person associated with the payment method."/>
......@@ -984,7 +989,7 @@
<memberEntity name="CheckoutAttribute"/>
</configuration>
<elements>
<element name="Address" positionX="126" positionY="521" width="128" height="240"/>
<element name="Address" positionX="126" positionY="521" width="128" height="255"/>
<element name="Cart" positionX="-576" positionY="558" width="128" height="60"/>
<element name="CartLineItem" positionX="-380" positionY="558" width="128" height="90"/>
<element name="Checkout" positionX="333" positionY="442" width="128" height="630"/>
......
......@@ -38,6 +38,7 @@ extern const struct BUYAddressAttributes {
__unsafe_unretained NSString *country;
__unsafe_unretained NSString *countryCode;
__unsafe_unretained NSString *firstName;
__unsafe_unretained NSString *identifier;
__unsafe_unretained NSString *lastName;
__unsafe_unretained NSString *phone;
__unsafe_unretained NSString *province;
......@@ -105,6 +106,15 @@ extern const struct BUYAddressUserInfo {
@property (nonatomic, strong) NSString* firstName;
/**
* Unique identifier for the address
*/
@property (nonatomic, strong) NSNumber* identifier;
@property (atomic) int64_t identifierValue;
- (int64_t)identifierValue;
- (void)setIdentifierValue:(int64_t)value_;
/**
* The last name of the person associated with the payment method.
*/
@property (nonatomic, strong) NSString* lastName;
......@@ -156,6 +166,9 @@ extern const struct BUYAddressUserInfo {
- (NSString*)primitiveFirstName;
- (void)setPrimitiveFirstName:(NSString*)value;
- (NSNumber*)primitiveIdentifier;
- (void)setPrimitiveIdentifier:(NSNumber*)value;
- (NSString*)primitiveLastName;
- (void)setPrimitiveLastName:(NSString*)value;
......
......@@ -36,6 +36,7 @@ const struct BUYAddressAttributes BUYAddressAttributes = {
.country = @"country",
.countryCode = @"countryCode",
.firstName = @"firstName",
.identifier = @"identifier",
.lastName = @"lastName",
.phone = @"phone",
.province = @"province",
......@@ -60,6 +61,12 @@ const struct BUYAddressUserInfo BUYAddressUserInfo = {
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
if ([key isEqualToString:@"identifierValue"]) {
NSSet *affectingKey = [NSSet setWithObject:@"identifier"];
keyPaths = [keyPaths setByAddingObjectsFromSet:affectingKey];
return keyPaths;
}
return keyPaths;
}
......@@ -155,6 +162,19 @@ const struct BUYAddressUserInfo BUYAddressUserInfo = {
[self didChangeValueForKey:@"firstName"];
}
- (NSNumber*)identifier {
[self willAccessValueForKey:@"identifier"];
id value = [self primitiveValueForKey:@"identifier"];
[self didAccessValueForKey:@"identifier"];
return value;
}
- (void)setIdentifier:(NSNumber*)value_ {
[self willChangeValueForKey:@"identifier"];
[self setPrimitiveValue:value_ forKey:@"identifier"];
[self didChangeValueForKey:@"identifier"];
}
- (NSString*)lastName {
[self willAccessValueForKey:@"lastName"];
id value = [self primitiveValueForKey:@"lastName"];
......@@ -222,6 +242,15 @@ const struct BUYAddressUserInfo BUYAddressUserInfo = {
#endif
- (int64_t)identifierValue {
NSNumber *result = [self identifier];
return [result longLongValue];
}
- (void)setIdentifierValue:(int64_t)value_ {
[self setIdentifier:@(value_)];
}
#if defined CORE_DATA_PERSISTENCE
@dynamic customer;
#endif
......
......@@ -59,6 +59,7 @@
#import "BUYWebCheckoutPaymentProvider.h"
#import "BUYClient.h"
#import "BUYClient+Address.h"
#import "BUYClient+Customers.h"
#import "BUYClient+Checkout.h"
#import "BUYClient+Storefront.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment