Commit 7254fd6b by Dima Bart

Make account credentials immutable. Simplify usage. Adjust tests.

parent c5e652a3
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#pragma mark - Init - #pragma mark - Init -
- (void)testInitWithoutItems { - (void)testInitWithoutItems {
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:nil]; BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[]];
XCTAssertNotNil(credentials); XCTAssertNotNil(credentials);
XCTAssertEqual(credentials.count, 0); XCTAssertEqual(credentials.count, 0);
} }
...@@ -60,48 +60,25 @@ ...@@ -60,48 +60,25 @@
} }
#pragma mark - Mutation - #pragma mark - Mutation -
- (void)testAddingUniqueItems { - (void)testExtendingCredentials {
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:[self sampleWithValidItems]];
BUYAccountCredentials *credentials = [BUYAccountCredentials credentials]; XCTAssertEqual(credentials.count, 2);
XCTAssertEqual(credentials.count, 0);
[credentials setCredentialItem:[self emailItem]];
XCTAssertEqual(credentials.count, 1);
[credentials setCredentialItems:@[ credentials = [credentials credentialsByAddingItems:@[
[self passwordItem], [BUYAccountCredentialItem itemWithFirstName:@"John"],
[self passwordConfirmationItem], [BUYAccountCredentialItem itemWithLastName:@"Doe"],
]]; ]];
XCTAssertEqual(credentials.count, 3); XCTAssertEqual(credentials.count, 4);
}
- (void)testAddingDuplicateItems {
/* ----------------------------------
* A duplicate item is considered the
* same based on the item key, not
* the value.
*/
BUYAccountCredentials *credentials = [BUYAccountCredentials credentials];
XCTAssertEqual(credentials.count, 0);
[credentials setCredentialItem:[BUYAccountCredentialItem itemEmailWithValue:@"john@appleseed.com"]];
XCTAssertEqual(credentials.count, 1);
[credentials setCredentialItem:[BUYAccountCredentialItem itemEmailWithValue:@"john@doe.com"]];
XCTAssertEqual(credentials.count, 1);
} }
#pragma mark - Serialization - #pragma mark - Serialization -
- (void)testJSONSerialization { - (void)testJSONSerialization {
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:[self sampleWithValidItems]]; BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[
[credentials setCredentialItems:@[ [BUYAccountCredentialItem itemWithEmail:@"john@doe.com"],
[BUYAccountCredentialItem itemEmailWithValue:@"john@doe.com"], [BUYAccountCredentialItem itemWithFirstName:@"John"],
[BUYAccountCredentialItem itemFirstNameWithValue:@"John"], [BUYAccountCredentialItem itemWithLastName:@"Doe"],
[BUYAccountCredentialItem itemLastNameWithValue:@"Doe"], [BUYAccountCredentialItem itemWithPassword:@"pass"],
[BUYAccountCredentialItem itemPasswordWithValue:@"pass"], [BUYAccountCredentialItem itemWithPasswordConfirmation:@"pass"],
[BUYAccountCredentialItem itemPasswordConfirmationWithValue:@"pass"],
]]; ]];
NSDictionary *json = [credentials JSONRepresentation]; NSDictionary *json = [credentials JSONRepresentation];
...@@ -110,27 +87,27 @@ ...@@ -110,27 +87,27 @@
XCTAssertNotNil(json); XCTAssertNotNil(json);
XCTAssertEqual(json.count, 1); XCTAssertEqual(json.count, 1);
XCTAssertNotNil(customer); XCTAssertNotNil(customer);
XCTAssertEqual(customer[BUYAccountEmailKey], @"john@doe.com"); XCTAssertEqual(customer[@"email"], @"john@doe.com");
XCTAssertEqual(customer[BUYAccountFirstNameKey], @"John"); XCTAssertEqual(customer[@"first_name"], @"John");
XCTAssertEqual(customer[BUYAccountLastNameKey], @"Doe"); XCTAssertEqual(customer[@"last_name"], @"Doe");
XCTAssertEqual(customer[BUYAccountPasswordKey], @"pass"); XCTAssertEqual(customer[@"password"], @"pass");
XCTAssertEqual(customer[BUYAccountPasswordConfirmationKey], @"pass"); XCTAssertEqual(customer[@"password_confirmation"], @"pass");
} }
#pragma mark - Utilities - #pragma mark - Utilities -
- (BUYAccountCredentialItem *)emailItem - (BUYAccountCredentialItem *)emailItem
{ {
return [BUYAccountCredentialItem itemEmailWithValue:@"john@smith.com"]; return [BUYAccountCredentialItem itemWithEmail:@"john@smith.com"];
} }
- (BUYAccountCredentialItem *)passwordItem - (BUYAccountCredentialItem *)passwordItem
{ {
return [BUYAccountCredentialItem itemPasswordWithValue:@"password"]; return [BUYAccountCredentialItem itemWithPassword:@"password"];
} }
- (BUYAccountCredentialItem *)passwordConfirmationItem - (BUYAccountCredentialItem *)passwordConfirmationItem
{ {
return [BUYAccountCredentialItem itemPasswordConfirmationWithValue:@"password"]; return [BUYAccountCredentialItem itemWithPasswordConfirmation:@"password"];
} }
- (NSArray *)sampleWithValidItems { - (NSArray *)sampleWithValidItems {
...@@ -143,8 +120,8 @@ ...@@ -143,8 +120,8 @@
- (NSArray *)sampleWithInvalidItems { - (NSArray *)sampleWithInvalidItems {
NSMutableArray *items = [NSMutableArray new]; NSMutableArray *items = [NSMutableArray new];
[items addObject:[self emailItem]]; [items addObject:[self emailItem]];
[items addObject:[BUYAccountCredentialItem itemPasswordWithValue:@""]]; [items addObject:[BUYAccountCredentialItem itemWithPassword:@""]];
[items addObject:[BUYAccountCredentialItem itemPasswordConfirmationWithValue:@""]]; [items addObject:[BUYAccountCredentialItem itemWithPasswordConfirmation:@""]];
return items; return items;
} }
......
...@@ -327,12 +327,13 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg"; ...@@ -327,12 +327,13 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg";
- (void)testCustomerCreationURL - (void)testCustomerCreationURL
{ {
BUYAccountCredentialItem *firstName = [BUYAccountCredentialItem itemWithKey:@"first_name" value:@"michael"]; BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[
BUYAccountCredentialItem *lastName = [BUYAccountCredentialItem itemWithKey:@"last_name" value:@"scott"]; [BUYAccountCredentialItem itemWithFirstName:@"michael"],
BUYAccountCredentialItem *email = [BUYAccountCredentialItem itemWithKey:@"email" value:@"fake@example.com"]; [BUYAccountCredentialItem itemWithLastName:@"scott"],
BUYAccountCredentialItem *password = [BUYAccountCredentialItem itemWithKey:@"password" value:@"password"]; [BUYAccountCredentialItem itemWithEmail:@"fake@example.com"],
BUYAccountCredentialItem *passwordConfirmation = [BUYAccountCredentialItem itemWithKey:@"password_confirmation" value:@"password"]; [BUYAccountCredentialItem itemWithPassword:@"password"],
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[firstName, lastName, email, password, passwordConfirmation]]; [BUYAccountCredentialItem itemWithPasswordConfirmation:@"password"],
]];
NSURLSessionDataTask *task = [self.client createCustomerWithCredentials:credentials callback:nil]; NSURLSessionDataTask *task = [self.client createCustomerWithCredentials:credentials callback:nil];
...@@ -345,19 +346,21 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg"; ...@@ -345,19 +346,21 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg";
XCTAssertNil(error); XCTAssertNil(error);
NSDictionary *dict = @{@"customer": @{ NSDictionary *dict = @{@"customer": @{
@"first_name": firstName.value, @"first_name": @"michael",
@"last_name": lastName.value, @"last_name": @"scott",
@"email": email.value, @"email": @"fake@example.com",
@"password": password.value, @"password": @"password",
@"password_confirmation": passwordConfirmation.value}}; @"password_confirmation": @"password"
}};
XCTAssertEqualObjects(payload, dict); XCTAssertEqualObjects(payload, dict);
} }
- (void)testLoginCustomerURL - (void)testLoginCustomerURL
{ {
BUYAccountCredentialItem *email = [BUYAccountCredentialItem itemWithKey:@"email" value:@"fake@example.com"]; BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[
BUYAccountCredentialItem *password = [BUYAccountCredentialItem itemWithKey:@"password" value:@"password"]; [BUYAccountCredentialItem itemWithEmail:@"fake@example.com"],
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[email, password]]; [BUYAccountCredentialItem itemWithPassword:@"password"],
]];
NSURLSessionDataTask *task = [self.client loginCustomerWithCredentials:credentials callback:nil]; NSURLSessionDataTask *task = [self.client loginCustomerWithCredentials:credentials callback:nil];
XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https"); XCTAssertEqualObjects(task.originalRequest.URL.scheme, @"https");
...@@ -368,7 +371,10 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg"; ...@@ -368,7 +371,10 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg";
NSDictionary *payload = [NSJSONSerialization JSONObjectWithData:task.originalRequest.HTTPBody options:0 error:&error]; NSDictionary *payload = [NSJSONSerialization JSONObjectWithData:task.originalRequest.HTTPBody options:0 error:&error];
XCTAssertNil(error); XCTAssertNil(error);
NSDictionary *dict = @{@"customer": @{@"email": email.value, @"password": password.value}}; NSDictionary *dict = @{@"customer": @{
@"email": @"fake@example.com",
@"password": @"password",
}};
XCTAssertEqualObjects(payload, dict); XCTAssertEqualObjects(payload, dict);
} }
...@@ -428,9 +434,11 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg"; ...@@ -428,9 +434,11 @@ NSString * const BUYFakeCustomerToken = @"dsfasdgafdg";
- (void)testCustomerActivation - (void)testCustomerActivation
{ {
BUYAccountCredentialItem *passwordItem = [BUYAccountCredentialItem itemWithKey:@"password" value:@"12345"];
BUYAccountCredentialItem *passwordConfItem = [BUYAccountCredentialItem itemWithKey:@"password_confirmation" value:@"12345"]; BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[
BUYAccountCredentials *credentials = [BUYAccountCredentials credentialsWithItems:@[passwordItem, passwordConfItem]]; [BUYAccountCredentialItem itemWithPassword:@"12345"],
[BUYAccountCredentialItem itemWithPasswordConfirmation:@"12345"],
]];
NSString *customerID = @"12345"; NSString *customerID = @"12345";
NSString *customerToken = @"12345"; NSString *customerToken = @"12345";
NSURLSessionDataTask *task = [self.client activateCustomerWithCredentials:credentials customerID:customerID customerToken:customerToken callback:nil]; NSURLSessionDataTask *task = [self.client activateCustomerWithCredentials:credentials customerID:customerID customerToken:customerToken callback:nil];
......
...@@ -156,10 +156,8 @@ ...@@ -156,10 +156,8 @@
return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) { return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSString *email = json[@"customer"][@"email"]; NSString *email = json[@"customer"][@"email"];
if (email && !error) { if (email && !error) {
BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemEmailWithValue:email]; BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemWithEmail:email];
[credentials setCredentialItem:emailItem]; [self loginCustomerWithCredentials:[credentials credentialsByAddingItems:@[emailItem]] callback:block];
[self loginCustomerWithCredentials:credentials callback:block];
} }
else { else {
block(nil, nil, error); block(nil, nil, error);
...@@ -175,10 +173,8 @@ ...@@ -175,10 +173,8 @@
return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) { return [self putRequestForURL:components.URL body:data completionHandler:^(NSDictionary *json, NSURLResponse *response, NSError *error) {
NSString *email = json[@"customer"][@"email"]; NSString *email = json[@"customer"][@"email"];
if (email && !error) { if (email && !error) {
BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemEmailWithValue:email]; BUYAccountCredentialItem *emailItem = [BUYAccountCredentialItem itemWithEmail:email];
[credentials setCredentialItem:emailItem]; [self loginCustomerWithCredentials:[credentials credentialsByAddingItems:@[emailItem]] callback:block];
[self loginCustomerWithCredentials:credentials callback:block];
} }
else { else {
block(nil, nil, error); block(nil, nil, error);
......
...@@ -27,12 +27,6 @@ ...@@ -27,12 +27,6 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
extern NSString * const BUYAccountFirstNameKey;
extern NSString * const BUYAccountLastNameKey;
extern NSString * const BUYAccountEmailKey;
extern NSString * const BUYAccountPasswordKey;
extern NSString * const BUYAccountPasswordConfirmationKey;
@class BUYAccountCredentialItem; @class BUYAccountCredentialItem;
/** /**
...@@ -41,16 +35,16 @@ extern NSString * const BUYAccountPasswordConfirmationKey; ...@@ -41,16 +35,16 @@ extern NSString * const BUYAccountPasswordConfirmationKey;
*/ */
@interface BUYAccountCredentials : NSObject @interface BUYAccountCredentials : NSObject
@property (nonatomic, strong, readonly) NSArray<BUYAccountCredentialItem *> *items;
@property (nonatomic, assign, readonly) NSUInteger count; @property (nonatomic, assign, readonly) NSUInteger count;
@property (nonatomic, assign, readonly, getter=isValid) BOOL valid; @property (nonatomic, assign, readonly, getter=isValid) BOOL valid;
@property (nonatomic, strong, readonly) NSDictionary *JSONRepresentation; @property (nonatomic, strong, readonly) NSDictionary *JSONRepresentation;
+ (BUYAccountCredentials *)credentials; + (BUYAccountCredentials *)credentialsWithItems:(NSArray<BUYAccountCredentialItem *> *)items;
+ (BUYAccountCredentials *)credentialsWithItems:(nullable NSArray<BUYAccountCredentialItem *> *)items; - (instancetype)initWithItems:(NSArray<BUYAccountCredentialItem *> *)items;
- (instancetype)initWithItems:(nullable NSArray<BUYAccountCredentialItem *> *)items;
- (void)setCredentialItems:(NSArray<BUYAccountCredentialItem *> *)items; - (BUYAccountCredentials *)credentialsByAddingItems:(NSArray<BUYAccountCredentialItem *> *)items;
- (void)setCredentialItem:(BUYAccountCredentialItem *)item;
@end @end
...@@ -65,14 +59,11 @@ extern NSString * const BUYAccountPasswordConfirmationKey; ...@@ -65,14 +59,11 @@ extern NSString * const BUYAccountPasswordConfirmationKey;
@property (nonatomic, strong, readonly) NSString *key; @property (nonatomic, strong, readonly) NSString *key;
@property (nonatomic, strong, readonly) NSString *value; @property (nonatomic, strong, readonly) NSString *value;
+ (instancetype)itemEmailWithValue:(NSString *)value; + (instancetype)itemWithEmail:(NSString *)value;
+ (instancetype)itemFirstNameWithValue:(NSString *)value; + (instancetype)itemWithFirstName:(NSString *)value;
+ (instancetype)itemLastNameWithValue:(NSString *)value; + (instancetype)itemWithLastName:(NSString *)value;
+ (instancetype)itemPasswordWithValue:(NSString *)value; + (instancetype)itemWithPassword:(NSString *)value;
+ (instancetype)itemPasswordConfirmationWithValue:(NSString *)value; + (instancetype)itemWithPasswordConfirmation:(NSString *)value;
+ (instancetype)itemWithKey:(NSString *)key value:(NSString *)value;
- (instancetype)initWithKey:(NSString *)key value:(NSString *)value;
@end @end
......
...@@ -26,26 +26,22 @@ ...@@ -26,26 +26,22 @@
#import "BUYAccountCredentials.h" #import "BUYAccountCredentials.h"
NSString * const BUYAccountFirstNameKey = @"first_name"; static NSString * const BUYAccountFirstNameKey = @"first_name";
NSString * const BUYAccountLastNameKey = @"last_name"; static NSString * const BUYAccountLastNameKey = @"last_name";
NSString * const BUYAccountEmailKey = @"email"; static NSString * const BUYAccountEmailKey = @"email";
NSString * const BUYAccountPasswordKey = @"password"; static NSString * const BUYAccountPasswordKey = @"password";
NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation"; static NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation";
#pragma mark - BUYAccountCredentials - #pragma mark - BUYAccountCredentials -
@interface BUYAccountCredentials() @interface BUYAccountCredentials()
@property (strong, nonatomic) NSMutableDictionary<NSString *, BUYAccountCredentialItem *> *items; @property (strong, nonatomic) NSDictionary<NSString *, BUYAccountCredentialItem *> *credentialItems;
@end @end
@implementation BUYAccountCredentials @implementation BUYAccountCredentials
+ (BUYAccountCredentials *)credentials #pragma mark - Init -
{
return [BUYAccountCredentials credentialsWithItems:nil];
}
+ (BUYAccountCredentials *)credentialsWithItems:(NSArray<BUYAccountCredentialItem *> *)items + (BUYAccountCredentials *)credentialsWithItems:(NSArray<BUYAccountCredentialItem *> *)items
{ {
return [[BUYAccountCredentials alloc] initWithItems:items]; return [[BUYAccountCredentials alloc] initWithItems:items];
...@@ -56,24 +52,38 @@ NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation"; ...@@ -56,24 +52,38 @@ NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation";
self = [super init]; self = [super init];
if (self) { if (self) {
_items = [NSMutableDictionary new]; NSMutableDictionary *container = [NSMutableDictionary new];
if (items.count > 0) { for (BUYAccountCredentialItem *item in items) {
[self setCredentialItems:items]; container[item.key] = item;
} }
_credentialItems = [container copy];
} }
return self; return self;
} }
#pragma mark - Adding Items -
- (BUYAccountCredentials *)credentialsByAddingItems:(NSArray<BUYAccountCredentialItem *> *)items
{
NSMutableArray *container = [self.items mutableCopy];
[container addObjectsFromArray:items];
return [BUYAccountCredentials credentialsWithItems:container];
}
#pragma mark - Accessors - #pragma mark - Accessors -
- (NSArray<BUYAccountCredentialItem *> *)items
{
return self.credentialItems.allValues;
}
- (NSUInteger)count - (NSUInteger)count
{ {
return self.items.count; return self.credentialItems.count;
} }
- (BOOL)isValid - (BOOL)isValid
{ {
__block BOOL valid = YES; __block BOOL valid = YES;
[self.items enumerateKeysAndObjectsUsingBlock:^(NSString *key, BUYAccountCredentialItem *item, BOOL * _Nonnull stop) { [self.credentialItems enumerateKeysAndObjectsUsingBlock:^(NSString *key, BUYAccountCredentialItem *item, BOOL * _Nonnull stop) {
if (!item.isValid) { if (!item.isValid) {
valid = NO; valid = NO;
*stop = YES; *stop = YES;
...@@ -82,25 +92,11 @@ NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation"; ...@@ -82,25 +92,11 @@ NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation";
return valid; return valid;
} }
- (void)setCredentialItems:(NSArray<BUYAccountCredentialItem *> *)items
{
NSAssert(items, @"BUYAccountCredentialItem array cannot be nil.");
for (BUYAccountCredentialItem *item in items) {
[self setCredentialItem:item];
}
}
- (void)setCredentialItem:(BUYAccountCredentialItem *)item
{
NSAssert(item, @"BUYAccountCredentialItem cannot be nil.");
self.items[item.key] = item;
}
#pragma mark - Serialization - #pragma mark - Serialization -
- (NSDictionary *)JSONRepresentation - (NSDictionary *)JSONRepresentation
{ {
__block NSMutableDictionary *customer = [NSMutableDictionary dictionary]; __block NSMutableDictionary *customer = [NSMutableDictionary dictionary];
[self.items enumerateKeysAndObjectsUsingBlock:^(NSString *key, BUYAccountCredentialItem *obj, BOOL *stop) { [self.credentialItems enumerateKeysAndObjectsUsingBlock:^(NSString *key, BUYAccountCredentialItem *obj, BOOL *stop) {
customer[key] = obj.value; customer[key] = obj.value;
}]; }];
return @{ @"customer": customer }; return @{ @"customer": customer };
...@@ -112,27 +108,27 @@ NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation"; ...@@ -112,27 +108,27 @@ NSString * const BUYAccountPasswordConfirmationKey = @"password_confirmation";
@implementation BUYAccountCredentialItem @implementation BUYAccountCredentialItem
#pragma mark - Init - #pragma mark - Init -
+ (instancetype)itemEmailWithValue:(NSString *)value + (instancetype)itemWithEmail:(NSString *)value
{ {
return [BUYAccountCredentialItem itemWithKey:BUYAccountEmailKey value:value]; return [BUYAccountCredentialItem itemWithKey:BUYAccountEmailKey value:value];
} }
+ (instancetype)itemFirstNameWithValue:(NSString *)value + (instancetype)itemWithFirstName:(NSString *)value
{ {
return [BUYAccountCredentialItem itemWithKey:BUYAccountFirstNameKey value:value]; return [BUYAccountCredentialItem itemWithKey:BUYAccountFirstNameKey value:value];
} }
+ (instancetype)itemLastNameWithValue:(NSString *)value + (instancetype)itemWithLastName:(NSString *)value
{ {
return [BUYAccountCredentialItem itemWithKey:BUYAccountLastNameKey value:value]; return [BUYAccountCredentialItem itemWithKey:BUYAccountLastNameKey value:value];
} }
+ (instancetype)itemPasswordWithValue:(NSString *)value + (instancetype)itemWithPassword:(NSString *)value
{ {
return [BUYAccountCredentialItem itemWithKey:BUYAccountPasswordKey value:value]; return [BUYAccountCredentialItem itemWithKey:BUYAccountPasswordKey value:value];
} }
+ (instancetype)itemPasswordConfirmationWithValue:(NSString *)value + (instancetype)itemWithPasswordConfirmation:(NSString *)value
{ {
return [BUYAccountCredentialItem itemWithKey:BUYAccountPasswordConfirmationKey value:value]; return [BUYAccountCredentialItem itemWithKey:BUYAccountPasswordConfirmationKey value:value];
} }
......
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