diff --git a/Common/Nodes/SLAsset.m b/Common/Nodes/SLAsset.m index ab0262c..c2dc41b 100644 --- a/Common/Nodes/SLAsset.m +++ b/Common/Nodes/SLAsset.m @@ -19,4 +19,9 @@ @implementation SLAsset @dynamic serial; @dynamic attributes; ++ (NSString *) type +{ + return @"asset"; +} + @end diff --git a/Common/Nodes/SLUser.h b/Common/Nodes/SLUser.h index 68e10bb..a3a99e7 100644 --- a/Common/Nodes/SLUser.h +++ b/Common/Nodes/SLUser.h @@ -26,16 +26,16 @@ /** */ -+ (void) registerUser:(SLUser *)theUser - withOrganization:(SLOrganization *)theOrg - withCallback:(SLSuccessCallback)theCallback; - -+ (void) registerUserWithEmail:(NSString *)email - withPassword:(NSString *)password - withJobTitle:(NSString *)jobTitle - withFirstName:(NSString *)firstName - withLastName:(NSString *)lastName - withOrganization:(SLOrganization *)theOrg - withCallback:(SLSuccessCallback)theCallback; +//+ (void) registerUser:(SLUser *)theUser +// withOrganization:(SLOrganization *)theOrg +// withCallback:(SLSuccessCallback)theCallback; +// +//+ (void) registerUserWithEmail:(NSString *)email +// withPassword:(NSString *)password +// withJobTitle:(NSString *)jobTitle +// withFirstName:(NSString *)firstName +// withLastName:(NSString *)lastName +// withOrganization:(SLOrganization *)theOrg +// withCallback:(SLSuccessCallback)theCallback; @end diff --git a/Common/Nodes/SLUser.m b/Common/Nodes/SLUser.m index 051efbd..7d25d5e 100644 --- a/Common/Nodes/SLUser.m +++ b/Common/Nodes/SLUser.m @@ -37,39 +37,39 @@ + (NSDictionary *) attributeMappings [attrMap setValue:@"dateDue" forKey:@"date_due"]; return [NSDictionary dictionaryWithDictionary: attrMap]; } - -+ (void) registerUser:(SLUser *)theUser withOrganization:(SLOrganization *)theOrg withCallback:(SLSuccessCallback)theCallback -{ - /* - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { - //NSLog(@"SLRequestCallback completionBlock!"); - //NSLog(@"<%@>: %@", [responseObject class], responseObject); - theCallback ? theCallback(true) : nil; - }; - */ - SLRelationship *rel = [[SLRelationship alloc] initWithName:@"member" withStartNode:theUser withEndNode:theOrg]; - [theUser pushWithAPIManager:[SLAPIManager sharedManager] withCallback:theCallback]; -} - - -+ (void) registerUserWithEmail:(NSString *)email - withPassword:(NSString *)password - withJobTitle:(NSString *)jobTitle - withFirstName:(NSString *)firstName - withLastName:(NSString *)lastName - withOrganization:(SLOrganization *)theOrg - withCallback:(SLSuccessCallback)theCallback -{ - NSDictionary *data = @{ - @"email": email, - @"password": password, - @"job_title": jobTitle, - @"name_first": firstName, - @"name_last": lastName - }; - SLUser *newUser = [SLUser createWithData:data - withRels:(NSArray *)@[]]; - [[self class] registerUser:newUser withOrganization:theOrg withCallback:theCallback]; -} +// +//+ (void) registerUser:(SLUser *)theUser withOrganization:(SLOrganization *)theOrg withCallback:(SLSuccessCallback)theCallback +//{ +// /* +// SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { +// //NSLog(@"SLRequestCallback completionBlock!"); +// //NSLog(@"<%@>: %@", [responseObject class], responseObject); +// theCallback ? theCallback(true) : nil; +// }; +// */ +// SLRelationship *rel = [[SLRelationship alloc] initWithName:@"member" withStartNode:theUser withEndNode:theOrg]; +// [theUser pushWithAPIManager:[SLAPIManager sharedManager] withCallback:theCallback]; +//} +// +// +//+ (void) registerUserWithEmail:(NSString *)email +// withPassword:(NSString *)password +// withJobTitle:(NSString *)jobTitle +// withFirstName:(NSString *)firstName +// withLastName:(NSString *)lastName +// withOrganization:(SLOrganization *)theOrg +// withCallback:(SLSuccessCallback)theCallback +//{ +// NSDictionary *data = @{ +// @"email": email, +// @"password": password, +// @"job_title": jobTitle, +// @"name_first": firstName, +// @"name_last": lastName +// }; +// SLUser *newUser = [SLUser createWithData:data +// withRels:(NSArray *)@[]]; +// [[self class] registerUser:newUser withOrganization:theOrg withCallback:theCallback]; +//} @end diff --git a/Common/SLAPIManager.h b/Common/SLAPIManager.h index 31d84f5..ba945c4 100644 --- a/Common/SLAPIManager.h +++ b/Common/SLAPIManager.h @@ -35,6 +35,18 @@ typedef NS_ENUM(NSUInteger, SLHTTPMethodType) @property (strong, nonatomic, setter=setPassword:) NSString *userPassword; @property (strong, nonatomic, setter=setOrganization:) NSString *userOrganization; + +/** + + */ ++(NSString *) sha1:(NSString *)plainText; + +/** + + */ ++(NSString *)hmac:(NSString *)plainText withSecret:(NSString *)key; + + /** Host for creating URL. See https://developer.apple.com/library/Mac/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html#jumpTo_31 for more details. @@ -46,11 +58,6 @@ typedef NS_ENUM(NSUInteger, SLHTTPMethodType) */ + (instancetype) sharedManager; -/** - - */ -- (void) setBaseURL:(NSURL *)theBaseURL; - /** Set the Email. */ @@ -86,13 +93,4 @@ typedef NS_ENUM(NSUInteger, SLHTTPMethodType) withOrganization:(NSString *)theOrganization; -///** -// Authenticate with user credentials. -// @param theEmail The user's email. -// @param thePassword The passsword. -// */ -//- (void) authenticateWithUser:(SLUser *)theUser -// withCallback:(SLSuccessCallback)theCallback DEPRECATED_ATTRIBUTE; - - @end diff --git a/Common/SLAPIManager.m b/Common/SLAPIManager.m index d544472..900ba63 100644 --- a/Common/SLAPIManager.m +++ b/Common/SLAPIManager.m @@ -65,6 +65,8 @@ - (void) setPassword:(NSString *)thePassword { +(NSString *) sha1:(NSString *)plainText { + // TODO: Throw exception if plainText is nil + unsigned char digest[CC_SHA1_DIGEST_LENGTH]; NSData *stringBytes = [plainText dataUsingEncoding: NSUTF8StringEncoding]; /* or some other encoding */ if (CC_SHA1([stringBytes bytes], [stringBytes length], digest)) { @@ -83,6 +85,9 @@ +(NSString *) sha1:(NSString *)plainText +(NSString *)hmac:(NSString *)plainText withSecret:(NSString *)key { + // TODO: Throw exception if either plaintText or key are nil + + const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding]; const char *cData = [plainText cStringUsingEncoding:NSASCIIStringEncoding]; @@ -101,108 +106,106 @@ +(NSString *)hmac:(NSString *)plainText withSecret:(NSString *)key return HMAC; } -- (void) performRequestWithMethod:(SLHTTPMethodType)theMethod withPath:(NSString *)thePath withParameters:(NSDictionary *)theParams withCallback:(SLRequestCallback)theCallback +- (PMKPromise *) performRequestWithMethod:(SLHTTPMethodType)theMethod + withPath:(NSString *)thePath + withParameters:(NSDictionary *)theParams { - AFHTTPRequestOperationManager *requestManager = self.httpManager; - //NSLog(@"requestManager: %@", requestManager); - - NSLog(@"baseURL: %@ , httpManager: %@", self.host, self.httpManager); - - if (self.host == nil) - { - @throw SLExceptionMissingHost; - } - - //NSLog(@"baseURl: %@", self.baseURL); - //NSLog(@"thePath: %@", thePath); - NSURL *fullPath = [[NSURL alloc] initWithScheme:@"http" host:self.host path:thePath]; - // NSURL *fullPath = [NSURL URLWithString:[NSString stringWithFormat:@"%@", thePath] relativeToURL:self.host]; - //NSLog(@"fullPath: %@", fullPath); - NSString *fullPathStr = [fullPath absoluteString]; - //NSLog(@"Full path: %@", fullPathStr); - - // Prepare headers used for authentication - // Expiry - NSTimeInterval timeInMiliseconds = [[NSDate date] timeIntervalSince1970]; - NSString *expiry = [NSString stringWithFormat:@"%f", timeInMiliseconds]; - [requestManager setValue:expiry forKey:@"X-SL-Expires"]; - // Organization - [requestManager setValue:self.userOrganization forKey:@"X-SL-Organization"]; - // Username - [requestManager setValue:self.userEmail forKey:@"X-SL-Username"]; - // HMAC - NSString *secret = _userPassword; - NSString *msg = @""; - NSString *hmac = [SLAPIManager hmac:msg withSecret:secret]; - [requestManager setValue:hmac forKey:@"hmac"]; - - - switch (theMethod) { - case SLHTTPMethodGET: - { - NSError *error; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:theParams - options:NSJSONWritingPrettyPrinted - error:&error]; - NSString *encodedJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; - NSLog(@"encodedJson: %@", encodedJson); - //encodedJson = @"{\"filter\":{\"fields\":true,\"rels\":true}}"; - NSLog(@"GET %@", fullPathStr); - [requestManager GET:fullPathStr parameters:@{@"p":encodedJson} success:^(AFHTTPRequestOperation *operation, id responseObject) { - NSLog(@"Success, JSON: %@", responseObject); - if (theCallback != nil) { - theCallback(nil, operation, responseObject); - } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - NSLog(@"Error: %@", error); - NSLog(@"Response: %@", operation.responseString); - if (theCallback != nil) { - theCallback(error, operation, nil); - } - }]; - } - break; - case SLHTTPMethodPOST: - { - [requestManager POST:fullPathStr parameters:theParams success:^(AFHTTPRequestOperation *operation, id responseObject) { - NSLog(@"Success, JSON: %@", responseObject); - if (theCallback != nil) { - theCallback(nil, operation, responseObject); - } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - NSLog(@"Error: %@", error); - NSLog(@"Response: %@", operation.responseString); - if (theCallback != nil) { - theCallback(error, operation, nil); - } - }]; - } - break; - case SLHTTPMethodPUT: + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { + + AFHTTPRequestOperationManager *requestManager = self.httpManager; + //NSLog(@"requestManager: %@", requestManager); + + NSLog(@"baseURL: %@ , httpManager: %@", self.host, self.httpManager); + + if (self.host == nil) { - [self performRequestWithMethod:SLHTTPMethodPUT withPath:thePath withParameters:theParams withCallback:theCallback]; + @throw SLExceptionMissingHost; } - break; - case SLHTTPMethodDELETE: - { - [self.httpManager DELETE:[fullPath absoluteString] parameters:theParams success:^(AFHTTPRequestOperation *operation, id responseObject) { - NSLog(@"Success, JSON: %@", responseObject); - if (theCallback != nil) { - theCallback(nil, operation, responseObject); - } - } failure:^(AFHTTPRequestOperation *operation, NSError *error) { - NSLog(@"Error: %@", error); - NSLog(@"Response: %@", operation.responseString); - if (theCallback != nil) { - theCallback(error, operation, nil); - } - }]; + + //NSLog(@"baseURl: %@", self.baseURL); + NSLog(@"thePath: %@", thePath); + NSString *absPath = [NSString stringWithFormat:@"/%@/%@", @"api/v1", thePath]; + NSLog(@"absPath: %@", absPath); + NSURL *fullPath = [[NSURL alloc] initWithScheme:@"http" host:self.host path:absPath]; + // NSURL *fullPath = [NSURL URLWithString:[NSString stringWithFormat:@"%@", thePath] relativeToURL:self.host]; + NSLog(@"fullPath: %@", fullPath); + NSString *fullPathStr = [fullPath absoluteString]; + NSLog(@"Full path: %@", fullPathStr); + + // Prepare headers used for authentication + // Expiry + NSTimeInterval timeInMiliseconds = [[NSDate date] timeIntervalSince1970]; + NSInteger expiryDuration = 60; // in seconds + NSString *expiry = [NSString stringWithFormat:@"%ld", (long) timeInMiliseconds + expiryDuration]; + [requestManager.requestSerializer setValue:expiry forHTTPHeaderField:@"X-SL-Expires"]; + // Organization + [requestManager.requestSerializer setValue:self.userOrganization forHTTPHeaderField:@"X-SL-Organization"]; + // Username + [requestManager.requestSerializer setValue:self.userEmail forHTTPHeaderField:@"X-SL-Username"]; + // HMAC + NSString *secret = _userPassword; + NSLog(@"Secret: %@", secret); + NSString *msg = @""; + NSString *hmac = [SLAPIManager hmac:msg withSecret:secret]; + [requestManager.requestSerializer setValue:hmac forHTTPHeaderField:@"hmac"]; + + switch (theMethod) { + case SLHTTPMethodGET: + { + NSError *error; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:theParams + options:NSJSONWritingPrettyPrinted + error:&error]; + NSString *encodedJson = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + NSLog(@"encodedJson: %@", encodedJson); + //encodedJson = @"{\"filter\":{\"fields\":true,\"rels\":true}}"; + NSLog(@"GET %@", fullPathStr); + [requestManager GET:fullPathStr parameters:@{@"p":encodedJson} success:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"Success, JSON: %@", responseObject); + fulfiller(PMKManifold(responseObject, operation)); + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); + NSLog(@"Response: %@", operation.responseString); + rejecter(error); + }]; + } + break; + case SLHTTPMethodPOST: + { + [requestManager POST:fullPathStr parameters:theParams success:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"Request: %@", operation.request); + NSLog(@"Success, JSON: %@", responseObject); + fulfiller(PMKManifold(responseObject, operation)); + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Request: %@", operation.request); + NSLog(@"Error: %@", error); + NSLog(@"Response: %@", operation.responseString); + rejecter(error); + }]; + } + break; + case SLHTTPMethodPUT: + { + [self performRequestWithMethod:SLHTTPMethodPUT withPath:thePath withParameters:theParams].then(fulfiller).catch(rejecter); + } + break; + case SLHTTPMethodDELETE: + { + [self.httpManager DELETE:[fullPath absoluteString] parameters:theParams success:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"Success, JSON: %@", responseObject); + fulfiller(PMKManifold(responseObject, operation)); + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); + NSLog(@"Response: %@", operation.responseString); + rejecter(error); + }]; + } + break; + default: + @throw SLExceptionImplementationNotFound; + break; } - break; - default: - @throw SLExceptionImplementationNotFound; - break; - } + }]; } @@ -212,37 +215,35 @@ - (PMKPromise *) authenticateWithUserEmail:(NSString *)theEmail { return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { - // [self setEmail:response[@"email"]]; - // [self setToken:response[@"token"]]; + // + [self setEmail:theEmail]; + [self setPassword:thePassword]; + [self setOrganization:theOrganization]; + // if (theEmail != nil && thePassword != nil && theOrganization != nil ) { - - [self performRequestWithMethod:SLHTTPMethodPOST withPath:@"authenticate" withParameters:@{@"email":theEmail, @"password":thePassword} withCallback:^(NSError *error, id operation, id responseObject) { - if (error == nil ) - { - // Store the token - NSDictionary *response = (NSDictionary *)responseObject; - - fulfiller(PMKManifold(response, operation)); - } else - { - rejecter(PMKManifold(error, responseObject, operation)); - } - }]; + [self performRequestWithMethod:SLHTTPMethodPOST + withPath:@"me" + withParameters:@{ + @"email":theEmail, + @"password":thePassword + }] + .then(^(id operation, id responseObject) { + + // Store the token + NSDictionary *response = (NSDictionary *)responseObject; + + fulfiller(PMKManifold(response, operation)); + }).catch(^(NSError *error, id operation, id responseObject) { + rejecter(error); + }); } else { rejecter([NSException exceptionWithName:NSInternalInconsistencyException reason:@"Authenticating requires user's email, password, and organization." userInfo:nil]); } - }]; } -//- (void) authenticateWithUser:(SLUser *)theUser -// withCallback:(SLSuccessCallback)theCallback -//{ -// [self authenticateWithUserEmail:[theUser get:@"email"] withPassword:[theUser get:@"password"] withCallback:theCallback]; -//} - @end diff --git a/Common/SLModel.h b/Common/SLModel.h index 559bc30..20a3461 100644 --- a/Common/SLModel.h +++ b/Common/SLModel.h @@ -60,13 +60,13 @@ ## Manipulating the Schema Sample code to put in your init method. - // Create a Mutable copy of the data - NSMutableDictionary *tempData = [self.data mutableCopy]; - // Make changes, by adding `SLValue`s - SLValue *idVal = [[SLValue alloc]initWithType:[NSString class]]; - [tempData setValue:idVal forKey:@"id"]; - // Change the base data schema to the new data schema. - self.data = tempData; + // Create a Mutable copy of the data + NSMutableDictionary *tempData = [self.data mutableCopy]; + // Make changes, by adding `SLValue`s + SLValue *idVal = [[SLValue alloc]initWithType:[NSString class]]; + [tempData setValue:idVal forKey:@"id"]; + // Change the base data schema to the new data schema. + self.data = tempData; @deprecated Use `MR_createEntity`. */ @@ -79,7 +79,7 @@ /** Returns an object initialized with the specific `SLNid` nid. - Used for initializing nodes given a known nid. + Used for initializing nodes given a known nid. If the node has already been initialized, that same node in memory will be returned. @param nid @@ -159,7 +159,7 @@ @param callback The C-block style callback. @return void - + @deprecate Use `readAllWithAPIManager` instead. */ + (PMKPromise *) readAll; @@ -187,13 +187,13 @@ /** - Creates a node client side (not persisted). + Creates a node client side (not persisted). This node needs to be be saved to be persisted in any manner. */ + (instancetype) createWithData:(NSDictionary *)theData withRels:(NSArray *)theRels; /** - Creates a node client side (not persisted). + Creates a node client side (not persisted). This node needs to be be saved to be persisted in any manner. */ + (instancetype) createWithData:(NSDictionary *)data; @@ -215,23 +215,13 @@ /** Deletes the node with the corresponding `SLNid`. */ -+ (void) deleteWithId:(SLNid)nid; - -/** - Deletes the node with the corresponding `SLNid`, with callback. - */ -+ (void) deleteWithId:(SLNid)nid withCallback:(SLSuccessCallback)callback; ++ (PMKPromise *) deleteWithId:(SLNid)nid; /** Deletes {node}. This is done by calling {deleteWithId} with the id of {node}. */ -+ (void) deleteWithNode:(SLModel *)node; - -/** - Deletes {node}. This is done by calling {deleteWithId} with the id of {node}. - */ -+ (void) deleteWithNode:(SLModel *)node withCallback:(SLSuccessCallback)callback; ++ (PMKPromise *) deleteWithNode:(SLModel *)node; /** @@ -239,22 +229,14 @@ {deleteWithId} to all nodes contained in the set {nodes} using their node id's. */ -+ (void) deleteWithNodeArray:(NSArray *)nodes; ++ (PMKPromise *) deleteWithNodeArray:(NSArray *)nodes; /** Deletes a set of nodes, {nodes}. This is done by applying the function {deleteWithId} to all nodes contained in the set {nodes} using their node id's. */ -+ (void) deleteWithNodeArray:(NSArray *)nodes withCallback:(SLSuccessCallback)callback; - -/** - Deletes a set of nodes, {nodes}. This is done by applying the function - {deleteWithId} to all nodes contained in the set {nodes} using their node - id's. - */ -+ (void) deleteWithNodeArray:(NSArray *)nodes withProgressCallback:(void (^)(NSUInteger idx))progress withCallback:(SLSuccessCallback)callback; - ++ (PMKPromise *) deleteWithNodeArray:(NSArray *)nodes withProgressCallback:(void (^)(NSUInteger idx, id item)) progress ; /** Return the {type} of this node. */ @@ -289,7 +271,7 @@ This done by iterating through {data} and compiling a list of node SLValues that haven't been saved. From the set of unsaved properties a update request to SLAPI may be formulated. - + @deprecated Use `pushWithAPIManager:withCallback` instead. */ - (void) save DEPRECATED_ATTRIBUTE; @@ -312,7 +294,7 @@ that haven't been saved. From the set of unsaved properties a update request to SLAPI may be formulated. */ -- (void) pushWithAPIManager:(SLAPIManager *)manager withCallback:(SLSuccessCallback)callback; +- (PMKPromise *) pushWithAPIManager:(SLAPIManager *)manager; /** Returns the value of the internal boolean {isSaved}. @@ -347,13 +329,8 @@ /** Delete's this instance from the database. */ -- (void) remove; - +- (PMKPromise *) remove; -/** - Delete's this instance from the database, with callback on completion. - */ -- (void) removeWithCallback:(SLSuccessCallback)callback; /** diff --git a/Common/SLModel.m b/Common/SLModel.m index 2090e37..81602da 100644 --- a/Common/SLModel.m +++ b/Common/SLModel.m @@ -194,8 +194,9 @@ - (void) loadRelsFromArray:(NSArray *)theRels inContext:(NSManagedObjectContext + (NSString *) type { + // return NSStringFromClass([instance class]); @throw [NSException exceptionWithName:NSInternalInconsistencyException - reason:[NSString stringWithFormat:@"You must override %@ in the subclass %@.", NSStringFromSelector(_cmd), [self class]] + reason:[NSString stringWithFormat:@"You must override method '%@' in the subclass '%@'.", NSStringFromSelector(_cmd), [self class]] userInfo:nil]; } @@ -257,7 +258,7 @@ + (PMKPromise *) readAll return [self readAllWithFilters:filters]; } -+ (PMKPromise *) readAllWithFilters:(NSDictionary *)filters withCallback:(void (^)(NSArray *))callback ++ (PMKPromise *) readAllWithFilters:(NSDictionary *)filters { SLAPIManager *manager = [[self class] sharedAPIManager]; NSLog(@"Manager: %@", manager); @@ -272,7 +273,10 @@ + (PMKPromise *) readAllWithAPIManager:(SLAPIManager *)manager withFilters:(NSDi [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { + NSLog(@"Inside saving block"); + + [manager performRequestWithMethod:SLHTTPMethodGET withPath:[[self class] type] withParameters:filters] + .then(^(id responseObject, id operation) { NSLog(@"SLRequestCallback completionBlock."); NSLog(@"<%@>: %@", [responseObject class], responseObject); NSMutableArray *nodes = [NSMutableArray array]; @@ -300,10 +304,8 @@ + (PMKPromise *) readAllWithAPIManager:(SLAPIManager *)manager withFilters:(NSDi // Return all nodes! fulfiller( [[self class] MR_findAll] ); - }; - - [manager performRequestWithMethod:SLHTTPMethodGET withPath:[[self class] type] withParameters:filters] - .then(completionBlock); + }) + .catch(rejecter); }]; @@ -358,80 +360,75 @@ + (instancetype) create + (PMKPromise *) deleteWithId:(SLNid)nid { - SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { - NSLog(@"SLRequestCallback completionBlock!"); - NSLog(@"<%@>: %@", [responseObject class], responseObject); + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { - // TODO: Check if successful - fulfiller(true); - }; - - NSString *thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],nid]; - NSLog(@"theDeletePath: %@", thePath); - return [[[self class] sharedAPIManager] performRequestWithMethod:SLHTTPMethodDELETE withPath:thePath withParameters:nil]; -} - -+ (void) deleteWithNode:(SLModel *)node -{ - [[self class] deleteWithNode:node withCallback:nil]; + SLRequestCallback completionBlock = ^(NSError *error, id operation, id responseObject) { + NSLog(@"SLRequestCallback completionBlock!"); + NSLog(@"<%@>: %@", [responseObject class], responseObject); + + // TODO: Check if successful + if (error != nil) { + fulfiller(PMKManifold(responseObject, operation)); + } else { + rejecter(error); + } + }; + + NSString *thePath = [NSString stringWithFormat:@"%@/%@", [[self class] type],nid]; + NSLog(@"theDeletePath: %@", thePath); + [[[self class] sharedAPIManager] performRequestWithMethod:SLHTTPMethodDELETE withPath:thePath withParameters:nil].then(completionBlock); + + }]; } -+ (void) deleteWithNode:(SLModel *)node withCallback:(SLSuccessCallback)callback ++ (PMKPromise *) deleteWithNode:(SLModel *)node { - [[self class] deleteWithId:node.nid withCallback:^(BOOL success) { - if (success) - { + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { + + [[self class] deleteWithId:node.nid].then(^() { node.nid = SLNidNodeNotCreated; // Remove - callback(true); - } else - { - callback(false); - } + fulfiller(node); + }).catch(rejecter); }]; } -+ (void) deleteWithNodeArray:(NSArray *)nodes ++ (PMKPromise *) deleteWithNodeArray:(NSArray *)nodes { - [[self class] deleteWithNodeArray:nodes withProgressCallback:nil withCallback:nil]; + return [[self class] deleteWithNodeArray:nodes withProgressCallback:nil]; } -+ (void) deleteWithNodeArray:(NSArray *)nodes withCallback:(SLSuccessCallback)callback -{ - [[self class] deleteWithNodeArray:nodes withProgressCallback:nil withCallback:callback]; -} - -+ (void) deleteWithNodeArray:(NSArray *)nodes withProgressCallback:(void (^)(NSUInteger idx))progress withCallback:(SLSuccessCallback)callback { ++ (PMKPromise *) deleteWithNodeArray:(NSArray *)nodes withProgressCallback:(void (^)(NSUInteger idx, id item)) progress { - __block BOOL successful = true; - __block NSUInteger completed = 0; - __block NSUInteger totalNodes = [nodes count]; - __block void (^ completionCallback)() = ^{ - // Check if all nodes have been processed (removed) - if (completed >= totalNodes) - { - // All nodes processed, check for completion callback - if (callback != nil) + return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) { + + __block NSUInteger completed = 0; + __block NSUInteger totalNodes = [nodes count]; + __block void (^ completionCallback)() = ^{ + // Check if all nodes have been processed (removed) + if (completed >= totalNodes) { - callback(successful); + // All nodes processed, check for completion callback + fulfiller(nodes); } + }; + SLModel *node; + for (node in nodes) + { + [node remove] + .then(^() + { + if (progress != nil) { + progress(completed, node); + } + completed++; + completionCallback(); + }).catch(^(NSError *error) { + rejecter(error); + }); } - }; - SLModel *node; - for (node in nodes) - { - [node removeWithCallback:^(BOOL success) - { - if (!success) { - successful = false; - } - if (progress != nil) { - progress(completed); - } - completed++; - completionCallback(); - }]; - } + + }]; } /* @@ -706,14 +703,9 @@ - (void) discardChangesTo:(NSString *)attr } } -- (void) remove -{ - [self removeWithCallback:nil]; -} - -- (void) removeWithCallback:(SLSuccessCallback)callback +- (PMKPromise *) remove { - [[self class] deleteWithNode:self withCallback:callback]; + return [[self class] deleteWithNode:self]; } - (void) didChangeValueForKey:(NSString *)key { diff --git a/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj b/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj index 79d7a22..c933ee8 100644 --- a/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj +++ b/Streamlyne Cocoa SDK.xcodeproj/project.pbxproj @@ -24,7 +24,6 @@ /* Begin PBXBuildFile section */ 771F4B97186029D90093674F /* Streamlyne.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 771F4B95186029D90093674F /* Streamlyne.xcdatamodeld */; }; 771F4B98186029D90093674F /* Streamlyne.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 771F4B95186029D90093674F /* Streamlyne.xcdatamodeld */; }; - 771F4BA318628AAA0093674F /* Streamlyne.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 771F4B95186029D90093674F /* Streamlyne.xcdatamodeld */; }; 7720FC1B18369CA10092D39B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7720FC1A18369CA10092D39B /* Foundation.framework */; }; 7720FC2918369CA20092D39B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7720FC2818369CA20092D39B /* XCTest.framework */; }; 7720FC2A18369CA20092D39B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7720FC1A18369CA10092D39B /* Foundation.framework */; }; @@ -71,42 +70,33 @@ 77AD7DFB1842F6DC0053C02C /* SLOrganization.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DE31842F6DC0053C02C /* SLOrganization.h */; }; 77AD7DFC1842F6DC0053C02C /* SLOrganization.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE41842F6DC0053C02C /* SLOrganization.m */; }; 77AD7DFE1842F6DC0053C02C /* SLOrganization.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE41842F6DC0053C02C /* SLOrganization.m */; }; - 77AD7DFF1842F6DC0053C02C /* SLOrganization.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE41842F6DC0053C02C /* SLOrganization.m */; }; 77AD7E001842F6DC0053C02C /* SLUser.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DE51842F6DC0053C02C /* SLUser.h */; }; 77AD7E011842F6DC0053C02C /* SLUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE61842F6DC0053C02C /* SLUser.m */; }; 77AD7E031842F6DC0053C02C /* SLUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE61842F6DC0053C02C /* SLUser.m */; }; - 77AD7E041842F6DC0053C02C /* SLUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE61842F6DC0053C02C /* SLUser.m */; }; 77AD7E051842F6DC0053C02C /* SLWorkOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DE71842F6DC0053C02C /* SLWorkOrder.h */; }; 77AD7E061842F6DC0053C02C /* SLWorkOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE81842F6DC0053C02C /* SLWorkOrder.m */; }; 77AD7E081842F6DC0053C02C /* SLWorkOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE81842F6DC0053C02C /* SLWorkOrder.m */; }; - 77AD7E091842F6DC0053C02C /* SLWorkOrder.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DE81842F6DC0053C02C /* SLWorkOrder.m */; }; 77AD7E0A1842F6DC0053C02C /* SLAPIManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DE91842F6DC0053C02C /* SLAPIManager.h */; }; 77AD7E0B1842F6DC0053C02C /* SLAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DEA1842F6DC0053C02C /* SLAPIManager.m */; }; 77AD7E0D1842F6DC0053C02C /* SLAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DEA1842F6DC0053C02C /* SLAPIManager.m */; }; - 77AD7E0E1842F6DC0053C02C /* SLAPIManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DEA1842F6DC0053C02C /* SLAPIManager.m */; }; 77AD7E0F1842F6DC0053C02C /* SLCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DEB1842F6DC0053C02C /* SLCommon.h */; }; 77AD7E101842F6DC0053C02C /* SLModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DEC1842F6DC0053C02C /* SLModel.h */; }; 77AD7E111842F6DC0053C02C /* SLModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DED1842F6DC0053C02C /* SLModel.m */; }; 77AD7E131842F6DC0053C02C /* SLModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DED1842F6DC0053C02C /* SLModel.m */; }; - 77AD7E141842F6DC0053C02C /* SLModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DED1842F6DC0053C02C /* SLModel.m */; }; 77AD7E151842F6DC0053C02C /* SLNodeProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DEE1842F6DC0053C02C /* SLNodeProtocol.h */; }; 77AD7E161842F6DC0053C02C /* SLObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DEF1842F6DC0053C02C /* SLObject.h */; }; 77AD7E171842F6DC0053C02C /* SLObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF01842F6DC0053C02C /* SLObject.m */; }; 77AD7E191842F6DC0053C02C /* SLObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF01842F6DC0053C02C /* SLObject.m */; }; - 77AD7E1A1842F6DC0053C02C /* SLObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF01842F6DC0053C02C /* SLObject.m */; }; 77AD7E1B1842F6DC0053C02C /* SLRelationship.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DF11842F6DC0053C02C /* SLRelationship.h */; }; 77AD7E1C1842F6DC0053C02C /* SLRelationship.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF21842F6DC0053C02C /* SLRelationship.m */; }; 77AD7E1E1842F6DC0053C02C /* SLRelationship.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF21842F6DC0053C02C /* SLRelationship.m */; }; - 77AD7E1F1842F6DC0053C02C /* SLRelationship.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF21842F6DC0053C02C /* SLRelationship.m */; }; 77AD7E201842F6DC0053C02C /* StreamlyneSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DF31842F6DC0053C02C /* StreamlyneSDK.h */; }; 77AD7E211842F6DC0053C02C /* SLValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7DF41842F6DC0053C02C /* SLValue.h */; }; 77AD7E221842F6DC0053C02C /* SLValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF51842F6DC0053C02C /* SLValue.m */; }; 77AD7E241842F6DC0053C02C /* SLValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF51842F6DC0053C02C /* SLValue.m */; }; - 77AD7E251842F6DC0053C02C /* SLValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7DF51842F6DC0053C02C /* SLValue.m */; }; 77AD7E2818430F1A0053C02C /* SLGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = 77AD7E2618430F1A0053C02C /* SLGroup.h */; }; 77AD7E2918430F1A0053C02C /* SLGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7E2718430F1A0053C02C /* SLGroup.m */; }; 77AD7E2B18430F1A0053C02C /* SLGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7E2718430F1A0053C02C /* SLGroup.m */; }; - 77AD7E2C18430F1A0053C02C /* SLGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 77AD7E2718430F1A0053C02C /* SLGroup.m */; }; 77B4EA0F184094D400435B97 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 77B4EA0E184094D400435B97 /* Cocoa.framework */; }; 77B4EA19184094D400435B97 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 77B4EA17184094D400435B97 /* InfoPlist.strings */; }; 77B4EA1D184094D400435B97 /* Streamlyne_Mac_SDK.m in Sources */ = {isa = PBXBuildFile; fileRef = 77B4EA1C184094D400435B97 /* Streamlyne_Mac_SDK.m */; }; @@ -116,7 +106,6 @@ 77B4EA2D184094D400435B97 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 77B4EA2B184094D400435B97 /* InfoPlist.strings */; }; 77B4EA371840960B00435B97 /* Guide in Resources */ = {isa = PBXBuildFile; fileRef = 77B4EA361840960B00435B97 /* Guide */; }; 77B4EA4F18409D0A00435B97 /* Streamlyne_iOS_SDKTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7720FC3618369CA20092D39B /* Streamlyne_iOS_SDKTests.m */; }; - 77B4EA5018409D3200435B97 /* Streamlyne_Mac_SDK.m in Sources */ = {isa = PBXBuildFile; fileRef = 77B4EA1C184094D400435B97 /* Streamlyne_Mac_SDK.m */; }; 77BE8F2518773B600098C907 /* SLSite.h in Headers */ = {isa = PBXBuildFile; fileRef = 77BE8F2318773B600098C907 /* SLSite.h */; }; 77BE8F2618773B600098C907 /* SLSite.h in Headers */ = {isa = PBXBuildFile; fileRef = 77BE8F2318773B600098C907 /* SLSite.h */; }; 77BE8F2718773B600098C907 /* SLSite.m in Sources */ = {isa = PBXBuildFile; fileRef = 77BE8F2418773B600098C907 /* SLSite.m */; }; @@ -580,6 +569,9 @@ LastUpgradeCheck = 0600; ORGANIZATIONNAME = Streamlyne; TargetAttributes = { + 7720FC2618369CA20092D39B = { + TestTargetID = 7720FC1618369CA10092D39B; + }; 77B4EA21184094D400435B97 = { TestTargetID = 77B4EA0C184094D400435B97; }; @@ -791,18 +783,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 77AD7E2C18430F1A0053C02C /* SLGroup.m in Sources */, - 77AD7E141842F6DC0053C02C /* SLModel.m in Sources */, - 77B4EA5018409D3200435B97 /* Streamlyne_Mac_SDK.m in Sources */, 77B4EA4F18409D0A00435B97 /* Streamlyne_iOS_SDKTests.m in Sources */, - 77AD7E1F1842F6DC0053C02C /* SLRelationship.m in Sources */, - 77AD7E1A1842F6DC0053C02C /* SLObject.m in Sources */, - 77AD7E251842F6DC0053C02C /* SLValue.m in Sources */, - 77AD7DFF1842F6DC0053C02C /* SLOrganization.m in Sources */, - 77AD7E091842F6DC0053C02C /* SLWorkOrder.m in Sources */, - 77AD7E041842F6DC0053C02C /* SLUser.m in Sources */, - 771F4BA318628AAA0093674F /* Streamlyne.xcdatamodeld in Sources */, - 77AD7E0E1842F6DC0053C02C /* SLAPIManager.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -967,6 +948,7 @@ "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/Streamlyne_Cocoa_SDK-fjqjkmnrhloggrcbsegetsdkwdqw/Build/Products/Release", ); PRODUCT_NAME = "Streamlyne-iOS-SDKTests"; + SDKROOT = iphoneos; WRAPPER_EXTENSION = xctest; }; name = Debug; @@ -988,6 +970,7 @@ "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/Streamlyne_Cocoa_SDK-fjqjkmnrhloggrcbsegetsdkwdqw/Build/Products/Release", ); PRODUCT_NAME = "Streamlyne-iOS-SDKTests"; + SDKROOT = iphoneos; WRAPPER_EXTENSION = xctest; }; name = Release; diff --git a/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m b/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m index 9ebcdf1..8661ec0 100644 --- a/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m +++ b/Streamlyne-iOS-SDKTests/Streamlyne_iOS_SDKTests.m @@ -18,13 +18,10 @@ @implementation Streamlyne_iOS_SDKTests // Macro - Set the flag for block completion #define StartBlock() __block BOOL waitingForBlock = YES - // Macro - Set the flag to stop the loop #define EndBlock() waitingForBlock = NO - // Macro - Wait and loop until flag is set #define WaitUntilBlockCompletes() WaitWhile(waitingForBlock) - // Macro - Wait for condition to be NO/false in blocks and asynchronous calls // Each test should have its own instance of a BOOL condition because of non-thread safe operations #define WaitWhile(condition) \ @@ -34,6 +31,10 @@ @implementation Streamlyne_iOS_SDKTests } \ } while(0) +// +#define XCTAssertStringEqual(a, b, format) \ +(XCTAssertTrue([a isEqualToString:b], format) ); + // - (void)setUp @@ -45,7 +46,8 @@ - (void)setUp // Put setup code here. This method is called before the invocation of each test method in the class. SLAPIManager *manager = [SLAPIManager sharedManager]; //[manager setBaseURL:[NSURL URLWithString:@"http://54.208.98.191:5000/api/"]]; - [manager setBaseURL:[NSURL URLWithString:@"http://localhost:5000/api/"]]; +// [manager setBaseURL:[NSURL URLWithString:@"http://localhost:5000/api/"]]; + [manager setHost:@"localhost:5000"]; [[SLAPIManager sharedManager] authenticateWithUserEmail:@"testing@streamlyne.co" @@ -68,604 +70,62 @@ - (void)tearDown [super tearDown]; } - +- (void) testPasswordSaving +{ + NSString *password = @"thisIsATest"; + NSString *encoded = @"99ca2860a3204a9f4e50d6940a67f5ed279f45a9"; + NSLog(@"%@ == %@", encoded, [SLAPIManager sha1:password]); + XCTAssertStringEqual(encoded, [SLAPIManager sha1:password], @"Password should have been correctly encoded."); + + SLAPIManager *manager = [SLAPIManager sharedManager]; + [manager setPassword:@"thisIsATest"]; + XCTAssertStringEqual(encoded, manager.userPassword, @"Password should have been encoded when saved."); + +} - (void) testAuthentication { - __block int pendingCallbacks = 0; - - void (^completionBlock)(BOOL) = ^(BOOL success){ - NSLog(@"Completion Block!"); - pendingCallbacks--; // Decrement - }; + StartBlock(); + SLAPIManager *manager = [SLAPIManager sharedManager]; + + [manager authenticateWithUserEmail:@"test@streamlyne.co" + withPassword:@"test" + withOrganization:@"test"] + .then(^() { + XCTAssertTrue(true, @"PARTY. IT WORKED."); + }).catch(^(NSError *error) { + XCTFail(@"%@", error); + }) + .finally(^() { + EndBlock(); + }); + + WaitUntilBlockCompletes(); } - - -//- (void)testExample -//{ -// //XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); -// -// __block int pendingCallbacks = 0; -// -// void (^completionBlock)(BOOL) = ^(BOOL success){ -// NSLog(@"Completion Block!"); -// pendingCallbacks--; // Decrement -// }; -// -// //[manager performRequestWithMethod:SLHTTPMethodGET withPath:@"user/" withParameters:nil withCallback:completionBlock]; -// -// /* -// [SLUser readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray *nodes){ -// completionBlock(true); -// }]; -// */ -// -// // SLUser *user1 = [SLUser createWithData:@{@"email":@"glavin.wiechert@gmail.com", @"password":@"test"} withRels:nil]; -// // NSLog(@"%@", user1); -// -// pendingCallbacks++; -// [SLWorkOrder readAllWithFilters:SLFiltersAllTrue withCallback:^(NSArray *workOrders) { -// NSLog(@"Work Orders: %@", workOrders); -// completionBlock(true); -// }]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// if (pendingCallbacks > 0) -// { -// //STFail(@"I know this will fail, thanks"); -// } -// -//} -// -//- (void) testSite -//{ -// SLAPIManager *manager = [SLAPIManager sharedManager]; -// -// __block int pendingCallbacks = 0; -// -// void (^completionBlock)(BOOL) = ^(BOOL success){ -// NSLog(@"Completion Block: '%d'", pendingCallbacks); -// pendingCallbacks = pendingCallbacks - 1; // Decrement -// }; -// -// // Create Site node -// pendingCallbacks++; -// SLSite *site1 = [SLSite createWithData:@{ -// @"name":@"test name", -// @"location":@"test location" -// } withRels:nil]; -// [site1 pushWithAPIManager:manager withCallback:completionBlock]; -// NSLog(@"%@", [site1 entity]); -// -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// -// // Read All Sites -// pendingCallbacks++; -// [SLSite readAllWithAPIManager:manager withFilters:SLFiltersAllTrue withCallback:^(NSArray *sites) { -// NSLog(@"Sites: %@", sites); -// -// /* -// // Iterate and display all -// for (SLSite *site in sites) { -// NSLog(@"%@", site); -// } -// */ -// -// completionBlock(true); -// }]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// NSLog(@"Pending Callbacks: %d", pendingCallbacks); -// //STFail(@"I know this will fail, thanks"); -// -//} -// -//- (void) testOrganization -//{ -// SLAPIManager *manager = [SLAPIManager sharedManager]; -// -// __block int pendingCallbacks = 0; -// -// void (^completionBlock)(BOOL) = ^(BOOL success){ -// NSLog(@"Completion Block: '%d'", pendingCallbacks); -// pendingCallbacks = pendingCallbacks - 1; // Decrement -// }; -// -// SLRequestCallback requestCompletionBlock = ^(NSError *error, id operation, id responseObject) { -// NSLog(@"SLRequestCallback completionBlock!"); -// NSLog(@"<%@>: %@", [responseObject class], responseObject); -// completionBlock(true); -// }; -// -// /* -// // Create -// pendingCallbacks++; -// [[SLAPIManager sharedManager] performRequestWithMethod:SLHTTPMethodPOST withPath:@"organization" withParameters:@{@"data":@{@"name":[NSString stringWithFormat:@"test-organization-%@",[NSDate date]]}} withCallback:requestCompletionBlock]; -// */ -// -// // Create -// pendingCallbacks++; -// SLOrganization *org1 = [SLOrganization createWithData:@{@"name": [NSString stringWithFormat:@"test-organization-%@",[NSDate date]] } withRels:nil]; -// NSLog(@"base url before save: %@", [SLAPIManager sharedManager].baseURL); -// [org1 pushWithAPIManager:manager withCallback:completionBlock]; -// -// // Read All -// pendingCallbacks++; -// [SLOrganization readAllWithFilters:SLFiltersAllTrue withCallback:^(NSArray *nodes) { -// NSLog(@"Organizations: %@", nodes); -// -// // Read All, again -// pendingCallbacks++; -// [SLOrganization readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray *nodes) { -// NSLog(@"Organizations: %@", nodes); -// -// completionBlock(true); -// }]; -// -// completionBlock(true); -// }]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// /* -// // Read with Id -// pendingCallbacks++; -// [SLOrganization readById:1 withCallback:^(id node) { -// SLOrganization *org1 = (SLOrganization *)node; -// NSLog(@"Organization: %@", org1); -// -// completionBlock(true); -// }]; -// -// // Delete -// pendingCallbacks++; -// [SLOrganization deleteWithId:1 withCallback:completionBlock]; -// */ -// -// if (pendingCallbacks > 0) -// { -// NSLog(@"Pending Callbacks: %d", pendingCallbacks); -// //STFail(@"I know this will fail, thanks"); -// } -// -//} -// -//- (void) testUser -//{ -// NSLog(@"testUser - SharedManager Base URL: %@", [SLAPIManager sharedManager].baseURL); -// -// __block int pendingCallbacks = 0; -// -// SLSuccessCallback completionBlock = ^(BOOL success){ -// NSLog(@"Completion Block: '%d'", pendingCallbacks); -// pendingCallbacks = pendingCallbacks - 1; // Decrement -// -// }; -// -// -// // SLValue *val = [[SLValue alloc] initWithType:[NSString class] withValue:@"Glavin" withPredicates:@[]]; -// -// //NSLog(@"Creating SLUser Node"); -// int r = arc4random() % 100; -// NSDictionary *data = @{ -// @"email": [NSString stringWithFormat:@"test-%u@streamlyne.co", r], -// @"password": @"test", -// @"job_title": @"developer", -// @"name_first": @"Testy", -// @"name_last": @"Tester" -// }; -// -// -// -// SLUser *user1 = [SLUser createWithData:data withRels:(NSArray *)@[]]; -// pendingCallbacks++; -// [SLOrganization readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray *orgs) { -// if ([orgs count]>1) { -// SLOrganization *org1 = (SLOrganization *) orgs[0]; -// NSLog(@"%lu number of Organizations", (unsigned long)[orgs count]); -// -// //NSLog(@"Organization: %@", org1); -// /* -// SLRelationship *rel = [[SLRelationship alloc] initWithName:@"member" withStartNode:user1 withEndNode:org1]; -// //[user1 addRelationship:rel]; -// //NSLog(@"User: %@", user1); -// NSLog(@"Dir User: %u", [rel directionWithNode:user1]); -// NSLog(@"Dir Org: %u", [rel directionWithNode:org1]); -// pendingCallbacks++; -// [user1 saveWithCallback:completionBlock]; -// */ -// -// pendingCallbacks++; -// [SLUser registerUser:user1 withOrganization:org1 withCallback:^(BOOL success) { -// -// // Authenticate / Login -// pendingCallbacks++; -// [[SLAPIManager sharedManager] authenticateWithUser:user1 withCallback:completionBlock]; -// -// // Read All -// pendingCallbacks++; -// [SLUser readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray *users){ -// //NSLog(@"Users: %@", users); -// NSLog(@"%lu number of Users", (unsigned long)[users count]); -// completionBlock(true); -// }]; -// -// /* -// // Update -// pendingCallbacks++; -// [user1 saveWithCallback:completionBlock]; -// */ -// -// completionBlock(true); -// }]; -// } -// completionBlock(true); -// }]; -// -// // Authenticate -// /* -// pendingCallbacks++; -// [[SLAPIManager sharedManager] performRequestWithMethod:SLHTTPMethodPOST withPath:@"authenticate" withParameters:@{@"email":@"test-46@gmail.com", @"password":@"test"} withCallback:^(NSError *error, id operation, id responseObject) { -// NSLog(@"Authentication completionBlock!"); -// NSLog(@"<%@>: %@", [responseObject class], responseObject); -// completionBlock(true); -// }]; -// */ -// -// -// //NSLog(@"%@", [user type]); -// //[SLNode deleteWithNode:user]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// -// if (pendingCallbacks > 0) -// { -// NSLog(@"Pending Callbacks: %d", pendingCallbacks); -// //STFail(@"I know this will fail, thanks"); -// } -// -// -//} -// -//- (void) testRelationship -//{ -// /* -// //NSLog(@"Creating Value"); -// SLValue *val = [[SLValue alloc] initWithType:[NSString class] withValue:@"totally" withPredicates:@[]]; -// -// -// //NSLog(@"Creating Node"); -// SLNode *node1 = [SLNode createWithData:@{@"test":val} withRels:(NSArray *)@[@"123"]]; -// //NSLog(@"%@", node1); -// SLNode *node2 = [SLNode createWithData:@{@"test":val} withRels:(NSArray *)@[@"123"]]; -// -// //NSLog(@"Creating Relationship"); -// SLRelationship *rel1 = [[SLRelationship alloc] initWithName:@"creator" withStartNode:node1 withEndNode:node2]; -// SLRelationshipDirection dir = [rel1 directionWithNode:node1]; -// if (dir == SLRelationshipIncoming) { -// NSLog(@"Incoming!"); -// } else if (dir == SLRelationshipIncoming) { -// NSLog(@"Outgoing!"); -// } -// -// [node1 addRelationship:rel1]; -// [((SLRelationship *)(node1.relationships[0])) directionWithNode:node1]; -// */ -//} -// -// -//- (void) testGroup -//{ -// -// __block int pendingCallbacks = 0; -// // -// SLSuccessCallback completionBlock = ^(BOOL success){ -// NSLog(@"Completion Block: '%d'", pendingCallbacks); -// pendingCallbacks = pendingCallbacks - 1; // Decrement -// }; -// -// -// // Read All Group -// NSLog(@"Read All Group"); -// pendingCallbacks++; -// [SLGroup readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray * nodes){ -// NSLog(@"# of Group: %lu", (unsigned long)[nodes count]); -// for (NSUInteger i = 0, len = [nodes count]; i < len; i++) -// { -// SLGroup *group = (SLGroup *) nodes[i]; -// NSLog(@"Group: %@", group); -// } -// completionBlock(true); -// }]; -// -// // Create -// pendingCallbacks++; -// SLGroup *group = [SLGroup createWithData:@{ -// @"name": @"Sample Group", -// @"description": @"This is a sample group" -// } withRels:(NSArray *)@[]]; -// [group pushWithAPIManager:SLSharedAPIManager withCallback:completionBlock]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// if (pendingCallbacks > 0) -// { -// NSLog(@"Pending Callbacks: %d", pendingCallbacks); -// //STFail(@"I know this will fail, thanks"); -// } -// -//} -// -// -// -//- (void) testAsset -//{ -// -// __block int pendingCallbacks = 0; -// // -// SLSuccessCallback completionBlock = ^(BOOL success){ -// NSLog(@"Completion Block: '%d'", pendingCallbacks); -// pendingCallbacks = pendingCallbacks - 1; // Decrement -// }; -// -// -// // Read All Work Orders -// NSLog(@"Read All Assets"); -// pendingCallbacks++; -// [SLAsset readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray * nodes){ -// NSLog(@"# of Asset: %lu", (unsigned long)[nodes count]); -// for (NSUInteger i = 0, len = [nodes count]; i < len; i++) -// { -// SLAsset *asset = (SLAsset *) nodes[i]; -// NSLog(@"Asset: %@", asset); -// } -// completionBlock(true); -// }]; -// -// // Create -// pendingCallbacks++; -// [SLUser readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray *nodes) { -// NSLog(@"nodes: %@", nodes); -// if ([nodes count] < 1) { -// NSLog(@"No users...."); -// } else -// { -// -// SLUser *user1 = nodes[0]; -// -// NSDictionary *newAssetData = @{ -// @"number_asset": @"ACSEM6001", -// @"number_serial": @"96-900-8414-1" -// ,@"description": @"ANALYZER, M609 Sulphur Stack" -// ,@"mfg": @"BOVAR" -// ,@"location": @"NEV600" -// ,@"cost_center": @"210PNV0064" -// }; -// SLAsset *asset = [SLAsset createWithData:newAssetData withRels:(NSArray *)@[]]; -// -// SLRelationship *rel = [[SLRelationship alloc] initWithName:@"creator" withStartNode:asset withEndNode:user1]; -// -// pendingCallbacks++; -// [asset pushWithAPIManager:SLSharedAPIManager withCallback:completionBlock]; -// -// /* -// pendingCallbacks++; -// [SLOrganization readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray * nodes) { -// SLOrganization *org1 = (SLOrganization *) nodes[0]; -// SLRelationship *rel2 = [[SLRelationship alloc] initWithName:@"member" withStartNode:user1 withEndNode:org1]; -// -// pendingCallbacks++; -// [user1 saveWithCallback:completionBlock]; -// -// completionBlock(true); -// }]; -// */ -// } -// -// completionBlock(true); -// }]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// if (pendingCallbacks > 0) -// { -// NSLog(@"Pending Callbacks: %d", pendingCallbacks); -// //STFail(@"I know this will fail, thanks"); -// } -// -//} -// -// -//- (void) testWorkOrder -//{ -// -// __block int pendingCallbacks = 0; -// // -// SLSuccessCallback completionBlock = ^(BOOL success){ -// NSLog(@"Completion Block: '%d'", pendingCallbacks); -// pendingCallbacks = pendingCallbacks - 1; // Decrement -// }; -// -// -// NSDictionary *newWorkOrderData = @{ -// @"description": @"This is a sample work order from SDK tests!" -// ,@"status": @"some status" -// ,@"notes_completion": @"After I created it made this note." -// //,@"date_due": [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle] -// //,@"date_completed": [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle] -// }; -// SLWorkOrder *workOrder = [SLWorkOrder createWithData:newWorkOrderData withRels:(NSArray *)@[]]; -// //workOrder.dateDue = [NSDate date]; -// //workOrder.dateCompleted = [NSDate date]; -// NSLog(@"Pending Nodes: %@", [SLWorkOrder pending]); -// -// pendingCallbacks++; -// [workOrder pushWithAPIManager:SLSharedAPIManager withCallback:^(BOOL success) { -// -// NSLog(@"There are now %lu Work Orders saved for Offline.", (unsigned long)[SLWorkOrder MR_countOfEntities]); -// -// completionBlock(success); -// -// NSLog(@"Pending Nodes: %@", [SLWorkOrder pending]); -// -// }]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// // Read All Work Orders -// NSLog(@"Read All Work Orders"); -// //pendingCallbacks++; -// //[SLWorkOrder readAllWithFilters:SLFiltersAllTrue withCallback:^(NSArray * nodes) { -// // NSLog(@"# of Work Orders: %lu", (unsigned long)[nodes count]); -// // NSLog(@"There are %lu Work Orders saved for Offline", (unsigned long)[SLWorkOrder MR_countOfEntities]); -// -// pendingCallbacks++; -// [SLWorkOrder readAllWithFilters:SLFiltersAllTrue withCallback:^(NSArray * nodes) { -// -// NSArray *cNodes = [SLWorkOrder MR_findAll]; -// NSLog(@"Nodes: %@", cNodes); -// -// NSLog(@"Count: %lu %lu", (unsigned long)[nodes count], (unsigned long)[cNodes count]); -// -// // Find one that is not in sync -// for (NSUInteger i = 0, len = [nodes count]; i < len; i++) -// { -// BOOL isPulled = false; -// SLWorkOrder *workOrder = (SLWorkOrder *) nodes[i]; -// //NSLog(@"Work Order: %@", workOrder); -// for (NSUInteger j = 0, jlen = [cNodes count]; j < jlen; j++) -// { -// SLWorkOrder *cWorkOrder = cNodes[j]; -// // NSLog(@"Work Order, Core Data: %@", cWorkOrder); -// if (workOrder.nid == cWorkOrder.nid) { -// //NSLog(@"Found %lu", i); -// isPulled = true; -// break; -// } else { -// //NSLog(@"Not same"); -// } -// } -// if (isPulled == true) { -// // NSLog(@"Work Order %@ is pulled.", workOrder); -// } else { -// NSLog(@"Work Order %@ is not pulled, for offline access.", workOrder); -// } -// } -// -// for (NSUInteger j = 0, jlen = [cNodes count]; j < jlen; j++) -// { -// BOOL isPushed = false; -// SLWorkOrder *cWorkOrder = cNodes[j]; -// //NSLog(@"Work Order: %@", workOrder); -// for (NSUInteger i = 0, len = [nodes count]; i < len; i++) -// { -// SLWorkOrder *workOrder = (SLWorkOrder *) nodes[i]; -// // NSLog(@"Work Order, Core Data: %@", cWorkOrder); -// if (workOrder.nid == cWorkOrder.nid) { -// //NSLog(@"Found %lu", i); -// isPushed = true; -// break; -// } else { -// //NSLog(@"Not same"); -// } -// } -// if (isPushed == true) { -// // NSLog(@"Work Order %@ is pushed.", workOrder); -// } else { -// NSLog(@"Work Order %@ is not pushed.", cWorkOrder); -// } -// } -// -// -// -// NSLog(@"# of Work Orders, 2: %lu", (unsigned long)[nodes count]); -// NSLog(@"There are %lu Work Orders saved for Offline, 2", (unsigned long)[SLWorkOrder MR_countOfEntities]); -// -// -// completionBlock(true); -// }]; -// -// // completionBlock(true); -// //}]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// -// // Create -// pendingCallbacks++; -// [SLUser readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray *nodes) { -// NSLog(@"# of Users: %lu", (unsigned long)[nodes count]); -// if ([nodes count] < 1) { -// NSLog(@"No users...."); -// } else -// { -// -// SLUser *user1 = nodes[0]; -// NSLog(@"user1: %@", user1); -// -// NSDictionary *newWorkOrderData = @{ -// @"description": @"This is a sample work order from SDK tests!" -// ,@"status": @"some status" -// ,@"notes_completion": @"After I created it made this note." -// //,@"date_due": [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle] -// //,@"date_completed": [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterFullStyle] -// }; -// SLWorkOrder *workOrder = [SLWorkOrder createWithData:newWorkOrderData withRels:(NSArray *)@[]]; -// -// SLRelationship *rel = [[SLRelationship alloc] initWithName:@"created" withStartNode:user1 withEndNode:workOrder]; -// -// pendingCallbacks++; -// [workOrder pushWithAPIManager:SLSharedAPIManager withCallback:^(BOOL success) { -// -// NSLog(@"There are now %lu Work Orders saved for Offline.", (unsigned long)[SLWorkOrder MR_countOfEntities]); -// -// completionBlock(success); -// }]; -// -// /* -// pendingCallbacks++; -// [SLOrganization readAllWithFilters:SLFiltersAllFalse withCallback:^(NSArray * nodes) { -// SLOrganization *org1 = (SLOrganization *) nodes[0]; -// SLRelationship *rel2 = [[SLRelationship alloc] initWithName:@"member" withStartNode:user1 withEndNode:org1]; -// -// pendingCallbacks++; -// [user1 saveWithCallback:completionBlock]; -// -// completionBlock(true); -// }]; -// */ -// } -// -// completionBlock(true); -// }]; -// -// // Wait -// [self waitUntilFinishedPending:&pendingCallbacks]; -// -// if (pendingCallbacks > 0) -// { -// NSLog(@"Pending Callbacks: %d", pendingCallbacks); -// //STFail(@"I know this will fail, thanks"); -// } -// -//} +- (void) testAssets +{ + + StartBlock(); + + [SLAsset readAll] + .then(^(NSArray *assets) { + NSLog(@"%@", assets); + + }) + .catch(^(NSError *error) { + NSLog(@"%@", error); + XCTFail(@"%@", error); + }) + .finally(^() { + EndBlock(); + }); + + WaitUntilBlockCompletes(); + +} @end