Commit 7254fd6b by Dima Bart

Make account credentials immutable. Simplify usage. Adjust tests.

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