Newer
Older
cramakri
committed
/*
* Copyright 2012 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//
// CISDOBIpadServiceManagerTest.m
// BisMac
//
// Created by Ramakrishnan Chandrasekhar on 10/30/12.
//
//
#import "CISDOBIpadServiceManagerTest.h"
#import "CISDOBIpadServiceManager.h"
#import "CISDOBIpadServiceManagerInternal.h"
#import "CISDOBIpadServiceInternal.h"
cramakri
committed
#import "CISDOBIpadService.h"
#import "CISDOBIpadServiceInternal.h"
cramakri
committed
#import "CISDOBConnection.h"
#import "CISDOBConnectionInternal.h"
cramakri
committed
#import "CISDOBIpadEntity.h"
@implementation CISDOBIpadServiceManagerTest
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
- (void)processNotification:(NSNotification *)note
{
if ([CISDOBIpadServiceWillLoginNotification isEqualToString: [note name]]) {
self.willLogin = YES;
}
if ([CISDOBIpadServiceDidLoginNotification isEqualToString: [note name]]) {
self.didLogin = YES;
}
if ([CISDOBIpadServiceWillRetrieveRootLevelEntitiesNotification isEqualToString: [note name]]) {
self.willRetrieveRootLevel = YES;
}
if ([CISDOBIpadServiceDidRetrieveRootLevelEntitiesNotification isEqualToString: [note name]]) {
self.didRetrieveRootLevel = YES;
}
if ([CISDOBIpadServiceWillSynchEntitiesNotification isEqualToString: [note name]]) {
self.willSynchEntities = YES;
}
if ([CISDOBIpadServiceDidSynchEntitiesNotification isEqualToString: [note name]]) {
self.didSynchEntities = YES;
}
if ([CISDOBIpadServiceWillDrillOnEntityNotification isEqualToString: [note name]]) {
self.willDrill = YES;
}
if ([CISDOBIpadServiceDidDrillOnEntityNotification isEqualToString: [note name]]) {
self.didDrill = YES;
}
if ([CISDOBIpadServiceWillRetrieveDetailsForEntityNotification isEqualToString: [note name]]) {
self.willRetrieveDetails = YES;
}
if ([CISDOBIpadServiceDidRetrieveDetailsForEntityNotification isEqualToString: [note name]]) {
self.didRetrieveDetails = YES;
}
}
- (void)registerForNotifications
{
self.willLogin = NO;
self.didLogin = NO;
self.willRetrieveRootLevel = NO;
self.didRetrieveRootLevel = NO;
self.willSynchEntities = NO;
self.didSynchEntities = NO;
self.willDrill = NO;
self.didDrill = NO;
self.willRetrieveDetails = NO;
self.didRetrieveDetails = NO;
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter
addObserverForName: nil
object: self.serviceManager
queue: [NSOperationQueue mainQueue]
usingBlock: ^(NSNotification *note) {
[self processNotification: note];
}];
}
- (void)unregisterForNotifications
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver: self];
}
cramakri
committed
- (void)setUp
{
[super setUp];
NSURL *url = [NSURL URLWithString: @"https://localhost:8443"];
NSURL *tempDir = [NSURL fileURLWithPath: NSTemporaryDirectory()];
NSURL *databaseUrl = [tempDir URLByAppendingPathComponent: @"ipad-test.db"];
NSError *error;
self.serviceManager = [[CISDOBIpadServiceManager alloc] initWithStoreUrl: databaseUrl openbisUrl: url trusted: YES error: &error];
STAssertNotNil(self.serviceManager, @"Service Manager file could not be created:\n%@", error);
cramakri
committed
self.serviceManager.authenticationChallengeBlock = ^(CISDOBAsyncCall *call, NSURLAuthenticationChallenge *challange) {
[call trustProtectionSpaceForAuthenticationChallenge: challange];
};
[self registerForNotifications];
cramakri
committed
}
- (void)tearDown
{
[self unregisterForNotifications];
cramakri
committed
[[NSFileManager defaultManager] removeItemAtURL: self.serviceManager.storeUrl error: nil];
[super tearDown];
}
- (void)configureAndRunCallSynchronously:(CISDOBAsyncCall *)call
{
[self configureCall: call];
// The ipad service may make multiple calls, so take that into account.
int waitTime = ((int) self.serviceManager.service.connection.timeoutInterval) * 2;
[self waitSeconds: waitTime forCallToComplete: call];
}
- (NSArray *)entitiesWithChildren
{
NSError *error;
NSFetchRequest* request = [self.serviceManager fetchRequestForEntities];
cramakri
committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
NSArray *elements = [self.serviceManager executeFetchRequest: request error: &error];
NSMutableArray *entitiesWithChildren = [NSMutableArray array];
for (CISDOBIpadEntity *entity in elements) {
if ([entity.childrenPermIds count] > 0) {
[entitiesWithChildren addObject: entity];
}
}
return entitiesWithChildren;
}
- (void)checkFindingChildren
{
NSError* error;
NSArray* allEntities = [self.serviceManager allIpadEntitiesOrError: &error];
for (CISDOBIpadEntity *entity in allEntities) {
if ([entity.childrenPermIds count] > 0) {
NSArray *children = [self.serviceManager entitiesByPermId: entity.childrenPermIds error: &error];
STAssertTrue([entity.childrenPermIds count] == [children count], @"Entity children %@ should resolve correctly. Found instead the following %@", entity.childrenPermIds, children);
}
}
}
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
- (void)assertNotLoggedIn
{
STAssertFalse(self.willLogin, @"Should not be logged in yet");
STAssertFalse(self.didLogin, @"Should not be logged in yet");
}
- (void)assertLoggedIn
{
STAssertTrue(self.willLogin, @"Should be logged in.");
STAssertTrue(self.didLogin, @"Should be logged in.");
}
- (void)assertBeforeRootLevelCall
{
STAssertFalse(self.willRetrieveRootLevel, @"Should not have retrieved root level");
STAssertFalse(self.didRetrieveRootLevel, @"Should not have retrieved root level");
STAssertFalse(self.willSynchEntities, @"Should not have processed root level");
STAssertFalse(self.didSynchEntities, @"Should not have processed root level");
}
- (void)assertAfterRootLevelCall
{
STAssertTrue(self.willRetrieveRootLevel, @"Should have retrieved root level");
STAssertTrue(self.didRetrieveRootLevel, @"Should have retrieved root level");
STAssertTrue(self.willSynchEntities, @"Should have processed root level");
STAssertTrue(self.didSynchEntities, @"Should have processed root level");
}
- (void)assertBeforeDrill
{
STAssertFalse(self.willDrill, @"Should not have drilled");
STAssertFalse(self.didDrill, @"Should not have drilled");
}
- (void)assertAfterDrill
{
STAssertTrue(self.willDrill, @"Should have drilled");
STAssertTrue(self.didDrill, @"Should have drilled");
}
- (void)assertBeforeDetails
{
STAssertFalse(self.willRetrieveDetails, @"Should not have retrieved details");
STAssertFalse(self.didRetrieveDetails, @"Should not have retrieved details");
}
- (void)assertAfterDetails
{
STAssertTrue(self.willRetrieveDetails, @"Should have retrieved details");
STAssertTrue(self.didRetrieveDetails, @"Should have retrieved details");
}
cramakri
committed
{
CISDOBAsyncCall *call;
[self assertNotLoggedIn];
cramakri
committed
call = [self.serviceManager loginUser: GetDefaultUserName() password: GetDefaultUserPassword()];
[self configureAndRunCallSynchronously: call];
[self assertLoggedIn];
}
- (void)performRootLevelCall
{
CISDOBAsyncCall *call;
[self assertBeforeRootLevelCall];
cramakri
committed
call = [self.serviceManager retrieveRootLevelEntities];
[self configureAndRunCallSynchronously: call];
[self assertAfterRootLevelCall];
cramakri
committed
STAssertNotNil(_callResult, @"The service manager should have returned some entities.");
cramakri
committed
- (void)performDrill:(CISDOBIpadEntity *)drillEntity
{
CISDOBAsyncCall *call;
[self assertBeforeDrill];
call = [self.serviceManager drillOnEntity: drillEntity];
cramakri
committed
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"The iPad service should have returned some entities.");
[self assertAfterDrill];
}
- (void)performDetails:(CISDOBIpadEntity *)detailsEntity
{
CISDOBAsyncCall *call;
call = [self.serviceManager detailsForEntity: detailsEntity];
cramakri
committed
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"The iPad service should have returned some entities.");
[self assertAfterDetails];
- (void)performDrillOnCollection:(NSArray *)drillEntities
{
CISDOBAsyncCall *call;
[self assertBeforeDrill];
call = [self.serviceManager drillOnEntities: drillEntities];
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"The iPad service should have returned some entities.");
[self assertAfterDrill];
}
- (void)performDetailsOnCollection:(NSArray *)detailsEntities
{
CISDOBAsyncCall *call;
call = [self.serviceManager detailsForEntities: detailsEntities];
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"The iPad service should have returned some entities.");
[self assertAfterDetails];
}
- (void)testPersistEntities
{
[self performLogin];
cramakri
committed
STAssertTrue([self.serviceManager shouldRefreshRootLevelEntitiesCall], @"We have not yet initialized the root level entities, so we should do so now");
[self performRootLevelCall];
cramakri
committed
STAssertFalse([self.serviceManager shouldRefreshRootLevelEntitiesCall], @"We have initialized the root level entities recently, no need to do it again.");
cramakri
committed
// Get drill information on some entity
NSArray *entitiesWithChildren = [self entitiesWithChildren];
STAssertTrue([entitiesWithChildren count] > 0, @"There should be some entities with children");
CISDOBIpadEntity *drillEntity = [entitiesWithChildren objectAtIndex: 0];
[self performDrill: drillEntity];
// Get detail information on some entities
CISDOBIpadEntity *detailsEntity = [entitiesWithChildren objectAtIndex: 1];
[self assertBeforeDetails];
[self performDetails: detailsEntity];
// Check that the children could be found
[self checkFindingChildren];
}
- (void)testPersistDrillAndDetailsOnCollections
{
[self performLogin];
[self performRootLevelCall];
// Get drill information on some entity
NSArray *entitiesWithChildren = [self entitiesWithChildren];
STAssertTrue([entitiesWithChildren count] > 0, @"There should be some entities with children");
CISDOBIpadEntity *drillEntity = [entitiesWithChildren objectAtIndex: 0];
[self performDrill: drillEntity];
// Get detail information on some entities
CISDOBIpadEntity *detailsEntity = [entitiesWithChildren objectAtIndex: 1];
[self assertBeforeDetails];
[self performDetails: detailsEntity];
cramakri
committed
// Check that the children could be found
[self checkFindingChildren];
}
- (void)testInvalidSessionToken
{
[self performLogin];
[self performRootLevelCall];
// Switch the session token
[self.serviceManager.service.connection setSessionTokenForTesting: @"junk"];
// Get drill information on some entity
NSArray *entitiesWithChildren = [self entitiesWithChildren];
STAssertTrue([entitiesWithChildren count] > 0, @"There should be some entities with children");
CISDOBIpadEntity *drillEntity = [entitiesWithChildren objectAtIndex: 0];
[self performDrill: drillEntity];
NSLog(@"Error %@", _callError);
}
- (void)retrieveRootLevelEntitiesSimulatingRemovalOfEntity:(CISDOBIpadEntity *)entityToRemove
{
// Make a root level call, but do have some entities removed from the list
CISDOBAsyncCall *call;
cramakri
committed
call = [self.serviceManager retrieveRootLevelEntitiesFromServer];
NSArray *removedEntities = [self.serviceManager.service convertToEntitiesPermIds: [NSArray arrayWithObject: entityToRemove.permId] refcons: [NSArray arrayWithObject: entityToRemove.refcon] count: 1];
CISDOBIpadServiceCall *serviceCall = (CISDOBIpadServiceCall *)((CISDOBIpadServiceManagerCall *)call).serviceCall;
CISDOBConnectionCall *connectionCall = (CISDOBConnectionCall *) serviceCall.connectionCall;
NSArray *oldParams = connectionCall.params;
NSMutableArray *params = [NSMutableArray arrayWithArray: oldParams];
// The service parameters are always in the 4th position
NSDictionary *oldServiceParams = [params objectAtIndex: 3];
NSMutableDictionary *serviceParams = [NSMutableDictionary dictionaryWithDictionary: oldServiceParams];
// Force the root request, bypassing the timing checks
[serviceParams setObject: removedEntities forKey: @"HIDE"];
[params replaceObjectAtIndex: 3 withObject: serviceParams];
connectionCall.params = params;
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"The service manager should have returned some entities.");
}
- (void)testDeletedEntities
{
[self performLogin];
[self performRootLevelCall];
// Pick an entity to remove from the next result set to simulate deletion
NSArray *entitiesWithChildren = [self entitiesWithChildren];
CISDOBIpadEntity *entityToRemove = [entitiesWithChildren objectAtIndex: 0];
// Remember the permId before we refresh because the entity will be deleted
NSArray *removedPermIds = [NSArray arrayWithObject: entityToRemove.permId];
self.serviceManager.mocSaveBlock = ^(CISDOBIpadServiceManager *manager, NSArray *entitiesToDelete) {
STAssertEquals((NSUInteger) 1, [entitiesToDelete count], @"Only one entity should be deleted");
STAssertEqualObjects(entityToRemove.permId, [entitiesToDelete objectAtIndex: 0], @"Only the specified object should be deleted");
};
[self retrieveRootLevelEntitiesSimulatingRemovalOfEntity: entityToRemove];
// Check that the entityToRemove is no longer found
NSError *error;
NSArray *removedEntities = [self.serviceManager entitiesByPermId: removedPermIds error: &error];
STAssertEquals([removedEntities count], (NSUInteger) 0, @"Removed entities should not be found anymore");
// Check that entityToRemove is still accessible
STAssertNil(entityToRemove.permId, @"The Entity's fields should have been set to nil");
- (void)testImageRetrieval
{
[self performLogin];
[self performRootLevelCall];
// Get drill information on some entity
NSArray *entitiesWithChildren = [self entitiesWithChildren];
CISDOBIpadEntity *entityWithImage = [entitiesWithChildren objectAtIndex: 0];
STAssertNil(entityWithImage.imageUrlString, @"Entity should not yet have an image");
// Check that getting an image for an entity without any images works correctly
CISDOBAsyncCall *call = [self.serviceManager imagesForEntity: entityWithImage];
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"Should have gotten an image object");
CISDOBIpadImage *image = _callResult;
STAssertEquals((NSUInteger) 0, [image.imageData length], @"Image data should be empty");
// Initialize the image url and get the image
[self performDetails: entityWithImage];
STAssertNotNil(entityWithImage.imageUrlString, @"Should have found an entity with a local image");
call = [self.serviceManager imagesForEntity: entityWithImage];
[self configureAndRunCallSynchronously: call];
STAssertNotNil(_callResult, @"Should have gotten an image object");
image = _callResult;
STAssertTrue([image.imageData length] > 0, @"Image data should not be empty");
cramakri
committed
STAssertEqualObjects(@"image/jpeg", image.MIMEType, @"Mime type should be image/jpeg");
STAssertNil(image.textEncodingName, @"Text encoding should be nil");
- (void)testNilUrl
{
[self.serviceManager setOpenbisUrl: nil trusted: YES];
CISDOBAsyncCall *call;
[self assertNotLoggedIn];
call = [self.serviceManager loginUser: GetDefaultUserName() password: GetDefaultUserPassword()];
[self configureAndRunCallSynchronously: call];
[self assertLoggedIn];
[self assertBeforeRootLevelCall];
call = [self.serviceManager retrieveRootLevelEntities];
[self configureAndRunCallSynchronously: call];
STAssertTrue(self.willRetrieveRootLevel, @"Should have retrieved root level");
STAssertTrue(self.didRetrieveRootLevel, @"Should have retrieved root level");
// No synch should have happened
STAssertNotNil(_callError, @"The service manager should have failed to return entities.");
}