From 3560564d952936c6d599654e94bbe5d3077dd707 Mon Sep 17 00:00:00 2001 From: giomfo Date: Tue, 9 Feb 2016 15:37:28 +0100 Subject: [PATCH 01/80] Add comment --- MatrixSDK/Data/MXRoomState.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index c8435f5ae5..29faeca02d 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -461,6 +461,7 @@ - (void)handleStateEvent:(MXEvent*)event else { // The user is no more part of the room. Remove him. + // This case happens during back pagination: we remove here users when they are not in the room yet. [members removeObjectForKey:event.stateKey]; } From a23d3a13b028583916c2dd7570c08e9441a49f2e Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 9 Feb 2016 16:29:53 +0100 Subject: [PATCH 02/80] Moving to r0 API: Removed the "v1" initialSync and events stream --- MatrixSDK/MXRestClient.h | 61 ++---- MatrixSDK/MXRestClient.m | 172 ++++------------- MatrixSDK/MXSession.m | 404 ++------------------------------------- 3 files changed, 61 insertions(+), 576 deletions(-) diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index d209da149a..20c024cf0d 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -946,54 +946,7 @@ typedef enum : NSUInteger failure:(void (^)(NSError *error))failure; -#pragma mark - Event operations -/** - Get this user's current state. - Get all the current information for all rooms (including messages and state events) and - presence of the users he has interaction with - - @param limit the maximum number of messages to return. - - @param success A block object called when the operation succeeds. - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. - */ -- (MXHTTPOperation*)initialSyncWithLimit:(NSInteger)limit - success:(void (^)(MXInitialSyncResponse *initialSyncResponse))success - failure:(void (^)(NSError *error))failure; - -/** - Get the list of public rooms hosted by the home server. - - @param success A block object called when the operation succeeds. rooms is an array of MXPublicRoom objects - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. - */ -- (MXHTTPOperation*)publicRooms:(void (^)(NSArray *rooms))success - failure:(void (^)(NSError *error))failure; - -/** - Get events from the given token. - - @param token the token to stream from. - @param serverTimeout the maximum time in ms to wait for an event. - @param clientTimeout the maximum time in ms the SDK must wait for the server response. - - @param success A block object called when the operation succeeds. It provides a `MXPaginationResponse` object. - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. - - @return a MXHTTPOperation instance. - */ -- (MXHTTPOperation *)eventsFromToken:(NSString*)token - serverTimeout:(NSUInteger)serverTimeout - clientTimeout:(NSUInteger)clientTimeout - success:(void (^)(MXPaginationResponse *paginatedResponse))success - failure:(void (^)(NSError *error))failure; - +#pragma mark - Sync /** Synchronise the client's state and receive new messages. Based on server sync C-S v2 API. @@ -1024,7 +977,19 @@ typedef enum : NSUInteger success:(void (^)(MXSyncResponse *syncResponse))success failure:(void (^)(NSError *error))failure; + #pragma mark - Directory operations +/** + Get the list of public rooms hosted by the home server. + + @param success A block object called when the operation succeeds. rooms is an array of MXPublicRoom objects + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. + */ +- (MXHTTPOperation*)publicRooms:(void (^)(NSArray *rooms))success + failure:(void (^)(NSError *error))failure; + /** Get the room ID corresponding to this room alias diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 38ee6a55da..4b7d15e9ef 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -1911,108 +1911,7 @@ - (MXHTTPOperation*)presenceListAddUsers:(NSArray*)users } -#pragma mark - Event operations -- (MXHTTPOperation*)initialSyncWithLimit:(NSInteger)limit - success:(void (^)(MXInitialSyncResponse *))success - failure:(void (^)(NSError *))failure -{ - return [httpClient requestWithMethod:@"GET" - path:@"api/v1/initialSync" - parameters:@{ - @"limit": [NSNumber numberWithInteger:limit] - } - success:^(NSDictionary *JSONResponse) { - if (success) - { - // Create model from JSON dictionary on the processing queue - dispatch_async(processingQueue, ^{ - - MXInitialSyncResponse *initialSync = [MXInitialSyncResponse modelFromJSON:JSONResponse]; - - dispatch_async(dispatch_get_main_queue(), ^{ - - success(initialSync); - - }); - - }); - - } - } - failure:^(NSError *error) { - if (failure) - { - failure(error); - } - }]; -} - -- (MXHTTPOperation *)eventsFromToken:(NSString*)token - serverTimeout:(NSUInteger)serverTimeout - clientTimeout:(NSUInteger)clientTimeout - success:(void (^)(MXPaginationResponse *paginatedResponse))success - failure:(void (^)(NSError *error))failure -{ - - // All query parameters are optional. Fill the request parameters on demand - NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - - if (token) - { - parameters[@"from"] = token; - } - if (-1 != serverTimeout) - { - parameters[@"timeout"] = [NSNumber numberWithInteger:serverTimeout]; - } - - NSTimeInterval clientTimeoutInSeconds = clientTimeout; - if (-1 != clientTimeoutInSeconds) - { - // If the Internet connection is lost, this timeout is used to be able to - // cancel the current request and notify the client so that it can retry with a new request. - clientTimeoutInSeconds = clientTimeoutInSeconds / 1000; - } - - MXHTTPOperation *operation = [httpClient requestWithMethod:@"GET" - path:@"api/v1/events" - parameters:parameters timeout:clientTimeoutInSeconds - success:^(NSDictionary *JSONResponse) - { - if (success) - { - // Create model from JSON dictionary on the processing queue - dispatch_async(processingQueue, ^{ - - MXPaginationResponse *paginatedResponse = [MXPaginationResponse modelFromJSON:JSONResponse]; - - dispatch_async(dispatch_get_main_queue(), ^{ - - success(paginatedResponse); - - }); - - }); - } - } - failure:^(NSError *error) - { - if (failure) - { - failure(error); - } - }]; - - // Disable retry because it interferes with clientTimeout - // Let the client manage retries on events streams - operation.maxNumberOfTries = 1; - - return operation; -} - -/** - server sync v2 - */ +#pragma mark - Sync - (MXHTTPOperation *)syncFromToken:(NSString*)token serverTimeout:(NSUInteger)serverTimeout clientTimeout:(NSUInteger)clientTimeout @@ -2083,40 +1982,6 @@ - (MXHTTPOperation *)syncFromToken:(NSString*)token return operation; } -- (MXHTTPOperation*)publicRooms:(void (^)(NSArray *rooms))success - failure:(void (^)(NSError *error))failure -{ - return [httpClient requestWithMethod:@"GET" - path:@"api/v1/publicRooms" - parameters:nil - success:^(NSDictionary *JSONResponse) { - if (success) - { - @autoreleasepool - { - // Create public rooms array from JSON on processing queue - dispatch_async(processingQueue, ^{ - - NSArray *publicRooms; - MXJSONModelSetMXJSONModelArray(publicRooms, MXPublicRoom, JSONResponse[@"chunk"]); - - dispatch_async(dispatch_get_main_queue(), ^{ - - success(publicRooms); - - }); - - }); - } - } - } - failure:^(NSError *error) { - if (failure) - { - failure(error); - } - }]; -} #pragma mark - read receipts /** @@ -2161,6 +2026,41 @@ - (MXHTTPOperation*)sendReadReceipts:(NSString*)roomId } #pragma mark - Directory operations +- (MXHTTPOperation*)publicRooms:(void (^)(NSArray *rooms))success + failure:(void (^)(NSError *error))failure +{ + return [httpClient requestWithMethod:@"GET" + path:@"api/v1/publicRooms" + parameters:nil + success:^(NSDictionary *JSONResponse) { + if (success) + { + @autoreleasepool + { + // Create public rooms array from JSON on processing queue + dispatch_async(processingQueue, ^{ + + NSArray *publicRooms; + MXJSONModelSetMXJSONModelArray(publicRooms, MXPublicRoom, JSONResponse[@"chunk"]); + + dispatch_async(dispatch_get_main_queue(), ^{ + + success(publicRooms); + + }); + + }); + } + } + } + failure:^(NSError *error) { + if (failure) + { + failure(error); + } + }]; +} + - (MXHTTPOperation*)roomIDForRoomAlias:(NSString*)roomAlias success:(void (^)(NSString *roomId))success failure:(void (^)(NSError *error))failure diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index dae6c06a2c..a055642085 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -26,9 +26,6 @@ #import "MXMemoryStore.h" #import "MXFileStore.h" -// FIXME SYNCV2 Enable server sync v2 -#define MXSESSION_ENABLE_SERVER_SYNC_V2 - #pragma mark - Constants definitions const NSString *MatrixSDKVersion = @"0.6.2"; @@ -346,30 +343,8 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit }]; }; -#ifdef MXSESSION_ENABLE_SERVER_SYNC_V2 - if (matrixRestClient.preferredAPIVersion == MXRestClientAPIVersion2) - { - // Resume the stream (presence will be retrieved durng server sync) - resumeEventsStream(); - } - else -#endif - { - // Then, apply - if (_loadPresenceBeforeCompletingSessionStart) - { - // Load presence before resuming the stream - loadPresence(^() { - resumeEventsStream(); - }, failure); - } - else - { - // Resume the stream and load presence in parralel - resumeEventsStream(); - loadPresence(nil, nil); - } - } + // Resume the stream (presence will be retrieved during server sync) + resumeEventsStream(); } else { @@ -388,18 +363,8 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit // Additional step: load push rules from the home server [_notificationCenter refreshRules:^{ - // Initial server sync - Check the supported C-S version. -#ifdef MXSESSION_ENABLE_SERVER_SYNC_V2 - if (matrixRestClient.preferredAPIVersion == MXRestClientAPIVersion2) - { - [self serverSyncWithServerTimeout:0 success:onServerSyncDone failure:failure clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; - } - else -#endif - { - // sync based on API v1 (Legacy) - [self initialServerSync:onServerSyncDone failure:failure]; - } + // Initial server sync + [self serverSyncWithServerTimeout:0 success:onServerSyncDone failure:failure clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; } failure:^(NSError *error) { [self setState:MXSessionStateHomeserverNotReachable]; @@ -416,190 +381,6 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit } } -- (void)streamEventsFromToken:(NSString*)token withLongPoll:(BOOL)longPoll -{ - [self streamEventsFromToken:token withLongPoll:longPoll serverTimeOut:(longPoll ? SERVER_TIMEOUT_MS : 0) clientTimeout:CLIENT_TIMEOUT_MS]; -} - -- (void)streamEventsFromToken:(NSString*)token withLongPoll:(BOOL)longPoll serverTimeOut:(NSUInteger)serverTimeout clientTimeout:(NSUInteger)clientTimeout -{ - eventStreamRequest = [matrixRestClient eventsFromToken:token serverTimeout:serverTimeout clientTimeout:clientTimeout success:^(MXPaginationResponse *paginatedResponse) { - - // eventStreamRequest is nil when the event stream has been paused - if (eventStreamRequest) - { - // Convert chunk array into an array of MXEvents - NSArray *events = paginatedResponse.chunk; - - // And handle them - [self handleLiveEvents:events]; - - _store.eventStreamToken = paginatedResponse.end; - - // Commit store changes - if ([_store respondsToSelector:@selector(commit)]) - { - [_store commit]; - } - - // there is a pending backgroundSync - if (onBackgroundSyncDone) - { - NSLog(@"[MXSession] background Sync with %tu new events", events.count); - - // Operations on session may occur during this block. For example, [MXSession close] may be triggered. - // We run a copy of the block to prevent app from crashing if the block is released by one of these operations. - MXOnBackgroundSyncDone onBackgroundSyncDoneCpy = [onBackgroundSyncDone copy]; - onBackgroundSyncDoneCpy(); - onBackgroundSyncDone = nil; - - // check that the application was not resumed while catching up - if (_state == MXSessionStateBackgroundSyncInProgress) - { - NSLog(@"[MXSession] go to paused "); - eventStreamRequest = nil; - [self setState:MXSessionStatePaused]; - return; - } - else - { - NSLog(@"[MXSession] resume after a background Sync "); - } - } - - // If we are resuming inform the app that it received the last uptodate data - if (onResumeDone) - { - NSLog(@"[MXSession] Events stream resumed with %tu new events", events.count); - - // Operations on session may occur during this block. For example, [MXSession close] or [MXSession pause] may be triggered. - // We run a copy of the block to prevent app from crashing if the block is released by one of these operations. - MXOnResumeDone onResumeDoneCpy = [onResumeDone copy]; - onResumeDoneCpy(); - onResumeDone = nil; - - // Stop here if [MXSession close] or [MXSession pause] has been triggered during onResumeDone block. - if (nil == _myUser || _state == MXSessionStatePaused) - { - return; - } - } - - // The event stream is running by now - [self setState:MXSessionStateRunning]; - - // Check SDK user did not called [MXSession close] or [MXSession pause] during the session state change notification handling. - if (nil == _myUser || _state == MXSessionStatePaused) - { - return; - } - - // Go streaming from the returned token - [self streamEventsFromToken:paginatedResponse.end withLongPoll:YES]; - - // Broadcast that a server sync has been processed. - [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionDidSyncNotification - object:self - userInfo:nil]; - } - - } failure:^(NSError *error) { - - if (onBackgroundSyncFail) - { - NSLog(@"[MXSession] background Sync fails %@", error); - - // Operations on session may occur during this block. For example, [MXSession close] may be triggered. - // We run a copy of the block to prevent app from crashing if the block is released by one of these operations. - MXOnBackgroundSyncFail onBackgroundSyncFailCpy = [onBackgroundSyncFail copy]; - onBackgroundSyncFailCpy(error); - onBackgroundSyncFail = nil; - - // check that the application was not resumed while catching up in background - if (_state == MXSessionStateBackgroundSyncInProgress) - { - NSLog(@"[MXSession] go to paused "); - eventStreamRequest = nil; - [self setState:MXSessionStatePaused]; - return; - } - else - { - NSLog(@"[MXSession] resume after a background Sync"); - } - } - - if (eventStreamRequest) - { - // on 64 bits devices, the error codes are huge integers. - int32_t code = (int32_t)error.code; - - if (code == kCFURLErrorCancelled) - { - NSLog(@"[MXSession] The connection has been cancelled."); - } - // timeout case : the request has been triggerd with a timeout value - // but there is no data to retrieve - else if ((code == kCFURLErrorTimedOut) && !longPoll) - { - NSLog(@"[MXSession] The connection has been timeout."); - - [eventStreamRequest cancel]; - eventStreamRequest = nil; - - // Broadcast that a server sync is processed. - [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionDidSyncNotification - object:self - userInfo:nil]; - - // switch back to the long poll management - [self streamEventsFromToken:token withLongPoll:YES]; - } - else - { - // Inform the app there is a problem with the connection to the homeserver - [self setState:MXSessionStateHomeserverNotReachable]; - - // Check if it is a network connectivity issue - AFNetworkReachabilityManager *networkReachabilityManager = [AFNetworkReachabilityManager sharedManager]; - NSLog(@"[MXSession] events stream broken. Network reachability: %d", networkReachabilityManager.isReachable); - - if (networkReachabilityManager.isReachable) - { - // The problem is not the network - // Relaunch the request in a random near futur. - // Random time it used to avoid all Matrix clients to retry all in the same time - // if there is server side issue like server restart - dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, [MXHTTPClient jitterTimeForRetry] * NSEC_PER_MSEC); - dispatch_after(delayTime, dispatch_get_main_queue(), ^(void) { - - if (eventStreamRequest) - { - NSLog(@"[MXSession] Retry resuming events stream"); - [self streamEventsFromToken:token withLongPoll:longPoll]; - } - }); - } - else - { - // The device is not connected to the internet, wait for the connection to be up again before retrying - __block __weak id reachabilityObserver = - [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingReachabilityDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { - - if (networkReachabilityManager.isReachable && eventStreamRequest) - { - [[NSNotificationCenter defaultCenter] removeObserver:reachabilityObserver]; - - NSLog(@"[MXSession] Retry resuming events stream"); - [self streamEventsFromToken:token withLongPoll:longPoll]; - } - }]; - } - } - } - }]; -} - - (void)handleLiveEvents:(NSArray*)events { for (MXEvent *event in events) @@ -772,18 +553,8 @@ - (void)resume:(void (^)())resumeDone if (!eventStreamRequest) { - // Relaunch live events stream (long polling) - Check supported C-S version -#ifdef MXSESSION_ENABLE_SERVER_SYNC_V2 - if (matrixRestClient.preferredAPIVersion == MXRestClientAPIVersion2) - { - [self serverSyncWithServerTimeout:0 success:nil failure:nil clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; - } - else -#endif - { - // sync based on API v1 (Legacy) - [self streamEventsFromToken:_store.eventStreamToken withLongPoll:NO]; - } + // Relaunch live events stream (long polling) + [self serverSyncWithServerTimeout:0 success:nil failure:nil clientTimeout:CLIENT_TIMEOUT_MS setPresence:nil]; } } } @@ -808,19 +579,8 @@ - (void)backgroundSync:(unsigned int)timeout success:(MXOnBackgroundSyncDone)bac // BackgroundSync from the latest known token onBackgroundSyncDone = backgroundSyncDone; onBackgroundSyncFail = backgroundSyncfails; - - // Check supported C-S version -#ifdef MXSESSION_ENABLE_SERVER_SYNC_V2 - if (matrixRestClient.preferredAPIVersion == MXRestClientAPIVersion2) - { - [self serverSyncWithServerTimeout:0 success:nil failure:nil clientTimeout:timeout setPresence:@"offline"]; - } - else -#endif - { - // sync based on API v1 (Legacy) - [self streamEventsFromToken:_store.eventStreamToken withLongPoll:NO serverTimeOut:0 clientTimeout:timeout]; - } + + [self serverSyncWithServerTimeout:0 success:nil failure:nil clientTimeout:timeout setPresence:@"offline"]; } } } @@ -835,19 +595,7 @@ - (BOOL)reconnect // retrieve the available data asap // disable the long poll to get the available data asap - - // Check supported C-S version -#ifdef MXSESSION_ENABLE_SERVER_SYNC_V2 - if (matrixRestClient.preferredAPIVersion == MXRestClientAPIVersion2) - { - [self serverSyncWithServerTimeout:0 success:nil failure:nil clientTimeout:10 setPresence:nil]; - } - else -#endif - { - // sync based on API v1 (Legacy) - [self streamEventsFromToken:_store.eventStreamToken withLongPoll:NO serverTimeOut:0 clientTimeout:10]; - } + [self serverSyncWithServerTimeout:0 success:nil failure:nil clientTimeout:10 setPresence:nil]; return YES; } @@ -910,125 +658,6 @@ - (void)close [self setState:MXSessionStateClosed]; } -#pragma mark - Internals - -- (void)initialServerSync:(void (^)())onServerSyncDone - failure:(void (^)(NSError *error))failure -{ - NSDate *startDate = [NSDate date]; - NSLog(@"[MXSession] Do a global initialSync"); - - // Then, we can do the global sync - [matrixRestClient initialSyncWithLimit:initialSyncMessagesLimit success:^(MXInitialSyncResponse *initialSync) { - - // Make sure [MXSession close] has not been called before the server response - if (nil == _myUser) - { - return; - } - - NSMutableArray * roomids = [[NSMutableArray alloc] init]; - - NSLog(@"[MXSession] Received %tu rooms in %.3fms", initialSync.rooms.count, [[NSDate date] timeIntervalSinceDate:startDate] * 1000); - - NSDate *startDate2 = [NSDate date]; - - for (MXRoomInitialSync* roomInitialSync in initialSync.rooms) - { - @autoreleasepool - { - MXRoom *room = [self getOrCreateRoom:roomInitialSync.roomId withInitialSync:roomInitialSync notify:NO]; - [roomids addObject:room.state.roomId]; - - if (roomInitialSync.messages) - { - [room handleMessages:roomInitialSync.messages - direction:MXEventDirectionBackwards isTimeOrdered:YES]; - - // Uncomment the following lines when SYN-482 will be fixed -// // If the initialSync returns less messages than requested, we got all history from the home server -// if (roomInitialSync.messages.chunk.count < initialSyncMessagesLimit) -// { -// [_store storeHasReachedHomeServerPaginationEndForRoom:room.state.roomId andValue:YES]; -// } - } - if (roomInitialSync.state) - { - [room handleStateEvents:roomInitialSync.state direction:MXEventDirectionSync]; - - if (!room.state.isPublic && room.state.members.count == 2) - { - // Update one-to-one room dictionary - [self handleOneToOneRoom:room]; - } - } - if (roomInitialSync.accountData) - { - [room handleAccounDataEvents:roomInitialSync.accountData direction:MXEventDirectionSync]; - } - - // Notify that room has been sync'ed - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomInitialSyncNotification - object:room - userInfo:nil]; - } - } - - // Manage presence - @autoreleasepool - { - for (MXEvent *presenceEvent in initialSync.presence) - { - [self handlePresenceEvent:presenceEvent direction:MXEventDirectionSync]; - } - } - - // Manage receipts - @autoreleasepool - { - for (MXEvent *receiptEvent in initialSync.receipts) - { - MXRoom *room = [self roomWithRoomId:receiptEvent.roomId]; - - if (room) - { - [room handleReceiptEvent:receiptEvent direction:MXEventDirectionSync]; - } - } - } - -// // init the receips to the latest received one. -// // else the unread messages counter will not be properly managed. -// for (MXRoomInitialSync* roomInitialSync in initialSync.rooms) -// { -// MXRoom *room = [self roomWithRoomId:roomInitialSync.roomId]; -// [room acknowledgeLatestEvent:NO]; -// } - - // Start listening to live events - _store.eventStreamToken = initialSync.end; - - // Commit store changes done in [room handleMessages] - if ([_store respondsToSelector:@selector(commit)]) - { - [_store commit]; - } - - NSLog(@"[MXSession] InitialSync events processed and stored in %.3fms", [[NSDate date] timeIntervalSinceDate:startDate2] * 1000); - - // Resume from the last known token - [self streamEventsFromToken:_store.eventStreamToken withLongPoll:YES]; - - [self setState:MXSessionStateRunning]; - - onServerSyncDone(); - - } failure:^(NSError *error) { - [self setState:MXSessionStateHomeserverNotReachable]; - failure(error); - }]; -} - #pragma mark - server sync v2 - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout @@ -1384,19 +1013,10 @@ - (MXHTTPOperation*)joinRoom:(NSString*)roomIdOrAlias kMXSessionNotificationRoomIdKey: room.state.roomId, }]; } - -#ifdef MXSESSION_ENABLE_SERVER_SYNC_V2 - if (matrixRestClient.preferredAPIVersion == MXRestClientAPIVersion2) - { - if (success) - { - success(room); - } - } - else -#endif + + if (success) { - [self initialSyncOfRoom:theRoomId withLimit:initialSyncMessagesLimit success:success failure:failure]; + success(room); } } failure:failure]; From 48e3970913b958e567fd682a368b5123b5b5b447 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 9 Feb 2016 17:41:25 +0100 Subject: [PATCH 03/80] Moving to r0 API: Enabled "v2_alpha" for /register --- MatrixSDK/MXRestClient.m | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 4b7d15e9ef..b5b526efec 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -274,15 +274,7 @@ - (NSString*)authActionPath:(MXAuthAction)authAction NSString *authActionPath = @"api/v1/login"; if (MXAuthActionRegister == authAction) { - // TODO GFO server register v2 is not available yet (use C-S v1 by default) -// if (preferredAPIVersion == MXRestClientAPIVersion2) -// { -// authActionPath = @"v2_alpha/register"; -// } -// else - { - authActionPath = @"api/v1/register"; - } + authActionPath = @"v2_alpha/register"; } return authActionPath; } @@ -293,15 +285,15 @@ - (MXHTTPOperation*)getRegisterOrLoginFlow:(MXAuthAction)authAction NSString *httpMethod = @"GET"; NSDictionary *parameters = nil; - // TODO GFO server register v2 is not available yet (use C-S v1 by default) -// if ((MXAuthActionRegister == authAction) && (preferredAPIVersion == MXRestClientAPIVersion2)) -// { -// // C-S API v2: use POST with no params to get the login mechanism to use when registering -// // The request will failed with Unauthorized status code, but the login mechanism will be available in response data. -// httpMethod = @"POST"; -// parameters = @{}; -// } - + + if (MXAuthActionRegister == authAction) + { + // For registration, use POST with no params to get the login mechanism to use + // The request will failed with Unauthorized status code, but the login mechanism will be available in response data. + httpMethod = @"POST"; + parameters = @{}; + } + return [httpClient requestWithMethod:httpMethod path:[self authActionPath:authAction] parameters:parameters From 30f44e7f7c5c1c546c5146fbfcf3fc03679fb3c6 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 11 Feb 2016 10:49:00 +0100 Subject: [PATCH 04/80] Moving to r0 API: Updated MXRoom as "v1" initialSync is gone --- MatrixSDK/Data/MXRoom.m | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 9eb6b6e900..75b01aedb5 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -1039,14 +1039,7 @@ - (BOOL)setReadReceiptToken:(NSString*)token ts:(long)ts } - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; -{ - // Sanity check on supported C-S version - if (mxSession.matrixRestClient.preferredAPIVersion < MXRestClientAPIVersion2) - { - NSLog(@"[MXRoom] acknowledgeLatestEvent failed: read receipts are not supported on C-S v1 API"); - return NO; - } - +{ MXEvent* event =[mxSession.store lastMessageOfRoom:_state.roomId withTypeIn:_acknowledgableEventTypes]; // Sanity check on event id: Do not send read receipt on event without id if (event.eventId && ([event.eventId hasPrefix:kMXRoomInviteStateEventIdPrefix] == NO)) From 983e3d83c5008088031522b3e2ab1680025689d7 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 11 Feb 2016 10:53:03 +0100 Subject: [PATCH 05/80] Moving to r0 API: Added MXRestClient.apiPathPrefix, kMXAPIPrefixPathR0 and kMXAPIPrefixPathUnstable --- MatrixSDK/MXRestClient.h | 27 ++++------ MatrixSDK/MXRestClient.m | 113 ++++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 77 deletions(-) diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index 20c024cf0d..fa8ba5d5db 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -24,9 +24,14 @@ #pragma mark - Constants definitions /** - Prefix used in path of home server API requests. + A constant representing the URI path for release 0 of the Client-Server HTTP API. */ -FOUNDATION_EXPORT NSString *const kMXAPIPrefixPath; +FOUNDATION_EXPORT NSString *const kMXAPIPrefixPathR0; + +/** + A constant representing tthe URI path for as-yet unspecified of the Client-Server HTTP API. + */ +FOUNDATION_EXPORT NSString *const kMXAPIPrefixPathUnstable; /** Prefix used in path of identity server API requests. @@ -110,17 +115,6 @@ typedef enum : NSUInteger */ @interface MXRestClient : NSObject -/** - The preferred Client-Server API version. This value is applied to each new MXRestClient instance - during initialisation step (see 'preferredAPIVersion' property). - By default the C-S API v2 is considered. - - CAUTION: Change of the preferred version impacts only the new MXRestClient instances. - - @param preferredAPIVersion the preferred C-S API version. - */ -+ (void)registerPreferredAPIVersion:(MXRestClientAPIVersion)preferredAPIVersion; - /** The homeserver. */ @@ -137,11 +131,10 @@ typedef enum : NSUInteger @property (nonatomic, readonly) NSString *homeserverSuffix; /** - The preferred Client-Server API version. This version is used during server requests insofar as it is supported. - A prior version is used in case the preferred one is not supported yet. - It is set during initialisation according to the registered value (see [registerPreferredAPIVersion:]). + The Client-Server API prefix to use. + By default, it is '/_matrix/client/r0'. See kMXAPIPrefixPathR0 and kMXAPIPrefixPathUnstable for constants. */ -@property (nonatomic, readonly) MXRestClientAPIVersion preferredAPIVersion; +@property (nonatomic) NSString *apiPathPrefix; /** The identity server. diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index b5b526efec..1860330d15 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -24,7 +24,8 @@ /** Prefix used in path of home server API requests. */ -NSString *const kMXAPIPrefixPath = @"/_matrix/client"; +NSString *const kMXAPIPrefixPathR0 = @"/_matrix/client/r0"; +NSString *const kMXAPIPrefixPathUnstable = @"/_matrix/client/unstable"; /** Prefix used in path of identity server API requests. @@ -55,9 +56,6 @@ */ NSString *const kMXRestClientErrorDomain = @"kMXRestClientErrorDomain"; -// Increase this preferred API version when new version is available -static MXRestClientAPIVersion _currentPreferredAPIVersion = MXRestClientAPIVersion2; - /** Authentication flow: register or login */ @@ -91,12 +89,7 @@ @interface MXRestClient () @end @implementation MXRestClient -@synthesize homeserver, homeserverSuffix, credentials, preferredAPIVersion; - -+ (void)registerPreferredAPIVersion:(MXRestClientAPIVersion)inPreferredAPIVersion -{ - _currentPreferredAPIVersion = inPreferredAPIVersion; -} +@synthesize homeserver, homeserverSuffix, credentials, apiPathPrefix; -(id)initWithHomeServer:(NSString *)inHomeserver andOnUnrecognizedCertificateBlock:(MXHTTPClientOnUnrecognizedCertificate)onUnrecognizedCertBlock { @@ -104,9 +97,9 @@ -(id)initWithHomeServer:(NSString *)inHomeserver andOnUnrecognizedCertificateBlo if (self) { homeserver = inHomeserver; - preferredAPIVersion = _currentPreferredAPIVersion; + apiPathPrefix = kMXAPIPrefixPathR0; - httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", homeserver, kMXAPIPrefixPath] + httpClient = [[MXHTTPClient alloc] initWithBaseURL:homeserver accessToken:nil andOnUnrecognizedCertificateBlock:onUnrecognizedCertBlock]; @@ -124,10 +117,10 @@ -(id)initWithCredentials:(MXCredentials*)inCredentials andOnUnrecognizedCertific if (self) { homeserver = inCredentials.homeServer; - preferredAPIVersion = _currentPreferredAPIVersion; + apiPathPrefix = kMXAPIPrefixPathR0; self.credentials = inCredentials; - httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", homeserver, kMXAPIPrefixPath] + httpClient = [[MXHTTPClient alloc] initWithBaseURL:homeserver accessToken:credentials.accessToken andOnUnrecognizedCertificateBlock:onUnrecognizedCertBlock]; @@ -248,7 +241,7 @@ - (MXHTTPOperation*)changePassword:(NSString*)oldPassword with:(NSString*)newPas }; return [httpClient requestWithMethod:@"POST" - path:@"v2_alpha/account/password" + path:[NSString stringWithFormat:@"%@/account/password", apiPathPrefix] parameters:parameters success:^(NSDictionary *JSONResponse) { success(); @@ -271,12 +264,12 @@ - (MXHTTPOperation*)changePassword:(NSString*)oldPassword with:(NSString*)newPas */ - (NSString*)authActionPath:(MXAuthAction)authAction { - NSString *authActionPath = @"api/v1/login"; + NSString *authActionPath = @"login"; if (MXAuthActionRegister == authAction) { - authActionPath = @"v2_alpha/register"; + authActionPath = @"register"; } - return authActionPath; + return [NSString stringWithFormat:@"%@/%@", apiPathPrefix, authActionPath]; } - (MXHTTPOperation*)getRegisterOrLoginFlow:(MXAuthAction)authAction @@ -425,7 +418,7 @@ - (MXHTTPOperation*)setPusherWithPushkey:(NSString *)pushkey }; return [httpClient requestWithMethod:@"POST" - path:@"api/v1/pushers/set" + path:[NSString stringWithFormat:@"%@/pushers/set", apiPathPrefix] parameters:parameters success:^(NSDictionary *JSONResponse) { success(); @@ -438,7 +431,7 @@ - (MXHTTPOperation*)setPusherWithPushkey:(NSString *)pushkey - (MXHTTPOperation *)pushRules:(void (^)(MXPushRulesResponse *pushRules))success failure:(void (^)(NSError *))failure { return [httpClient requestWithMethod:@"GET" - path:@"api/v1/pushrules/" + path:[NSString stringWithFormat:@"%@/pushrules", apiPathPrefix] parameters:nil success:^(NSDictionary *JSONResponse) { @autoreleasepool @@ -484,7 +477,7 @@ - (MXHTTPOperation *)enablePushRule:(NSString*)ruleId NSString *enabled = enable ? @"true": @"false"; return [httpClient requestWithMethod:@"PUT" - path:[NSString stringWithFormat:@"api/v1/pushrules/%@/%@/%@/enabled", scope, kindString, ruleId] + path:[NSString stringWithFormat:@"%@/pushrules/%@/%@/%@/enabled", apiPathPrefix, scope, kindString, ruleId] parameters:nil data:[enabled dataUsingEncoding:NSUTF8StringEncoding] headers:headers @@ -531,7 +524,7 @@ - (MXHTTPOperation *)removePushRule:(NSString*)ruleId } return [httpClient requestWithMethod:@"DELETE" - path:[NSString stringWithFormat:@"api/v1/pushrules/%@/%@/%@", scope, kindString, ruleId] + path:[NSString stringWithFormat:@"%@/pushrules/%@/%@/%@", apiPathPrefix, scope, kindString, ruleId] parameters:nil success:^(NSDictionary *JSONResponse) { if (success) @@ -589,7 +582,7 @@ - (MXHTTPOperation *)addPushRule:(NSString*)ruleId if (content) { return [httpClient requestWithMethod:@"PUT" - path:[NSString stringWithFormat:@"api/v1/pushrules/%@/%@/%@", scope, kindString, ruleId] + path:[NSString stringWithFormat:@"%@/pushrules/%@/%@/%@", apiPathPrefix, scope, kindString, ruleId] parameters:content success:^(NSDictionary *JSONResponse) { if (success) @@ -622,7 +615,7 @@ - (MXHTTPOperation*)sendEventToRoom:(NSString*)roomId failure:(void (^)(NSError *error))failure { // Prepare the path by adding a random transaction id (This id is used to prevent duplicated event). - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/send/%@/%tu", roomId, eventTypeString, arc4random_uniform(INT32_MAX)]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/send/%@/%tu", apiPathPrefix, roomId, eventTypeString, arc4random_uniform(INT32_MAX)]; return [httpClient requestWithMethod:@"PUT" path:path @@ -660,7 +653,7 @@ - (MXHTTPOperation*)sendStateEventToRoom:(NSString*)roomId success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/%@", roomId, eventTypeString]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/%@", apiPathPrefix, roomId, eventTypeString]; return [httpClient requestWithMethod:@"PUT" path:path parameters:content @@ -722,7 +715,7 @@ - (MXHTTPOperation*)doMembershipRequest:(NSString*)roomId success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/%@", roomId, membership]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/%@", apiPathPrefix, roomId, membership]; // A body is required even if empty if (nil == parameters) @@ -761,7 +754,7 @@ - (MXHTTPOperation*)setRoomTopic:(NSString*)roomId success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.topic", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.topic", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"PUT" path:path parameters:@{ @@ -794,7 +787,7 @@ - (MXHTTPOperation*)topicOfRoom:(NSString*)roomId success:(void (^)(NSString *topic))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.topic", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.topic", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -829,7 +822,7 @@ - (MXHTTPOperation *)setRoomAvatar:(NSString *)roomId success:(void (^)())success failure:(void (^)(NSError *))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.avatar", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.avatar", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"PUT" path:path parameters:@{ @@ -862,7 +855,7 @@ - (MXHTTPOperation *)avatarOfRoom:(NSString *)roomId success:(void (^)(NSString *))success failure:(void (^)(NSError *))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.avatar", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.avatar", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -896,7 +889,7 @@ - (MXHTTPOperation*)setRoomName:(NSString*)roomId success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.name", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.name", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"PUT" path:path parameters:@{ @@ -929,7 +922,7 @@ - (MXHTTPOperation*)nameOfRoom:(NSString*)roomId success:(void (^)(NSString *name))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.name", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.name", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -963,7 +956,7 @@ - (MXHTTPOperation*)joinRoom:(NSString*)roomIdOrAlias failure:(void (^)(NSError *error))failure { // Characters in a room alias need to be escaped in the URL - NSString *path = [NSString stringWithFormat:@"api/v1/join/%@", [roomIdOrAlias stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]; + NSString *path = [NSString stringWithFormat:@"%@/join/%@", apiPathPrefix, [roomIdOrAlias stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]; return [httpClient requestWithMethod:@"POST" path:path parameters:nil @@ -1046,7 +1039,7 @@ - (MXHTTPOperation*)inviteByThreePid:(NSString*)medium return nil; } - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/invite", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/invite", apiPathPrefix, roomId]; // This request must not have the protocol part NSString *identityServer = _identityServer; @@ -1093,7 +1086,7 @@ - (MXHTTPOperation*)kickUser:(NSString*)userId success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state/m.room.member/%@", roomId, userId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state/m.room.member/%@", apiPathPrefix, roomId, userId]; NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"membership"] = @"leave"; @@ -1186,7 +1179,7 @@ - (MXHTTPOperation*)createRoom:(NSString*)name } return [httpClient requestWithMethod:@"POST" - path:@"api/v1/createRoom" + path:[NSString stringWithFormat:@"%@/createRoom", apiPathPrefix] parameters:parameters success:^(NSDictionary *JSONResponse) { if (success) @@ -1220,7 +1213,7 @@ - (MXHTTPOperation*)messagesForRoom:(NSString*)roomId success:(void (^)(MXPaginationResponse *paginatedResponse))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/messages", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/messages", apiPathPrefix, roomId]; // All query parameters are optional. Fill the request parameters on demand NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; @@ -1273,7 +1266,7 @@ - (MXHTTPOperation*)membersOfRoom:(NSString*)roomId success:(void (^)(NSArray *roomMemberEvents))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/members", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/members", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"GET" path:path @@ -1313,7 +1306,7 @@ - (MXHTTPOperation*)stateOfRoom:(NSString*)roomId success:(void (^)(NSDictionary *JSONData))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/state", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/state", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"GET" path:path @@ -1347,7 +1340,7 @@ - (MXHTTPOperation*)sendTypingNotificationInRoom:(NSString*)roomId success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/typing/%@", roomId, self.credentials.userId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/typing/%@", apiPathPrefix, roomId, self.credentials.userId]; // Fill the request parameters on demand NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; @@ -1395,7 +1388,7 @@ - (MXHTTPOperation*)redactEvent:(NSString*)eventId success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/redact/%@", roomId, eventId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/redact/%@", apiPathPrefix, roomId, eventId]; // All query parameters are optional. Fill the request parameters on demand NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; @@ -1435,7 +1428,7 @@ - (MXHTTPOperation*)initialSyncOfRoom:(NSString*)roomId success:(void (^)(MXRoomInitialSync *roomInitialSync))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/rooms/%@/initialSync", roomId]; + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/initialSync", apiPathPrefix, roomId]; return [httpClient requestWithMethod:@"GET" path:path @@ -1473,7 +1466,7 @@ - (MXHTTPOperation*)tagsOfRoom:(NSString*)roomId success:(void (^)(NSArray *tags))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"v2_alpha/user/%@/rooms/%@/tags", credentials.userId, roomId]; + NSString *path = [NSString stringWithFormat:@"%@/user/%@/rooms/%@/tags", apiPathPrefix, credentials.userId, roomId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -1519,7 +1512,7 @@ - (MXHTTPOperation*)addTag:(NSString*)tag parameters[@"order"] = order; } - NSString *path = [NSString stringWithFormat:@"v2_alpha/user/%@/rooms/%@/tags/%@", credentials.userId, roomId, tag]; + NSString *path = [NSString stringWithFormat:@"%@/user/%@/rooms/%@/tags/%@", apiPathPrefix, credentials.userId, roomId, tag]; return [httpClient requestWithMethod:@"PUT" path:path parameters:parameters @@ -1551,7 +1544,7 @@ - (MXHTTPOperation*)removeTag:(NSString*)tag success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"v2_alpha/user/%@/rooms/%@/tags/%@", credentials.userId, roomId, tag]; + NSString *path = [NSString stringWithFormat:@"%@/user/%@/rooms/%@/tags/%@", apiPathPrefix, credentials.userId, roomId, tag]; return [httpClient requestWithMethod:@"DELETE" path:path parameters:nil @@ -1575,7 +1568,7 @@ - (MXHTTPOperation*)setDisplayName:(NSString*)displayname success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/profile/%@/displayname", credentials.userId]; + NSString *path = [NSString stringWithFormat:@"%@/profile/%@/displayname", apiPathPrefix, credentials.userId]; return [httpClient requestWithMethod:@"PUT" path:path parameters:@{ @@ -1613,7 +1606,7 @@ - (MXHTTPOperation*)displayNameForUser:(NSString*)userId userId = credentials.userId; } - NSString *path = [NSString stringWithFormat:@"api/v1/profile/%@/displayname", userId]; + NSString *path = [NSString stringWithFormat:@"%@/profile/%@/displayname", apiPathPrefix, userId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -1648,7 +1641,7 @@ - (MXHTTPOperation*)setAvatarUrl:(NSString*)avatarUrl success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/profile/%@/avatar_url", credentials.userId]; + NSString *path = [NSString stringWithFormat:@"%@/profile/%@/avatar_url", apiPathPrefix, credentials.userId]; return [httpClient requestWithMethod:@"PUT" path:path parameters:@{ @@ -1686,7 +1679,7 @@ - (MXHTTPOperation*)avatarUrlForUser:(NSString*)userId userId = credentials.userId; } - NSString *path = [NSString stringWithFormat:@"api/v1/profile/%@/avatar_url", userId]; + NSString *path = [NSString stringWithFormat:@"%@/profile/%@/avatar_url", apiPathPrefix, userId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -1723,7 +1716,7 @@ - (MXHTTPOperation*)setPresence:(MXPresence)presence andStatusMessage:(NSString* success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/presence/%@/status", credentials.userId]; + NSString *path = [NSString stringWithFormat:@"%@/presence/%@/status", apiPathPrefix, credentials.userId]; NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"presence"] = [MXTools presenceString:presence]; @@ -1767,7 +1760,7 @@ - (MXHTTPOperation*)presence:(NSString*)userId userId = credentials.userId; } - NSString *path = [NSString stringWithFormat:@"api/v1/presence/%@/status", userId]; + NSString *path = [NSString stringWithFormat:@"%@/presence/%@/status", apiPathPrefix, userId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -1803,7 +1796,7 @@ - (MXHTTPOperation*)allUsersPresence:(void (^)(NSArray *userPresenceEvents))succ // a global initialSync // @TODO: Change it with C-S API v2 new APIs return [httpClient requestWithMethod:@"GET" - path:@"api/v1/initialSync" + path:[NSString stringWithFormat:@"%@/initialSync", apiPathPrefix] parameters:@{ @"limit": [NSNumber numberWithInteger:0] } @@ -1838,7 +1831,7 @@ - (MXHTTPOperation*)allUsersPresence:(void (^)(NSArray *userPresenceEvents))succ - (MXHTTPOperation*)presenceList:(void (^)(MXPresenceResponse *presence))success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/presence/list/%@", credentials.userId]; + NSString *path = [NSString stringWithFormat:@"%@/presence/list/%@", apiPathPrefix, credentials.userId]; return [httpClient requestWithMethod:@"GET" path:path parameters:nil @@ -1871,7 +1864,7 @@ - (MXHTTPOperation*)presenceListAddUsers:(NSArray*)users success:(void (^)())success failure:(void (^)(NSError *error))failure { - NSString *path = [NSString stringWithFormat:@"api/v1/presence/list/%@", credentials.userId]; + NSString *path = [NSString stringWithFormat:@"%@/presence/list/%@", apiPathPrefix, credentials.userId]; NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"invite"] = users; @@ -1941,7 +1934,7 @@ - (MXHTTPOperation *)syncFromToken:(NSString*)token } MXHTTPOperation *operation = [httpClient requestWithMethod:@"GET" - path:@"v2_alpha/sync" + path:[NSString stringWithFormat:@"%@/sync", apiPathPrefix] parameters:parameters timeout:clientTimeoutInSeconds success:^(NSDictionary *JSONResponse) { if (success) @@ -1993,7 +1986,7 @@ - (MXHTTPOperation*)sendReadReceipts:(NSString*)roomId failure:(void (^)(NSError *error))failure { return [httpClient requestWithMethod:@"POST" - path: [NSString stringWithFormat:@"v2_alpha/rooms/%@/receipt/m.read/%@", roomId, eventId] + path: [NSString stringWithFormat:@"%@/rooms/%@/receipt/m.read/%@", apiPathPrefix, roomId, eventId] parameters:[[NSDictionary alloc] init] success:^(NSDictionary *JSONResponse) { @@ -2022,7 +2015,7 @@ - (MXHTTPOperation*)publicRooms:(void (^)(NSArray *rooms))success failure:(void (^)(NSError *error))failure { return [httpClient requestWithMethod:@"GET" - path:@"api/v1/publicRooms" + path:[NSString stringWithFormat:@"%@/publicRooms", apiPathPrefix] parameters:nil success:^(NSDictionary *JSONResponse) { if (success) @@ -2058,7 +2051,7 @@ - (MXHTTPOperation*)roomIDForRoomAlias:(NSString*)roomAlias failure:(void (^)(NSError *error))failure { // Note: characters in a room alias need to be escaped in the URL - NSString *path = [NSString stringWithFormat:@"api/v1/directory/room/%@", [roomAlias stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]; + NSString *path = [NSString stringWithFormat:@"%@/directory/room/%@", apiPathPrefix, [roomAlias stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]; return [httpClient requestWithMethod:@"GET" path:path @@ -2365,7 +2358,7 @@ - (MXHTTPOperation *)turnServer:(void (^)(MXTurnServerResponse *))success failure:(void (^)(NSError *))failure { return [httpClient requestWithMethod:@"GET" - path:@"api/v1/voip/turnServer" + path:[NSString stringWithFormat:@"%@/voip/turnServer", apiPathPrefix] parameters:nil success:^(NSDictionary *JSONResponse) { if (success) @@ -2416,7 +2409,7 @@ - (MXHTTPOperation*)search:(NSDictionary*)parameters success:(void (^)(MXSearchRoomEventResults *roomEventResults))success failure:(void (^)(NSError *error))failure { - NSString *path = @"api/v1/search"; + NSString *path = [NSString stringWithFormat:@"%@/search", apiPathPrefix]; if (nextBatch) { path = [NSString stringWithFormat:@"%@?next_batch=%@", path, nextBatch]; From cc772f0366abe10b500e4e46884e5e1863ad5b3f Mon Sep 17 00:00:00 2001 From: giomfo Date: Thu, 11 Feb 2016 11:26:41 +0100 Subject: [PATCH 06/80] MXHTTPClient: Log error code and description --- MatrixSDK/Utils/MXHTTPClient.m | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MatrixSDK/Utils/MXHTTPClient.m b/MatrixSDK/Utils/MXHTTPClient.m index 3f8a7cd32d..f8b057c2be 100644 --- a/MatrixSDK/Utils/MXHTTPClient.m +++ b/MatrixSDK/Utils/MXHTTPClient.m @@ -192,6 +192,7 @@ - (void)tryRequest:(MXHTTPOperation*)mxHTTPOperation #if DEBUG NSLog(@"[MXHTTPClient] Request %p failed for path: %@ - HTTP code: %ld", mxHTTPOperation, path, (long)operation.response.statusCode); + NSLog(@"[MXHTTPClient] error: %@", error); #else // Hide access token in printed path NSMutableString *printedPath = [NSMutableString stringWithString:path]; @@ -204,6 +205,15 @@ - (void)tryRequest:(MXHTTPOperation*)mxHTTPOperation } } NSLog(@"[MXHTTPClient] Request %p failed for path: %@ - HTTP code: %ld", mxHTTPOperation, printedPath, (long)operation.response.statusCode); + + if (error.userInfo[NSLocalizedDescriptionKey]) + { + NSLog(@"[MXHTTPClient] error domain: %@, code:%zd, description: %@", error.domain, error.code, error.userInfo[NSLocalizedDescriptionKey]); + } + else + { + NSLog(@"[MXHTTPClient] error domain: %@, code:%zd", error.domain, error.code); + } #endif if (operation.responseData) From bcffecceeab01c119d21d18747ea5d311f2ea850 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 11 Feb 2016 11:27:23 +0100 Subject: [PATCH 07/80] Moving to r0 API: MXSession: Simplified startWithMessagesLimit as initialSync v1 does not need to be supported anymore --- MatrixSDK/MXSession.m | 64 ++++--------------------------------------- 1 file changed, 6 insertions(+), 58 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index a055642085..d212140cc3 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -286,65 +286,13 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit // Can we resume from data available in the cache if (_store.isPermanent && _store.eventStreamToken && 0 < _store.rooms.count) { - // Note since server sync v2, we don't need to handle presence separately. - // TODO: the following code should be cleaned when sync v1 will be deprecated by removing 'loadPresence' function. - - // In sync v1, MXSession.loadPresenceBeforeCompletingSessionStart leads 2 scenarios to load presence. - // Cut the actions into blocks to realize them - void (^loadPresence) (void (^onPresenceDone)(), void (^onPresenceError)(NSError *error)) = ^void(void (^onPresenceDone)(), void (^onPresenceError)(NSError *error)) { - NSDate *startDate = [NSDate date]; - [matrixRestClient allUsersPresence:^(NSArray *userPresenceEvents) { - - // Make sure [MXSession close] has not been called before the server response - if (nil == _myUser) - { - return; - } - - NSLog(@"[MXSession] Got presence of %tu users in %.0fms", userPresenceEvents.count, [[NSDate date] timeIntervalSinceDate:startDate] * 1000); - - NSDate *t0 = [NSDate date]; - - @autoreleasepool - { - for (MXEvent *userPresenceEvent in userPresenceEvents) - { - NSString *userId; - MXJSONModelSetString(userId, userPresenceEvent.content[@"user_id"]); - if (userId) - { - MXUser *user = [self getOrCreateUser:userId]; - [user updateWithPresenceEvent:userPresenceEvent]; - } - } - } - - if (onPresenceDone) - { - onPresenceDone(); - } - - NSLog(@"[MXSession] Presences proceeded in %.0fms", [[NSDate date] timeIntervalSinceDate:t0] * 1000); - - } failure:^(NSError *error) { - if (onPresenceError) - { - onPresenceError(error); - } - }]; - }; - - void (^resumeEventsStream) () = ^void() { - NSLog(@"[MXSession] Resuming the events stream from %@...", _store.eventStreamToken); - NSDate *startDate2 = [NSDate date]; - [self resume:^{ - NSLog(@"[MXSession] Events stream resumed in %.0fms", [[NSDate date] timeIntervalSinceDate:startDate2] * 1000); - onServerSyncDone(); - }]; - }; - // Resume the stream (presence will be retrieved during server sync) - resumeEventsStream(); + NSLog(@"[MXSession] Resuming the events stream from %@...", _store.eventStreamToken); + NSDate *startDate2 = [NSDate date]; + [self resume:^{ + NSLog(@"[MXSession] Events stream resumed in %.0fms", [[NSDate date] timeIntervalSinceDate:startDate2] * 1000); + onServerSyncDone(); + }]; } else { From bfcf35fe2f78df61f209c1c792a8743ddfaa7cfe Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 11 Feb 2016 11:29:41 +0100 Subject: [PATCH 08/80] Moving to r0 API: MXRestClient: Removed allUsersPresence because it used the old v1 initialSync --- MatrixSDK/MXRestClient.h | 11 ----------- MatrixSDK/MXRestClient.m | 39 --------------------------------------- 2 files changed, 50 deletions(-) diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index fa8ba5d5db..dceba26566 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -927,17 +927,6 @@ typedef enum : NSUInteger success:(void (^)(MXPresenceResponse *presence))success failure:(void (^)(NSError *error))failure; -/** - Get the presence for all of the user's friends. - - @param success A block object called when the operation succeeds. It provides an array of presence events. - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. - */ -- (MXHTTPOperation*)allUsersPresence:(void (^)(NSArray *userPresenceEvents))success - failure:(void (^)(NSError *error))failure; - #pragma mark - Sync /** diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 1860330d15..4293d2fef8 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -1789,45 +1789,6 @@ - (MXHTTPOperation*)presence:(NSString*)userId }]; } -- (MXHTTPOperation*)allUsersPresence:(void (^)(NSArray *userPresenceEvents))success - failure:(void (^)(NSError *error))failure -{ - // In C-S API v1, the only way to get all user presence is to make - // a global initialSync - // @TODO: Change it with C-S API v2 new APIs - return [httpClient requestWithMethod:@"GET" - path:[NSString stringWithFormat:@"%@/initialSync", apiPathPrefix] - parameters:@{ - @"limit": [NSNumber numberWithInteger:0] - } - success:^(NSDictionary *JSONResponse) { - if (success) - { - // Create model from JSON dictionary on the processing queue - dispatch_async(processingQueue, ^{ - - // Parse only events from the `presence` field of the response. - // There is no interest to parse all JSONResponse with the MXInitialSyncResponse model, - // which is CPU expensive due to the possible high number of rooms states events. - NSArray *presence; - MXJSONModelSetMXJSONModelArray(presence, MXEvent, JSONResponse[@"presence"]); - - dispatch_async(dispatch_get_main_queue(), ^{ - - success(presence); - - }); - }); - } - } - failure:^(NSError *error) { - if (failure) - { - failure(error); - } - }]; -} - - (MXHTTPOperation*)presenceList:(void (^)(MXPresenceResponse *presence))success failure:(void (^)(NSError *error))failure { From 4bc7d6e9f84a71b270e032f9fd27d715f2388cea Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 11 Feb 2016 11:46:02 +0100 Subject: [PATCH 09/80] Moving to r0 API: MXJSONModels: Removed objects used by the old v1 initialSync --- MatrixSDK/JSONModels/MXJSONModels.h | 32 +---------------------------- MatrixSDK/JSONModels/MXJSONModels.m | 24 +--------------------- 2 files changed, 2 insertions(+), 54 deletions(-) diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index c7030e095f..f79bc341bc 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -783,7 +783,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end -#pragma mark - Server sync v1 response +#pragma mark - Server sync #pragma mark - /** @@ -843,36 +843,6 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end -/** - `MXInitialSyncResponse` represents the request response for server initial sync v1. @see http://matrix.org/docs/api/client-server/#!/-events/initial_sync - */ -@interface MXInitialSyncResponse : MXJSONModel - - /** - List of rooms. - */ - @property (nonatomic) NSArray *rooms; - - /** - The presence status of other users. - */ - @property (nonatomic) NSArray *presence; - - /** - The read receipts. - */ - @property (nonatomic) NSArray *receipts; - - /** - The opaque token for the end. - */ - @property (nonatomic) NSString *end; - -@end - -#pragma mark - Server sync v2 response -#pragma mark - - /** `MXRoomSyncState` represents the state updates for a room during server sync v2. */ diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index d92fff5df7..d621d7e6a7 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -735,7 +735,7 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary @end -#pragma mark - Server sync v1 response +#pragma mark - Server sync #pragma mark - @implementation MXRoomInitialSync @@ -762,28 +762,6 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary @end -@implementation MXInitialSyncResponse - -+ (id)modelFromJSON:(NSDictionary *)JSONDictionary -{ - MXInitialSyncResponse *initialSyncResponse = [[MXInitialSyncResponse alloc] init]; - if (initialSyncResponse) - { - MXJSONModelSetMXJSONModelArray(initialSyncResponse.rooms, MXRoomInitialSync, JSONDictionary[@"rooms"]); - MXJSONModelSetMXJSONModelArray(initialSyncResponse.presence, MXEvent, JSONDictionary[@"presence"]); - MXJSONModelSetMXJSONModelArray(initialSyncResponse.receipts, MXEvent, JSONDictionary[@"receipts"]); - MXJSONModelSetString(initialSyncResponse.end, JSONDictionary[@"end"]); - } - - return initialSyncResponse; -} - -@end - - -#pragma mark - Server sync v2 response -#pragma mark - - @implementation MXRoomSyncState + (id)modelFromJSON:(NSDictionary *)JSONDictionary From 2ec19a8b3fac2f815b1b502e1f6e64547786212d Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 11 Feb 2016 16:51:50 +0100 Subject: [PATCH 10/80] Moving to r0 API: the pushrules API needs a / at the end of this path --- MatrixSDK/MXRestClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 4293d2fef8..5eede39a62 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -431,7 +431,7 @@ - (MXHTTPOperation*)setPusherWithPushkey:(NSString *)pushkey - (MXHTTPOperation *)pushRules:(void (^)(MXPushRulesResponse *pushRules))success failure:(void (^)(NSError *))failure { return [httpClient requestWithMethod:@"GET" - path:[NSString stringWithFormat:@"%@/pushrules", apiPathPrefix] + path:[NSString stringWithFormat:@"%@/pushrules/", apiPathPrefix] parameters:nil success:^(NSDictionary *JSONResponse) { @autoreleasepool From 25caa8816e9070c35189d3820353eac7206693b7 Mon Sep 17 00:00:00 2001 From: giomfo Date: Thu, 11 Feb 2016 17:34:34 +0100 Subject: [PATCH 11/80] BugFix vector-ios #75 Email login broken? --- MatrixSDK/MXRestClient.m | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 38ee6a55da..e7fc4e1f97 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -361,11 +361,29 @@ - (MXHTTPOperation*)registerOrLogin:(MXAuthAction)authAction parameters:(NSDicti - (MXHTTPOperation*)registerOrLoginWithUser:(MXAuthAction)authAction user:(NSString *)user andPassword:(NSString *)password success:(void (^)(MXCredentials *))success failure:(void (^)(NSError *))failure { - NSDictionary *parameters = @{ - @"type": kMXLoginFlowTypePassword, - @"user": user, - @"password": password - }; + // Is it an email or a username? + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^\\S+@\\S+\\.\\S+$" options:NSRegularExpressionCaseInsensitive error:nil]; + BOOL isEmailAddress = (nil != [regex firstMatchInString:user options:0 range:NSMakeRange(0, user.length)]); + + NSDictionary *parameters; + + if (isEmailAddress) + { + parameters = @{ + @"type": kMXLoginFlowTypePassword, + @"medium": @"email", + @"address": user, + @"password": password + }; + } + else + { + parameters = @{ + @"type": kMXLoginFlowTypePassword, + @"user": user, + @"password": password + }; + } return [self registerOrLogin:authAction parameters:parameters From f12628595ce9ce07fd6e4e9124c511a6fede08aa Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 15 Feb 2016 10:06:11 +0100 Subject: [PATCH 12/80] Fix compilation issue due to change on [MXRoom paginateBackMessages] --- MatrixSDKTests/MXEventTests.m | 2 +- MatrixSDKTests/MXRoomStateDynamicTests.m | 2 +- MatrixSDKTests/MXRoomTests.m | 2 +- MatrixSDKTests/MXStoreMemoryStoreTests.m | 14 ++++----- MatrixSDKTests/MXStoreTests.m | 40 ++++++++++++------------ 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index 55ed896bb2..bb2d281121 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -114,7 +114,7 @@ - (void)testIsState }]; [room resetBackState]; - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTAssertGreaterThan(eventCount, 0, "We should have received events in registerEventListenerForTypes"); diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index ffef54e17a..afdfec83f1 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -159,7 +159,7 @@ - (void)testBackPaginationForScenario1 }]; [room resetBackState]; - [room paginateBackMessages:10 complete:^{ + [room paginateBackMessages:10 onlyFromStore:NO complete:^{ XCTAssertGreaterThan(eventCount, 4, @"We must have received events"); diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index c014e8de71..087593cbbc 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -277,7 +277,7 @@ - (void)testPaginateBackMessagesCancel }]; [room resetBackState]; - MXHTTPOperation *pagination = [room paginateBackMessages:100 complete:^() { + MXHTTPOperation *pagination = [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTFail(@"The cancelled operation must not complete"); [expectation fulfill]; diff --git a/MatrixSDKTests/MXStoreMemoryStoreTests.m b/MatrixSDKTests/MXStoreMemoryStoreTests.m index 7c9e991f8e..2de1a43264 100644 --- a/MatrixSDKTests/MXStoreMemoryStoreTests.m +++ b/MatrixSDKTests/MXStoreMemoryStoreTests.m @@ -200,7 +200,7 @@ - (void)testMXMemoryStorePaginate // First make a call to paginateBackMessages that will make a request to the server [room resetBackState]; - [room paginateBackMessages:100 complete:^{ + [room paginateBackMessages:100 onlyFromStore:NO complete:^{ XCTAssertEqual(firstEventInTheRoom.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); @@ -216,7 +216,7 @@ - (void)testMXMemoryStorePaginate }]; [room resetBackState]; - [room paginateBackMessages:100 complete:^{ + [room paginateBackMessages:100 onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, eventCount2); XCTAssertEqual(firstEventInTheRoom2.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); @@ -253,7 +253,7 @@ - (void)testMXMemoryStorePaginateAgain }]; [room resetBackState]; - [room paginateBackMessages:8 complete:^() { + [room paginateBackMessages:8 onlyFromStore:NO complete:^() { [room removeAllListeners]; @@ -284,11 +284,11 @@ - (void)testMXMemoryStorePaginateAgain // The several paginations [room resetBackState]; - [room paginateBackMessages:2 complete:^() { + [room paginateBackMessages:2 onlyFromStore:NO complete:^() { - [room paginateBackMessages:5 complete:^() { + [room paginateBackMessages:5 onlyFromStore:NO complete:^() { - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { // Now, compare the result with the reference XCTAssertEqual(roomEvents.count, 8); @@ -346,7 +346,7 @@ - (void)testMXMemoryStoreLastMessage [self doTestWithMXMemoryStore:^(MXRoom *room) { [room resetBackState]; - [room paginateBackMessages:8 complete:^() { + [room paginateBackMessages:8 onlyFromStore:NO complete:^() { MXEvent *lastMessage = [room lastMessageWithTypeIn:nil]; XCTAssertEqual(lastMessage.eventType, MXEventTypeRoomMessage); diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 3080e37ca1..5188f25136 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -254,7 +254,7 @@ - (void)checkPaginateBack:(MXRoom*)room }]; [room resetBackState]; - [room paginateBackMessages:5 complete:^() { + [room paginateBackMessages:5 onlyFromStore:NO complete:^() { XCTAssertEqual(eventCount, 5, @"We should get as many messages as requested"); @@ -287,7 +287,7 @@ - (void)checkPaginateBackFilter:(MXRoom*)room }]; [room resetBackState]; - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -319,7 +319,7 @@ - (void)checkPaginateBackOrder:(MXRoom*)room }]; [room resetBackState]; - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTAssertNotEqual(prev_ts, -1, "We should have received events in registerEventListenerForTypes"); @@ -343,7 +343,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room }]; [room resetBackState]; - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -367,7 +367,7 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room }]; [room resetBackState]; - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { // Use another MXRoom instance to do pagination in several times MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; @@ -386,16 +386,16 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 7); } - [room2 paginateBackMessages:2 complete:^() { + [room2 paginateBackMessages:2 onlyFromStore:NO complete:^() { if (mxSession.store.isPermanent) { XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 5); } - [room2 paginateBackMessages:5 complete:^() { + [room2 paginateBackMessages:5 onlyFromStore:NO complete:^() { - [room2 paginateBackMessages:100 complete:^() { + [room2 paginateBackMessages:100 onlyFromStore:NO complete:^() { [self assertNoDuplicate:room2Events text:@"events got one by one with testSeveralPaginateBacks"]; @@ -465,7 +465,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 7); } - [room2 paginateBackMessages:2 complete:^() { + [room2 paginateBackMessages:2 onlyFromStore:NO complete:^() { if (mxSession.store.isPermanent) { @@ -483,9 +483,9 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room } else if (3 == liveEvents) - [room2 paginateBackMessages:5 complete:^() { + [room2 paginateBackMessages:5 onlyFromStore:NO complete:^() { - [room2 paginateBackMessages:100 complete:^() { + [room2 paginateBackMessages:100 onlyFromStore:NO complete:^() { [self assertNoDuplicate:room2Events text:@"events got one by one with testSeveralPaginateBacks"]; @@ -520,7 +520,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room // Take a snapshot of all room history [room resetBackState]; - [room paginateBackMessages:100 complete:^{ + [room paginateBackMessages:100 onlyFromStore:NO complete:^{ // Messages are now in the cache // Start checking pagination from the cache @@ -540,7 +540,7 @@ - (void)checkCanPaginateFromHomeServer:(MXRoom*)room [room resetBackState]; XCTAssertTrue(room.canPaginate, @"We can always paginate at the beginning"); - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTAssertFalse(room.canPaginate, @"We must have reached the end of the pagination"); @@ -557,7 +557,7 @@ - (void)checkCanPaginateFromMXStore:(MXRoom*)room [room resetBackState]; XCTAssertTrue(room.canPaginate, @"We can always paginate at the beginning"); - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { XCTAssertFalse(room.canPaginate, @"We must have reached the end of the pagination"); @@ -578,7 +578,7 @@ - (void)checkLastMessageAfterPaginate:(MXRoom*)room MXEvent *lastMessage2 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage2.eventId, lastMessage.eventId, @"The last message should stay the same"); - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { MXEvent *lastMessage3 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage3.eventId, lastMessage.eventId, @"The last message should stay the same"); @@ -632,7 +632,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room }]; [room2 resetBackState]; - [room2 paginateBackMessages:100 complete:^{ + [room2 paginateBackMessages:100 onlyFromStore:NO complete:^{ XCTAssertEqual(events.count, 5, "The room should contain only 5 messages (the last message sent while the user is not in the room is not visible)"); [expectation fulfill]; @@ -692,7 +692,7 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room // First count how many messages to retrieve [room resetBackState]; - [room paginateBackMessages:100 complete:^() { + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { // Paginate for the exact number of events in the room NSUInteger pagEnd = eventCount; @@ -700,7 +700,7 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room [mxSession.store deleteRoom:room.state.roomId]; [room resetBackState]; - [room paginateBackMessages:pagEnd complete:^{ + [room paginateBackMessages:pagEnd onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, pagEnd, @"We should get as many messages as requested"); @@ -708,7 +708,7 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room // Try to load more messages eventCount = 0; - [room paginateBackMessages:1 complete:^{ + [room paginateBackMessages:1 onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, 0, @"There must be no more event"); XCTAssertFalse(room.canPaginate, @"SDK must now indicate there is no more event to paginate"); @@ -1079,7 +1079,7 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass MXRoom *room = [mxSession roomWithRoomId:roomId]; [room resetBackState]; - [room paginateBackMessages:10 complete:^{ + [room paginateBackMessages:10 onlyFromStore:NO complete:^{ NSString *roomPaginationToken = [store paginationTokenOfRoom:roomId]; XCTAssert(roomPaginationToken, @"The room must have a pagination after a pagination"); From fa6de2757d155f1ee0166c1cb740016ccb8cb27b Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 15 Feb 2016 10:06:32 +0100 Subject: [PATCH 13/80] Fix compilation issue due to change on kMXAPIPrefixPath --- MatrixSDKTests/MXHTTPClientTests.m | 8 ++++---- MatrixSDKTests/MXJSONModelTests.m | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MatrixSDKTests/MXHTTPClientTests.m b/MatrixSDKTests/MXHTTPClientTests.m index 5270e7bd1d..2572434d77 100644 --- a/MatrixSDKTests/MXHTTPClientTests.m +++ b/MatrixSDKTests/MXHTTPClientTests.m @@ -43,13 +43,13 @@ - (void)tearDown - (void)testMainThread { - MXHTTPClient *httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPath] + MXHTTPClient *httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPathR0] andOnUnrecognizedCertificateBlock:nil]; XCTestExpectation *expectation = [self expectationWithDescription:@"asyncTest"]; [httpClient requestWithMethod:@"GET" - path:@"api/v1/publicRooms" + path:@"publicRooms" parameters:nil success:^(NSDictionary *JSONResponse) { XCTAssertTrue([NSThread isMainThread], @"The block callback must be called from the main thread"); @@ -66,13 +66,13 @@ - (void)testMainThread { - (void)testMXError { - MXHTTPClient *httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPath] + MXHTTPClient *httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPathR0] andOnUnrecognizedCertificateBlock:nil]; XCTestExpectation *expectation = [self expectationWithDescription:@"asyncTest"]; [httpClient requestWithMethod:@"GET" - path:@"api/v1/notExistingAPI" + path:@"notExistingAPI" parameters:nil success:^(NSDictionary *JSONResponse) { XCTFail(@"The request must fail as the API path does not exist"); diff --git a/MatrixSDKTests/MXJSONModelTests.m b/MatrixSDKTests/MXJSONModelTests.m index c5f8b86205..0fafd0efcb 100644 --- a/MatrixSDKTests/MXJSONModelTests.m +++ b/MatrixSDKTests/MXJSONModelTests.m @@ -61,7 +61,7 @@ - (void)setUp { [super setUp]; - httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPath] + httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPathR0] andOnUnrecognizedCertificateBlock:nil]; } @@ -78,7 +78,7 @@ - (void)testModelFromJSON // Use publicRooms JSON response to check modelFromJSON [httpClient requestWithMethod:@"GET" - path:@"api/v1/publicRooms" + path:@"publicRooms" parameters:nil success:^(NSDictionary *JSONResponse) { From 40d77544a75b5981e165751a44eca7d657392e2c Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 15 Feb 2016 10:57:53 +0100 Subject: [PATCH 14/80] Fixed MXJSONModelTest tests after Mantle removal --- MatrixSDKTests/MXJSONModelTests.m | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/MatrixSDKTests/MXJSONModelTests.m b/MatrixSDKTests/MXJSONModelTests.m index 0fafd0efcb..fe6b6c1937 100644 --- a/MatrixSDKTests/MXJSONModelTests.m +++ b/MatrixSDKTests/MXJSONModelTests.m @@ -31,14 +31,6 @@ @implementation MXJSONModelTestClass @end -@interface MXJSONModelTestClass2 : MXJSONModel - -@property (nonatomic) NSString *foo; - -@end -@implementation MXJSONModelTestClass2 - -@end @interface MXJSONModelTestClass64Bits : MXJSONModel @@ -47,6 +39,17 @@ @interface MXJSONModelTestClass64Bits : MXJSONModel @end @implementation MXJSONModelTestClass64Bits ++ (id)modelFromJSON:(NSDictionary *)JSONDictionary +{ + MXJSONModelTestClass64Bits *o = [[MXJSONModelTestClass64Bits alloc] init]; + if (o) + { + MXJSONModelSetUInt64(o.ts, JSONDictionary[@"ts"]); + } + + return o; +} + @end @interface MXJSONModelTests : XCTestCase @@ -142,17 +145,6 @@ - (void)testRemoveNullValuesInJSON XCTAssert(((NSDictionary*)cleanDict[@"dict1"][@"dict2"]).count == 0, @"JSON null value must be removed. Found: %@", cleanDict[@"dict1"][@"dict2"]); } -- (void)testNullValue -{ - NSDictionary *JSONDict = @{ - @"foo" : [NSNull null] - }; - - MXJSONModelTestClass2 *model = [MXJSONModelTestClass2 modelFromJSON:JSONDict]; - - XCTAssertNil(model.foo, @"JSON null value must be converted to nil. Found: %@", model.foo); -} - - (void)test64BitsValue { NSDictionary *JSONDict = @{ From dba2691a73c3bc788533dae17df654c8c724daa5 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 15 Feb 2016 17:02:41 +0100 Subject: [PATCH 15/80] Fixed testModelsFromJSON test --- MatrixSDKTests/MXJSONModelTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDKTests/MXJSONModelTests.m b/MatrixSDKTests/MXJSONModelTests.m index fe6b6c1937..8899dc1ba2 100644 --- a/MatrixSDKTests/MXJSONModelTests.m +++ b/MatrixSDKTests/MXJSONModelTests.m @@ -107,7 +107,7 @@ - (void)testModelsFromJSON // Use publicRooms JSON response to check modelFromJSON [httpClient requestWithMethod:@"GET" - path:@"api/v1/publicRooms" + path:[NSString stringWithFormat:@"%@/publicRooms", kMXAPIPrefixPathR0] parameters:nil success:^(NSDictionary *JSONResponse) { From a5b4b98d6a4d495a2183f9f43956a275c84fce9c Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 16 Feb 2016 09:09:18 +0100 Subject: [PATCH 16/80] Moving to r0 API: Fix bug in joinRoom introduced by sync V2: according to the function description, the full state of the room must be known before calling the succcess callback. --- MatrixSDK/MXSession.m | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index d212140cc3..d1ae598263 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -962,10 +962,7 @@ - (MXHTTPOperation*)joinRoom:(NSString*)roomIdOrAlias }]; } - if (success) - { - success(room); - } + [self initialSyncOfRoom:theRoomId withLimit:initialSyncMessagesLimit success:success failure:failure]; } failure:failure]; } From 2050bb655ff74def4378492961069e8001ba585a Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 16 Feb 2016 09:10:19 +0100 Subject: [PATCH 17/80] Fixed testInviteByOtherInLive test: check membership before doing tests --- MatrixSDKTests/MXRoomStateTests.m | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index da751f81bd..2fbd7336b0 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -534,24 +534,27 @@ - (void)testInviteByOtherInLive newRoom = [mxSession roomWithRoomId:roomId]; XCTAssertNotNil(newRoom); - - XCTAssertEqual(newRoom.state.membership, MXMembershipInvite); - XCTAssertEqualObjects(newRoom.state.name, @"Invite test"); - - // The room must have only one member: Alice who has been invited by Bob. - // While Alice does not join the room, we cannot get more information - XCTAssertEqual(newRoom.state.members.count, 1); - - MXRoomMember *alice = [newRoom.state memberWithUserId:aliceRestClient.credentials.userId]; - XCTAssertNotNil(alice); - XCTAssertEqual(alice.membership, MXMembershipInvite); - XCTAssert([alice.originUserId isEqualToString:bobRestClient.credentials.userId], @"Wrong inviter: %@", alice.originUserId); - - // The last message should be an invite m.room.member - MXEvent *lastMessage = [newRoom lastMessageWithTypeIn:nil]; - XCTAssertEqual(lastMessage.eventType, MXEventTypeRoomMember, @"The last message should be an invite m.room.member"); - XCTAssertLessThan([[NSDate date] timeIntervalSince1970] * 1000 - lastMessage.originServerTs, 3000); + if (newRoom.state.membership != MXMembershipUnknown) + { + XCTAssertEqual(newRoom.state.membership, MXMembershipInvite); + + XCTAssertEqualObjects(newRoom.state.name, @"Invite test"); + + // The room must have only one member: Alice who has been invited by Bob. + // While Alice does not join the room, we cannot get more information + XCTAssertEqual(newRoom.state.members.count, 1); + + MXRoomMember *alice = [newRoom.state memberWithUserId:aliceRestClient.credentials.userId]; + XCTAssertNotNil(alice); + XCTAssertEqual(alice.membership, MXMembershipInvite); + XCTAssert([alice.originUserId isEqualToString:bobRestClient.credentials.userId], @"Wrong inviter: %@", alice.originUserId); + + // The last message should be an invite m.room.member + MXEvent *lastMessage = [newRoom lastMessageWithTypeIn:nil]; + XCTAssertEqual(lastMessage.eventType, MXEventTypeRoomMember, @"The last message should be an invite m.room.member"); + XCTAssertLessThan([[NSDate date] timeIntervalSince1970] * 1000 - lastMessage.originServerTs, 3000); + } } }]; From 1c9dd50297e93c23d31662c745b805c6860960ec Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 16 Feb 2016 11:55:15 +0100 Subject: [PATCH 18/80] Moving to r0 API: Fixed bug where roomId was missing from MXEvents received from sync v2 --- MatrixSDK/Data/MXRoom.m | 21 +++++++++++++------ .../Data/Store/MXFileStore/MXFileStore.m | 2 +- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 75b01aedb5..08d3524d74 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -173,6 +173,9 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // Note: We consider it is not required to clone the existing room state here, because no notification is posted for these events. for (MXEvent *event in roomSync.state.events) { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + [self handleStateEvent:event direction:MXEventDirectionSync]; } @@ -189,6 +192,9 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // They will be added at the end of the stored events, so we keep the chronologinal order. for (MXEvent *event in roomSync.timeline.events) { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + // Make room data digest the live event [self handleLiveEvent:event]; } @@ -212,6 +218,9 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // They will be added at the end of the stored events, so we keep the chronologinal order. for (MXEvent *event in roomSync.timeline.events) { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + // Make room data digest the live event [self handleLiveEvent:event]; } @@ -242,6 +251,9 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // Handle here ephemeral events (if any) for (MXEvent *event in roomSync.ephemeral.events) { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + [self handleLiveEvent:event]; } @@ -260,12 +272,9 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync event.eventId = [NSString stringWithFormat:@"%@%@", kMXRoomInviteStateEventIdPrefix, [[NSProcessInfo processInfo] globallyUniqueString]]; } - // Report the room id if not defined - if (!event.roomId) - { - event.roomId = _state.roomId; - } - + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + [self handleLiveEvent:event]; } } diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index 4b5a509219..c46a5a9b08 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -20,7 +20,7 @@ #import "MXFileStoreMetaData.h" -NSUInteger const kMXFileVersion = 19; +NSUInteger const kMXFileVersion = 20; NSString *const kMXFileStoreFolder = @"MXFileStore"; NSString *const kMXFileStoreMedaDataFile = @"MXFileStore"; From 553ecd09a7e1df8d1abad510f4fb1eeee5932e11 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 16 Feb 2016 15:51:18 +0100 Subject: [PATCH 19/80] SDK tests: Continue to use api/v1 registration while the code is not updated --- MatrixSDKTests/MXRestClientNoAuthAPITests.m | 4 ++++ MatrixSDKTests/MatrixSDKTestsData.m | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/MatrixSDKTests/MXRestClientNoAuthAPITests.m b/MatrixSDKTests/MXRestClientNoAuthAPITests.m index a469bf9104..a4d513fa33 100644 --- a/MatrixSDKTests/MXRestClientNoAuthAPITests.m +++ b/MatrixSDKTests/MXRestClientNoAuthAPITests.m @@ -51,6 +51,9 @@ - (void)tearDown { - (void)createTestAccount:(void (^)())onReady { // Register the user + // @TODO: Update the registration code to support r0 registration and + // remove this patch that redirects the registration to a deprecated CS API. + mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; [mxRestClient registerWithUser:MXTESTS_USER andPassword:MXTESTS_PWD success:^(MXCredentials *credentials) { @@ -68,6 +71,7 @@ - (void)createTestAccount:(void (^)())onReady NSAssert(NO, @"Cannot create the test account"); } }]; + mxRestClient.apiPathPrefix = kMXAPIPrefixPathR0; } - (void)testInit diff --git a/MatrixSDKTests/MatrixSDKTestsData.m b/MatrixSDKTests/MatrixSDKTestsData.m index c8c6f3b786..a38ffad1d2 100644 --- a/MatrixSDKTests/MatrixSDKTestsData.m +++ b/MatrixSDKTests/MatrixSDKTestsData.m @@ -86,6 +86,9 @@ - (void)getBobCredentials:(void (^)())success else { // First, try register the user + // @TODO: Update the registration code to support r0 registration and + // remove this patch that redirects the registration to a deprecated CS API. + mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; [mxRestClient registerWithUser:MXTESTS_BOB andPassword:MXTESTS_BOB_PWD success:^(MXCredentials *credentials) { _bobCredentials = credentials; @@ -97,6 +100,7 @@ - (void)getBobCredentials:(void (^)())success { // The user already exists. This error is normal. // Log Bob in to get his keys + mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; [mxRestClient loginWithUser:MXTESTS_BOB andPassword:MXTESTS_BOB_PWD success:^(MXCredentials *credentials) { _bobCredentials = credentials; @@ -105,12 +109,14 @@ - (void)getBobCredentials:(void (^)())success } failure:^(NSError *error) { NSAssert(NO, @"Cannot log mxBOB in"); }]; + mxRestClient.apiPathPrefix = kMXAPIPrefixPathR0; } else { NSAssert(NO, @"Cannot create mxBOB account. Make sure the homeserver at %@ is running", mxRestClient.homeserver); } }]; + mxRestClient.apiPathPrefix = kMXAPIPrefixPathR0; } } @@ -436,6 +442,9 @@ - (void)getAliceCredentials:(void (^)())success } else { + // @TODO: Update the registration code to support r0 registration and + // remove this patch that redirects the registration to a deprecated CS API. + mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; // First, try register the user [mxRestClient registerWithUser:MXTESTS_ALICE andPassword:MXTESTS_ALICE_PWD success:^(MXCredentials *credentials) { @@ -448,6 +457,7 @@ - (void)getAliceCredentials:(void (^)())success { // The user already exists. This error is normal. // Log Bob in to get his keys + mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; [mxRestClient loginWithUser:MXTESTS_ALICE andPassword:MXTESTS_ALICE_PWD success:^(MXCredentials *credentials) { _aliceCredentials = credentials; @@ -456,12 +466,14 @@ - (void)getAliceCredentials:(void (^)())success } failure:^(NSError *error) { NSAssert(NO, @"Cannot log mxAlice in"); }]; + mxRestClient.apiPathPrefix = kMXAPIPrefixPathR0; } else { NSAssert(NO, @"Cannot create mxAlice account"); } }]; + mxRestClient.apiPathPrefix = kMXAPIPrefixPathR0; } } From aa2c44d5487ffe9cbb58ef092beb8df47e5ff080 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 16 Feb 2016 16:15:57 +0100 Subject: [PATCH 20/80] SDK tests: Removed testUserNotNilAvatarUrl test as it is no more relevant (the hs does not neccessary set a user avatar) --- MatrixSDKTests/MXRestClientTests.m | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index c59594470e..acc61bc0f8 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -892,23 +892,6 @@ - (void)testOtherUserAvatarUrl }]; } -- (void)testUserNotNilAvatarUrl -{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - [bobRestClient avatarUrlForUser:nil success:^(NSString *avatarUrl) { - - XCTAssert([avatarUrl hasPrefix:@"mxc://"], @"mxBob has no avatar defined. So the home server should have allocated one on the Matrix content repository"); - [expectation fulfill]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - - }]; -} - #pragma mark - Presence operations - (void)testUserPresence From 90d1ac40fa9897a6699947e618c6015b87f66211 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 16 Feb 2016 16:37:54 +0100 Subject: [PATCH 21/80] SDK tests: Fixed testListenerForRoomMessageOnly --- MatrixSDKTests/MXSessionTests.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index c5ae4c730f..948fad6ecd 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -230,13 +230,18 @@ - (void)testListenerForRoomMessageOnly // Listen to m.room.message only // We should not see events coming before (m.room.create, and all state events) + __block NSInteger messagesCount = 0; [mxSession listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) { if (MXEventDirectionForwards == direction) { XCTAssertEqual(event.eventType, MXEventTypeRoomMessage, @"We must receive only m.room.message event - Event: %@", event); - [expectation fulfill]; + + if (++messagesCount == 5) + { + [expectation fulfill]; + } } }]; From 01d55588212f4b7a02f2b3f46d3e172ee011b88a Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 17 Feb 2016 11:44:50 +0100 Subject: [PATCH 22/80] Moving to r0 API: Bug fix on archived rooms: we have to pass received events to a room about to be left before releasing it. A SDK user may have listener to this room and may want to receive the leave membership event --- MatrixSDK/MXSession.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index d1ae598263..1f235136ac 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -699,6 +699,11 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout MXRoom *room = [self roomWithRoomId:roomId]; if (room) { + // FIXME SYNCV2: While 'handleArchivedRoomSync' is not available, + // use 'handleJoinedRoomSync' to pass the last events to the room before leaving it. + // The room will then able to notify its listeners. + [room handleJoinedRoomSync:leftRoomSync]; + // Look for the last room member event MXEvent *roomMemberEvent; NSInteger index = leftRoomSync.timeline.events.count; From 0bce4ff497fff583c50ff01d00f32c6ecb2eeba3 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 17 Feb 2016 11:54:08 +0100 Subject: [PATCH 23/80] SDK tests: Fixed [MXSessiontests testState] test according to the changes made by https://github.com/matrix-org/matrix-ios-sdk/commit/bed57bf6 --- MatrixSDKTests/MXSessionTests.m | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index 948fad6ecd..a88a86973c 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -599,13 +599,19 @@ - (void)testState XCTAssertEqual(MXSessionStatePaused, mxSession.state); [mxSession resume:^{ - XCTAssertEqual(MXSessionStateRunning, mxSession.state); - [mxSession close]; - XCTAssertEqual(MXSessionStateClosed, mxSession.state); + // As advertised the session state will be updated after the call of this block + dispatch_async(dispatch_get_main_queue(), ^{ + + XCTAssertEqual(MXSessionStateRunning, mxSession.state); + + [mxSession close]; + XCTAssertEqual(MXSessionStateClosed, mxSession.state); + + mxSession = nil; + [expectation fulfill]; + }); - mxSession = nil; - [expectation fulfill]; }]; XCTAssertEqual(MXSessionStateSyncInProgress, mxSession.state); @@ -1101,7 +1107,6 @@ - (void)testInvitedRooms XCTAssertEqual(invitedRooms.count, prevInviteCount + 1); XCTAssertNotEqual([invitedRooms indexOfObject:impactedRoom], NSNotFound, @"The room must be in the invitation list"); - XCTAssertNotNil(event.inviteRoomState, @"The event must be an invite"); testState++; @@ -1127,7 +1132,7 @@ - (void)testInvitedRooms }]; // Make Alice invite Bob in a room - [aliceRestClient createRoom:nil visibility:kMXRoomVisibilityPrivate roomAlias:nil topic:nil success:^(MXCreateRoomResponse *response) { + [aliceRestClient createRoom:@"A room name" visibility:kMXRoomVisibilityPrivate roomAlias:nil topic:nil success:^(MXCreateRoomResponse *response) { testRoomId = response.roomId; From 9ecb1646c41dcaa10b653cf8c088d9e774c12761 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 17 Feb 2016 15:23:25 +0100 Subject: [PATCH 24/80] Tag: ordering bug fix: do as the web client: a tagged room with no order value has higher priority than the tagged rooms with order values --- MatrixSDK/MXSession.m | 4 ++-- MatrixSDKTests/MXSessionTests.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 1f235136ac..ea72cc393b 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -1603,11 +1603,11 @@ - (NSComparisonResult)compareRoomsByTag:(NSString*)tag room1:(MXRoom*)room1 room } else if (tag1.order) { - result = NSOrderedAscending; + result = NSOrderedDescending; } else if (tag2.order) { - result = NSOrderedDescending; + result = NSOrderedAscending; } // In case of same order, order rooms by their last event diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index a88a86973c..dc71ac20b9 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -894,12 +894,12 @@ - (void)testRoomByTagsOrderWithStringTagOrder - (void)testRoomByTagsOrderWithFloatTagOrder { - [self doRoomByTagsOrderTest:self withOrder1:@"0.2" order2:@"0.9" order3:nil]; + [self doRoomByTagsOrderTest:self withOrder1:nil order2:@"0.2" order3:@"0.9"]; } - (void)testRoomByTagsOrderWithFloatAndStringTagOrder { - [self doRoomByTagsOrderTest:self withOrder1:@"0.9" order2:@"apples" order3:nil]; + [self doRoomByTagsOrderTest:self withOrder1:nil order2:@"0.9" order3:@"apples"]; } - (void)testTagRoomsWithSameOrder From 1f7b739f89dc895885f14884121d7be764afd771 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 17 Feb 2016 15:57:16 +0100 Subject: [PATCH 25/80] [MXRoomTag roomTagsWithTagEvent]: Fixed weird systematic conversion of tag order into a number. This bug made [MXStoreTests checkRoomAccountDataTags] test fail --- MatrixSDK/JSONModels/MXJSONModels.m | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index d621d7e6a7..0b71685ed4 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -211,30 +211,27 @@ - (id)initWithName:(NSString *)name andOrder:(NSString *)order + (NSDictionary *)roomTagsWithTagEvent:(MXEvent *)event { - NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; - [formatter setMaximumFractionDigits:16]; - [formatter setMinimumFractionDigits:0]; - [formatter setDecimalSeparator:@"."]; - [formatter setGroupingSeparator:@""]; - NSMutableDictionary *tags = [NSMutableDictionary dictionary]; for (NSString *tagName in event.content[@"tags"]) { - NSString *order; + NSString *order = event.content[@"tags"][tagName][@"order"]; // Be robust if the server sends an integer tag order - if ([event.content[@"tags"][tagName][@"order"] isKindOfClass:NSNumber.class]) + // Do some cleaning if the order is a number (and do nothing if the order is a string) + if ([order isKindOfClass:NSNumber.class]) { - NSLog(@"[MXRoomTag] Warning: the room tag order is an integer value not a string in this event: %@", event); + NSLog(@"[MXRoomTag] Warning: the room tag order is an number value not a string in this event: %@", event); + + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + [formatter setMaximumFractionDigits:16]; + [formatter setMinimumFractionDigits:0]; + [formatter setDecimalSeparator:@"."]; + [formatter setGroupingSeparator:@""]; + order = [formatter stringFromNumber:event.content[@"tags"][tagName][@"order"]]; - } - else - { - order = event.content[@"tags"][tagName][@"order"]; - + if (order) { - // Do some cleaning if the order is a number (and do nothing if the order is a string) NSNumber *value = [formatter numberFromString:order]; if (!value) { @@ -243,7 +240,7 @@ - (id)initWithName:(NSString *)name andOrder:(NSString *)order value = [formatter numberFromString:order]; [formatter setDecimalSeparator:@"."]; } - + if (value) { // remove trailing 0 From 384792a15624fa645577f1542ef77ecd9e9fe8f9 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 17 Feb 2016 16:25:06 +0100 Subject: [PATCH 26/80] Moving to r0 API: Removed tests on [MXRestClient initialSyncWithLimit] and [MXRestClient eventsFromToken] as the methods do not exist anymore --- MatrixSDKTests/MXRestClientTests.m | 204 ----------------------------- 1 file changed, 204 deletions(-) diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index acc61bc0f8..63e4e74d8a 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -543,150 +543,6 @@ - (void) removeAgeField:(MXRoomInitialSync*)roomInitialSync } } -// Compare the result of initialSyncOfRoom with the data retrieved from a global initialSync -- (void)testInitialSyncOfRoomAndGlobalInitialSync -{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - - [bobRestClient initialSyncWithLimit:3 success:^(MXInitialSyncResponse *initialSyncResponse) { - - MXRoomInitialSync *roomDataInGlobal; - - for (MXRoomInitialSync *roomSync in initialSyncResponse.rooms) - { - if ([roomId isEqualToString:roomSync.roomId]) - { - roomDataInGlobal = roomSync; - } - } - - XCTAssertNotNil(roomDataInGlobal); - - [bobRestClient initialSyncOfRoom:roomId withLimit:3 success:^(MXRoomInitialSync *roomInitialSync) { - - XCTAssertNotNil(roomInitialSync); - - // Do some cleaning before comparison - // Remove presence from initialSyncOfRoom result - roomInitialSync.presence = nil; - - // Remove new added field receipts from initialSyncOfRoom result - roomInitialSync.receipts = nil; - - // Remove visibility from global initialSync - roomDataInGlobal.visibility = nil; - - // Remove the `age` field which is time dynamic - [self removeAgeField:roomDataInGlobal]; - [self removeAgeField:roomInitialSync]; - - // Do the comparison - XCTAssertEqualObjects(roomDataInGlobal, roomInitialSync); - - [expectation fulfill]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - }]; -} - -- (void)testInitialSyncOfRoomAndGlobalInitialSyncOnRoomWithTwoUsers -{ - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; - [sharedData doMXRestClientTestWithBobAndAliceInARoom:self - readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { - - [sharedData for:bobRestClient andRoom:roomId sendMessages:5 success:^{ - [bobRestClient leaveRoom:roomId success:^{ - [aliceRestClient sendTextMessageToRoom:roomId text:@"Hi bob" success:^(NSString *eventId) { - [aliceRestClient inviteUser:bobRestClient.credentials.userId toRoom:roomId success:^{ - [bobRestClient joinRoom:roomId success:^(NSString *theRoomId) { - - [bobRestClient initialSyncWithLimit:10 success:^(MXInitialSyncResponse *initialSyncResponse) { - - MXRoomInitialSync *roomDataInGlobal; - - for (MXRoomInitialSync *roomSync in initialSyncResponse.rooms) - { - if ([roomId isEqualToString:roomSync.roomId]) - { - roomDataInGlobal = roomSync; - } - } - - XCTAssertNotNil(roomDataInGlobal); - - [bobRestClient initialSyncOfRoom:roomId withLimit:10 success:^(MXRoomInitialSync *roomInitialSync) { - - XCTAssertNotNil(roomInitialSync); - - // Do some cleaning before comparison - // Remove presence from initialSyncOfRoom result - roomInitialSync.presence = nil; - - // Remove new added field receipts from initialSyncOfRoom result - roomInitialSync.receipts = nil; - - // Remove visibility from global initialSync - roomDataInGlobal.visibility = nil; - - // Remove the `age` field which is time dynamic - [self removeAgeField:roomDataInGlobal]; - [self removeAgeField:roomInitialSync]; - - // Do the comparison - XCTAssertEqualObjects(roomDataInGlobal, roomInitialSync); - - //[expectation fulfill]; - - [bobRestClient messagesForRoom:roomId from:roomDataInGlobal.messages.start to:nil limit:1 success:^(MXPaginationResponse *paginatedResponse) { - - //NSLog(@"%@", JSONData[@"messages"][@"chunk"]); - NSLog(@"%@", roomDataInGlobal.messages.chunk); - NSLog(@"-------"); - NSLog(@"%@", paginatedResponse.chunk); - - [expectation fulfill]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - - } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); - }]; - } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); - }]; - }failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); - }]; - } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); - }]; - }]; - }]; -} - - - (void)testMXRoomMemberEventContent { [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -929,66 +785,6 @@ - (void)testUserPresence } -#pragma mark - Event operations -- (void)testEventsFromTokenServerTimeout -{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - // Delay the test to filter out Bob presence events the HS can send due to requests made in doMXRestClientTestWithBob - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - - NSDate *refDate = [NSDate date]; - [bobRestClient eventsFromToken:@"END" serverTimeout:1000 clientTimeout:40000 success:^(MXPaginationResponse *paginatedResponse) { - - XCTAssertNotNil(paginatedResponse); - - // Check expected response params - XCTAssertNotNil(paginatedResponse.start); - XCTAssertNotNil(paginatedResponse.end); - XCTAssertNotNil(paginatedResponse.chunk); - XCTAssertEqual(paginatedResponse.chunk.count, 0, @"Events should not come in this short stream time (1s)"); - - if (paginatedResponse.chunk.count) { - NSLog(@"####"); - } - - NSDate *now = [NSDate date]; - XCTAssertLessThanOrEqual([now timeIntervalSinceDate:refDate], 2, @"The HS did not timeout as expected"); // Give 2s for the HS to timeout - - [expectation fulfill]; - - } failure:^(NSError *error) { - XCTFail(@"The request should not fail - NSError: %@", error); - [expectation fulfill]; - }]; - }); - }]; -} - -- (void)testEventsFromTokenClientTimeout -{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - NSDate *refDate = [NSDate date]; - - [bobRestClient eventsFromToken:@"END" serverTimeout:5000 clientTimeout:1000 success:^(MXPaginationResponse *paginatedResponse) { - - XCTFail(@"The request must fail. The client timeout should have fired"); - [expectation fulfill]; - - } failure:^(NSError *error) { - - XCTAssertEqual(error.code, NSURLErrorTimedOut); - - NSDate *now = [NSDate date]; - XCTAssertLessThanOrEqual([now timeIntervalSinceDate:refDate], 2, @"The SDK did not timeout as expected"); // Give 2s for the SDK MXRestClient to timeout - - [expectation fulfill]; - }]; - }]; -} - - #pragma mark - Content upload - (void)testUrlOfContent { From 4b1728ccdf8ef8076f1833e0b846459099ab02ab Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 17 Feb 2016 18:04:57 +0100 Subject: [PATCH 27/80] Moving to r0 API: Removed [MXSession handleLiveEvents]. It was dead code --- MatrixSDK/MXSession.m | 123 ------------------------------------------ 1 file changed, 123 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index ea72cc393b..bcb1566eb9 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -329,129 +329,6 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit } } -- (void)handleLiveEvents:(NSArray*)events -{ - for (MXEvent *event in events) - { - @autoreleasepool - { - switch (event.eventType) - { - case MXEventTypePresence: - { - [self handlePresenceEvent:event direction:MXEventDirectionForwards]; - break; - } - - case MXEventTypeReceipt: - { - if (event.roomId) - { - MXRoom *room = [self roomWithRoomId:event.roomId]; - if (room) - { - [room handleLiveEvent:event]; - } - else - { - NSLog(@"[MXSession] Warning: Received a receipt notification for an unknown room: %@. Event: %@", event.roomId, event); - } - } - break; - } - - case MXEventTypeTypingNotification: - { - if (event.roomId) - { - MXRoom *room = [self roomWithRoomId:event.roomId]; - if (room) - { - [room handleLiveEvent:event]; - } - else - { - NSLog(@"[MXSession] Warning: Received a typing notification for an unknown room: %@. Event: %@", event.roomId, event); - } - } - break; - } - - case MXEventTypeRoomTag: - { - if (event.roomId) - { - MXRoom *room = [self roomWithRoomId:event.roomId]; - [room handleAccounDataEvents:@[event] direction:MXEventDirectionForwards]; - } - break; - } - - default: - if (event.roomId) - { - // Check join membership event in order to get the full state of the room - if (MXEventTypeRoomMember == event.eventType && NO == [self isRoomInitialSyncing:event.roomId]) - { - MXMembership roomMembership = MXMembershipUnknown; - MXRoom *room = [self roomWithRoomId:event.roomId]; - if (room) - { - roomMembership = room.state.membership; - } - - if (MXMembershipUnknown == roomMembership || MXMembershipInvite == roomMembership) - { - MXRoomMemberEventContent *roomMemberContent = [MXRoomMemberEventContent modelFromJSON:event.content]; - if (MXMembershipJoin == [MXTools membership:roomMemberContent.membership]) - { - // If we receive this event while [MXSession joinRoom] has not been called, - // it means the join has been done by another device. We need to make an initialSync on the room - // to get a valid room state. - // For info, a user can get the full state of the room only when he has joined the room. So it is - // the right timing to do it. - // SDK client will be notified when the full state is available thanks to `kMXRoomInitialSyncNotification`. - NSLog(@"[MXSession] Make a initialSyncOfRoom as the room seems to be joined from another device or MXSession. This also happens when creating a room: the HS autojoins the creator. Room: %@", event.roomId); - [self initialSyncOfRoom:event.roomId withLimit:10 success:nil failure:nil]; - } - } - } - - // Prepare related room - MXRoom *room = [self getOrCreateRoom:event.roomId withInitialSync:nil notify:YES]; - BOOL isOneToOneRoom = (!room.state.isPublic && room.state.members.count == 2); - - // Make room data digest the event - [room handleLiveEvent:event]; - - // Update one-to-one room dictionary - if (isOneToOneRoom || (!room.state.isPublic && room.state.members.count == 2)) - { - [self handleOneToOneRoom:room]; - } - - // Remove the room from the rooms list if the user has been kicked or banned - if (MXEventTypeRoomMember == event.eventType) - { - if (MXMembershipLeave == room.state.membership || MXMembershipBan == room.state.membership) - { - // Notify the room is going to disappear - [[NSNotificationCenter defaultCenter] postNotificationName:kMXSessionWillLeaveRoomNotification - object:self - userInfo:@{ - kMXSessionNotificationRoomIdKey: event.roomId, - kMXSessionNotificationEventKey: event - }]; - [self removeRoom:event.roomId]; - } - } - } - break; - } - } - } -} - - (void)handlePresenceEvent:(MXEvent *)event direction:(MXEventDirection)direction { // Update MXUser with presence data From 33c521847379010bf87c479d6a3be0235dba77f7 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 09:12:53 +0100 Subject: [PATCH 28/80] Moving to r0 API: Removed the usage of /initialSync for a room when creating or joining a room. With v2, we receive the data from /sync. There is no need to get it twice --- MatrixSDK/MXSession.m | 171 +++++++++++++----------------------------- 1 file changed, 51 insertions(+), 120 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index bcb1566eb9..bd59e32bb4 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -106,11 +106,6 @@ The list of global events listeners (`MXSessionEventListener`). */ MXOnBackgroundSyncFail onBackgroundSyncFail; - /** - The list of rooms ids where a room initialSync is in progress (made by [self initialSyncOfRoom]) - */ - NSMutableArray *roomsInInitialSyncing; - /** The maintained list of rooms where the user has a pending invitation. */ @@ -131,7 +126,6 @@ - (id)initWithMatrixRestClient:(MXRestClient*)mxRestClient users = [NSMutableDictionary dictionary]; oneToOneRooms = [NSMutableDictionary dictionary]; globalEventListeners = [NSMutableArray array]; - roomsInInitialSyncing = [NSMutableArray array]; _notificationCenter = [[MXNotificationCenter alloc] initWithMatrixSession:self]; // By default, load presence data in parallel if a full initialSync is not required @@ -462,10 +456,6 @@ - (void)close [oneToOneRooms removeAllObjects]; - // Clean list of rooms being sync'ed - [roomsInInitialSyncing removeAllObjects]; - roomsInInitialSyncing = nil; - // Clean notification center [_notificationCenter removeAllListeners]; _notificationCenter = nil; @@ -821,7 +811,32 @@ - (MXHTTPOperation*)createRoom:(NSString*)name { return [matrixRestClient createRoom:name visibility:visibility roomAlias:roomAlias topic:topic success:^(MXCreateRoomResponse *response) { - [self initialSyncOfRoom:response.roomId withLimit:initialSyncMessagesLimit success:success failure:failure]; + // Wait to receive data from /sync about this room before returning + if (success) + { + MXRoom *room = [self roomWithRoomId:response.roomId]; + if (room) + { + // The first /sync response for this room may have happened before the + // homeserver answer to the createRoom request. + success(room); + } + else + { + // Else, just wait for the corresponding kMXRoomInitialSyncNotification + // that will be fired from MXRoom. + __block id initialSyncObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomInitialSyncNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + + MXRoom *room = note.object; + + if ([room.state.roomId isEqualToString:response.roomId]) + { + success(room); + [[NSNotificationCenter defaultCenter] removeObserver:initialSyncObserver]; + } + }]; + } + } } failure:failure]; } @@ -844,7 +859,31 @@ - (MXHTTPOperation*)joinRoom:(NSString*)roomIdOrAlias }]; } - [self initialSyncOfRoom:theRoomId withLimit:initialSyncMessagesLimit success:success failure:failure]; + // Wait to receive data from /sync about this room before returning + if (success) + { + if (room.state.membership == MXMembershipJoin) + { + // The /sync corresponding to this join fmay have happened before the + // homeserver answer to the joinRoom request. + success(room); + } + else + { + // Else, just wait for the corresponding kMXRoomInitialSyncNotification + // that will be fired from MXRoom. + __block id initialSyncObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomInitialSyncNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + + MXRoom *syncedRoom = note.object; + + if (syncedRoom == room) + { + success(room); + [[NSNotificationCenter defaultCenter] removeObserver:initialSyncObserver]; + } + }]; + } + } } failure:failure]; } @@ -884,114 +923,6 @@ - (MXHTTPOperation*)leaveRoom:(NSString*)roomId } -#pragma mark - Initial sync per room -- (MXHTTPOperation*)initialSyncOfRoom:(NSString*)roomId - withLimit:(NSInteger)limit - success:(void (^)(MXRoom *room))success - failure:(void (^)(NSError *error))failure -{ - [roomsInInitialSyncing addObject:roomId]; - - // Do an initial sync to get state and messages in the room - return [matrixRestClient initialSyncOfRoom:roomId withLimit:limit success:^(MXRoomInitialSync *roomInitialSync) { - - if (MXSessionStateClosed == _state) - { - // Do not go further if the session is closed - return; - } - - NSString *theRoomId = roomInitialSync.roomId; - - // Clean the store for this room - if (![_store respondsToSelector:@selector(rooms)] || [_store.rooms indexOfObject:theRoomId] != NSNotFound) - { - NSLog(@"[MXSession] initialSyncOfRoom clean the store (%@).", theRoomId); - [_store deleteRoom:theRoomId]; - } - - // Retrieve an existing room or create a new one. - MXRoom *room = [self getOrCreateRoom:theRoomId withInitialSync:roomInitialSync notify:YES]; - - // Manage room messages - if (roomInitialSync.messages) - { - [room handleMessages:roomInitialSync.messages direction:MXEventDirectionSync isTimeOrdered:YES]; - - // Uncomment the following lines when SYN-482 will be fixed -// // If the initialSync returns less messages than requested, we got all history from the home server -// if (roomInitialSync.messages.chunk.count < limit) -// { -// [_store storeHasReachedHomeServerPaginationEndForRoom:room.state.roomId andValue:YES]; -// } - } - - // Manage room state - if (roomInitialSync.state) - { - [room handleStateEvents:roomInitialSync.state direction:MXEventDirectionSync]; - - if (!room.state.isPublic && room.state.members.count == 2) - { - // Update one-to-one room dictionary - [self handleOneToOneRoom:room]; - } - } - - // Manage the private data that this user has attached to this room - if (roomInitialSync.accountData) - { - [room handleAccounDataEvents:roomInitialSync.accountData direction:MXEventDirectionForwards]; - } - - // Manage presence provided by this API - for (MXEvent *presenceEvent in roomInitialSync.presence) - { - [self handlePresenceEvent:presenceEvent direction:MXEventDirectionSync]; - } - - // Manage receipts provided by this API - for (MXEvent *receiptEvent in roomInitialSync.receipts) - { - [room handleReceiptEvent:receiptEvent direction:MXEventDirectionSync]; - } - -// // init the receips to the latest received one. -// [room acknowledgeLatestEvent:NO]; - - // Commit store changes done in [room handleMessages] - if ([_store respondsToSelector:@selector(commit)]) - { - [_store commit]; - } - - [roomsInInitialSyncing removeObject:roomId]; - - // Notify that room has been sync'ed - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomInitialSyncNotification - object:room - userInfo:nil]; - if (success) - { - success(room); - } - - } failure:^(NSError *error) { - NSLog(@"[MXSession] initialSyncOfRoom failed for room %@. Error: %@", roomId, error); - - if (failure) - { - failure(error); - } - }]; -} - -- (BOOL)isRoomInitialSyncing:(NSString*)roomId -{ - return (NSNotFound != [roomsInInitialSyncing indexOfObject:roomId]); -} - - #pragma mark - The user's rooms - (MXRoom *)roomWithRoomId:(NSString *)roomId { From a582d552880b751601a95656eff1c2dfe5a103b3 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 11:05:14 +0100 Subject: [PATCH 29/80] Moving to r0 API: Updated comments to remove the v2 term --- MatrixSDK/Data/MXRoom.h | 8 ++++---- MatrixSDK/Data/MXRoom.m | 2 +- MatrixSDK/JSONModels/MXJSONModels.h | 14 +++++++------- MatrixSDK/MXRestClient.h | 22 +++------------------- MatrixSDK/MXRestClient.m | 11 ----------- MatrixSDK/MXSession.m | 2 +- 6 files changed, 16 insertions(+), 43 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 41233698fd..f5c64ba9c4 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -38,7 +38,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomInitialSyncNotification; /** - Posted when a limited timeline is observed for an existing room during server sync v2. + Posted when a limited timeline is observed for an existing room during server sync. All the existing messages have been removed from the room storage. Only the messages received during this sync are available. The token where to start back pagination has been updated. @@ -120,17 +120,17 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom - (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession andStateEvents:(NSArray*)stateEvents andAccountData:(MXRoomAccountData*)accountData; -#pragma mark - server sync v2 +#pragma mark - server sync /** - Update room data according to the provided sync response (since API v2) + Update room data according to the provided sync response. @param roomSync information to sync the room with the home server data */ - (void)handleJoinedRoomSync:(MXRoomSync*)roomSync; /** - Update the invited room state according to the provided data (since API v2) + Update the invited room state according to the provided data. @param invitedRoom information to update the room state. */ diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 08d3524d74..7d52dd6ef6 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -154,7 +154,7 @@ - (BOOL)canPaginate || ![mxSession.store hasReachedHomeServerPaginationEndForRoom:_state.roomId]; } -#pragma mark - sync v2 +#pragma mark - Sync - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync { diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index f79bc341bc..84e8e5325a 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -844,7 +844,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXRoomSyncState` represents the state updates for a room during server sync v2. + `MXRoomSyncState` represents the state updates for a room during server sync. */ @interface MXRoomSyncState : MXJSONModel @@ -856,7 +856,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXRoomSyncTimeline` represents the timeline of messages and state changes for a room during server sync v2. + `MXRoomSyncTimeline` represents the timeline of messages and state changes for a room during server sync. */ @interface MXRoomSyncTimeline : MXJSONModel @@ -914,7 +914,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXRoomSync` represents the response for a room during server sync v2. + `MXRoomSync` represents the response for a room during server sync. */ @interface MXRoomSync : MXJSONModel @@ -941,7 +941,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXInvitedRoomSync` represents a room invitation during server sync v2. + `MXInvitedRoomSync` represents a room invitation during server sync. */ @interface MXInvitedRoomSync : MXJSONModel @@ -957,7 +957,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXRoomsSyncResponse` represents the rooms list in server sync v2 response. + `MXRoomsSyncResponse` represents the rooms list in server sync response. */ @interface MXRoomsSyncResponse : MXJSONModel @@ -979,7 +979,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXPresenceSyncResponse` represents the updates to the presence status of other users during server sync v2. + `MXPresenceSyncResponse` represents the updates to the presence status of other users during server sync. */ @interface MXPresenceSyncResponse : MXJSONModel @@ -991,7 +991,7 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end /** - `MXSyncResponse` represents the request response for server sync v2. + `MXSyncResponse` represents the request response for server sync. */ @interface MXSyncResponse : MXJSONModel diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index dceba26566..d9621e4bb4 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -88,22 +88,6 @@ typedef enum : NSUInteger MXThumbnailingMethodCrop } MXThumbnailingMethod; -/** - `MXRestClientAPIVersion` lists the existing C-S API versions. - */ -typedef enum : NSUInteger -{ - /** - C-S API V1. - */ - MXRestClientAPIVersion1, - - /** - C-S API V2. - */ - MXRestClientAPIVersion2 - -} MXRestClientAPIVersion; /** `MXRestClient` makes requests to Matrix servers. @@ -778,7 +762,7 @@ typedef enum : NSUInteger @param limit the maximum number of messages to return. @param success A block object called when the operation succeeds. It provides the model created from - the home server JSON response. @see http://matrix.org/docs/api/client-server/#!/-rooms/get_room_sync_data) + the home server JSON response. @see http://matrix.org/docs/api/client-server/#!/-rooms/get_room_sync_data @param failure A block object called when the operation fails. @return a MXHTTPOperation instance. @@ -930,7 +914,7 @@ typedef enum : NSUInteger #pragma mark - Sync /** - Synchronise the client's state and receive new messages. Based on server sync C-S v2 API. + Synchronise the client's state and receive new messages. Synchronise the client's state with the latest state on the server. Client's use this API when they first log in to get an initial snapshot @@ -1154,7 +1138,7 @@ typedef enum : NSUInteger #pragma mark - read receipts /** - Send a read receipt (available only on C-S v2). + Send a read receipt. @param roomId the id of the room. @param eventId the id of the event. diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 889b3102e6..3b5e8c18b3 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -1948,17 +1948,6 @@ - (MXHTTPOperation *)syncFromToken:(NSString*)token #pragma mark - read receipts -/** - Send a read receipt (available only on C-S v2). - - @param roomId the id of the room. - @param eventId the id of the event. - @param success A block object called when the operation succeeds. It returns - the event id of the event generated on the home server - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. - */ - (MXHTTPOperation*)sendReadReceipts:(NSString*)roomId eventId:(NSString*)eventId success:(void (^)(NSString *eventId))success diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index bd59e32bb4..54d064376e 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -473,7 +473,7 @@ - (void)close [self setState:MXSessionStateClosed]; } -#pragma mark - server sync v2 +#pragma mark - Server sync - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout success:(void (^)())success From 4dccc542437d2f3cc464ddbb6f2cc2764a883f5b Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 11:07:03 +0100 Subject: [PATCH 30/80] Moving to r0 API: MXSession.loadPresenceBeforeCompletingSessionStart has no more meaning with v2 --- MatrixSDK/MXSession.h | 15 --------------- MatrixSDK/MXSession.m | 3 --- 2 files changed, 18 deletions(-) diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index 8c079ecf7c..4561496ed6 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -302,21 +302,6 @@ typedef void (^MXOnBackgroundSyncFail)(NSError *error); - (void)setStore:(id)store success:(void (^)())onStoreDataReady failure:(void (^)(NSError *error))failure; -/** - This property is used only in case of server sync v1. It is deprecated for server sync v2 and later. - - When the SDK starts on data stored in MXStore, this option indicates if it must load - users presences information before calling the `onServerSyncDone` block of [MXSession start]. - - This requires to make a request to the home server which can be useless for some applications. - - If `loadPresenceBeforeCompletingSessionStart` is set to NO, the request will be done but it parralel - with the call of the `onServerSyncDone` block. - - Default is NO. - */ -@property (nonatomic) BOOL loadPresenceBeforeCompletingSessionStart; - /** Enable VoIP by setting the external VoIP stack to use. diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 54d064376e..9cfd112500 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -127,9 +127,6 @@ - (id)initWithMatrixRestClient:(MXRestClient*)mxRestClient oneToOneRooms = [NSMutableDictionary dictionary]; globalEventListeners = [NSMutableArray array]; _notificationCenter = [[MXNotificationCenter alloc] initWithMatrixSession:self]; - - // By default, load presence data in parallel if a full initialSync is not required - _loadPresenceBeforeCompletingSessionStart = NO; [self setState:MXSessionStateInitialised]; } From 650a7e80e88f66edfc41ef9f2f9791bd6ed02174 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 13:30:42 +0100 Subject: [PATCH 31/80] Moving to r0 API: event userId has been replaced by sender --- MatrixSDK/JSONModels/MXEvent.h | 7 +------ MatrixSDK/JSONModels/MXEvent.m | 7 ------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/MatrixSDK/JSONModels/MXEvent.h b/MatrixSDK/JSONModels/MXEvent.h index 028309395e..a7377be3c2 100644 --- a/MatrixSDK/JSONModels/MXEvent.h +++ b/MatrixSDK/JSONModels/MXEvent.h @@ -166,15 +166,10 @@ typedef enum : NSUInteger @property (nonatomic) NSString *roomId; /** - Contains the fully-qualified ID of the user who sent this event (since API v2). + Contains the fully-qualified ID of the user who sent this event. */ @property (nonatomic) NSString *sender; -/** -Contains the fully-qualified ID of the user who sent this event (deprecated since API v2). - */ -@property (nonatomic) NSString *userId; - /** The event content. The keys in this dictionary depend on the event type. diff --git a/MatrixSDK/JSONModels/MXEvent.m b/MatrixSDK/JSONModels/MXEvent.m index 4a1309d41f..43269465c2 100644 --- a/MatrixSDK/JSONModels/MXEvent.m +++ b/MatrixSDK/JSONModels/MXEvent.m @@ -96,7 +96,6 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary MXJSONModelSetString(event.type, JSONDictionary[@"type"]); MXJSONModelSetString(event.roomId, JSONDictionary[@"room_id"]); MXJSONModelSetString(event.sender, JSONDictionary[@"sender"]); - MXJSONModelSetString(event.userId, JSONDictionary[@"user_id"]); MXJSONModelSetDictionary(event.content, JSONDictionary[@"content"]); MXJSONModelSetString(event.stateKey, JSONDictionary[@"state_key"]); MXJSONModelSetUInt64(event.originServerTs, JSONDictionary[@"origin_server_ts"]); @@ -154,11 +153,6 @@ - (void)finalise self.sender = self.content[@"user_id"]; } } - else if (nil == self.sender) - { - // Catch up the legacy field user_id (deprecated in v2) - self.sender = self.userId; - } // Clean JSON data by removing all null values _content = [MXJSONModel removeNullValuesInJSON:_content]; @@ -206,7 +200,6 @@ - (NSDictionary *)JSONDictionary JSONDictionary[@"type"] = _type; JSONDictionary[@"room_id"] = _roomId; JSONDictionary[@"sender"] = _sender; - JSONDictionary[@"user_id"] = _userId; JSONDictionary[@"content"] = _content; JSONDictionary[@"state_key"] = _stateKey; JSONDictionary[@"origin_server_ts"] = @(_originServerTs); From ae05dad6b9ac62e31bdc5ff31f55f55327bdf559 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 14:18:53 +0100 Subject: [PATCH 32/80] Moving to r0 API: [MXSession getOrCreateRoom:::] the withInitialSync is now useless --- MatrixSDK/MXSession.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 9cfd112500..5b59a1f2c5 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -844,7 +844,7 @@ - (MXHTTPOperation*)joinRoom:(NSString*)roomIdOrAlias { return [matrixRestClient joinRoom:roomIdOrAlias success:^(NSString *theRoomId) { - MXRoom *room = [self getOrCreateRoom:theRoomId withInitialSync:nil notify:YES]; + MXRoom *room = [self getOrCreateRoom:theRoomId notify:YES]; // check if the room is in the invited rooms list if ([self removeInvitedRoom:room]) @@ -960,19 +960,19 @@ - (MXRoom *)privateOneToOneRoomWithUserId:(NSString*)userId return nil; } -- (MXRoom *)getOrCreateRoom:(NSString *)roomId withInitialSync:(MXRoomInitialSync*)initialSync notify:(BOOL)notify +- (MXRoom *)getOrCreateRoom:(NSString *)roomId notify:(BOOL)notify { MXRoom *room = [self roomWithRoomId:roomId]; if (nil == room) { - room = [self createRoom:roomId withInitialSync:initialSync notify:notify]; + room = [self createRoom:roomId notify:notify]; } return room; } -- (MXRoom *)createRoom:(NSString *)roomId withInitialSync:(MXRoomInitialSync*)initialSync notify:(BOOL)notify +- (MXRoom *)createRoom:(NSString *)roomId notify:(BOOL)notify { - MXRoom *room = [[MXRoom alloc] initWithRoomId:roomId andMatrixSession:self andInitialSync:initialSync]; + MXRoom *room = [[MXRoom alloc] initWithRoomId:roomId andMatrixSession:self]; [self addRoom:room notify:notify]; return room; From d8ee3a9befc5e653d22a883c864d5eccddc98375 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 15:26:07 +0100 Subject: [PATCH 33/80] Moving to r0 API: MXRoomState: get room visibility from the join_rules event instead of the visibility field of initialSync. --- MatrixSDK/Data/MXRoomState.m | 61 ++++++------------------------------ 1 file changed, 9 insertions(+), 52 deletions(-) diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index 29faeca02d..655a90f3ad 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -38,12 +38,6 @@ @interface MXRoomState () */ MXMembership membership; - // The visibility flag in JSON metadata deprecated in API v2 - MXRoomVisibility visibility; - - // YES when the property 'isPublic' has been defined. - BOOL isVisibilityKnown; - /** Maximum power level observed in power level list */ @@ -99,10 +93,6 @@ - (id)initWithRoomId:(NSString*)roomId // Store optional metadata if (initialSync) { - if (initialSync.visibility) - { - visibility = initialSync.visibility; - } if (initialSync.membership) { membership = [MXTools membership:initialSync.membership]; @@ -179,48 +169,21 @@ - (NSArray *)members return [thirdPartyInvites allValues]; } -- (void)setIsPublic:(BOOL)isPublicValue -{ - isPublic = isPublicValue; - isVisibilityKnown = YES; -} - - (BOOL)isPublic { - if (isVisibilityKnown) - { - return isPublic; - } - - // Check the legacy visibility metadata - if (visibility) - { - if ([visibility isEqualToString:kMXRoomVisibilityPublic]) - { - self.isPublic = YES; - } - else - { - self.isPublic = NO; - } - } - else + // The information is in the join_rule state event + isPublic = NO; + MXEvent *event = [stateEvents objectForKey:kMXEventTypeStringRoomJoinRules]; + if (event && [self contentOfEvent:event]) { - isPublic = NO; - - // Check this in the room state events - MXEvent *event = [stateEvents objectForKey:kMXEventTypeStringRoomJoinRules]; - if (event && [self contentOfEvent:event]) + NSString *join_rule; + MXJSONModelSetString(join_rule, [self contentOfEvent:event][@"join_rule"]); + if ([join_rule isEqualToString:kMXRoomVisibilityPublic]) { - NSString *join_rule; - MXJSONModelSetString(join_rule, [self contentOfEvent:event][@"join_rule"]); - if ([join_rule isEqualToString:kMXRoomVisibilityPublic]) - { - isPublic = YES; - } + isPublic = YES; } } - + return isPublic; } @@ -655,12 +618,6 @@ - (id)copyWithZone:(NSZone *)zone stateCopy->thirdPartyInvites = [[NSMutableDictionary allocWithZone:zone] initWithDictionary:thirdPartyInvites]; stateCopy->membersWithThirdPartyInviteTokenCache= [[NSMutableDictionary allocWithZone:zone] initWithDictionary:membersWithThirdPartyInviteTokenCache]; - - if (visibility) - { - stateCopy->visibility = [visibility copyWithZone:zone]; - } - stateCopy->isVisibilityKnown = isVisibilityKnown; stateCopy->isPublic = isPublic; stateCopy->membership = membership; From 74eb2e3c927777017591badaa7979751a480dcf4 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 15:26:55 +0100 Subject: [PATCH 34/80] Moving to r0 API: Update MXFileStore version as last changes break it --- MatrixSDK/Data/Store/MXFileStore/MXFileStore.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index c46a5a9b08..db79fcc588 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -20,7 +20,7 @@ #import "MXFileStoreMetaData.h" -NSUInteger const kMXFileVersion = 20; +NSUInteger const kMXFileVersion = 21; NSString *const kMXFileStoreFolder = @"MXFileStore"; NSString *const kMXFileStoreMedaDataFile = @"MXFileStore"; From 458b73e3bd4b59353751f8a85642d28fd9f12758 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 18 Feb 2016 18:11:30 +0100 Subject: [PATCH 35/80] Context api: Added the C-S api request --- MatrixSDK/JSONModels/MXJSONModels.h | 37 ++++++++++++++++++++++++++++ MatrixSDK/JSONModels/MXJSONModels.m | 24 ++++++++++++++++++ MatrixSDK/MXRestClient.h | 24 +++++++++++++++++- MatrixSDK/MXRestClient.m | 38 +++++++++++++++++++++++++++++ MatrixSDKTests/MXRestClientTests.m | 36 +++++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 1 deletion(-) diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index 84e8e5325a..08a369302f 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -612,6 +612,43 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end +#pragma mark - Context +#pragma mark - +/** + `MXEventContext` represents to the response to the /context request. + */ +@interface MXEventContext : MXJSONModel + + /** + A token that can be used to paginate backwards with. + */ + @property (nonatomic) NSString *start; + + /** + A list of room events that happened just before the requested event. + The order is antichronological. + */ + @property (nonatomic) NSArray *eventsBefore; + + /** + A list of room events that happened just after the requested event. + The order is chronological. + */ + @property (nonatomic) NSArray *eventsAfter; + + /** + A token that can be used to paginate forwards with. + */ + @property (nonatomic) NSString *end; + + /** + The state of the room at the last event returned. + */ + @property (nonatomic) NSArray *state; + +@end + + #pragma mark - Search #pragma mark - diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 0b71685ed4..042357ddf4 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -569,6 +569,30 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary @end +#pragma mark - Context +#pragma mark - +/** + `MXEventContext` represents to the response to the /context request. + */ +@implementation MXEventContext + ++ (id)modelFromJSON:(NSDictionary *)JSONDictionary +{ + MXEventContext *eventContext = [[MXEventContext alloc] init]; + if (eventContext) + { + MXJSONModelSetString(eventContext.start, JSONDictionary[@"start"]); + MXJSONModelSetMXJSONModelArray(eventContext.eventsBefore, MXEvent, JSONDictionary[@"events_before"]); + MXJSONModelSetMXJSONModelArray(eventContext.eventsAfter, MXEvent, JSONDictionary[@"events_after"]); + MXJSONModelSetString(eventContext.end, JSONDictionary[@"end"]); + MXJSONModelSetMXJSONModelArray(eventContext.state, MXEvent, JSONDictionary[@"state"]); + } + + return eventContext; +} +@end + + #pragma mark - Search #pragma mark - diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index d9621e4bb4..390cf0ac9d 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -762,7 +762,7 @@ typedef enum : NSUInteger @param limit the maximum number of messages to return. @param success A block object called when the operation succeeds. It provides the model created from - the home server JSON response. @see http://matrix.org/docs/api/client-server/#!/-rooms/get_room_sync_data + the homeserver JSON response. @see http://matrix.org/docs/api/client-server/#!/-rooms/get_room_sync_data @param failure A block object called when the operation fails. @return a MXHTTPOperation instance. @@ -773,6 +773,28 @@ typedef enum : NSUInteger failure:(void (^)(NSError *error))failure; +/** + Get the context surrounding an event. + + This API returns a number of events that happened just before and after the specified event. + + @param eventId the id of the event to get context around. + @param roomId the id of the room to get events from. + @param limit the maximum number of messages to return. + + @param success A block object called when the operation succeeds. It provides the model created from + the homeserver JSON response. + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. + */ +- (MXHTTPOperation*)contextOfEvent:(NSString*)eventId + inRoom:(NSString*)roomId + limit:(NSUInteger)limit + success:(void (^)(MXEventContext *eventContext))success + failure:(void (^)(NSError *error))failure; + + #pragma mark - Room tags operations /** List the tags of a room. diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index 3b5e8c18b3..f7795ddad3 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -1478,6 +1478,44 @@ - (MXHTTPOperation*)initialSyncOfRoom:(NSString*)roomId }]; } +- (MXHTTPOperation*)contextOfEvent:(NSString*)eventId + inRoom:(NSString*)roomId + limit:(NSUInteger)limit + success:(void (^)(MXEventContext *eventContext))success + failure:(void (^)(NSError *error))failure +{ + NSString *path = [NSString stringWithFormat:@"%@/rooms/%@/context/%@", apiPathPrefix, roomId, eventId]; + + return [httpClient requestWithMethod:@"GET" + path:path + parameters:@{ + @"limit": [NSNumber numberWithInteger:limit] + } + success:^(NSDictionary *JSONResponse) { + if (success) + { + // Create model from JSON dictionary on the processing queue + dispatch_async(processingQueue, ^{ + + MXEventContext *eventContext = [MXEventContext modelFromJSON:JSONResponse]; + + dispatch_async(dispatch_get_main_queue(), ^{ + + success(eventContext); + + }); + + }); + } + } + failure:^(NSError *error) { + if (failure) + { + failure(error); + } + }]; +} + #pragma mark - Room tags operations - (MXHTTPOperation*)tagsOfRoom:(NSString*)roomId diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index 63e4e74d8a..e2b4d01f30 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -529,6 +529,42 @@ - (void)testInitialSyncOfRoom }]; } +- (void)testContextOfEvent +{ + [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + + [bobRestClient initialSyncOfRoom:roomId withLimit:10 success:^(MXRoomInitialSync *roomInitialSync) { + + // Pick an message event in the middle of created ones + MXEvent *event = roomInitialSync.messages.chunk[5]; + + MXEvent *eventBefore = roomInitialSync.messages.chunk[4]; + MXEvent *eventAfter = roomInitialSync.messages.chunk[6]; + + // Get the context around it + [bobRestClient contextOfEvent:event.eventId inRoom:roomId limit:10 success:^(MXEventContext *eventContext) { + + XCTAssertNotNil(eventContext); + XCTAssertNotNil(eventContext.start); + XCTAssertNotNil(eventContext.end); + XCTAssertGreaterThanOrEqual(eventContext.state.count, 0); + + XCTAssertEqualObjects(eventBefore.eventId, eventContext.eventsBefore[0].eventId); + XCTAssertEqualObjects(eventAfter.eventId, eventContext.eventsAfter[0].eventId); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + }]; + }]; +} + // Remove the `age` field from a dictionary and all its sub dictionaries - (void) removeAgeField:(MXRoomInitialSync*)roomInitialSync { From 561054fe083080bd4856c486eeb54e5dc7f1eae7 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 19 Feb 2016 10:49:44 +0100 Subject: [PATCH 36/80] Moving to r0 API: MXRoom: Removed methods the public ones. They are now used only internally by sync v2 parsing methods. --- MatrixSDK/Data/MXRoom.h | 29 ----------------------------- MatrixSDK/Data/MXRoom.m | 40 ++++++++++++++++++---------------------- 2 files changed, 18 insertions(+), 51 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index f5c64ba9c4..fd92b3579c 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -136,35 +136,6 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom */ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync; -#pragma mark - handle events - -/** - Handle bunch of events received in case of back pagination, global initial sync or room initial sync. - - @param roomMessages the response in which events are stored. - @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. - @param isTimeOrdered tell whether the events are in chronological order. - */ -- (void)handleMessages:(MXPaginationResponse*)roomMessages - direction:(MXEventDirection)direction - isTimeOrdered:(BOOL)isTimeOrdered; - -- (void)handleStateEvents:(NSArray*)roomStateEvents direction:(MXEventDirection)direction; - -/** - Handle an event (message or state) that comes from the events streaming. - - @param event the event to handle. - */ -- (void)handleLiveEvent:(MXEvent*)event; - -/** - Handle private user data events. - - @param accounDataEvents the events to handle. - @param direction the process direction: MXEventDirectionSync or MXEventDirectionForwards. MXEventDirectionBackwards is not applicable here. - */ -- (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(MXEventDirection)direction; #pragma mark - Back pagination /** diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 7d52dd6ef6..00158f47b8 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -280,6 +280,13 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync } #pragma mark - Messages handling +/** + Handle bunch of events received in case of back pagination, global initial sync or room initial sync. + + @param roomMessages the response in which events are stored. + @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. + @param isTimeOrdered tell whether the events are in chronological order. + */ - (void)handleMessages:(MXPaginationResponse*)roomMessages direction:(MXEventDirection)direction isTimeOrdered:(BOOL)isTimeOrdered @@ -395,28 +402,6 @@ - (void)cloneState:(MXEventDirection)direction } } -- (void)handleStateEvents:(NSArray*)roomStateEvents direction:(MXEventDirection)direction -{ - // check if there is something to do - if (!roomStateEvents || (roomStateEvents.count == 0)) - { - return; - } - - [self cloneState:direction]; - - for (MXEvent *event in roomStateEvents) - { - [self handleStateEvent:event direction:direction]; - } - - // Update store with new room state only when all state event have been processed - if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) - { - [mxSession.store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; - } -} - - (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction { // Update the room state @@ -469,6 +454,11 @@ - (void)handleRedaction:(MXEvent*)redactionEvent #pragma mark - Handle live event +/** + Handle an event (message or state) that comes from the events streaming. + + @param event the event to handle. + */ - (void)handleLiveEvent:(MXEvent*)event { // Handle first typing notifications @@ -509,6 +499,12 @@ - (void)handleLiveEvent:(MXEvent*)event #pragma mark - Room private account data handling +/** + Handle private user data events. + + @param accounDataEvents the events to handle. + @param direction the process direction: MXEventDirectionSync or MXEventDirectionForwards. MXEventDirectionBackwards is not applicable here. + */ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(MXEventDirection)direction { for (MXEvent *event in accounDataEvents) From 1ca88b7b475e9e66e8cb38dd1ec895d60b9ae0ac Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 22 Feb 2016 10:07:14 +0100 Subject: [PATCH 37/80] Event timeline. Created MXEventTimeline. WIP --- MatrixSDK.xcodeproj/project.pbxproj | 8 + MatrixSDK/Data/MXEventTimeLine.h | 147 +++ MatrixSDK/Data/MXEventTimeLine.m | 610 ++++++++++++ MatrixSDK/Data/MXRoom.h | 79 +- MatrixSDK/Data/MXRoom.m | 1019 +++++++++----------- MatrixSDK/Data/MXSessionEventListener.m | 7 +- MatrixSDK/MXSession.m | 2 +- MatrixSDKTests/MXEventTests.m | 2 +- MatrixSDKTests/MXNotificationCenterTests.m | 4 +- MatrixSDKTests/MXRoomStateDynamicTests.m | 4 +- MatrixSDKTests/MXRoomStateTests.m | 8 +- MatrixSDKTests/MXRoomTests.m | 16 +- MatrixSDKTests/MXSessionTests.m | 6 +- MatrixSDKTests/MXStoreMemoryStoreTests.m | 12 +- MatrixSDKTests/MXStoreTests.m | 22 +- 15 files changed, 1245 insertions(+), 701 deletions(-) create mode 100644 MatrixSDK/Data/MXEventTimeLine.h create mode 100644 MatrixSDK/Data/MXEventTimeLine.m diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 0cd351ceb8..f58118117e 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -62,6 +62,8 @@ 32481A841C03572900782AD3 /* MXRoomAccountData.h in Headers */ = {isa = PBXBuildFile; fileRef = 32481A821C03572900782AD3 /* MXRoomAccountData.h */; }; 32481A851C03572900782AD3 /* MXRoomAccountData.m in Sources */ = {isa = PBXBuildFile; fileRef = 32481A831C03572900782AD3 /* MXRoomAccountData.m */; }; 325653831A2E14ED00CC0423 /* MXStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 325653821A2E14ED00CC0423 /* MXStoreTests.m */; }; + 326056851C76FDF2009D44AD /* MXEventTimeLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 326056831C76FDF1009D44AD /* MXEventTimeLine.h */; }; + 326056861C76FDF2009D44AD /* MXEventTimeLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 326056841C76FDF1009D44AD /* MXEventTimeLine.m */; }; 3264E2A21BDF8D1500F89A86 /* MXCoreDataRoomState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264E29E1BDF8D1500F89A86 /* MXCoreDataRoomState.h */; }; 3264E2A31BDF8D1500F89A86 /* MXCoreDataRoomState.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264E29F1BDF8D1500F89A86 /* MXCoreDataRoomState.m */; }; 3264E2A41BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264E2A01BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h */; }; @@ -207,6 +209,8 @@ 32481A821C03572900782AD3 /* MXRoomAccountData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXRoomAccountData.h; sourceTree = ""; }; 32481A831C03572900782AD3 /* MXRoomAccountData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXRoomAccountData.m; sourceTree = ""; }; 325653821A2E14ED00CC0423 /* MXStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXStoreTests.m; sourceTree = ""; }; + 326056831C76FDF1009D44AD /* MXEventTimeLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXEventTimeLine.h; sourceTree = ""; }; + 326056841C76FDF1009D44AD /* MXEventTimeLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEventTimeLine.m; sourceTree = ""; }; 3264E29E1BDF8D1500F89A86 /* MXCoreDataRoomState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXCoreDataRoomState.h; sourceTree = ""; }; 3264E29F1BDF8D1500F89A86 /* MXCoreDataRoomState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXCoreDataRoomState.m; sourceTree = ""; }; 3264E2A01BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXCoreDataRoomState+CoreDataProperties.h"; sourceTree = ""; }; @@ -325,6 +329,8 @@ 32481A831C03572900782AD3 /* MXRoomAccountData.m */, 3220093619EFA4C9008DE41D /* MXEventListener.h */, 3220093719EFA4C9008DE41D /* MXEventListener.m */, + 326056831C76FDF1009D44AD /* MXEventTimeLine.h */, + 326056841C76FDF1009D44AD /* MXEventTimeLine.m */, 3220094319EFBF30008DE41D /* MXSessionEventListener.h */, 3220094419EFBF30008DE41D /* MXSessionEventListener.m */, 329FB1731A0A3A1600A5E88E /* MXRoomMember.h */, @@ -644,6 +650,7 @@ 320DFDE019DD99B60068622A /* MXSession.h in Headers */, 324095221AFA432F00D81C97 /* MXCallStackCall.h in Headers */, 3233606F1A403A0D0071A488 /* MXFileStore.h in Headers */, + 326056851C76FDF2009D44AD /* MXEventTimeLine.h in Headers */, 327137271A24D50A00DB6757 /* MXMyUser.h in Headers */, 3220093819EFA4C9008DE41D /* MXEventListener.h in Headers */, 71DE22E11BC7C51200284153 /* MXReceiptData.h in Headers */, @@ -802,6 +809,7 @@ 329FB1761A0A3A1600A5E88E /* MXRoomMember.m in Sources */, 323360701A403A0D0071A488 /* MXFileStore.m in Sources */, 32D7767E1A27860600FC4AA2 /* MXMemoryStore.m in Sources */, + 326056861C76FDF2009D44AD /* MXEventTimeLine.m in Sources */, 323B2B011BCE9B6700B11F34 /* MXCoreDataEvent.m in Sources */, 3265CB391A14C43E00E24B2F /* MXRoomState.m in Sources */, 323B2AD01BCD3EF000B11F34 /* MXCoreDataStore.m in Sources */, diff --git a/MatrixSDK/Data/MXEventTimeLine.h b/MatrixSDK/Data/MXEventTimeLine.h new file mode 100644 index 0000000000..7765af0090 --- /dev/null +++ b/MatrixSDK/Data/MXEventTimeLine.h @@ -0,0 +1,147 @@ +/* + Copyright 2016 OpenMarket Ltd + + 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. + */ + +#import + +#import "MXEvent.h" +#import "MXJSONModels.h" +#import "MXRoomMember.h" +#import "MXEventListener.h" +#import "MXRoomState.h" +#import "MXHTTPOperation.h" + +/** + Block called when an event of the registered types has been handled in the timeline. + This is a specialisation of the `MXOnEvent` block. + + @param event the new event. + @param direction the origin of the event. + @param roomState the room state right before the event + */ +typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoomState *roomState); + +@class MXRoom; + +/** + A `MXEventTimeLine` instance represents a contiguous sequence of events in a room. + */ + +@interface MXEventTimeLine : NSObject + +@property (nonatomic, readonly) NSString *initialEventId; + +@property (nonatomic, readonly) BOOL isLiveTimeLine; + + +/** + The state of the room corresponding to the top most recent room event. + */ +@property (nonatomic, readonly) MXRoomState *state; + + +- (id)initWithRoom:(MXRoom*)room andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId; + + +#pragma mark - Pagination +/** + Check if this timelime can be extended + + This returns true if we either have more events, or if we have a + pagination token which means we can paginate in that direction. It does not + necessarily mean that there are more events available in that direction at + this time. + + @param direction MXEventDirectionBackwards to check if we can paginate backwards. + MXEventDirectionForwards to check if we can go forwards + @return true if we can paginate in the given direction + */ +- (BOOL)canPaginate:(MXEventDirection)direction; + +/** + Reset the back state so that future calls to paginate start over from live. + Must be called when opening a room if interested in history. + */ +- (void)resetBackState; + +/** + Get more messages. + The retrieved events will be sent to registered listeners. + + @param numItems the number of items to get. + @param onlyFromStore if YES, return available events from the store, do not make a pagination request to the homeserver. + @param direction ... + @param complete A block object called when the operation is complete. + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. This instance can be nil + if no request to the home server is required. + */ +- (MXHTTPOperation*)paginate:(NSUInteger)numItems + direction:(MXEventDirection)direction + onlyFromStore:(BOOL)onlyFromStore + complete:(void (^)())complete + failure:(void (^)(NSError *error))failure; + + +#pragma mark - Server sync +/** + Update room data according to the provided sync response. + + @param roomSync information to sync the room with the home server data + */ +- (void)handleJoinedRoomSync:(MXRoomSync*)roomSync; + +/** + Update the invited room state according to the provided data. + + @param invitedRoom information to update the room state. + */ +- (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync; + + +#pragma mark - Events listeners +/** + Register a listener to events of this room. + + @param onEvent the block that will called once a new event has been handled. + @return a reference to use to unregister the listener + */ +- (id)listenToEvents:(MXOnRoomEvent)onEvent; + +/** + Register a listener for some types of events. + + @param types an array of event types strings (MXEventTypeString) to listen to. + @param onEvent the block that will called once a new event has been handled. + @return a reference to use to unregister the listener + */ +- (id)listenToEventsOfTypes:(NSArray*)types onEvent:(MXOnRoomEvent)onEvent; + +/** + Unregister a listener. + + @param listener the reference of the listener to remove. + */ +- (void)removeListener:(id)listener; + +/** + Unregister all listeners. + */ +- (void)removeAllListeners; + +- (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction; + +@end diff --git a/MatrixSDK/Data/MXEventTimeLine.m b/MatrixSDK/Data/MXEventTimeLine.m new file mode 100644 index 0000000000..45b3877399 --- /dev/null +++ b/MatrixSDK/Data/MXEventTimeLine.m @@ -0,0 +1,610 @@ +/* + Copyright 2016 OpenMarket Ltd + + 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. + */ + +#import "MXEventTimeLine.h" + +#import "MXSession.h" +#import "MXMemoryStore.h" + +#import "MXError.h" + +NSString *const kMXRoomInviteStateEventIdPrefix2 = @"invite-"; + +@interface MXEventTimeLine () +{ + // The list of event listeners (`MXEventListener`) of this timeline + NSMutableArray *eventListeners; + + // The historical state of the room when paginating back + MXRoomState *backState; + + // The state that was in the `state` property before it changed + // It is cached because it costs time to recompute it from the current state + // It is particularly noticeable for rooms with a lot of members (ie a lot of + // room members state events) + MXRoomState *previousState; + + MXRoom *room; + + id store; +} +@end + +@implementation MXEventTimeLine + +- (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId +{ + self = [super init]; + if (self) + { + _initialEventId = initialEventId; + room = room2; + eventListeners = [NSMutableArray array]; + + _state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:room.mxSession andDirection:YES]; + + + if (_initialEventId) + { + store = [[MXMemoryStore alloc] init]; + [store openWithCredentials:room.mxSession.matrixRestClient.credentials onComplete:nil failure:nil]; + } + else + { + store = room.mxSession.store; + } + } + return self; +} + +- (BOOL)isLiveTimeLine +{ + return !_initialEventId; +} + + +#pragma mark - Pagination +- (BOOL)canPaginate:(MXEventDirection)direction +{ + BOOL canPaginate = NO; + + if (direction == MXEventDirectionBackwards) + { + // canPaginate depends on two things: + // - did we end to paginate from the local MXStore? + // - did we reach the top of the pagination in our requests to the home server + canPaginate = (0 < [store remainingMessagesForPaginationInRoom:_state.roomId]) + || ![store hasReachedHomeServerPaginationEndForRoom:_state.roomId]; + + } + else + { + if (self.isLiveTimeLine) + { + canPaginate = NO; + } + else + { + NSAssert(NO, @"TODO: canPaginate"); + } + } + + return canPaginate; +} + +#pragma mark - Back pagination +- (void)resetBackState +{ + // Reset the back state to the current room state + backState = [[MXRoomState alloc] initBackStateWith:_state]; + + // Reset store pagination + [store resetPaginationOfRoom:_state.roomId]; +} + +- (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)direction onlyFromStore:(BOOL)onlyFromStore complete:(void (^)())complete failure:(void (^)(NSError *))failure +{ + MXHTTPOperation *operation; + + NSAssert(nil != backState, @"[MXRoom] paginateBackMessages: resetBackState must be called before starting the back pagination"); + + // Return messages in the store first + NSUInteger messagesFromStoreCount = 0; + NSArray *messagesFromStore = [store paginateRoom:_state.roomId numMessages:numItems]; + if (messagesFromStore) + { + messagesFromStoreCount = messagesFromStore.count; + } + + NSLog(@"[MXRoom] paginateBackMessages %tu messages in %@ (%tu are retrieved from the store)", numItems, _state.roomId, messagesFromStoreCount); + + if (messagesFromStoreCount) + { + @autoreleasepool + { + // messagesFromStore are in chronological order + // Handle events from the most recent + for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) + { + MXEvent *event = messagesFromStore[i]; + [self handleMessage:event direction:MXEventDirectionBackwards]; + } + + numItems -= messagesFromStoreCount; + } + } + + if (onlyFromStore && messagesFromStoreCount) + { + complete(); + + NSLog(@"[MXRoom] paginateBackMessages : is done from the store"); + return nil; + } + + if (0 < numItems && NO == [store hasReachedHomeServerPaginationEndForRoom:_state.roomId]) + { + // Not enough messages: make a pagination request to the home server + // from last known token + NSString *paginationToken = [store paginationTokenOfRoom:_state.roomId]; + if (nil == paginationToken) { + paginationToken = @"END"; + } + + NSLog(@"[MXRoom] paginateBackMessages : request %tu messages from the server", numItems); + + operation = [room.mxSession.matrixRestClient messagesForRoom:_state.roomId + from:paginationToken + to:nil + limit:numItems + success:^(MXPaginationResponse *paginatedResponse) { + + @autoreleasepool + { + NSLog(@"[MXRoom] paginateBackMessages : get %tu messages from the server", paginatedResponse.chunk.count); + + // Check pagination end - @see SPEC-319 ticket + if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) + { + // We run out of items + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + } + + // Process received events and update pagination tokens + [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; + + // Commit store changes + if ([store respondsToSelector:@selector(commit)]) + { + [store commit]; + } + + // Inform the method caller + complete(); + + NSLog(@"[MXRoom] paginateBackMessages : is done"); + } + + } failure:^(NSError *error) { + // Check whether the pagination end is reached + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) + { + // We run out of items + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + + NSLog(@"[MXRoom] paginateBackMessages: pagination end has been reached"); + + // Ignore the error + complete(); + return; + } + + NSLog(@"[MXRoom] paginateBackMessages error: %@", error); + failure(error); + }]; + + if (messagesFromStoreCount) + { + // Disable retry to let the caller handle messages from store without delay. + // The caller will trigger a new pagination if need. + operation.maxNumberOfTries = 1; + } + } + else + { + // Nothing more to do + complete(); + + NSLog(@"[MXRoom] paginateBackMessages : is done"); + } + + return operation; +} + + +#pragma mark - Server sync +- (void)handleJoinedRoomSync:(MXRoomSync *)roomSync +{ + // Is it an initial sync for this room? + BOOL isRoomInitialSync = (self.state.membership == MXMembershipUnknown || self.state.membership == MXMembershipInvite); + + // Check whether the room was pending on an invitation. + if (self.state.membership == MXMembershipInvite) + { + // Reset the storage of this room. An initial sync of the room will be done with the provided 'roomSync'. + NSLog(@"[MXRoom] handleJoinedRoomSync: clean invited room from the store (%@).", self.state.roomId); + [store deleteRoom:self.state.roomId]; + } + + // Build/Update first the room state corresponding to the 'start' of the timeline. + // Note: We consider it is not required to clone the existing room state here, because no notification is posted for these events. + for (MXEvent *event in roomSync.state.events) + { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + + [self handleStateEvent:event direction:MXEventDirectionSync]; + } + + // Update store with new room state when all state event have been processed + if ([store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) + { + [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; + } + + // Handle now timeline.events, the room state is updated during this step too (Note: timeline events are in chronological order) + if (isRoomInitialSync) + { + // Here the events are handled in forward direction (see [handleLiveEvent:]). + // They will be added at the end of the stored events, so we keep the chronologinal order. + for (MXEvent *event in roomSync.timeline.events) + { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + + // Make room data digest the live event + [self handleLiveEvent:event]; + } + + // Check whether we got all history from the home server + if (!roomSync.timeline.limited) + { + [store storeHasReachedHomeServerPaginationEndForRoom:self.state.roomId andValue:YES]; + } + } + else + { + // Check whether some events have not been received from server. + if (roomSync.timeline.limited) + { + // Flush the existing messages for this room by keeping state events. + [store deleteAllMessagesInRoom:_state.roomId]; + } + + // Here the events are handled in forward direction (see [handleLiveEvent:]). + // They will be added at the end of the stored events, so we keep the chronologinal order. + for (MXEvent *event in roomSync.timeline.events) + { + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + + // Make room data digest the live event + [self handleLiveEvent:event]; + } + } + + // In case of limited timeline, update token where to start back pagination + if (roomSync.timeline.limited) + { + [store storePaginationTokenOfRoom:_state.roomId andToken:roomSync.timeline.prevBatch]; + } + + // Finalize initial sync + if (isRoomInitialSync) + { + // Notify that room has been sync'ed + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomInitialSyncNotification + object:room + userInfo:nil]; + } + else if (roomSync.timeline.limited) + { + // The room has been resync with a limited timeline - Post notification + [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomSyncWithLimitedTimelineNotification + object:room + userInfo:nil]; + } +} + +- (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync +{ + // Handle the state events as live events (the room state will be updated, and the listeners (if any) will be notified). + for (MXEvent *event in invitedRoomSync.inviteState.events) + { + // Add a fake event id if none in order to be able to store the event + if (!event.eventId) + { + event.eventId = [NSString stringWithFormat:@"%@%@", kMXRoomInviteStateEventIdPrefix2, [[NSProcessInfo processInfo] globallyUniqueString]]; + } + + // Report the room id in the event as it is skipped in /sync response + event.roomId = _state.roomId; + + [self handleLiveEvent:event]; + } +} + + +#pragma mark - Messages handling +/** + Handle bunch of events received in case of back pagination, global initial sync or room initial sync. + + @param roomMessages the response in which events are stored. + @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. + @param isTimeOrdered tell whether the events are in chronological order. + */ +- (void)handleMessages:(MXPaginationResponse*)roomMessages + direction:(MXEventDirection)direction + isTimeOrdered:(BOOL)isTimeOrdered +{ + // Here direction is MXEventDirectionBackwards or MXEventDirectionSync + if (direction == MXEventDirectionForwards) + { + NSLog(@"[MXRoom] handleMessages error: forward direction is not supported"); + return; + } + + NSArray *events = roomMessages.chunk; + + // Handles messages according to their time order + if (NO == isTimeOrdered) + { + // [MXRestClient messages] returns messages in reverse chronological order + for (MXEvent *event in events) { + + // Make sure we have not processed this event yet + if (![store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) + { + [self handleMessage:event direction:direction]; + + // Store the event + [store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionBackwards]; + } + } + + // Store how far back we've paginated + [store storePaginationTokenOfRoom:_state.roomId andToken:roomMessages.end]; + } + else + { + // InitialSync returns messages in chronological order + // We have to read them in reverse to fill the store from the beginning. + for (NSInteger i = events.count - 1; i >= 0; i--) + { + MXEvent *event = events[i]; + + // Make sure we have not processed this event yet + MXEvent *storedEvent = [store eventWithEventId:event.eventId inRoom:_state.roomId]; + if (!storedEvent) + { + [self handleMessage:event direction:direction]; + + // Store the event + [store storeEventForRoom:_state.roomId event:event direction:direction]; + } + } + + // Store where to start pagination + [store storePaginationTokenOfRoom:_state.roomId andToken:roomMessages.start]; + } +} + +- (void)handleMessage:(MXEvent*)event direction:(MXEventDirection)direction +{ + if (event.isState) + { + // Consider here state event (except during initial sync) + if (direction != MXEventDirectionSync) + { + [self cloneState:direction]; + + [self handleStateEvent:event direction:direction]; + + // Update store with new room state once a live event has been processed + if (direction == MXEventDirectionForwards) + { + if ([store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) + { + [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; + } + } + } + } + + // Notify listener only for past events here + // Live events are already notified from handleLiveEvent + if (MXEventDirectionForwards != direction) + { + [self notifyListeners:event direction:direction]; + } + else + { + MXReceiptData* data = [[MXReceiptData alloc] init]; + data.userId = event.sender; + data.eventId = event.eventId; + data.ts = event.originServerTs; + + [store storeReceipt:data roomId:_state.roomId]; + // notifyListeners call is performed in the calling method. + } +} + + +#pragma mark - State events handling +- (void)cloneState:(MXEventDirection)direction +{ + // create a new instance of the state + if (MXEventDirectionBackwards == direction) + { + backState = [backState copy]; + } + else + { + // Keep the previous state in cache for future usage in [self notifyListeners] + previousState = _state; + + _state = [_state copy]; + } +} + +- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction +{ + // Update the room state + if (MXEventDirectionBackwards == direction) + { + [backState handleStateEvent:event]; + } + else + { + // Forwards and initialSync events update the current state of the room + + [_state handleStateEvent:event]; + + // Special handling for presence + if (MXEventTypeRoomMember == event.eventType) + { + // Update MXUser data + MXUser *user = [room.mxSession getOrCreateUser:event.sender]; + + MXRoomMember *roomMember = [_state memberWithUserId:event.sender]; + if (roomMember && MXMembershipJoin == roomMember.membership) + { + [user updateWithRoomMemberEvent:event roomMember:roomMember]; + } + } + } +} + + +#pragma mark - Handle live event +/** + Handle an event (message or state) that comes from the events streaming. + + @param event the event to handle. + */ +- (void)handleLiveEvent:(MXEvent*)event +{ + // Handle first typing notifications + if (event.eventType == MXEventTypeTypingNotification) + { + // Typing notifications events are not room messages nor room state events + // They are just volatile information + //MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); + + // Notify listeners + [self notifyListeners:event direction:MXEventDirectionForwards]; + } + else if (event.eventType == MXEventTypeReceipt) + { + //[self handleReceiptEvent:event direction:MXEventDirectionForwards]; + } + else + { + // Make sure we have not processed this event yet + if (![store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) + { + // Handle here redaction event from live event stream + if (event.eventType == MXEventTypeRoomRedaction) + { + //[self handleRedaction:event]; + } + + [self handleMessage:event direction:MXEventDirectionForwards]; + + // Store the event + [store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionForwards]; + + // And notify listeners + [self notifyListeners:event direction:MXEventDirectionForwards]; + } + } +} + + +#pragma mark - Events listeners +- (id)listenToEvents:(MXOnRoomEvent)onEvent +{ + return [self listenToEventsOfTypes:nil onEvent:onEvent]; +} + +- (id)listenToEventsOfTypes:(NSArray*)types onEvent:(MXOnRoomEvent)onEvent +{ + MXEventListener *listener = [[MXEventListener alloc] initWithSender:self andEventTypes:types andListenerBlock:onEvent]; + + [eventListeners addObject:listener]; + + return listener; +} + +- (void)removeListener:(id)listener +{ + [eventListeners removeObject:listener]; +} + +- (void)removeAllListeners +{ + [eventListeners removeAllObjects]; +} + +- (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction +{ + MXRoomState * roomState; + + if (MXEventDirectionBackwards == direction) + { + roomState = backState; + } + else + { + if ([event isState]) + { + // Provide the state of the room before this event + roomState = previousState; + } + else + { + roomState = _state; + } + } + + // Notify all listeners + // The SDK client may remove a listener while calling them by enumeration + // So, use a copy of them + NSArray *listeners = [eventListeners copy]; + + for (MXEventListener *listener in listeners) + { + // And check the listener still exists before calling it + if (NSNotFound != [eventListeners indexOfObject:listener]) + { + [listener notify:event direction:direction andCustomObject:roomState]; + } + } +} + + +@end diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index f5c64ba9c4..9b14e7fe07 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -24,6 +24,7 @@ #import "MXRoomAccountData.h" #import "MXHTTPOperation.h" #import "MXCall.h" +#import "MXEventTimeLine.h" @class MXRoom; @class MXSession; @@ -46,16 +47,6 @@ FOUNDATION_EXPORT NSString *const kMXRoomInitialSyncNotification; */ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; -/** - Block called when an event of the registered types has been handled by the `MXRoom` instance. - This is a specialisation of the `MXOnEvent` block. - - @param event the new event. - @param direction the origin of the event. - @param roomState the room state right before the event - */ -typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoomState *roomState); - /** `MXRoom` is the class */ @@ -67,7 +58,12 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom @property (nonatomic, readonly) MXSession *mxSession; /** - The uptodate state of the room. + The live events timeline. + */ +@property (nonatomic, readonly) MXEventTimeLine *liveTimeLine; + +/** + The up-to-date state of the room. */ @property (nonatomic, readonly) MXRoomState *state; @@ -116,7 +112,7 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom - (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession; -- (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession andInitialSync:(MXRoomInitialSync*)initialSync; +//- (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession andInitialSync:(MXRoomInitialSync*)initialSync; - (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession andStateEvents:(NSArray*)stateEvents andAccountData:(MXRoomAccountData*)accountData; @@ -136,35 +132,6 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom */ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync; -#pragma mark - handle events - -/** - Handle bunch of events received in case of back pagination, global initial sync or room initial sync. - - @param roomMessages the response in which events are stored. - @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. - @param isTimeOrdered tell whether the events are in chronological order. - */ -- (void)handleMessages:(MXPaginationResponse*)roomMessages - direction:(MXEventDirection)direction - isTimeOrdered:(BOOL)isTimeOrdered; - -- (void)handleStateEvents:(NSArray*)roomStateEvents direction:(MXEventDirection)direction; - -/** - Handle an event (message or state) that comes from the events streaming. - - @param event the event to handle. - */ -- (void)handleLiveEvent:(MXEvent*)event; - -/** - Handle private user data events. - - @param accounDataEvents the events to handle. - @param direction the process direction: MXEventDirectionSync or MXEventDirectionForwards. MXEventDirectionBackwards is not applicable here. - */ -- (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(MXEventDirection)direction; #pragma mark - Back pagination /** @@ -538,36 +505,6 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom - (MXCall*)placeCallWithVideo:(BOOL)video; -#pragma mark - Events listeners -/** - Register a listener to events of this room. - - @param onEvent the block that will called once a new event has been handled. - @return a reference to use to unregister the listener - */ -- (id)listenToEvents:(MXOnRoomEvent)onEvent; - -/** - Register a listener for some types of events. - - @param types an array of event types strings (MXEventTypeString) to listen to. - @param onEvent the block that will called once a new event has been handled. - @return a reference to use to unregister the listener - */ -- (id)listenToEventsOfTypes:(NSArray*)types onEvent:(MXOnRoomEvent)onEvent; - -/** - Unregister a listener. - - @param listener the reference of the listener to remove. - */ -- (void)removeListener:(id)listener; - -/** - Unregister all listeners. - */ -- (void)removeAllListeners; - #pragma mark - Receipts management /** diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 7d52dd6ef6..b3b6ef3f8d 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -28,17 +28,6 @@ @interface MXRoom () { - // The list of event listeners (`MXEventListener`) in this room - NSMutableArray *eventListeners; - - // The historical state of the room when paginating back - MXRoomState *backState; - - // The state that was in the `state` property before it changed - // It is cached because it costs time to recompute it from the current state - // It is particularly noticeable for rooms with a lot of members (ie a lot of - // room members state events) - MXRoomState *previousState; } @end @@ -51,10 +40,8 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 if (self) { mxSession = mxSession2; - - eventListeners = [NSMutableArray array]; - - _state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:mxSession2 andDirection:YES]; + + _liveTimeLine = [[MXEventTimeLine alloc] initWithRoom:self andRoomId:roomId initialEventId:nil]; _accountData = [[MXRoomAccountData alloc] init]; @@ -83,29 +70,29 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 return self; } -- (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 andInitialSync:(MXRoomInitialSync*)initialSync -{ - self = [self initWithRoomId:roomId andMatrixSession:mxSession2]; - if (self) - { - _state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:mxSession2 andInitialSync:initialSync andDirection:YES]; - - if (initialSync.invite) - { - // Process the invite event content: it contains a partial room state - [self handleStateEvent:initialSync.invite direction:MXEventDirectionSync]; - if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) - { - [mxSession.store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; - } - - // Put the invite in the room messages list so that - [self handleMessage:initialSync.invite direction:MXEventDirectionSync]; - [mxSession.store storeEventForRoom:roomId event:initialSync.invite direction:MXEventDirectionSync]; - } - } - return self; -} +//- (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 andInitialSync:(MXRoomInitialSync*)initialSync +//{ +// self = [self initWithRoomId:roomId andMatrixSession:mxSession2]; +// if (self) +// { +// self.state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:mxSession2 andInitialSync:initialSync andDirection:YES]; +// +// if (initialSync.invite) +// { +// // Process the invite event content: it contains a partial room state +// [self handleStateEvent:initialSync.invite direction:MXEventDirectionSync]; +// if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) +// { +// [mxSession.store storeStateForRoom:self.state.roomId stateEvents:self.state.stateEvents]; +// } +// +// // Put the invite in the room messages list so that +// [self handleMessage:initialSync.invite direction:MXEventDirectionSync]; +// [mxSession.store storeEventForRoom:roomId event:initialSync.invite direction:MXEventDirectionSync]; +// } +// } +// return self; +//} - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 andStateEvents:(NSArray *)stateEvents andAccountData:(MXRoomAccountData*)accountData { @@ -116,7 +103,7 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 { for (MXEvent *event in stateEvents) { - [self handleStateEvent:event direction:MXEventDirectionSync]; + //[self handleStateEvent:event direction:MXEventDirectionSync]; } _accountData = accountData; @@ -126,9 +113,14 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 } #pragma mark - Properties implementation +- (MXRoomState *)state +{ + return _liveTimeLine.state; +} + - (void)setPartialTextMessage:(NSString *)partialTextMessage { - [mxSession.store storePartialTextMessageForRoom:_state.roomId partialTextMessage:partialTextMessage]; + [mxSession.store storePartialTextMessageForRoom:self.state.roomId partialTextMessage:partialTextMessage]; if ([mxSession.store respondsToSelector:@selector(commit)]) { [mxSession.store commit]; @@ -137,12 +129,12 @@ - (void)setPartialTextMessage:(NSString *)partialTextMessage - (NSString *)partialTextMessage { - return [mxSession.store partialTextMessageOfRoom:_state.roomId]; + return [mxSession.store partialTextMessageOfRoom:self.state.roomId]; } - (MXEvent *)lastMessageWithTypeIn:(NSArray*)types { - return [mxSession.store lastMessageOfRoom:_state.roomId withTypeIn:types]; + return [mxSession.store lastMessageOfRoom:self.state.roomId withTypeIn:types]; } - (BOOL)canPaginate @@ -150,365 +142,274 @@ - (BOOL)canPaginate // canPaginate depends on two things: // - did we end to paginate from the local MXStore? // - did we reach the top of the pagination in our requests to the home server - return (0 < [mxSession.store remainingMessagesForPaginationInRoom:_state.roomId]) - || ![mxSession.store hasReachedHomeServerPaginationEndForRoom:_state.roomId]; + return (0 < [mxSession.store remainingMessagesForPaginationInRoom:self.state.roomId]) + || ![mxSession.store hasReachedHomeServerPaginationEndForRoom:self.state.roomId]; } -#pragma mark - Sync +#pragma mark - Sync - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync { - // Is it an initial sync for this room? - BOOL isRoomInitialSync = (self.state.membership == MXMembershipUnknown || self.state.membership == MXMembershipInvite); - - // Check whether the room was pending on an invitation. - if (self.state.membership == MXMembershipInvite) - { - // Reset the storage of this room. An initial sync of the room will be done with the provided 'roomSync'. - NSLog(@"[MXRoom] handleJoinedRoomSync: clean invited room from the store (%@).", self.state.roomId); - [mxSession.store deleteRoom:self.state.roomId]; - } - - // Build/Update first the room state corresponding to the 'start' of the timeline. - // Note: We consider it is not required to clone the existing room state here, because no notification is posted for these events. - for (MXEvent *event in roomSync.state.events) - { - // Report the room id in the event as it is skipped in /sync response - event.roomId = _state.roomId; + [_liveTimeLine handleJoinedRoomSync:roomSync]; - [self handleStateEvent:event direction:MXEventDirectionSync]; - } - - // Update store with new room state when all state event have been processed - if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) - { - [mxSession.store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; - } - - // Handle now timeline.events, the room state is updated during this step too (Note: timeline events are in chronological order) - if (isRoomInitialSync) - { - // Here the events are handled in forward direction (see [handleLiveEvent:]). - // They will be added at the end of the stored events, so we keep the chronologinal order. - for (MXEvent *event in roomSync.timeline.events) - { - // Report the room id in the event as it is skipped in /sync response - event.roomId = _state.roomId; - - // Make room data digest the live event - [self handleLiveEvent:event]; - } - - // Check whether we got all history from the home server - if (!roomSync.timeline.limited) - { - [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:self.state.roomId andValue:YES]; - } - } - else - { - // Check whether some events have not been received from server. - if (roomSync.timeline.limited) - { - // Flush the existing messages for this room by keeping state events. - [mxSession.store deleteAllMessagesInRoom:_state.roomId]; - } - - // Here the events are handled in forward direction (see [handleLiveEvent:]). - // They will be added at the end of the stored events, so we keep the chronologinal order. - for (MXEvent *event in roomSync.timeline.events) - { - // Report the room id in the event as it is skipped in /sync response - event.roomId = _state.roomId; - - // Make room data digest the live event - [self handleLiveEvent:event]; - } - } - - // In case of limited timeline, update token where to start back pagination - if (roomSync.timeline.limited) - { - [mxSession.store storePaginationTokenOfRoom:_state.roomId andToken:roomSync.timeline.prevBatch]; - } - - // Finalize initial sync - if (isRoomInitialSync) - { - // Notify that room has been sync'ed - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomInitialSyncNotification - object:self - userInfo:nil]; - } - else if (roomSync.timeline.limited) - { - // The room has been resync with a limited timeline - Post notification - [[NSNotificationCenter defaultCenter] postNotificationName:kMXRoomSyncWithLimitedTimelineNotification - object:self - userInfo:nil]; - } - // Handle here ephemeral events (if any) for (MXEvent *event in roomSync.ephemeral.events) { // Report the room id in the event as it is skipped in /sync response - event.roomId = _state.roomId; - - [self handleLiveEvent:event]; - } - - // Handle account data events (if any) - [self handleAccounDataEvents:roomSync.accountData.events direction:MXEventDirectionForwards]; -} - -- (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync -{ - // Handle the state events as live events (the room state will be updated, and the listeners (if any) will be notified). - for (MXEvent *event in invitedRoomSync.inviteState.events) - { - // Add a fake event id if none in order to be able to store the event - if (!event.eventId) - { - event.eventId = [NSString stringWithFormat:@"%@%@", kMXRoomInviteStateEventIdPrefix, [[NSProcessInfo processInfo] globallyUniqueString]]; - } - - // Report the room id in the event as it is skipped in /sync response - event.roomId = _state.roomId; - - [self handleLiveEvent:event]; - } -} - -#pragma mark - Messages handling -- (void)handleMessages:(MXPaginationResponse*)roomMessages - direction:(MXEventDirection)direction - isTimeOrdered:(BOOL)isTimeOrdered -{ - // Here direction is MXEventDirectionBackwards or MXEventDirectionSync - if (direction == MXEventDirectionForwards) - { - NSLog(@"[MXRoom] handleMessages error: forward direction is not supported"); - return; - } - - NSArray *events = roomMessages.chunk; - - // Handles messages according to their time order - if (NO == isTimeOrdered) - { - // [MXRestClient messages] returns messages in reverse chronological order - for (MXEvent *event in events) { + event.roomId = self.state.roomId; - // Make sure we have not processed this event yet - if (![mxSession.store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) + // Handle first typing notifications + if (event.eventType == MXEventTypeTypingNotification) { - [self handleMessage:event direction:direction]; - - // Store the event - [mxSession.store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionBackwards]; - } - } + // Typing notifications events are not room messages nor room state events + // They are just volatile information + MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); - // Store how far back we've paginated - [mxSession.store storePaginationTokenOfRoom:_state.roomId andToken:roomMessages.end]; - } - else - { - // InitialSync returns messages in chronological order - // We have to read them in reverse to fill the store from the beginning. - for (NSInteger i = events.count - 1; i >= 0; i--) - { - MXEvent *event = events[i]; - - // Make sure we have not processed this event yet - MXEvent *storedEvent = [mxSession.store eventWithEventId:event.eventId inRoom:_state.roomId]; - if (!storedEvent) - { - [self handleMessage:event direction:direction]; - - // Store the event - [mxSession.store storeEventForRoom:_state.roomId event:event direction:direction]; + // Notify listeners + [_liveTimeLine notifyListeners:event direction:MXEventDirectionForwards]; } - } - - // Store where to start pagination - [mxSession.store storePaginationTokenOfRoom:_state.roomId andToken:roomMessages.start]; - } -} - -- (void)handleMessage:(MXEvent*)event direction:(MXEventDirection)direction -{ - if (event.isState) - { - // Consider here state event (except during initial sync) - if (direction != MXEventDirectionSync) - { - [self cloneState:direction]; - - [self handleStateEvent:event direction:direction]; - - // Update store with new room state once a live event has been processed - if (direction == MXEventDirectionForwards) + else if (event.eventType == MXEventTypeReceipt) { - if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) - { - [mxSession.store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; - } + [self handleReceiptEvent:event direction:MXEventDirectionForwards]; } - } - } - - // Notify listener only for past events here - // Live events are already notified from handleLiveEvent - if (MXEventDirectionForwards != direction) - { - [self notifyListeners:event direction:direction]; - } - else - { - MXReceiptData* data = [[MXReceiptData alloc] init]; - data.userId = event.sender; - data.eventId = event.eventId; - data.ts = event.originServerTs; - - [mxSession.store storeReceipt:data roomId:_state.roomId]; - // notifyListeners call is performed in the calling method. - } -} - - -#pragma mark - State events handling - -- (void)cloneState:(MXEventDirection)direction -{ - // create a new instance of the state - if (MXEventDirectionBackwards == direction) - { - backState = [backState copy]; - } - else - { - // Keep the previous state in cache for future usage in [self notifyListeners] - previousState = _state; - - _state = [_state copy]; - } -} - -- (void)handleStateEvents:(NSArray*)roomStateEvents direction:(MXEventDirection)direction -{ - // check if there is something to do - if (!roomStateEvents || (roomStateEvents.count == 0)) - { - return; } - [self cloneState:direction]; - - for (MXEvent *event in roomStateEvents) - { - [self handleStateEvent:event direction:direction]; - } - - // Update store with new room state only when all state event have been processed - if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) - { - [mxSession.store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; - } + // Handle account data events (if any) + [self handleAccounDataEvents:roomSync.accountData.events direction:MXEventDirectionForwards]; } -- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction +- (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync { - // Update the room state - if (MXEventDirectionBackwards == direction) - { - [backState handleStateEvent:event]; - } - else - { - // Forwards and initialSync events update the current state of the room - - [_state handleStateEvent:event]; - - // Special handling for presence - if (MXEventTypeRoomMember == event.eventType) - { - // Update MXUser data - MXUser *user = [mxSession getOrCreateUser:event.sender]; - - MXRoomMember *roomMember = [_state memberWithUserId:event.sender]; - if (roomMember && MXMembershipJoin == roomMember.membership) - { - [user updateWithRoomMemberEvent:event roomMember:roomMember]; - } - } - } + [_liveTimeLine handleInvitedRoomSync:invitedRoomSync]; } -#pragma mark - Handle redaction -- (void)handleRedaction:(MXEvent*)redactionEvent -{ - // Check whether the redacted event has been already processed - MXEvent *redactedEvent = [mxSession.store eventWithEventId:redactionEvent.redacts inRoom:_state.roomId]; - if (redactedEvent) - { - // Redact the stored event - redactedEvent = [redactedEvent prune]; - redactedEvent.redactedBecause = redactionEvent.JSONDictionary; - - if (redactedEvent.isState) { - // FIXME: The room state must be refreshed here since this redacted event. - } - - // Store the event - [mxSession.store replaceEvent:redactedEvent inRoom:_state.roomId]; - } -} +#pragma mark - Messages handling +/** + Handle bunch of events received in case of back pagination, global initial sync or room initial sync. + @param roomMessages the response in which events are stored. + @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. + @param isTimeOrdered tell whether the events are in chronological order. + */ +//- (void)handleMessages:(MXPaginationResponse*)roomMessages +// direction:(MXEventDirection)direction +// isTimeOrdered:(BOOL)isTimeOrdered +//{ +// // Here direction is MXEventDirectionBackwards or MXEventDirectionSync +// if (direction == MXEventDirectionForwards) +// { +// NSLog(@"[MXRoom] handleMessages error: forward direction is not supported"); +// return; +// } +// +// NSArray *events = roomMessages.chunk; +// +// // Handles messages according to their time order +// if (NO == isTimeOrdered) +// { +// // [MXRestClient messages] returns messages in reverse chronological order +// for (MXEvent *event in events) { +// +// // Make sure we have not processed this event yet +// if (![mxSession.store eventExistsWithEventId:event.eventId inRoom:self.state.roomId]) +// { +// [self handleMessage:event direction:direction]; +// +// // Store the event +// [mxSession.store storeEventForRoom:self.state.roomId event:event direction:MXEventDirectionBackwards]; +// } +// } +// +// // Store how far back we've paginated +// [mxSession.store storePaginationTokenOfRoom:self.state.roomId andToken:roomMessages.end]; +// } +// else +// { +// // InitialSync returns messages in chronological order +// // We have to read them in reverse to fill the store from the beginning. +// for (NSInteger i = events.count - 1; i >= 0; i--) +// { +// MXEvent *event = events[i]; +// +// // Make sure we have not processed this event yet +// MXEvent *storedEvent = [mxSession.store eventWithEventId:event.eventId inRoom:self.state.roomId]; +// if (!storedEvent) +// { +// [self handleMessage:event direction:direction]; +// +// // Store the event +// [mxSession.store storeEventForRoom:self.state.roomId event:event direction:direction]; +// } +// } +// +// // Store where to start pagination +// [mxSession.store storePaginationTokenOfRoom:self.state.roomId andToken:roomMessages.start]; +// } +//} +// +//- (void)handleMessage:(MXEvent*)event direction:(MXEventDirection)direction +//{ +// if (event.isState) +// { +// // Consider here state event (except during initial sync) +// if (direction != MXEventDirectionSync) +// { +// [self cloneState:direction]; +// +// [self handleStateEvent:event direction:direction]; +// +// // Update store with new room state once a live event has been processed +// if (direction == MXEventDirectionForwards) +// { +// if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) +// { +// [mxSession.store storeStateForRoom:self.state.roomId stateEvents:self.state.stateEvents]; +// } +// } +// } +// } +// +// // Notify listener only for past events here +// // Live events are already notified from handleLiveEvent +// if (MXEventDirectionForwards != direction) +// { +// [self notifyListeners:event direction:direction]; +// } +// else +// { +// MXReceiptData* data = [[MXReceiptData alloc] init]; +// data.userId = event.sender; +// data.eventId = event.eventId; +// data.ts = event.originServerTs; +// +// [mxSession.store storeReceipt:data roomId:self.state.roomId]; +// // notifyListeners call is performed in the calling method. +// } +//} -#pragma mark - Handle live event -- (void)handleLiveEvent:(MXEvent*)event -{ - // Handle first typing notifications - if (event.eventType == MXEventTypeTypingNotification) - { - // Typing notifications events are not room messages nor room state events - // They are just volatile information - MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); +#pragma mark - State events handling - // Notify listeners - [self notifyListeners:event direction:MXEventDirectionForwards]; - } - else if (event.eventType == MXEventTypeReceipt) - { - [self handleReceiptEvent:event direction:MXEventDirectionForwards]; - } - else - { - // Make sure we have not processed this event yet - if (![mxSession.store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) - { - // Handle here redaction event from live event stream - if (event.eventType == MXEventTypeRoomRedaction) - { - [self handleRedaction:event]; - } - - [self handleMessage:event direction:MXEventDirectionForwards]; - - // Store the event - [mxSession.store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionForwards]; - - // And notify listeners - [self notifyListeners:event direction:MXEventDirectionForwards]; - } - } -} +//- (void)cloneState:(MXEventDirection)direction +//{ +// // create a new instance of the state +// if (MXEventDirectionBackwards == direction) +// { +// backState = [backState copy]; +// } +// else +// { +// // Keep the previous state in cache for future usage in [self notifyListeners] +// previousState = self.state; +// +// self.state = [self.state copy]; +// } +//} +// +//- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction +//{ +// // Update the room state +// if (MXEventDirectionBackwards == direction) +// { +// [backState handleStateEvent:event]; +// } +// else +// { +// // Forwards and initialSync events update the current state of the room +// +// [self.state handleStateEvent:event]; +// +// // Special handling for presence +// if (MXEventTypeRoomMember == event.eventType) +// { +// // Update MXUser data +// MXUser *user = [mxSession getOrCreateUser:event.sender]; +// +// MXRoomMember *roomMember = [self.state memberWithUserId:event.sender]; +// if (roomMember && MXMembershipJoin == roomMember.membership) +// { +// [user updateWithRoomMemberEvent:event roomMember:roomMember]; +// } +// } +// } +//} + +//#pragma mark - Handle redaction +// +//- (void)handleRedaction:(MXEvent*)redactionEvent +//{ +// // Check whether the redacted event has been already processed +// MXEvent *redactedEvent = [mxSession.store eventWithEventId:redactionEvent.redacts inRoom:self.state.roomId]; +// if (redactedEvent) +// { +// // Redact the stored event +// redactedEvent = [redactedEvent prune]; +// redactedEvent.redactedBecause = redactionEvent.JSONDictionary; +// +// if (redactedEvent.isState) { +// // FIXME: The room state must be refreshed here since this redacted event. +// } +// +// // Store the event +// [mxSession.store replaceEvent:redactedEvent inRoom:self.state.roomId]; +// } +//} + + +//#pragma mark - Handle live event +// +///** +// Handle an event (message or state) that comes from the events streaming. +// +// @param event the event to handle. +// */ +//- (void)handleLiveEvent:(MXEvent*)event +//{ +// // Handle first typing notifications +// if (event.eventType == MXEventTypeTypingNotification) +// { +// // Typing notifications events are not room messages nor room state events +// // They are just volatile information +// MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); +// +// // Notify listeners +// [self notifyListeners:event direction:MXEventDirectionForwards]; +// } +// else if (event.eventType == MXEventTypeReceipt) +// { +// [self handleReceiptEvent:event direction:MXEventDirectionForwards]; +// } +// else +// { +// // Make sure we have not processed this event yet +// if (![mxSession.store eventExistsWithEventId:event.eventId inRoom:self.state.roomId]) +// { +// // Handle here redaction event from live event stream +// if (event.eventType == MXEventTypeRoomRedaction) +// { +// [self handleRedaction:event]; +// } +// +// [self handleMessage:event direction:MXEventDirectionForwards]; +// +// // Store the event +// [mxSession.store storeEventForRoom:self.state.roomId event:event direction:MXEventDirectionForwards]; +// +// // And notify listeners +// [self notifyListeners:event direction:MXEventDirectionForwards]; +// } +// } +//} #pragma mark - Room private account data handling +/** + Handle private user data events. + + @param accounDataEvents the events to handle. + @param direction the process direction: MXEventDirectionSync or MXEventDirectionForwards. MXEventDirectionBackwards is not applicable here. + */ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(MXEventDirection)direction { for (MXEvent *event in accounDataEvents) @@ -518,11 +419,11 @@ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(M // Update the store if ([mxSession.store respondsToSelector:@selector(storeAccountDataForRoom:userData:)]) { - [mxSession.store storeAccountDataForRoom:_state.roomId userData:_accountData]; + [mxSession.store storeAccountDataForRoom:self.state.roomId userData:_accountData]; } // And notify listeners - [self notifyListeners:event direction:direction]; + [_liveTimeLine notifyListeners:event direction:direction]; } } @@ -530,11 +431,12 @@ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(M #pragma mark - Back pagination - (void)resetBackState { - // Reset the back state to the current room state - backState = [[MXRoomState alloc] initBackStateWith:_state]; - - // Reset store pagination - [mxSession.store resetPaginationOfRoom:_state.roomId]; + [_liveTimeLine resetBackState]; +// // Reset the back state to the current room state +// backState = [[MXRoomState alloc] initBackStateWith:self.state]; +// +// // Reset store pagination +// [mxSession.store resetPaginationOfRoom:self.state.roomId]; } - (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems @@ -542,127 +444,129 @@ - (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems complete:(void (^)())complete failure:(void (^)(NSError *error))failure { - MXHTTPOperation *operation; - - NSAssert(nil != backState, @"[MXRoom] paginateBackMessages: resetBackState must be called before starting the back pagination"); - - // Return messages in the store first - NSUInteger messagesFromStoreCount = 0; - NSArray *messagesFromStore = [mxSession.store paginateRoom:_state.roomId numMessages:numItems]; - if (messagesFromStore) - { - messagesFromStoreCount = messagesFromStore.count; - } - - NSLog(@"[MXRoom] paginateBackMessages %tu messages in %@ (%tu are retrieved from the store)", numItems, _state.roomId, messagesFromStoreCount); - - if (messagesFromStoreCount) - { - @autoreleasepool - { - // messagesFromStore are in chronological order - // Handle events from the most recent - for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) - { - MXEvent *event = messagesFromStore[i]; - [self handleMessage:event direction:MXEventDirectionBackwards]; - } - - numItems -= messagesFromStoreCount; - } - } - - if (onlyFromStore && messagesFromStoreCount) - { - complete(); - - NSLog(@"[MXRoom] paginateBackMessages : is done from the store"); - return nil; - } - - if (0 < numItems && NO == [mxSession.store hasReachedHomeServerPaginationEndForRoom:_state.roomId]) - { - // Not enough messages: make a pagination request to the home server - // from last known token - NSString *paginationToken = [mxSession.store paginationTokenOfRoom:_state.roomId]; - if (nil == paginationToken) { - paginationToken = @"END"; - } - - NSLog(@"[MXRoom] paginateBackMessages : request %tu messages from the server", numItems); - - operation = [mxSession.matrixRestClient messagesForRoom:_state.roomId - from:paginationToken - to:nil - limit:numItems - success:^(MXPaginationResponse *paginatedResponse) { - - @autoreleasepool - { - NSLog(@"[MXRoom] paginateBackMessages : get %tu messages from the server", paginatedResponse.chunk.count); - - // Check pagination end - @see SPEC-319 ticket - if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) - { - // We run out of items - [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; - } - - // Process received events and update pagination tokens - [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; - - // Commit store changes - if ([mxSession.store respondsToSelector:@selector(commit)]) - { - [mxSession.store commit]; - } - - // Inform the method caller - complete(); - - NSLog(@"[MXRoom] paginateBackMessages : is done"); - } - - } failure:^(NSError *error) { - // Check whether the pagination end is reached - MXError *mxError = [[MXError alloc] initWithNSError:error]; - if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) - { - // We run out of items - [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; - - NSLog(@"[MXRoom] paginateBackMessages: pagination end has been reached"); - - // Ignore the error - complete(); - return; - } - - NSLog(@"[MXRoom] paginateBackMessages error: %@", error); - failure(error); - }]; - - if (messagesFromStoreCount) - { - // Disable retry to let the caller handle messages from store without delay. - // The caller will trigger a new pagination if need. - operation.maxNumberOfTries = 1; - } - } - else - { - // Nothing more to do - complete(); - - NSLog(@"[MXRoom] paginateBackMessages : is done"); - } - - return operation; + return [_liveTimeLine paginate:numItems direction:MXEventDirectionBackwards onlyFromStore:onlyFromStore complete:complete failure:failure]; + +// MXHTTPOperation *operation; +// +// NSAssert(nil != backState, @"[MXRoom] paginateBackMessages: resetBackState must be called before starting the back pagination"); +// +// // Return messages in the store first +// NSUInteger messagesFromStoreCount = 0; +// NSArray *messagesFromStore = [mxSession.store paginateRoom:self.state.roomId numMessages:numItems]; +// if (messagesFromStore) +// { +// messagesFromStoreCount = messagesFromStore.count; +// } +// +// NSLog(@"[MXRoom] paginateBackMessages %tu messages in %@ (%tu are retrieved from the store)", numItems, self.state.roomId, messagesFromStoreCount); +// +// if (messagesFromStoreCount) +// { +// @autoreleasepool +// { +// // messagesFromStore are in chronological order +// // Handle events from the most recent +// for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) +// { +// MXEvent *event = messagesFromStore[i]; +// [self handleMessage:event direction:MXEventDirectionBackwards]; +// } +// +// numItems -= messagesFromStoreCount; +// } +// } +// +// if (onlyFromStore && messagesFromStoreCount) +// { +// complete(); +// +// NSLog(@"[MXRoom] paginateBackMessages : is done from the store"); +// return nil; +// } +// +// if (0 < numItems && NO == [mxSession.store hasReachedHomeServerPaginationEndForRoom:self.state.roomId]) +// { +// // Not enough messages: make a pagination request to the home server +// // from last known token +// NSString *paginationToken = [mxSession.store paginationTokenOfRoom:self.state.roomId]; +// if (nil == paginationToken) { +// paginationToken = @"END"; +// } +// +// NSLog(@"[MXRoom] paginateBackMessages : request %tu messages from the server", numItems); +// +// operation = [mxSession.matrixRestClient messagesForRoom:self.state.roomId +// from:paginationToken +// to:nil +// limit:numItems +// success:^(MXPaginationResponse *paginatedResponse) { +// +// @autoreleasepool +// { +// NSLog(@"[MXRoom] paginateBackMessages : get %tu messages from the server", paginatedResponse.chunk.count); +// +// // Check pagination end - @see SPEC-319 ticket +// if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) +// { +// // We run out of items +// [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:self.state.roomId andValue:YES]; +// } +// +// // Process received events and update pagination tokens +// [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; +// +// // Commit store changes +// if ([mxSession.store respondsToSelector:@selector(commit)]) +// { +// [mxSession.store commit]; +// } +// +// // Inform the method caller +// complete(); +// +// NSLog(@"[MXRoom] paginateBackMessages : is done"); +// } +// +// } failure:^(NSError *error) { +// // Check whether the pagination end is reached +// MXError *mxError = [[MXError alloc] initWithNSError:error]; +// if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) +// { +// // We run out of items +// [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:self.state.roomId andValue:YES]; +// +// NSLog(@"[MXRoom] paginateBackMessages: pagination end has been reached"); +// +// // Ignore the error +// complete(); +// return; +// } +// +// NSLog(@"[MXRoom] paginateBackMessages error: %@", error); +// failure(error); +// }]; +// +// if (messagesFromStoreCount) +// { +// // Disable retry to let the caller handle messages from store without delay. +// // The caller will trigger a new pagination if need. +// operation.maxNumberOfTries = 1; +// } +// } +// else +// { +// // Nothing more to do +// complete(); +// +// NSLog(@"[MXRoom] paginateBackMessages : is done"); +// } +// +// return operation; } - (NSUInteger)remainingMessagesForPaginationInStore { - return [mxSession.store remainingMessagesForPaginationInRoom:_state.roomId]; + return [mxSession.store remainingMessagesForPaginationInRoom:self.state.roomId]; } @@ -672,7 +576,7 @@ - (MXHTTPOperation*)sendEventOfType:(MXEventTypeString)eventTypeString success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient sendEventToRoom:_state.roomId eventType:eventTypeString content:content success:success failure:failure]; + return [mxSession.matrixRestClient sendEventToRoom:self.state.roomId eventType:eventTypeString content:content success:success failure:failure]; } - (MXHTTPOperation*)sendStateEventOfType:(MXEventTypeString)eventTypeString @@ -680,7 +584,7 @@ - (MXHTTPOperation*)sendStateEventOfType:(MXEventTypeString)eventTypeString success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient sendStateEventToRoom:_state.roomId eventType:eventTypeString content:content success:success failure:failure]; + return [mxSession.matrixRestClient sendStateEventToRoom:self.state.roomId eventType:eventTypeString content:content success:success failure:failure]; } - (MXHTTPOperation*)sendMessageOfType:(MXMessageType)msgType @@ -688,28 +592,28 @@ - (MXHTTPOperation*)sendMessageOfType:(MXMessageType)msgType success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient sendMessageToRoom:_state.roomId msgType:msgType content:content success:success failure:failure]; + return [mxSession.matrixRestClient sendMessageToRoom:self.state.roomId msgType:msgType content:content success:success failure:failure]; } - (MXHTTPOperation*)sendTextMessage:(NSString*)text success:(void (^)(NSString *eventId))success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient sendTextMessageToRoom:_state.roomId text:text success:success failure:failure]; + return [mxSession.matrixRestClient sendTextMessageToRoom:self.state.roomId text:text success:success failure:failure]; } - (MXHTTPOperation*)setTopic:(NSString*)topic success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient setRoomTopic:_state.roomId topic:topic success:success failure:failure]; + return [mxSession.matrixRestClient setRoomTopic:self.state.roomId topic:topic success:success failure:failure]; } - (MXHTTPOperation*)setAvatar:(NSString*)avatar success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient setRoomAvatar:_state.roomId avatar:avatar success:success failure:failure]; + return [mxSession.matrixRestClient setRoomAvatar:self.state.roomId avatar:avatar success:success failure:failure]; } @@ -717,13 +621,13 @@ - (MXHTTPOperation*)setName:(NSString*)name success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient setRoomName:_state.roomId name:name success:success failure:failure]; + return [mxSession.matrixRestClient setRoomName:self.state.roomId name:name success:success failure:failure]; } - (MXHTTPOperation*)join:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession joinRoom:_state.roomId success:^(MXRoom *room) { + return [mxSession joinRoom:self.state.roomId success:^(MXRoom *room) { success(); } failure:failure]; } @@ -731,21 +635,21 @@ - (MXHTTPOperation*)join:(void (^)())success - (MXHTTPOperation*)leave:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession leaveRoom:_state.roomId success:success failure:failure]; + return [mxSession leaveRoom:self.state.roomId success:success failure:failure]; } - (MXHTTPOperation*)inviteUser:(NSString*)userId success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient inviteUser:userId toRoom:_state.roomId success:success failure:failure]; + return [mxSession.matrixRestClient inviteUser:userId toRoom:self.state.roomId success:success failure:failure]; } - (MXHTTPOperation*)inviteUserByEmail:(NSString*)email success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient inviteUserByEmail:email toRoom:_state.roomId success:success failure:failure]; + return [mxSession.matrixRestClient inviteUserByEmail:email toRoom:self.state.roomId success:success failure:failure]; } - (MXHTTPOperation*)kickUser:(NSString*)userId @@ -753,7 +657,7 @@ - (MXHTTPOperation*)kickUser:(NSString*)userId success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient kickUser:userId fromRoom:_state.roomId reason:reason success:success failure:failure]; + return [mxSession.matrixRestClient kickUser:userId fromRoom:self.state.roomId reason:reason success:success failure:failure]; } - (MXHTTPOperation*)banUser:(NSString*)userId @@ -761,14 +665,14 @@ - (MXHTTPOperation*)banUser:(NSString*)userId success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient banUser:userId inRoom:_state.roomId reason:reason success:success failure:failure]; + return [mxSession.matrixRestClient banUser:userId inRoom:self.state.roomId reason:reason success:success failure:failure]; } - (MXHTTPOperation*)unbanUser:(NSString*)userId success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient unbanUser:userId inRoom:_state.roomId success:success failure:failure]; + return [mxSession.matrixRestClient unbanUser:userId inRoom:self.state.roomId success:success failure:failure]; } - (MXHTTPOperation*)setPowerLevelOfUserWithUserID:(NSString *)userId powerLevel:(NSUInteger)powerLevel @@ -777,7 +681,7 @@ - (MXHTTPOperation*)setPowerLevelOfUserWithUserID:(NSString *)userId powerLevel: { // To set this new value, we have to take the current powerLevels content, // Update it with expected values and send it to the home server. - NSMutableDictionary *newPowerLevelsEventContent = [NSMutableDictionary dictionaryWithDictionary:_state.powerLevels.JSONDictionary]; + NSMutableDictionary *newPowerLevelsEventContent = [NSMutableDictionary dictionaryWithDictionary:self.state.powerLevels.JSONDictionary]; NSMutableDictionary *newPowerLevelsEventContentUsers = [NSMutableDictionary dictionaryWithDictionary:newPowerLevelsEventContent[@"users"]]; newPowerLevelsEventContentUsers[userId] = [NSNumber numberWithUnsignedInteger:powerLevel]; @@ -795,7 +699,7 @@ - (MXHTTPOperation*)sendTypingNotification:(BOOL)typing success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient sendTypingNotificationInRoom:_state.roomId typing:typing timeout:timeout success:success failure:failure]; + return [mxSession.matrixRestClient sendTypingNotificationInRoom:self.state.roomId typing:typing timeout:timeout success:success failure:failure]; } - (MXHTTPOperation*)redactEvent:(NSString*)eventId @@ -803,7 +707,7 @@ - (MXHTTPOperation*)redactEvent:(NSString*)eventId success:(void (^)())success failure:(void (^)(NSError *error))failure { - return [mxSession.matrixRestClient redactEvent:eventId inRoom:_state.roomId reason:reason success:success failure:failure]; + return [mxSession.matrixRestClient redactEvent:eventId inRoom:self.state.roomId reason:reason success:success failure:failure]; } @@ -813,7 +717,7 @@ - (void)storeOutgoingMessage:(MXEvent*)outgoingMessage if ([mxSession.store respondsToSelector:@selector(storeOutgoingMessageForRoom:outgoingMessage:)] && [mxSession.store respondsToSelector:@selector(commit)]) { - [mxSession.store storeOutgoingMessageForRoom:_state.roomId outgoingMessage:outgoingMessage]; + [mxSession.store storeOutgoingMessageForRoom:self.state.roomId outgoingMessage:outgoingMessage]; [mxSession.store commit]; } } @@ -823,7 +727,7 @@ - (void)removeAllOutgoingMessages if ([mxSession.store respondsToSelector:@selector(removeAllOutgoingMessagesFromRoom:)] && [mxSession.store respondsToSelector:@selector(commit)]) { - [mxSession.store removeAllOutgoingMessagesFromRoom:_state.roomId]; + [mxSession.store removeAllOutgoingMessagesFromRoom:self.state.roomId]; [mxSession.store commit]; } } @@ -833,7 +737,7 @@ - (void)removeOutgoingMessage:(NSString*)outgoingMessageEventId if ([mxSession.store respondsToSelector:@selector(removeOutgoingMessageFromRoom:outgoingMessage:)] && [mxSession.store respondsToSelector:@selector(commit)]) { - [mxSession.store removeOutgoingMessageFromRoom:_state.roomId outgoingMessage:outgoingMessageEventId]; + [mxSession.store removeOutgoingMessageFromRoom:self.state.roomId outgoingMessage:outgoingMessageEventId]; [mxSession.store commit]; } } @@ -850,7 +754,7 @@ - (void)updateOutgoingMessage:(NSString *)outgoingMessageEventId withOutgoingMes { if ([mxSession.store respondsToSelector:@selector(outgoingMessagesInRoom:)]) { - return [mxSession.store outgoingMessagesInRoom:_state.roomId]; + return [mxSession.store outgoingMessagesInRoom:self.state.roomId]; } else { @@ -866,7 +770,7 @@ - (MXHTTPOperation*)addTag:(NSString*)tag failure:(void (^)(NSError *error))failure { // _accountData.tags will be updated by the live streams - return [mxSession.matrixRestClient addTag:tag withOrder:order toRoom:_state.roomId success:success failure:failure]; + return [mxSession.matrixRestClient addTag:tag withOrder:order toRoom:self.state.roomId success:success failure:failure]; } - (MXHTTPOperation*)removeTag:(NSString*)tag @@ -874,7 +778,7 @@ - (MXHTTPOperation*)removeTag:(NSString*)tag failure:(void (^)(NSError *error))failure { // _accountData.tags will be updated by the live streams - return [mxSession.matrixRestClient removeTag:tag fromRoom:_state.roomId success:success failure:failure]; + return [mxSession.matrixRestClient removeTag:tag fromRoom:self.state.roomId success:success failure:failure]; } - (MXHTTPOperation*)replaceTag:(NSString*)oldTag @@ -918,71 +822,10 @@ - (MXHTTPOperation*)replaceTag:(NSString*)oldTag #pragma mark - Voice over IP - (MXCall *)placeCallWithVideo:(BOOL)video { - return [mxSession.callManager placeCallInRoom:_state.roomId withVideo:video]; + return [mxSession.callManager placeCallInRoom:self.state.roomId withVideo:video]; } -#pragma mark - Events listeners -- (id)listenToEvents:(MXOnRoomEvent)onEvent -{ - return [self listenToEventsOfTypes:nil onEvent:onEvent]; -} - -- (id)listenToEventsOfTypes:(NSArray*)types onEvent:(MXOnRoomEvent)onEvent -{ - MXEventListener *listener = [[MXEventListener alloc] initWithSender:self andEventTypes:types andListenerBlock:onEvent]; - - [eventListeners addObject:listener]; - - return listener; -} - -- (void)removeListener:(id)listener -{ - [eventListeners removeObject:listener]; -} - -- (void)removeAllListeners -{ - [eventListeners removeAllObjects]; -} - -- (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction -{ - MXRoomState * roomState; - - if (MXEventDirectionBackwards == direction) - { - roomState = backState; - } - else - { - if ([event isState]) - { - // Provide the state of the room before this event - roomState = previousState; - } - else - { - roomState = _state; - } - } - - // Notify all listeners - // The SDK client may remove a listener while calling them by enumeration - // So, use a copy of them - NSArray *listeners = [eventListeners copy]; - - for (MXEventListener *listener in listeners) - { - // And check the listener still exists before calling it - if (NSNotFound != [eventListeners indexOfObject:listener]) - { - [listener notify:event direction:direction andCustomObject:roomState]; - } - } -} - #pragma mark - Receipts management - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)direction @@ -1011,7 +854,7 @@ - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)directio data.eventId = eventId; data.ts = ((NSNumber*)[params objectForKey:@"ts"]).longLongValue; - managedEvents |= [mxSession.store storeReceipt:data roomId:_state.roomId]; + managedEvents |= [mxSession.store storeReceipt:data roomId:self.state.roomId]; } } } @@ -1021,7 +864,7 @@ - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)directio if (managedEvents) { // Notify listeners - [self notifyListeners:event direction:direction]; + [_liveTimeLine notifyListeners:event direction:direction]; } return managedEvents; @@ -1035,7 +878,7 @@ - (BOOL)setReadReceiptToken:(NSString*)token ts:(long)ts data.eventId = token; data.ts = ts; - if ([mxSession.store storeReceipt:data roomId:_state.roomId]) + if ([mxSession.store storeReceipt:data roomId:self.state.roomId]) { if ([mxSession.store respondsToSelector:@selector(commit)]) { @@ -1049,7 +892,7 @@ - (BOOL)setReadReceiptToken:(NSString*)token ts:(long)ts - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; { - MXEvent* event =[mxSession.store lastMessageOfRoom:_state.roomId withTypeIn:_acknowledgableEventTypes]; + MXEvent* event =[mxSession.store lastMessageOfRoom:self.state.roomId withTypeIn:_acknowledgableEventTypes]; // Sanity check on event id: Do not send read receipt on event without id if (event.eventId && ([event.eventId hasPrefix:kMXRoomInviteStateEventIdPrefix] == NO)) { @@ -1059,7 +902,7 @@ - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; data.eventId = event.eventId; data.ts = (uint64_t) ([[NSDate date] timeIntervalSince1970] * 1000); - if ([mxSession.store storeReceipt:data roomId:_state.roomId]) + if ([mxSession.store storeReceipt:data roomId:self.state.roomId]) { if ([mxSession.store respondsToSelector:@selector(commit)]) { @@ -1068,7 +911,7 @@ - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; if (sendReceipt) { - [mxSession.matrixRestClient sendReadReceipts:_state.roomId eventId:event.eventId success:^(NSString *eventId) { + [mxSession.matrixRestClient sendReadReceipts:self.state.roomId eventId:event.eventId success:^(NSString *eventId) { } failure:^(NSError *error) { @@ -1089,12 +932,12 @@ - (NSComparisonResult)compareOriginServerTs:(MXRoom *)otherRoom -(NSArray*) unreadEvents { - return [mxSession.store unreadEvents:_state.roomId withTypeIn:_acknowledgableEventTypes]; + return [mxSession.store unreadEvents:self.state.roomId withTypeIn:_acknowledgableEventTypes]; } - (NSArray*)getEventReceipts:(NSString*)eventId sorted:(BOOL)sort { - NSArray *receipts = [mxSession.store getEventReceipts:_state.roomId eventId:eventId sorted:sort]; + NSArray *receipts = [mxSession.store getEventReceipts:self.state.roomId eventId:eventId sorted:sort]; // if some receipts are found if (receipts) @@ -1126,7 +969,7 @@ - (NSArray*)getEventReceipts:(NSString*)eventId sorted:(BOOL)sort - (NSString *)description { - return [NSString stringWithFormat:@" %@: %@ - %@", self, _state.roomId, _state.name, _state.topic]; + return [NSString stringWithFormat:@" %@: %@ - %@", self, self.state.roomId, self.state.name, self.state.topic]; } @end diff --git a/MatrixSDK/Data/MXSessionEventListener.m b/MatrixSDK/Data/MXSessionEventListener.m index d4f98b235a..53a64fb60a 100644 --- a/MatrixSDK/Data/MXSessionEventListener.m +++ b/MatrixSDK/Data/MXSessionEventListener.m @@ -45,7 +45,7 @@ - (void)addRoomToSpy:(MXRoom*)room if (![roomEventListeners objectForKey:room.state.roomId]) { roomEventListeners[room.state.roomId] = - [room listenToEventsOfTypes:self.eventTypes onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:self.eventTypes onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { self.listenerBlock(event, direction, roomState); }]; } @@ -56,7 +56,7 @@ - (void)removeSpiedRoom:(MXRoom*)room { if ([roomEventListeners objectForKey:room.state.roomId]) { - [room removeListener:roomEventListeners[room.state.roomId]]; + [room.liveTimeLine removeListener:roomEventListeners[room.state.roomId]]; [roomEventListeners removeObjectForKey:room.state.roomId]; } } @@ -69,8 +69,7 @@ - (void)removeAllSpiedRooms for (NSString *roomId in roomEventListeners) { MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room removeListener:roomEventListeners[room.state.roomId]]; - + [room.liveTimeLine removeListener:roomEventListeners[room.state.roomId]]; } [roomEventListeners removeAllObjects]; } diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 5b59a1f2c5..1f4035185a 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -440,7 +440,7 @@ - (void)close // Clean MXRooms for (MXRoom *room in rooms.allValues) { - [room removeAllListeners]; + [room.liveTimeLine removeAllListeners]; } [rooms removeAllObjects]; diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index bb2d281121..f12c73753e 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -106,7 +106,7 @@ - (void)testIsState __block NSUInteger eventCount = 0; - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTAssertFalse(event.isState, "Room messages are not states. message: %@", event); diff --git a/MatrixSDKTests/MXNotificationCenterTests.m b/MatrixSDKTests/MXNotificationCenterTests.m index 519504d902..fd9e2c69b6 100644 --- a/MatrixSDKTests/MXNotificationCenterTests.m +++ b/MatrixSDKTests/MXNotificationCenterTests.m @@ -145,7 +145,7 @@ - (void)testDefaultPushOnAllNonYouMessagesRule mxSession = bobSession; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [bobSession.notificationCenter listenToNotifications:^(MXEvent *event, MXRoomState *roomState, MXPushRule *rule) { @@ -181,7 +181,7 @@ - (void)testDefaultContentCondition mxSession = bobSession; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { NSString *messageFromAlice = @"mxBob: you should be notified for this message"; diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index afdfec83f1..fb233c4c0e 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -107,7 +107,7 @@ - (void)testBackPaginationForScenario1 MXRoom *room = [mxSession roomWithRoomId:roomId]; __block NSUInteger eventCount = 0; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { // Check each expected event and their roomState contect // Events are received in the reverse order @@ -191,7 +191,7 @@ - (void)testLiveEventsForScenario1 MXRoom *room = [mxSession roomWithRoomId:roomId]; __block NSUInteger eventCount = 0; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { // Check each expected event and their roomState contect // Events are live. Then comes in order diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index 2fbd7336b0..8ae1ac5b7a 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -119,7 +119,7 @@ - (void)testRoomTopicLive XCTAssertNil(room.state.topic, @"There must be no room topic yet. Found: %@", room.state.topic); // Listen to live event. We should receive only one: a m.room.topic event - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(event.eventType, MXEventTypeRoomTopic); @@ -192,7 +192,7 @@ - (void)testRoomAvatarLive XCTAssertNil(room.state.avatar, @"There must be no room avatar yet. Found: %@", room.state.avatar); // Listen to live event. We should receive only one: a m.room.avatar event - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(event.eventType, MXEventTypeRoomAvatar); @@ -264,7 +264,7 @@ - (void)testRoomNameLive XCTAssertNil(room.state.name, @"There must be no room name yet. Found: %@", room.state.name); // Listen to live event. We should receive only one: a m.room.name event - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(event.eventType, MXEventTypeRoomName); @@ -594,7 +594,7 @@ - (void)testMXRoomJoin MXRoom *newRoom = [mxSession roomWithRoomId:roomId]; - [newRoom listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [newRoom.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventDirectionForwards == event) { // We should receive only join events in live diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index 087593cbbc..637e59ec8b 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -70,7 +70,7 @@ - (void)testListenerForAllLiveEvents }; // Register the listener - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(direction, MXEventDirectionForwards); @@ -124,7 +124,7 @@ - (void)testListenerForRoomMessageLiveEvents }; // Register the listener for m.room.message.only - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(direction, MXEventDirectionForwards); @@ -166,7 +166,7 @@ - (void)testLeave NSString *roomId = room.state.roomId; __block MXMembership lastKnownMembership = MXMembershipUnknown; - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { lastKnownMembership = room.state.membership; }]; @@ -238,7 +238,7 @@ - (void)testSetPowerLevelOfUser MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomPowerLevels] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomPowerLevels] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual([room.state.powerLevels powerLevelOfUserWithUserID:aliceRestClient.credentials.userId], 36); @@ -269,7 +269,7 @@ - (void)testPaginateBackMessagesCancel MXRoom *room = [mxSession roomWithRoomId:roomId]; __block NSUInteger eventCount = 0; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTFail(@"We should not receive events. Received: %@", event); @@ -309,7 +309,7 @@ - (void)testTypingUsersNotifications XCTAssertEqual(room.typingUsers.count, 0); - [room listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(room.typingUsers.count, 1); XCTAssertEqualObjects(room.typingUsers[0], bobRestClient.credentials.userId); @@ -341,7 +341,7 @@ - (void)testAddAndRemoveTag __block NSUInteger tagEventUpdata = 0; // Wait for the m.tag event to get the room tags update - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (++tagEventUpdata == 1) { @@ -387,7 +387,7 @@ - (void)testReplaceTag NSString *newTagOrder = nil; // Wait for the m.tag event that corresponds to "newTag" - [room listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { MXRoomTag *newRoomTag = room.accountData.tags[newTag]; if (newRoomTag) diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index dc71ac20b9..3cb5d3c77f 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -361,7 +361,7 @@ - (void)testClose MXRoom *room = [mxSession roomWithRoomId:roomId]; XCTAssert(room); - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTFail(@"We should not receive events after closing the session. Received: %@", event); }]; @@ -464,7 +464,7 @@ - (void)testPauseResume }]; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTAssertFalse(paused, @"We should not receive events when paused. Received: %@", event); }]; @@ -531,7 +531,7 @@ - (void)testPauseResumeOnNothingNew }]; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTAssertFalse(paused, @"We should not receive events when paused. Received: %@", event); }]; diff --git a/MatrixSDKTests/MXStoreMemoryStoreTests.m b/MatrixSDKTests/MXStoreMemoryStoreTests.m index 2de1a43264..48b3b33ef9 100644 --- a/MatrixSDKTests/MXStoreMemoryStoreTests.m +++ b/MatrixSDKTests/MXStoreMemoryStoreTests.m @@ -191,7 +191,7 @@ - (void)testMXMemoryStorePaginate __block NSUInteger eventCount = 0; __block MXEvent *firstEventInTheRoom; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; @@ -204,11 +204,11 @@ - (void)testMXMemoryStorePaginate XCTAssertEqual(firstEventInTheRoom.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); - [room removeAllListeners]; + [room.liveTimeLine removeAllListeners]; __block NSUInteger eventCount2 = 0; __block MXEvent *firstEventInTheRoom2; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount2++; @@ -245,7 +245,7 @@ - (void)testMXMemoryStorePaginateAgain __block NSInteger paginateBackMessagesCallCount = 0; __block NSMutableArray *roomEvents = [NSMutableArray array]; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(paginateBackMessagesCallCount, 1, @"Messages must asynchronously come"); @@ -255,10 +255,10 @@ - (void)testMXMemoryStorePaginateAgain [room resetBackState]; [room paginateBackMessages:8 onlyFromStore:NO complete:^() { - [room removeAllListeners]; + [room.liveTimeLine removeAllListeners]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [room2Events addObject:event]; diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 5188f25136..8b0bf7e56f 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -248,7 +248,7 @@ - (void)checkPaginateBack:(MXRoom*)room ]; __block NSUInteger eventCount = 0; - [room listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; }]; @@ -276,7 +276,7 @@ - (void)checkPaginateBackFilter:(MXRoom*)room ]; __block NSUInteger eventCount = 0; - [room listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; @@ -309,7 +309,7 @@ - (void)checkPaginateBackOrder:(MXRoom*)room ]; __block uint64_t prev_ts = -1; - [room listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssert(event.originServerTs, @"The event should have an attempt: %@", event); @@ -335,7 +335,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room { __block NSUInteger eventCount = 0; __block NSMutableArray *events = [NSMutableArray array]; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; @@ -361,7 +361,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room - (void)checkSeveralPaginateBacks:(MXRoom*)room { __block NSMutableArray *roomEvents = [NSMutableArray array]; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [roomEvents addObject:event]; }]; @@ -373,7 +373,7 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room2 listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [room2Events addObject:event]; }]; @@ -443,7 +443,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room2 listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventDirectionForwards != direction) { @@ -452,7 +452,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room }]; __block NSUInteger liveEvents = 0; - [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventDirectionForwards == direction) { @@ -619,7 +619,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room [room2 join:^{ NSMutableArray *events = [NSMutableArray array]; - [room2 listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (0 == events.count) { @@ -685,7 +685,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room { __block NSUInteger eventCount = 0; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; }]; @@ -735,7 +735,7 @@ - (void)checkRedactEvent:(MXRoom*)room { __block NSString *messageEventId; - [room listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventTypeRoomMessage == event.eventType) { From c7adcde9810930b947eedb0fa1981bda99932bd1 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 22 Feb 2016 17:16:00 +0100 Subject: [PATCH 38/80] MXStoreTests: Fixed checkCanPaginateFromHomeServer tests. The regression was due to https://github.com/matrix-org/matrix-ios-sdk/commit/cde06bfe396e615b7995d44817cdb317ea45d5aa --- MatrixSDKTests/MXStoreTests.m | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 8b0bf7e56f..e4d26e24bc 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -542,9 +542,17 @@ - (void)checkCanPaginateFromHomeServer:(MXRoom*)room [room paginateBackMessages:100 onlyFromStore:NO complete:^() { - XCTAssertFalse(room.canPaginate, @"We must have reached the end of the pagination"); + // Due to SPEC-319, we need to paginate twice to be sure to hit the limit + [room paginateBackMessages:100 onlyFromStore:NO complete:^() { - [expectation fulfill]; + XCTAssertFalse(room.canPaginate, @"We must have reached the end of the pagination"); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; } failure:^(NSError *error) { XCTFail(@"The request should not fail - NSError: %@", error); From 3c61af5d99aa83e0dc227266c710ee91fbdb424d Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 22 Feb 2016 17:57:33 +0100 Subject: [PATCH 39/80] Event timeline: Complete code moving from MXRoom to MXEventTimeline --- MatrixSDK/Data/MXEventTimeLine.h | 9 + MatrixSDK/Data/MXEventTimeLine.m | 21 +- MatrixSDK/Data/MXRoom.h | 13 +- MatrixSDK/Data/MXRoom.m | 384 +------------------------------ 4 files changed, 33 insertions(+), 394 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeLine.h b/MatrixSDK/Data/MXEventTimeLine.h index 7765af0090..317472cda8 100644 --- a/MatrixSDK/Data/MXEventTimeLine.h +++ b/MatrixSDK/Data/MXEventTimeLine.h @@ -55,6 +55,15 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom - (id)initWithRoom:(MXRoom*)room andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId; +#pragma mark - Initialisation +/** + Process a state event in order to update the room state. + + @param event the state event. + */ +- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction; + + #pragma mark - Pagination /** Check if this timelime can be extended diff --git a/MatrixSDK/Data/MXEventTimeLine.m b/MatrixSDK/Data/MXEventTimeLine.m index 45b3877399..032ffce4b0 100644 --- a/MatrixSDK/Data/MXEventTimeLine.m +++ b/MatrixSDK/Data/MXEventTimeLine.m @@ -81,15 +81,14 @@ - (BOOL)canPaginate:(MXEventDirection)direction { BOOL canPaginate = NO; - if (direction == MXEventDirectionBackwards) - { - // canPaginate depends on two things: - // - did we end to paginate from the local MXStore? - // - did we reach the top of the pagination in our requests to the home server - canPaginate = (0 < [store remainingMessagesForPaginationInRoom:_state.roomId]) - || ![store hasReachedHomeServerPaginationEndForRoom:_state.roomId]; - - } + if (direction == MXEventDirectionBackwards) + { + // canPaginate depends on two things: + // - did we end to paginate from the local MXStore? + // - did we reach the top of the pagination in our requests to the home server + canPaginate = (0 < [store remainingMessagesForPaginationInRoom:_state.roomId]) + || ![store hasReachedHomeServerPaginationEndForRoom:_state.roomId]; + } else { if (self.isLiveTimeLine) @@ -105,6 +104,7 @@ - (BOOL)canPaginate:(MXEventDirection)direction return canPaginate; } + #pragma mark - Back pagination - (void)resetBackState { @@ -480,8 +480,7 @@ - (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction } else { - // Forwards and initialSync events update the current state of the room - + // Forwards events update the current state of the room [_state handleStateEvent:event]; // Special handling for presence diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 9b14e7fe07..0ac53f5464 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -93,11 +93,6 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; */ - (MXEvent*)lastMessageWithTypeIn:(NSArray*)type; -/** - Flag indicating if there are still events (in the past) to get with paginateBackMessages. - */ -@property (nonatomic, readonly) BOOL canPaginate; - /** The unread events. They are filtered by acknowledgableEventTypes. @@ -112,10 +107,9 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; - (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession; -//- (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession andInitialSync:(MXRoomInitialSync*)initialSync; - - (id)initWithRoomId:(NSString*)roomId andMatrixSession:(MXSession*)mxSession andStateEvents:(NSArray*)stateEvents andAccountData:(MXRoomAccountData*)accountData; + #pragma mark - server sync /** @@ -134,6 +128,11 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; #pragma mark - Back pagination +/** + Flag indicating if there are still events (in the past) to get with paginateBackMessages. + */ +@property (nonatomic, readonly) BOOL canPaginate; + /** Reset the back state so that future calls to paginate start over from live. Must be called when opening a room if interested in history. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index b3b6ef3f8d..5cb3d0aa58 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -70,30 +70,6 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 return self; } -//- (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 andInitialSync:(MXRoomInitialSync*)initialSync -//{ -// self = [self initWithRoomId:roomId andMatrixSession:mxSession2]; -// if (self) -// { -// self.state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:mxSession2 andInitialSync:initialSync andDirection:YES]; -// -// if (initialSync.invite) -// { -// // Process the invite event content: it contains a partial room state -// [self handleStateEvent:initialSync.invite direction:MXEventDirectionSync]; -// if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) -// { -// [mxSession.store storeStateForRoom:self.state.roomId stateEvents:self.state.stateEvents]; -// } -// -// // Put the invite in the room messages list so that -// [self handleMessage:initialSync.invite direction:MXEventDirectionSync]; -// [mxSession.store storeEventForRoom:roomId event:initialSync.invite direction:MXEventDirectionSync]; -// } -// } -// return self; -//} - - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 andStateEvents:(NSArray *)stateEvents andAccountData:(MXRoomAccountData*)accountData { self = [self initWithRoomId:roomId andMatrixSession:mxSession2]; @@ -103,7 +79,7 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 { for (MXEvent *event in stateEvents) { - //[self handleStateEvent:event direction:MXEventDirectionSync]; + [_liveTimeLine handleStateEvent:event direction:MXEventDirectionSync]; } _accountData = accountData; @@ -137,19 +113,10 @@ - (MXEvent *)lastMessageWithTypeIn:(NSArray*)types return [mxSession.store lastMessageOfRoom:self.state.roomId withTypeIn:types]; } -- (BOOL)canPaginate -{ - // canPaginate depends on two things: - // - did we end to paginate from the local MXStore? - // - did we reach the top of the pagination in our requests to the home server - return (0 < [mxSession.store remainingMessagesForPaginationInRoom:self.state.roomId]) - || ![mxSession.store hasReachedHomeServerPaginationEndForRoom:self.state.roomId]; -} - - #pragma mark - Sync - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync { + // Let the live timeline handle live events [_liveTimeLine handleJoinedRoomSync:roomSync]; // Handle here ephemeral events (if any) @@ -180,229 +147,11 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync { + // Let the live timeline handle live events [_liveTimeLine handleInvitedRoomSync:invitedRoomSync]; } -#pragma mark - Messages handling -/** - Handle bunch of events received in case of back pagination, global initial sync or room initial sync. - - @param roomMessages the response in which events are stored. - @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. - @param isTimeOrdered tell whether the events are in chronological order. - */ -//- (void)handleMessages:(MXPaginationResponse*)roomMessages -// direction:(MXEventDirection)direction -// isTimeOrdered:(BOOL)isTimeOrdered -//{ -// // Here direction is MXEventDirectionBackwards or MXEventDirectionSync -// if (direction == MXEventDirectionForwards) -// { -// NSLog(@"[MXRoom] handleMessages error: forward direction is not supported"); -// return; -// } -// -// NSArray *events = roomMessages.chunk; -// -// // Handles messages according to their time order -// if (NO == isTimeOrdered) -// { -// // [MXRestClient messages] returns messages in reverse chronological order -// for (MXEvent *event in events) { -// -// // Make sure we have not processed this event yet -// if (![mxSession.store eventExistsWithEventId:event.eventId inRoom:self.state.roomId]) -// { -// [self handleMessage:event direction:direction]; -// -// // Store the event -// [mxSession.store storeEventForRoom:self.state.roomId event:event direction:MXEventDirectionBackwards]; -// } -// } -// -// // Store how far back we've paginated -// [mxSession.store storePaginationTokenOfRoom:self.state.roomId andToken:roomMessages.end]; -// } -// else -// { -// // InitialSync returns messages in chronological order -// // We have to read them in reverse to fill the store from the beginning. -// for (NSInteger i = events.count - 1; i >= 0; i--) -// { -// MXEvent *event = events[i]; -// -// // Make sure we have not processed this event yet -// MXEvent *storedEvent = [mxSession.store eventWithEventId:event.eventId inRoom:self.state.roomId]; -// if (!storedEvent) -// { -// [self handleMessage:event direction:direction]; -// -// // Store the event -// [mxSession.store storeEventForRoom:self.state.roomId event:event direction:direction]; -// } -// } -// -// // Store where to start pagination -// [mxSession.store storePaginationTokenOfRoom:self.state.roomId andToken:roomMessages.start]; -// } -//} -// -//- (void)handleMessage:(MXEvent*)event direction:(MXEventDirection)direction -//{ -// if (event.isState) -// { -// // Consider here state event (except during initial sync) -// if (direction != MXEventDirectionSync) -// { -// [self cloneState:direction]; -// -// [self handleStateEvent:event direction:direction]; -// -// // Update store with new room state once a live event has been processed -// if (direction == MXEventDirectionForwards) -// { -// if ([mxSession.store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) -// { -// [mxSession.store storeStateForRoom:self.state.roomId stateEvents:self.state.stateEvents]; -// } -// } -// } -// } -// -// // Notify listener only for past events here -// // Live events are already notified from handleLiveEvent -// if (MXEventDirectionForwards != direction) -// { -// [self notifyListeners:event direction:direction]; -// } -// else -// { -// MXReceiptData* data = [[MXReceiptData alloc] init]; -// data.userId = event.sender; -// data.eventId = event.eventId; -// data.ts = event.originServerTs; -// -// [mxSession.store storeReceipt:data roomId:self.state.roomId]; -// // notifyListeners call is performed in the calling method. -// } -//} - - -#pragma mark - State events handling - -//- (void)cloneState:(MXEventDirection)direction -//{ -// // create a new instance of the state -// if (MXEventDirectionBackwards == direction) -// { -// backState = [backState copy]; -// } -// else -// { -// // Keep the previous state in cache for future usage in [self notifyListeners] -// previousState = self.state; -// -// self.state = [self.state copy]; -// } -//} -// -//- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction -//{ -// // Update the room state -// if (MXEventDirectionBackwards == direction) -// { -// [backState handleStateEvent:event]; -// } -// else -// { -// // Forwards and initialSync events update the current state of the room -// -// [self.state handleStateEvent:event]; -// -// // Special handling for presence -// if (MXEventTypeRoomMember == event.eventType) -// { -// // Update MXUser data -// MXUser *user = [mxSession getOrCreateUser:event.sender]; -// -// MXRoomMember *roomMember = [self.state memberWithUserId:event.sender]; -// if (roomMember && MXMembershipJoin == roomMember.membership) -// { -// [user updateWithRoomMemberEvent:event roomMember:roomMember]; -// } -// } -// } -//} - -//#pragma mark - Handle redaction -// -//- (void)handleRedaction:(MXEvent*)redactionEvent -//{ -// // Check whether the redacted event has been already processed -// MXEvent *redactedEvent = [mxSession.store eventWithEventId:redactionEvent.redacts inRoom:self.state.roomId]; -// if (redactedEvent) -// { -// // Redact the stored event -// redactedEvent = [redactedEvent prune]; -// redactedEvent.redactedBecause = redactionEvent.JSONDictionary; -// -// if (redactedEvent.isState) { -// // FIXME: The room state must be refreshed here since this redacted event. -// } -// -// // Store the event -// [mxSession.store replaceEvent:redactedEvent inRoom:self.state.roomId]; -// } -//} - - -//#pragma mark - Handle live event -// -///** -// Handle an event (message or state) that comes from the events streaming. -// -// @param event the event to handle. -// */ -//- (void)handleLiveEvent:(MXEvent*)event -//{ -// // Handle first typing notifications -// if (event.eventType == MXEventTypeTypingNotification) -// { -// // Typing notifications events are not room messages nor room state events -// // They are just volatile information -// MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); -// -// // Notify listeners -// [self notifyListeners:event direction:MXEventDirectionForwards]; -// } -// else if (event.eventType == MXEventTypeReceipt) -// { -// [self handleReceiptEvent:event direction:MXEventDirectionForwards]; -// } -// else -// { -// // Make sure we have not processed this event yet -// if (![mxSession.store eventExistsWithEventId:event.eventId inRoom:self.state.roomId]) -// { -// // Handle here redaction event from live event stream -// if (event.eventType == MXEventTypeRoomRedaction) -// { -// [self handleRedaction:event]; -// } -// -// [self handleMessage:event direction:MXEventDirectionForwards]; -// -// // Store the event -// [mxSession.store storeEventForRoom:self.state.roomId event:event direction:MXEventDirectionForwards]; -// -// // And notify listeners -// [self notifyListeners:event direction:MXEventDirectionForwards]; -// } -// } -//} - - #pragma mark - Room private account data handling /** Handle private user data events. @@ -429,14 +178,14 @@ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(M #pragma mark - Back pagination +- (BOOL)canPaginate +{ + return [_liveTimeLine canPaginate:MXEventDirectionBackwards]; +} + - (void)resetBackState { [_liveTimeLine resetBackState]; -// // Reset the back state to the current room state -// backState = [[MXRoomState alloc] initBackStateWith:self.state]; -// -// // Reset store pagination -// [mxSession.store resetPaginationOfRoom:self.state.roomId]; } - (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems @@ -445,123 +194,6 @@ - (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems failure:(void (^)(NSError *error))failure { return [_liveTimeLine paginate:numItems direction:MXEventDirectionBackwards onlyFromStore:onlyFromStore complete:complete failure:failure]; - -// MXHTTPOperation *operation; -// -// NSAssert(nil != backState, @"[MXRoom] paginateBackMessages: resetBackState must be called before starting the back pagination"); -// -// // Return messages in the store first -// NSUInteger messagesFromStoreCount = 0; -// NSArray *messagesFromStore = [mxSession.store paginateRoom:self.state.roomId numMessages:numItems]; -// if (messagesFromStore) -// { -// messagesFromStoreCount = messagesFromStore.count; -// } -// -// NSLog(@"[MXRoom] paginateBackMessages %tu messages in %@ (%tu are retrieved from the store)", numItems, self.state.roomId, messagesFromStoreCount); -// -// if (messagesFromStoreCount) -// { -// @autoreleasepool -// { -// // messagesFromStore are in chronological order -// // Handle events from the most recent -// for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) -// { -// MXEvent *event = messagesFromStore[i]; -// [self handleMessage:event direction:MXEventDirectionBackwards]; -// } -// -// numItems -= messagesFromStoreCount; -// } -// } -// -// if (onlyFromStore && messagesFromStoreCount) -// { -// complete(); -// -// NSLog(@"[MXRoom] paginateBackMessages : is done from the store"); -// return nil; -// } -// -// if (0 < numItems && NO == [mxSession.store hasReachedHomeServerPaginationEndForRoom:self.state.roomId]) -// { -// // Not enough messages: make a pagination request to the home server -// // from last known token -// NSString *paginationToken = [mxSession.store paginationTokenOfRoom:self.state.roomId]; -// if (nil == paginationToken) { -// paginationToken = @"END"; -// } -// -// NSLog(@"[MXRoom] paginateBackMessages : request %tu messages from the server", numItems); -// -// operation = [mxSession.matrixRestClient messagesForRoom:self.state.roomId -// from:paginationToken -// to:nil -// limit:numItems -// success:^(MXPaginationResponse *paginatedResponse) { -// -// @autoreleasepool -// { -// NSLog(@"[MXRoom] paginateBackMessages : get %tu messages from the server", paginatedResponse.chunk.count); -// -// // Check pagination end - @see SPEC-319 ticket -// if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) -// { -// // We run out of items -// [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:self.state.roomId andValue:YES]; -// } -// -// // Process received events and update pagination tokens -// [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; -// -// // Commit store changes -// if ([mxSession.store respondsToSelector:@selector(commit)]) -// { -// [mxSession.store commit]; -// } -// -// // Inform the method caller -// complete(); -// -// NSLog(@"[MXRoom] paginateBackMessages : is done"); -// } -// -// } failure:^(NSError *error) { -// // Check whether the pagination end is reached -// MXError *mxError = [[MXError alloc] initWithNSError:error]; -// if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) -// { -// // We run out of items -// [mxSession.store storeHasReachedHomeServerPaginationEndForRoom:self.state.roomId andValue:YES]; -// -// NSLog(@"[MXRoom] paginateBackMessages: pagination end has been reached"); -// -// // Ignore the error -// complete(); -// return; -// } -// -// NSLog(@"[MXRoom] paginateBackMessages error: %@", error); -// failure(error); -// }]; -// -// if (messagesFromStoreCount) -// { -// // Disable retry to let the caller handle messages from store without delay. -// // The caller will trigger a new pagination if need. -// operation.maxNumberOfTries = 1; -// } -// } -// else -// { -// // Nothing more to do -// complete(); -// -// NSLog(@"[MXRoom] paginateBackMessages : is done"); -// } -// -// return operation; } - (NSUInteger)remainingMessagesForPaginationInStore From 412bc034417ff1a95d7a6ba488ffdadc03641c35 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 22 Feb 2016 18:14:57 +0100 Subject: [PATCH 40/80] Event timeline: Made kMXRoomInviteStateEventIdPrefix common to MXEventTimeline and MXRoom --- MatrixSDK/Data/MXEventTimeLine.h | 5 +++++ MatrixSDK/Data/MXEventTimeLine.m | 4 ++-- MatrixSDK/Data/MXRoom.m | 2 -- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeLine.h b/MatrixSDK/Data/MXEventTimeLine.h index 317472cda8..91bc114ced 100644 --- a/MatrixSDK/Data/MXEventTimeLine.h +++ b/MatrixSDK/Data/MXEventTimeLine.h @@ -23,6 +23,11 @@ #import "MXRoomState.h" #import "MXHTTPOperation.h" +/** + Prefix used to build fake invite event. + */ +FOUNDATION_EXPORT NSString *const kMXRoomInviteStateEventIdPrefix; + /** Block called when an event of the registered types has been handled in the timeline. This is a specialisation of the `MXOnEvent` block. diff --git a/MatrixSDK/Data/MXEventTimeLine.m b/MatrixSDK/Data/MXEventTimeLine.m index 032ffce4b0..ff4037ef02 100644 --- a/MatrixSDK/Data/MXEventTimeLine.m +++ b/MatrixSDK/Data/MXEventTimeLine.m @@ -21,7 +21,7 @@ #import "MXError.h" -NSString *const kMXRoomInviteStateEventIdPrefix2 = @"invite-"; +NSString *const kMXRoomInviteStateEventIdPrefix = @"invite-"; @interface MXEventTimeLine () { @@ -338,7 +338,7 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync // Add a fake event id if none in order to be able to store the event if (!event.eventId) { - event.eventId = [NSString stringWithFormat:@"%@%@", kMXRoomInviteStateEventIdPrefix2, [[NSProcessInfo processInfo] globallyUniqueString]]; + event.eventId = [NSString stringWithFormat:@"%@%@", kMXRoomInviteStateEventIdPrefix, [[NSProcessInfo processInfo] globallyUniqueString]]; } // Report the room id in the event as it is skipped in /sync response diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 5cb3d0aa58..1cc87beb47 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -24,8 +24,6 @@ NSString *const kMXRoomSyncWithLimitedTimelineNotification = @"kMXRoomSyncWithLimitedTimelineNotification"; NSString *const kMXRoomInitialSyncNotification = @"kMXRoomInitialSyncNotification"; -NSString *const kMXRoomInviteStateEventIdPrefix = @"invite-"; - @interface MXRoom () { } From 092432d246b9d401f8e1f9143e4322b3a3c16caa Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 08:44:36 +0100 Subject: [PATCH 41/80] Event timeline: Renaming EventTimeLine -> EventTimeline --- MatrixSDK.xcodeproj/project.pbxproj | 16 +++++++------- .../{MXEventTimeLine.h => MXEventTimeline.h} | 6 ++--- .../{MXEventTimeLine.m => MXEventTimeline.m} | 10 ++++----- MatrixSDK/Data/MXRoom.h | 4 ++-- MatrixSDK/Data/MXRoom.m | 22 +++++++++---------- MatrixSDK/Data/MXSessionEventListener.m | 6 ++--- MatrixSDK/MXSession.m | 2 +- MatrixSDKTests/MXEventTests.m | 2 +- MatrixSDKTests/MXNotificationCenterTests.m | 4 ++-- MatrixSDKTests/MXRoomStateDynamicTests.m | 4 ++-- MatrixSDKTests/MXRoomStateTests.m | 8 +++---- MatrixSDKTests/MXRoomTests.m | 16 +++++++------- MatrixSDKTests/MXSessionTests.m | 6 ++--- MatrixSDKTests/MXStoreMemoryStoreTests.m | 12 +++++----- MatrixSDKTests/MXStoreTests.m | 22 +++++++++---------- 15 files changed, 70 insertions(+), 70 deletions(-) rename MatrixSDK/Data/{MXEventTimeLine.h => MXEventTimeline.h} (96%) rename MatrixSDK/Data/{MXEventTimeLine.m => MXEventTimeline.m} (99%) diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index f58118117e..1f5acc01a5 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -62,8 +62,8 @@ 32481A841C03572900782AD3 /* MXRoomAccountData.h in Headers */ = {isa = PBXBuildFile; fileRef = 32481A821C03572900782AD3 /* MXRoomAccountData.h */; }; 32481A851C03572900782AD3 /* MXRoomAccountData.m in Sources */ = {isa = PBXBuildFile; fileRef = 32481A831C03572900782AD3 /* MXRoomAccountData.m */; }; 325653831A2E14ED00CC0423 /* MXStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 325653821A2E14ED00CC0423 /* MXStoreTests.m */; }; - 326056851C76FDF2009D44AD /* MXEventTimeLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 326056831C76FDF1009D44AD /* MXEventTimeLine.h */; }; - 326056861C76FDF2009D44AD /* MXEventTimeLine.m in Sources */ = {isa = PBXBuildFile; fileRef = 326056841C76FDF1009D44AD /* MXEventTimeLine.m */; }; + 326056851C76FDF2009D44AD /* MXEventTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 326056831C76FDF1009D44AD /* MXEventTimeline.h */; }; + 326056861C76FDF2009D44AD /* MXEventTimeline.m in Sources */ = {isa = PBXBuildFile; fileRef = 326056841C76FDF1009D44AD /* MXEventTimeline.m */; }; 3264E2A21BDF8D1500F89A86 /* MXCoreDataRoomState.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264E29E1BDF8D1500F89A86 /* MXCoreDataRoomState.h */; }; 3264E2A31BDF8D1500F89A86 /* MXCoreDataRoomState.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264E29F1BDF8D1500F89A86 /* MXCoreDataRoomState.m */; }; 3264E2A41BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h in Headers */ = {isa = PBXBuildFile; fileRef = 3264E2A01BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h */; }; @@ -209,8 +209,8 @@ 32481A821C03572900782AD3 /* MXRoomAccountData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXRoomAccountData.h; sourceTree = ""; }; 32481A831C03572900782AD3 /* MXRoomAccountData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXRoomAccountData.m; sourceTree = ""; }; 325653821A2E14ED00CC0423 /* MXStoreTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXStoreTests.m; sourceTree = ""; }; - 326056831C76FDF1009D44AD /* MXEventTimeLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXEventTimeLine.h; sourceTree = ""; }; - 326056841C76FDF1009D44AD /* MXEventTimeLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEventTimeLine.m; sourceTree = ""; }; + 326056831C76FDF1009D44AD /* MXEventTimeline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXEventTimeline.h; sourceTree = ""; }; + 326056841C76FDF1009D44AD /* MXEventTimeline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEventTimeline.m; sourceTree = ""; }; 3264E29E1BDF8D1500F89A86 /* MXCoreDataRoomState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXCoreDataRoomState.h; sourceTree = ""; }; 3264E29F1BDF8D1500F89A86 /* MXCoreDataRoomState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXCoreDataRoomState.m; sourceTree = ""; }; 3264E2A01BDF8D1500F89A86 /* MXCoreDataRoomState+CoreDataProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MXCoreDataRoomState+CoreDataProperties.h"; sourceTree = ""; }; @@ -329,8 +329,8 @@ 32481A831C03572900782AD3 /* MXRoomAccountData.m */, 3220093619EFA4C9008DE41D /* MXEventListener.h */, 3220093719EFA4C9008DE41D /* MXEventListener.m */, - 326056831C76FDF1009D44AD /* MXEventTimeLine.h */, - 326056841C76FDF1009D44AD /* MXEventTimeLine.m */, + 326056831C76FDF1009D44AD /* MXEventTimeline.h */, + 326056841C76FDF1009D44AD /* MXEventTimeline.m */, 3220094319EFBF30008DE41D /* MXSessionEventListener.h */, 3220094419EFBF30008DE41D /* MXSessionEventListener.m */, 329FB1731A0A3A1600A5E88E /* MXRoomMember.h */, @@ -650,7 +650,7 @@ 320DFDE019DD99B60068622A /* MXSession.h in Headers */, 324095221AFA432F00D81C97 /* MXCallStackCall.h in Headers */, 3233606F1A403A0D0071A488 /* MXFileStore.h in Headers */, - 326056851C76FDF2009D44AD /* MXEventTimeLine.h in Headers */, + 326056851C76FDF2009D44AD /* MXEventTimeline.h in Headers */, 327137271A24D50A00DB6757 /* MXMyUser.h in Headers */, 3220093819EFA4C9008DE41D /* MXEventListener.h in Headers */, 71DE22E11BC7C51200284153 /* MXReceiptData.h in Headers */, @@ -809,7 +809,7 @@ 329FB1761A0A3A1600A5E88E /* MXRoomMember.m in Sources */, 323360701A403A0D0071A488 /* MXFileStore.m in Sources */, 32D7767E1A27860600FC4AA2 /* MXMemoryStore.m in Sources */, - 326056861C76FDF2009D44AD /* MXEventTimeLine.m in Sources */, + 326056861C76FDF2009D44AD /* MXEventTimeline.m in Sources */, 323B2B011BCE9B6700B11F34 /* MXCoreDataEvent.m in Sources */, 3265CB391A14C43E00E24B2F /* MXRoomState.m in Sources */, 323B2AD01BCD3EF000B11F34 /* MXCoreDataStore.m in Sources */, diff --git a/MatrixSDK/Data/MXEventTimeLine.h b/MatrixSDK/Data/MXEventTimeline.h similarity index 96% rename from MatrixSDK/Data/MXEventTimeLine.h rename to MatrixSDK/Data/MXEventTimeline.h index 91bc114ced..298501cc01 100644 --- a/MatrixSDK/Data/MXEventTimeLine.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -41,14 +41,14 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom @class MXRoom; /** - A `MXEventTimeLine` instance represents a contiguous sequence of events in a room. + A `MXEventTimeline` instance represents a contiguous sequence of events in a room. */ -@interface MXEventTimeLine : NSObject +@interface MXEventTimeline : NSObject @property (nonatomic, readonly) NSString *initialEventId; -@property (nonatomic, readonly) BOOL isLiveTimeLine; +@property (nonatomic, readonly) BOOL isLiveTimeline; /** diff --git a/MatrixSDK/Data/MXEventTimeLine.m b/MatrixSDK/Data/MXEventTimeline.m similarity index 99% rename from MatrixSDK/Data/MXEventTimeLine.m rename to MatrixSDK/Data/MXEventTimeline.m index ff4037ef02..801e26ddd8 100644 --- a/MatrixSDK/Data/MXEventTimeLine.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -14,7 +14,7 @@ limitations under the License. */ -#import "MXEventTimeLine.h" +#import "MXEventTimeline.h" #import "MXSession.h" #import "MXMemoryStore.h" @@ -23,7 +23,7 @@ NSString *const kMXRoomInviteStateEventIdPrefix = @"invite-"; -@interface MXEventTimeLine () +@interface MXEventTimeline () { // The list of event listeners (`MXEventListener`) of this timeline NSMutableArray *eventListeners; @@ -43,7 +43,7 @@ @interface MXEventTimeLine () } @end -@implementation MXEventTimeLine +@implementation MXEventTimeline - (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId { @@ -70,7 +70,7 @@ - (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NS return self; } -- (BOOL)isLiveTimeLine +- (BOOL)isLiveTimeline { return !_initialEventId; } @@ -91,7 +91,7 @@ - (BOOL)canPaginate:(MXEventDirection)direction } else { - if (self.isLiveTimeLine) + if (self.isLiveTimeline) { canPaginate = NO; } diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 0ac53f5464..40d343d989 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -24,7 +24,7 @@ #import "MXRoomAccountData.h" #import "MXHTTPOperation.h" #import "MXCall.h" -#import "MXEventTimeLine.h" +#import "MXEventTimeline.h" @class MXRoom; @class MXSession; @@ -60,7 +60,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; /** The live events timeline. */ -@property (nonatomic, readonly) MXEventTimeLine *liveTimeLine; +@property (nonatomic, readonly) MXEventTimeline *liveTimeline; /** The up-to-date state of the room. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 1cc87beb47..e5afb34ab6 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -39,7 +39,7 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 { mxSession = mxSession2; - _liveTimeLine = [[MXEventTimeLine alloc] initWithRoom:self andRoomId:roomId initialEventId:nil]; + _liveTimeline = [[MXEventTimeline alloc] initWithRoom:self andRoomId:roomId initialEventId:nil]; _accountData = [[MXRoomAccountData alloc] init]; @@ -77,7 +77,7 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 { for (MXEvent *event in stateEvents) { - [_liveTimeLine handleStateEvent:event direction:MXEventDirectionSync]; + [_liveTimeline handleStateEvent:event direction:MXEventDirectionSync]; } _accountData = accountData; @@ -89,7 +89,7 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 #pragma mark - Properties implementation - (MXRoomState *)state { - return _liveTimeLine.state; + return _liveTimeline.state; } - (void)setPartialTextMessage:(NSString *)partialTextMessage @@ -115,7 +115,7 @@ - (MXEvent *)lastMessageWithTypeIn:(NSArray*)types - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync { // Let the live timeline handle live events - [_liveTimeLine handleJoinedRoomSync:roomSync]; + [_liveTimeline handleJoinedRoomSync:roomSync]; // Handle here ephemeral events (if any) for (MXEvent *event in roomSync.ephemeral.events) @@ -131,7 +131,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); // Notify listeners - [_liveTimeLine notifyListeners:event direction:MXEventDirectionForwards]; + [_liveTimeline notifyListeners:event direction:MXEventDirectionForwards]; } else if (event.eventType == MXEventTypeReceipt) { @@ -146,7 +146,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync { // Let the live timeline handle live events - [_liveTimeLine handleInvitedRoomSync:invitedRoomSync]; + [_liveTimeline handleInvitedRoomSync:invitedRoomSync]; } @@ -170,7 +170,7 @@ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(M } // And notify listeners - [_liveTimeLine notifyListeners:event direction:direction]; + [_liveTimeline notifyListeners:event direction:direction]; } } @@ -178,12 +178,12 @@ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(M #pragma mark - Back pagination - (BOOL)canPaginate { - return [_liveTimeLine canPaginate:MXEventDirectionBackwards]; + return [_liveTimeline canPaginate:MXEventDirectionBackwards]; } - (void)resetBackState { - [_liveTimeLine resetBackState]; + [_liveTimeline resetBackState]; } - (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems @@ -191,7 +191,7 @@ - (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems complete:(void (^)())complete failure:(void (^)(NSError *error))failure { - return [_liveTimeLine paginate:numItems direction:MXEventDirectionBackwards onlyFromStore:onlyFromStore complete:complete failure:failure]; + return [_liveTimeline paginate:numItems direction:MXEventDirectionBackwards onlyFromStore:onlyFromStore complete:complete failure:failure]; } - (NSUInteger)remainingMessagesForPaginationInStore @@ -494,7 +494,7 @@ - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)directio if (managedEvents) { // Notify listeners - [_liveTimeLine notifyListeners:event direction:direction]; + [_liveTimeline notifyListeners:event direction:direction]; } return managedEvents; diff --git a/MatrixSDK/Data/MXSessionEventListener.m b/MatrixSDK/Data/MXSessionEventListener.m index 53a64fb60a..c4afa704b4 100644 --- a/MatrixSDK/Data/MXSessionEventListener.m +++ b/MatrixSDK/Data/MXSessionEventListener.m @@ -45,7 +45,7 @@ - (void)addRoomToSpy:(MXRoom*)room if (![roomEventListeners objectForKey:room.state.roomId]) { roomEventListeners[room.state.roomId] = - [room.liveTimeLine listenToEventsOfTypes:self.eventTypes onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:self.eventTypes onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { self.listenerBlock(event, direction, roomState); }]; } @@ -56,7 +56,7 @@ - (void)removeSpiedRoom:(MXRoom*)room { if ([roomEventListeners objectForKey:room.state.roomId]) { - [room.liveTimeLine removeListener:roomEventListeners[room.state.roomId]]; + [room.liveTimeline removeListener:roomEventListeners[room.state.roomId]]; [roomEventListeners removeObjectForKey:room.state.roomId]; } } @@ -69,7 +69,7 @@ - (void)removeAllSpiedRooms for (NSString *roomId in roomEventListeners) { MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeLine removeListener:roomEventListeners[room.state.roomId]]; + [room.liveTimeline removeListener:roomEventListeners[room.state.roomId]]; } [roomEventListeners removeAllObjects]; } diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 1f4035185a..c378cb5195 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -440,7 +440,7 @@ - (void)close // Clean MXRooms for (MXRoom *room in rooms.allValues) { - [room.liveTimeLine removeAllListeners]; + [room.liveTimeline removeAllListeners]; } [rooms removeAllObjects]; diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index f12c73753e..5955bec20a 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -106,7 +106,7 @@ - (void)testIsState __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTAssertFalse(event.isState, "Room messages are not states. message: %@", event); diff --git a/MatrixSDKTests/MXNotificationCenterTests.m b/MatrixSDKTests/MXNotificationCenterTests.m index fd9e2c69b6..31f38b605c 100644 --- a/MatrixSDKTests/MXNotificationCenterTests.m +++ b/MatrixSDKTests/MXNotificationCenterTests.m @@ -145,7 +145,7 @@ - (void)testDefaultPushOnAllNonYouMessagesRule mxSession = bobSession; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [bobSession.notificationCenter listenToNotifications:^(MXEvent *event, MXRoomState *roomState, MXPushRule *rule) { @@ -181,7 +181,7 @@ - (void)testDefaultContentCondition mxSession = bobSession; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { NSString *messageFromAlice = @"mxBob: you should be notified for this message"; diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index fb233c4c0e..f34a854d30 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -107,7 +107,7 @@ - (void)testBackPaginationForScenario1 MXRoom *room = [mxSession roomWithRoomId:roomId]; __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { // Check each expected event and their roomState contect // Events are received in the reverse order @@ -191,7 +191,7 @@ - (void)testLiveEventsForScenario1 MXRoom *room = [mxSession roomWithRoomId:roomId]; __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { // Check each expected event and their roomState contect // Events are live. Then comes in order diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index 8ae1ac5b7a..6b4bc19cd3 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -119,7 +119,7 @@ - (void)testRoomTopicLive XCTAssertNil(room.state.topic, @"There must be no room topic yet. Found: %@", room.state.topic); // Listen to live event. We should receive only one: a m.room.topic event - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(event.eventType, MXEventTypeRoomTopic); @@ -192,7 +192,7 @@ - (void)testRoomAvatarLive XCTAssertNil(room.state.avatar, @"There must be no room avatar yet. Found: %@", room.state.avatar); // Listen to live event. We should receive only one: a m.room.avatar event - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(event.eventType, MXEventTypeRoomAvatar); @@ -264,7 +264,7 @@ - (void)testRoomNameLive XCTAssertNil(room.state.name, @"There must be no room name yet. Found: %@", room.state.name); // Listen to live event. We should receive only one: a m.room.name event - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(event.eventType, MXEventTypeRoomName); @@ -594,7 +594,7 @@ - (void)testMXRoomJoin MXRoom *newRoom = [mxSession roomWithRoomId:roomId]; - [newRoom.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [newRoom.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventDirectionForwards == event) { // We should receive only join events in live diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index 637e59ec8b..6802082f5f 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -70,7 +70,7 @@ - (void)testListenerForAllLiveEvents }; // Register the listener - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(direction, MXEventDirectionForwards); @@ -124,7 +124,7 @@ - (void)testListenerForRoomMessageLiveEvents }; // Register the listener for m.room.message.only - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(direction, MXEventDirectionForwards); @@ -166,7 +166,7 @@ - (void)testLeave NSString *roomId = room.state.roomId; __block MXMembership lastKnownMembership = MXMembershipUnknown; - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { lastKnownMembership = room.state.membership; }]; @@ -238,7 +238,7 @@ - (void)testSetPowerLevelOfUser MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomPowerLevels] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomPowerLevels] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual([room.state.powerLevels powerLevelOfUserWithUserID:aliceRestClient.credentials.userId], 36); @@ -269,7 +269,7 @@ - (void)testPaginateBackMessagesCancel MXRoom *room = [mxSession roomWithRoomId:roomId]; __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTFail(@"We should not receive events. Received: %@", event); @@ -309,7 +309,7 @@ - (void)testTypingUsersNotifications XCTAssertEqual(room.typingUsers.count, 0); - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringTypingNotification] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(room.typingUsers.count, 1); XCTAssertEqualObjects(room.typingUsers[0], bobRestClient.credentials.userId); @@ -341,7 +341,7 @@ - (void)testAddAndRemoveTag __block NSUInteger tagEventUpdata = 0; // Wait for the m.tag event to get the room tags update - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (++tagEventUpdata == 1) { @@ -387,7 +387,7 @@ - (void)testReplaceTag NSString *newTagOrder = nil; // Wait for the m.tag event that corresponds to "newTag" - [room.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomTag] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { MXRoomTag *newRoomTag = room.accountData.tags[newTag]; if (newRoomTag) diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index 3cb5d3c77f..2311dfe5fd 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -361,7 +361,7 @@ - (void)testClose MXRoom *room = [mxSession roomWithRoomId:roomId]; XCTAssert(room); - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTFail(@"We should not receive events after closing the session. Received: %@", event); }]; @@ -464,7 +464,7 @@ - (void)testPauseResume }]; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTAssertFalse(paused, @"We should not receive events when paused. Received: %@", event); }]; @@ -531,7 +531,7 @@ - (void)testPauseResumeOnNothingNew }]; MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; XCTAssertFalse(paused, @"We should not receive events when paused. Received: %@", event); }]; diff --git a/MatrixSDKTests/MXStoreMemoryStoreTests.m b/MatrixSDKTests/MXStoreMemoryStoreTests.m index 48b3b33ef9..37c1543194 100644 --- a/MatrixSDKTests/MXStoreMemoryStoreTests.m +++ b/MatrixSDKTests/MXStoreMemoryStoreTests.m @@ -191,7 +191,7 @@ - (void)testMXMemoryStorePaginate __block NSUInteger eventCount = 0; __block MXEvent *firstEventInTheRoom; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; @@ -204,11 +204,11 @@ - (void)testMXMemoryStorePaginate XCTAssertEqual(firstEventInTheRoom.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); - [room.liveTimeLine removeAllListeners]; + [room.liveTimeline removeAllListeners]; __block NSUInteger eventCount2 = 0; __block MXEvent *firstEventInTheRoom2; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount2++; @@ -245,7 +245,7 @@ - (void)testMXMemoryStorePaginateAgain __block NSInteger paginateBackMessagesCallCount = 0; __block NSMutableArray *roomEvents = [NSMutableArray array]; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssertEqual(paginateBackMessagesCallCount, 1, @"Messages must asynchronously come"); @@ -255,10 +255,10 @@ - (void)testMXMemoryStorePaginateAgain [room resetBackState]; [room paginateBackMessages:8 onlyFromStore:NO complete:^() { - [room.liveTimeLine removeAllListeners]; + [room.liveTimeline removeAllListeners]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [room2Events addObject:event]; diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index e4d26e24bc..3d6d9e5b55 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -248,7 +248,7 @@ - (void)checkPaginateBack:(MXRoom*)room ]; __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; }]; @@ -276,7 +276,7 @@ - (void)checkPaginateBackFilter:(MXRoom*)room ]; __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; @@ -309,7 +309,7 @@ - (void)checkPaginateBackOrder:(MXRoom*)room ]; __block uint64_t prev_ts = -1; - [room.liveTimeLine listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { XCTAssert(event.originServerTs, @"The event should have an attempt: %@", event); @@ -335,7 +335,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room { __block NSUInteger eventCount = 0; __block NSMutableArray *events = [NSMutableArray array]; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; @@ -361,7 +361,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room - (void)checkSeveralPaginateBacks:(MXRoom*)room { __block NSMutableArray *roomEvents = [NSMutableArray array]; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [roomEvents addObject:event]; }]; @@ -373,7 +373,7 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room2.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { [room2Events addObject:event]; }]; @@ -443,7 +443,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room2.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventDirectionForwards != direction) { @@ -452,7 +452,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room }]; __block NSUInteger liveEvents = 0; - [room.liveTimeLine listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventDirectionForwards == direction) { @@ -627,7 +627,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room [room2 join:^{ NSMutableArray *events = [NSMutableArray array]; - [room2.liveTimeLine listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (0 == events.count) { @@ -693,7 +693,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room { __block NSUInteger eventCount = 0; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { eventCount++; }]; @@ -743,7 +743,7 @@ - (void)checkRedactEvent:(MXRoom*)room { __block NSString *messageEventId; - [room.liveTimeLine listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { if (MXEventTypeRoomMessage == event.eventType) { From 39b2ce2d48585ab84194249b9652c8a2b54e0245 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 09:00:50 +0100 Subject: [PATCH 42/80] Event timeline: Move all pagination API from MXRoom to MXEventTimeline --- MatrixSDK/Data/MXEventTimeline.h | 10 ++- MatrixSDK/Data/MXEventTimeline.m | 5 ++ MatrixSDK/Data/MXRoom.h | 39 --------- MatrixSDK/Data/MXRoom.m | 25 ------ MatrixSDKTests/MXEventTests.m | 4 +- MatrixSDKTests/MXRoomStateDynamicTests.m | 8 +- MatrixSDKTests/MXRoomTests.m | 4 +- MatrixSDKTests/MXStoreCoreDataStoreTests.m | 2 +- MatrixSDKTests/MXStoreFileStoreTests.m | 2 +- MatrixSDKTests/MXStoreMemoryStoreTests.m | 42 +++++----- MatrixSDKTests/MXStoreNoStoreTests.m | 2 +- MatrixSDKTests/MXStoreTests.m | 92 +++++++++++----------- 12 files changed, 92 insertions(+), 143 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index 298501cc01..7b929a2f0c 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -79,7 +79,7 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom this time. @param direction MXEventDirectionBackwards to check if we can paginate backwards. - MXEventDirectionForwards to check if we can go forwards + MXEventDirectionForwards to check if we can go forwards @return true if we can paginate in the given direction */ - (BOOL)canPaginate:(MXEventDirection)direction; @@ -109,6 +109,14 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom complete:(void (^)())complete failure:(void (^)(NSError *error))failure; +/** + Get the number of messages we can still back paginate from the store. + It provides the count of events available without making a request to the home server. + + @return the count of remaining messages in store. + */ +- (NSUInteger)remainingMessagesForBackPaginationInStore; + #pragma mark - Server sync /** diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 801e26ddd8..1718cc4e20 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -235,6 +235,11 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d return operation; } +- (NSUInteger)remainingMessagesForBackPaginationInStore +{ + return [store remainingMessagesForPaginationInRoom:_state.roomId]; +} + #pragma mark - Server sync - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 40d343d989..16c88d9603 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -127,45 +127,6 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync; -#pragma mark - Back pagination -/** - Flag indicating if there are still events (in the past) to get with paginateBackMessages. - */ -@property (nonatomic, readonly) BOOL canPaginate; - -/** - Reset the back state so that future calls to paginate start over from live. - Must be called when opening a room if interested in history. - */ -- (void)resetBackState; - -/** - Get more messages from the past. - The retrieved events will be sent to registered listeners. - - @param numItems the number of items to get. - @param onlyFromStore if YES, return available events from the store, do not make a pagination request to the homeserver. - @param complete A block object called when the operation is complete. - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. This instance can be nil - if no request to the home server is required. - */ -- (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems - onlyFromStore:(BOOL)onlyFromStore - complete:(void (^)())complete - failure:(void (^)(NSError *error))failure; - - -/** - Get the number of messages we can still paginate from the store. - It provides the count of events available without making a request to the home server. - - @return the count of remaining messages in store. - */ -- (NSUInteger)remainingMessagesForPaginationInStore; - - #pragma mark - Room operations /** Send a generic non state event to a room. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index e5afb34ab6..ec8009dad6 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -175,31 +175,6 @@ - (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(M } -#pragma mark - Back pagination -- (BOOL)canPaginate -{ - return [_liveTimeline canPaginate:MXEventDirectionBackwards]; -} - -- (void)resetBackState -{ - [_liveTimeline resetBackState]; -} - -- (MXHTTPOperation*)paginateBackMessages:(NSUInteger)numItems - onlyFromStore:(BOOL)onlyFromStore - complete:(void (^)())complete - failure:(void (^)(NSError *error))failure -{ - return [_liveTimeline paginate:numItems direction:MXEventDirectionBackwards onlyFromStore:onlyFromStore complete:complete failure:failure]; -} - -- (NSUInteger)remainingMessagesForPaginationInStore -{ - return [mxSession.store remainingMessagesForPaginationInRoom:self.state.roomId]; -} - - #pragma mark - Room operations - (MXHTTPOperation*)sendEventOfType:(MXEventTypeString)eventTypeString content:(NSDictionary*)content diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index 5955bec20a..217d1bc3d8 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -113,8 +113,8 @@ - (void)testIsState }]; - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertGreaterThan(eventCount, 0, "We should have received events in registerEventListenerForTypes"); diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index f34a854d30..4f52c30e30 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -158,8 +158,8 @@ - (void)testBackPaginationForScenario1 }]; - [room resetBackState]; - [room paginateBackMessages:10 onlyFromStore:NO complete:^{ + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:10 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertGreaterThan(eventCount, 4, @"We must have received events"); @@ -514,8 +514,8 @@ - (void)testBackPaginationForScenario2 }]; - [room resetBackState]; - [room paginateBackMessages:20 complete:^{ + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:2 direction:MXEventDirectionBackwards0 complete:^{ XCTAssertGreaterThan(eventCount, 8, @"We must have received events"); diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index 6802082f5f..fba6e1fcf5 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -276,8 +276,8 @@ - (void)testPaginateBackMessagesCancel }]; - [room resetBackState]; - MXHTTPOperation *pagination = [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + MXHTTPOperation *pagination = [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTFail(@"The cancelled operation must not complete"); [expectation fulfill]; diff --git a/MatrixSDKTests/MXStoreCoreDataStoreTests.m b/MatrixSDKTests/MXStoreCoreDataStoreTests.m index dc3ad9f71b..33e4bf8cce 100644 --- a/MatrixSDKTests/MXStoreCoreDataStoreTests.m +++ b/MatrixSDKTests/MXStoreCoreDataStoreTests.m @@ -124,7 +124,7 @@ - (void)testMXCoreDataStoreCanPaginateFromHomeServer - (void)testMXCoreDataStoreCanPaginateFromMXStore { // Preload more messages than the room history counts so that all messages are already loaded - // room.canPaginate will use [MXStore canPaginateInRoom] + // room.liveTimeline.canPaginate will use [MXStore canPaginateInRoom] [self doTestWithMXCoreDataStoreAndMessagesLimit:100 readyToTest:^(MXRoom *room) { [self checkCanPaginateFromMXStore:room]; }]; diff --git a/MatrixSDKTests/MXStoreFileStoreTests.m b/MatrixSDKTests/MXStoreFileStoreTests.m index c1733beae5..fbb0a6630b 100644 --- a/MatrixSDKTests/MXStoreFileStoreTests.m +++ b/MatrixSDKTests/MXStoreFileStoreTests.m @@ -122,7 +122,7 @@ - (void)testMXFileStoreCanPaginateFromHomeServer - (void)testMXFileStoreCanPaginateFromMXStore { // Preload more messages than the room history counts so that all messages are already loaded - // room.canPaginate will use [MXStore canPaginateInRoom] + // room.liveTimeline.canPaginate will use [MXStore canPaginateInRoom] [self doTestWithMXFileStoreAndMessagesLimit:100 readyToTest:^(MXRoom *room) { [self checkCanPaginateFromMXStore:room]; }]; diff --git a/MatrixSDKTests/MXStoreMemoryStoreTests.m b/MatrixSDKTests/MXStoreMemoryStoreTests.m index 37c1543194..5f941e592d 100644 --- a/MatrixSDKTests/MXStoreMemoryStoreTests.m +++ b/MatrixSDKTests/MXStoreMemoryStoreTests.m @@ -122,7 +122,7 @@ - (void)testMXMemoryStoreCanPaginateFromHomeServer - (void)testMXMemoryStoreCanPaginateFromMXStore { // Preload more messages than the room history counts so that all messages are already loaded - // room.canPaginate will use [MXStore canPaginateInRoom] + // room.liveTimeline.canPaginate will use [MXStore canPaginateInRoom] [self doTestWithMXMemoryStoreAndMessagesLimit:100 readyToTest:^(MXRoom *room) { [self checkCanPaginateFromMXStore:room]; }]; @@ -199,8 +199,8 @@ - (void)testMXMemoryStorePaginate }]; // First make a call to paginateBackMessages that will make a request to the server - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^{ + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(firstEventInTheRoom.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); @@ -215,8 +215,8 @@ - (void)testMXMemoryStorePaginate firstEventInTheRoom2 = event; }]; - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^{ + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, eventCount2); XCTAssertEqual(firstEventInTheRoom2.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); @@ -252,8 +252,8 @@ - (void)testMXMemoryStorePaginateAgain [roomEvents addObject:event]; }]; - [room resetBackState]; - [room paginateBackMessages:8 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:8 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { [room.liveTimeline removeAllListeners]; @@ -264,31 +264,31 @@ - (void)testMXMemoryStorePaginateAgain if (room2Events.count <=2) { - XCTAssertEqual(paginateBackMessagesCallCount, 1, @"Messages for 'paginateBackMessages:2' must synchronously come"); + XCTAssertEqual(paginateBackMessagesCallCount, 1, @"Messages for 'paginate:2 direction:MXEventDirectionBackwards' must synchronously come"); } else if (room2Events.count <=7) { - XCTAssertEqual(paginateBackMessagesCallCount, 1, @"Messages for 'paginateBackMessages:5' must synchronously come"); + XCTAssertEqual(paginateBackMessagesCallCount, 1, @"Messages for 'paginate:5 direction:MXEventDirectionBackwards' must synchronously come"); } else if (room2Events.count <=8) { - XCTAssertEqual(paginateBackMessagesCallCount, 1, @"The first messages for 'paginateBackMessages:100' must synchronously come"); + XCTAssertEqual(paginateBackMessagesCallCount, 1, @"The first messages for 'paginate:100 direction:MXEventDirectionBackwards' must synchronously come"); } else { - XCTAssertEqual(paginateBackMessagesCallCount, 4, @"Other Messages for 'paginateBackMessages:100' must ssynchronously come"); + XCTAssertEqual(paginateBackMessagesCallCount, 4, @"Other Messages for 'paginate:100 direction:MXEventDirectionBackwards' must ssynchronously come"); } }]; - XCTAssertTrue(room.canPaginate, @"There is still at least one event to retrieve from the server"); + XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"There is still at least one event to retrieve from the server"); // The several paginations - [room resetBackState]; - [room paginateBackMessages:2 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:2 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - [room paginateBackMessages:5 onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { // Now, compare the result with the reference XCTAssertEqual(roomEvents.count, 8); @@ -303,10 +303,10 @@ - (void)testMXMemoryStorePaginateAgain XCTAssertTrue([event2.eventId isEqualToString:event.eventId], @"Events mismatch: %@ - %@", event, event2); } - XCTAssertFalse(room.canPaginate, @"We reach the beginning of the history"); + XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We reach the beginning of the history"); - [room resetBackState]; - XCTAssertTrue(room.canPaginate, @"We must be able to paginate again"); + [room.liveTimeline resetBackState]; + XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must be able to paginate again"); [expectation fulfill]; @@ -345,8 +345,8 @@ - (void)testMXMemoryStoreLastMessage { [self doTestWithMXMemoryStore:^(MXRoom *room) { - [room resetBackState]; - [room paginateBackMessages:8 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:8 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { MXEvent *lastMessage = [room lastMessageWithTypeIn:nil]; XCTAssertEqual(lastMessage.eventType, MXEventTypeRoomMessage); diff --git a/MatrixSDKTests/MXStoreNoStoreTests.m b/MatrixSDKTests/MXStoreNoStoreTests.m index 4feaf315a7..80f3024166 100644 --- a/MatrixSDKTests/MXStoreNoStoreTests.m +++ b/MatrixSDKTests/MXStoreNoStoreTests.m @@ -116,7 +116,7 @@ - (void)testMXNoStoreCanPaginateFromHomeServer - (void)testMXNoStoreCanPaginateFromMXStore { // Preload more messages than the room history counts so that all messages are already loaded - // room.canPaginate will use [MXStore canPaginateInRoom] + // room.liveTimeline.canPaginate will use [MXStore canPaginateInRoom] [self doTestWithMXNoStoreAndMessagesLimit:100 readyToTest:^(MXRoom *room) { [self checkCanPaginateFromMXStore:room]; }]; diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 3d6d9e5b55..08d2661e18 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -253,8 +253,8 @@ - (void)checkPaginateBack:(MXRoom*)room eventCount++; }]; - [room resetBackState]; - [room paginateBackMessages:5 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertEqual(eventCount, 5, @"We should get as many messages as requested"); @@ -286,8 +286,8 @@ - (void)checkPaginateBackFilter:(MXRoom*)room }]; - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -318,8 +318,8 @@ - (void)checkPaginateBackOrder:(MXRoom*)room }]; - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertNotEqual(prev_ts, -1, "We should have received events in registerEventListenerForTypes"); @@ -342,8 +342,8 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room [events addObject:event]; }]; - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -366,8 +366,8 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room [roomEvents addObject:event]; }]; - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { // Use another MXRoom instance to do pagination in several times MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; @@ -379,23 +379,23 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room }]; // The several paginations - [room2 resetBackState]; + [room2.liveTimeline resetBackState]; if (mxSession.store.isPermanent) { - XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 7); + XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 7); } - [room2 paginateBackMessages:2 onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:2 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { if (mxSession.store.isPermanent) { - XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 5); + XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 5); } - [room2 paginateBackMessages:5 onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - [room2 paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { [self assertNoDuplicate:room2Events text:@"events got one by one with testSeveralPaginateBacks"]; @@ -462,14 +462,14 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room { if (mxSession.store.isPermanent) { - XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 7); + XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 7); } - [room2 paginateBackMessages:2 onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:2 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { if (mxSession.store.isPermanent) { - XCTAssertGreaterThanOrEqual(room2.remainingMessagesForPaginationInStore, 5); + XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 5); } // Try with 2 more live events @@ -483,9 +483,9 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room } else if (3 == liveEvents) - [room2 paginateBackMessages:5 onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - [room2 paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { [self assertNoDuplicate:room2Events text:@"events got one by one with testSeveralPaginateBacks"]; @@ -519,12 +519,12 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room }]; // Take a snapshot of all room history - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^{ + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ // Messages are now in the cache // Start checking pagination from the cache - [room2 resetBackState]; + [room2.liveTimeline resetBackState]; [room sendTextMessage:@"How is the pagination #1?" success:nil failure:nil]; @@ -537,15 +537,15 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room - (void)checkCanPaginateFromHomeServer:(MXRoom*)room { - [room resetBackState]; - XCTAssertTrue(room.canPaginate, @"We can always paginate at the beginning"); + [room.liveTimeline resetBackState]; + XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We can always paginate at the beginning"); - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { // Due to SPEC-319, we need to paginate twice to be sure to hit the limit - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - XCTAssertFalse(room.canPaginate, @"We must have reached the end of the pagination"); + XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must have reached the end of the pagination"); [expectation fulfill]; @@ -562,12 +562,12 @@ - (void)checkCanPaginateFromHomeServer:(MXRoom*)room - (void)checkCanPaginateFromMXStore:(MXRoom*)room { - [room resetBackState]; - XCTAssertTrue(room.canPaginate, @"We can always paginate at the beginning"); + [room.liveTimeline resetBackState]; + XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We can always paginate at the beginning"); - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - XCTAssertFalse(room.canPaginate, @"We must have reached the end of the pagination"); + XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must have reached the end of the pagination"); [expectation fulfill]; @@ -582,11 +582,11 @@ - (void)checkLastMessageAfterPaginate:(MXRoom*)room MXEvent *lastMessage = [room lastMessageWithTypeIn:nil]; XCTAssertEqual(lastMessage.eventType, MXEventTypeRoomMessage); - [room resetBackState]; + [room.liveTimeline resetBackState]; MXEvent *lastMessage2 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage2.eventId, lastMessage.eventId, @"The last message should stay the same"); - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { MXEvent *lastMessage3 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage3.eventId, lastMessage.eventId, @"The last message should stay the same"); @@ -639,8 +639,8 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room }]; - [room2 resetBackState]; - [room2 paginateBackMessages:100 onlyFromStore:NO complete:^{ + [room2.liveTimeline resetBackState]; + [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(events.count, 5, "The room should contain only 5 messages (the last message sent while the user is not in the room is not visible)"); [expectation fulfill]; @@ -699,27 +699,27 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room }]; // First count how many messages to retrieve - [room resetBackState]; - [room paginateBackMessages:100 onlyFromStore:NO complete:^() { + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { // Paginate for the exact number of events in the room NSUInteger pagEnd = eventCount; eventCount = 0; [mxSession.store deleteRoom:room.state.roomId]; - [room resetBackState]; + [room.liveTimeline resetBackState]; - [room paginateBackMessages:pagEnd onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:pagEnd direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, pagEnd, @"We should get as many messages as requested"); - XCTAssert(room.canPaginate, @"At this point the SDK cannot know it reaches the beginning of the history"); + XCTAssert([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"At this point the SDK cannot know it reaches the beginning of the history"); // Try to load more messages eventCount = 0; - [room paginateBackMessages:1 onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:1 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, 0, @"There must be no more event"); - XCTAssertFalse(room.canPaginate, @"SDK must now indicate there is no more event to paginate"); + XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"SDK must now indicate there is no more event to paginate"); [expectation fulfill]; @@ -1086,8 +1086,8 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass [mxSession start:^{ MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room resetBackState]; - [room paginateBackMessages:10 onlyFromStore:NO complete:^{ + [room.liveTimeline resetBackState]; + [room.liveTimeline paginate:10 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ NSString *roomPaginationToken = [store paginationTokenOfRoom:roomId]; XCTAssert(roomPaginationToken, @"The room must have a pagination after a pagination"); From d23d5af7a487ffebbdc33d3f155304f2d081e305 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 11:11:56 +0100 Subject: [PATCH 43/80] Event timeline: Documented MXEventTimeline --- MatrixSDK/Data/MXEventTimeline.h | 81 ++++++++--- MatrixSDK/Data/MXEventTimeline.m | 227 ++++++++++++++++--------------- 2 files changed, 180 insertions(+), 128 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index 7b929a2f0c..6f8c1fefb3 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -34,34 +34,60 @@ FOUNDATION_EXPORT NSString *const kMXRoomInviteStateEventIdPrefix; @param event the new event. @param direction the origin of the event. - @param roomState the room state right before the event + @param roomState the room state right before the event. */ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoomState *roomState); @class MXRoom; + /** A `MXEventTimeline` instance represents a contiguous sequence of events in a room. - */ + + There are two kinds of timeline: + + - live timelines: they receive live events from the events stream. You can paginate + backwards but not forwards. + All (live or backwards) events they receive are stored in the store of the current + MXSession. + - past timelines: they start in the past from an `initialEventId`. They are filled + with events on calls of [MXEventTimeline paginate] in backwards or forwards direction. + Events are stored in a in-memory store (MXMemoryStore). So, they are not permanent. + */ @interface MXEventTimeline : NSObject +/** + The initial event id used to initialise the timeline. + Nil in case of live timeline. + */ @property (nonatomic, readonly) NSString *initialEventId; +/** + Indicate if this timeline is a live one. + */ @property (nonatomic, readonly) BOOL isLiveTimeline; - /** - The state of the room corresponding to the top most recent room event. + The state of the room at the top most recent event of the timeline. */ @property (nonatomic, readonly) MXRoomState *state; +#pragma mark - Initialisation +/** + Create a timeline instance for a room. + + @param room the room associated to the timeline + @param roomId @TODO: remove. + @param initialEventId the initial event for the timeline. A nil value will create a live timeline. + @return a MXEventTimeline instance. + */ - (id)initWithRoom:(MXRoom*)room andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId; -#pragma mark - Initialisation /** + @TODO: Change to initialiseState Process a state event in order to update the room state. @param event the state event. @@ -71,37 +97,42 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom #pragma mark - Pagination /** - Check if this timelime can be extended + Check if this timelime can be extended. - This returns true if we either have more events, or if we have a - pagination token which means we can paginate in that direction. It does not - necessarily mean that there are more events available in that direction at - this time. + This returns true if we either have more events, or if we have a pagination + token which means we can paginate in that direction. It does not necessarily + mean that there are more events available in that direction at this time. + + canPaginate in forward direction has no meaning for a live timeline. @param direction MXEventDirectionBackwards to check if we can paginate backwards. - MXEventDirectionForwards to check if we can go forwards - @return true if we can paginate in the given direction + MXEventDirectionForwards to check if we can go forwards. + @return true if we can paginate in the given direction. */ - (BOOL)canPaginate:(MXEventDirection)direction; /** - Reset the back state so that future calls to paginate start over from live. - Must be called when opening a room if interested in history. + Reset the back state so that future calls to paginate start over from live or + from the `initialEventId`. */ -- (void)resetBackState; +- (void)resetBackState; // @TODO: Rename /** Get more messages. The retrieved events will be sent to registered listeners. + + It is not possible to paginate forwards on a live timeline. @param numItems the number of items to get. - @param onlyFromStore if YES, return available events from the store, do not make a pagination request to the homeserver. - @param direction ... + @param direction `MXEventDirectionForwards` or `MXEventDirectionBackwards` + @param onlyFromStore if YES, return available events from the store, do not make + a pagination request to the homeserver. + @param complete A block object called when the operation is complete. @param failure A block object called when the operation fails. - @return a MXHTTPOperation instance. This instance can be nil - if no request to the home server is required. + @return a MXHTTPOperation instance. This instance can be nil if no request + to the homeserver is required. */ - (MXHTTPOperation*)paginate:(NSUInteger)numItems direction:(MXEventDirection)direction @@ -120,14 +151,14 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom #pragma mark - Server sync /** - Update room data according to the provided sync response. + For live timeline, update data according to the received /sync response. @param roomSync information to sync the room with the home server data */ - (void)handleJoinedRoomSync:(MXRoomSync*)roomSync; /** - Update the invited room state according to the provided data. + For live timeline, update invited room state according to the received /sync response. @param invitedRoom information to update the room state. */ @@ -136,7 +167,7 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom #pragma mark - Events listeners /** - Register a listener to events of this room. + Register a listener to events of this timeline. @param onEvent the block that will called once a new event has been handled. @return a reference to use to unregister the listener @@ -164,6 +195,12 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom */ - (void)removeAllListeners; +/** + Notifiy all listeners of the timeline about the given event. + + @param event the event to notify. + @param the event direction. + */ - (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction; @end diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 1718cc4e20..27a7481190 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -25,20 +25,22 @@ @interface MXEventTimeline () { - // The list of event listeners (`MXEventListener`) of this timeline + // The list of event listeners (`MXEventListener`) of this timeline. NSMutableArray *eventListeners; - // The historical state of the room when paginating back + // The historical state of the room when paginating back. MXRoomState *backState; - // The state that was in the `state` property before it changed - // It is cached because it costs time to recompute it from the current state - // It is particularly noticeable for rooms with a lot of members (ie a lot of - // room members state events) + // The state that was in the `state` property before it changed. + // It is cached because it costs time to recompute it from the current state. + // This is particularly noticeable for rooms with a lot of members (ie a lot of + // room members state events). MXRoomState *previousState; + // The associated room. MXRoom *room; + // The store to store events, id store; } @end @@ -56,14 +58,16 @@ - (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NS _state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:room.mxSession andDirection:YES]; - + // Is it a past or live timeline? if (_initialEventId) { + // Events for a past timeline are store in memory store = [[MXMemoryStore alloc] init]; [store openWithCredentials:room.mxSession.matrixRestClient.credentials onComplete:nil failure:nil]; } else { + // Live: store events in the session store store = room.mxSession.store; } } @@ -84,8 +88,8 @@ - (BOOL)canPaginate:(MXEventDirection)direction if (direction == MXEventDirectionBackwards) { // canPaginate depends on two things: - // - did we end to paginate from the local MXStore? - // - did we reach the top of the pagination in our requests to the home server + // - did we end to paginate from the MXStore? + // - did we reach the top of the pagination in our requests to the home server? canPaginate = (0 < [store remainingMessagesForPaginationInRoom:_state.roomId]) || ![store hasReachedHomeServerPaginationEndForRoom:_state.roomId]; } @@ -93,11 +97,12 @@ - (BOOL)canPaginate:(MXEventDirection)direction { if (self.isLiveTimeline) { + // Matrix is not yet able to guess the future canPaginate = NO; } else { - NSAssert(NO, @"TODO: canPaginate"); + NSAssert(NO, @"TODO: canPaginate forwards is not yet supported"); } } @@ -119,117 +124,128 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d { MXHTTPOperation *operation; - NSAssert(nil != backState, @"[MXRoom] paginateBackMessages: resetBackState must be called before starting the back pagination"); + NSAssert(nil != backState, @"[MXEventTimeline] paginate: resetBackState must be called before starting the back pagination"); - // Return messages in the store first - NSUInteger messagesFromStoreCount = 0; - NSArray *messagesFromStore = [store paginateRoom:_state.roomId numMessages:numItems]; - if (messagesFromStore) + if (direction == MXEventDirectionBackwards) { - messagesFromStoreCount = messagesFromStore.count; - } + // Return messages from the store first + NSUInteger messagesFromStoreCount = 0; + NSArray *messagesFromStore = [store paginateRoom:_state.roomId numMessages:numItems]; + if (messagesFromStore) + { + messagesFromStoreCount = messagesFromStore.count; + } - NSLog(@"[MXRoom] paginateBackMessages %tu messages in %@ (%tu are retrieved from the store)", numItems, _state.roomId, messagesFromStoreCount); + NSLog(@"[MXEventTimeline] paginate %tu messages in %@ (%tu are retrieved from the store)", numItems, _state.roomId, messagesFromStoreCount); - if (messagesFromStoreCount) - { - @autoreleasepool + if (messagesFromStoreCount) { - // messagesFromStore are in chronological order - // Handle events from the most recent - for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) + @autoreleasepool { - MXEvent *event = messagesFromStore[i]; - [self handleMessage:event direction:MXEventDirectionBackwards]; - } + // messagesFromStore are in chronological order + // Handle events from the most recent + for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) + { + MXEvent *event = messagesFromStore[i]; + [self handleMessage:event direction:MXEventDirectionBackwards]; + } - numItems -= messagesFromStoreCount; + numItems -= messagesFromStoreCount; + } } - } - if (onlyFromStore && messagesFromStoreCount) - { - complete(); - - NSLog(@"[MXRoom] paginateBackMessages : is done from the store"); - return nil; - } + if (onlyFromStore && messagesFromStoreCount) + { + complete(); - if (0 < numItems && NO == [store hasReachedHomeServerPaginationEndForRoom:_state.roomId]) - { - // Not enough messages: make a pagination request to the home server - // from last known token - NSString *paginationToken = [store paginationTokenOfRoom:_state.roomId]; - if (nil == paginationToken) { - paginationToken = @"END"; + NSLog(@"[MXEventTimeline] paginate : is done from the store"); + return nil; } - NSLog(@"[MXRoom] paginateBackMessages : request %tu messages from the server", numItems); - - operation = [room.mxSession.matrixRestClient messagesForRoom:_state.roomId - from:paginationToken - to:nil - limit:numItems - success:^(MXPaginationResponse *paginatedResponse) { - - @autoreleasepool - { - NSLog(@"[MXRoom] paginateBackMessages : get %tu messages from the server", paginatedResponse.chunk.count); - - // Check pagination end - @see SPEC-319 ticket - if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) - { - // We run out of items - [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; - } - - // Process received events and update pagination tokens - [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; - - // Commit store changes - if ([store respondsToSelector:@selector(commit)]) - { - [store commit]; - } - - // Inform the method caller - complete(); - - NSLog(@"[MXRoom] paginateBackMessages : is done"); - } - - } failure:^(NSError *error) { - // Check whether the pagination end is reached - MXError *mxError = [[MXError alloc] initWithNSError:error]; - if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) - { - // We run out of items - [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; - - NSLog(@"[MXRoom] paginateBackMessages: pagination end has been reached"); - - // Ignore the error - complete(); - return; - } - - NSLog(@"[MXRoom] paginateBackMessages error: %@", error); - failure(error); - }]; + if (0 < numItems && NO == [store hasReachedHomeServerPaginationEndForRoom:_state.roomId]) + { + // Not enough messages: make a pagination request to the home server + // from last known token + NSString *paginationToken = [store paginationTokenOfRoom:_state.roomId]; + if (nil == paginationToken) { + paginationToken = @"END"; + } - if (messagesFromStoreCount) + NSLog(@"[MXEventTimeline] paginate : request %tu messages from the server", numItems); + + operation = [room.mxSession.matrixRestClient messagesForRoom:_state.roomId + from:paginationToken + to:nil + limit:numItems + success:^(MXPaginationResponse *paginatedResponse) { + + @autoreleasepool + { + NSLog(@"[MXEventTimeline] paginate : get %tu messages from the server", paginatedResponse.chunk.count); + + // Check pagination end - @see SPEC-319 ticket + if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) + { + // We run out of items + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + } + + // Process received events and update pagination tokens + [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; + + // Commit store changes + if ([store respondsToSelector:@selector(commit)]) + { + [store commit]; + } + + // Inform the method caller + complete(); + + NSLog(@"[MXEventTimeline] paginate: is done"); + } + + } failure:^(NSError *error) { + // Check whether the pagination end is reached + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) + { + // We run out of items + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + + NSLog(@"[MXEventTimeline] paginate: pagination end has been reached"); + + // Ignore the error + complete(); + return; + } + + NSLog(@"[MXEventTimeline] paginate error: %@", error); + failure(error); + }]; + + if (messagesFromStoreCount) + { + // Disable retry to let the caller handle messages from store without delay. + // The caller will trigger a new pagination if need. + operation.maxNumberOfTries = 1; + } + } + else { - // Disable retry to let the caller handle messages from store without delay. - // The caller will trigger a new pagination if need. - operation.maxNumberOfTries = 1; + // Nothing more to do + complete(); + + NSLog(@"[MXEventTimeline] paginate: is done"); } } + else if (!self.isLiveTimeline) + { + NSAssert(NO, @"TODO: paginate forwards is not yet supported"); + } else { - // Nothing more to do - complete(); - - NSLog(@"[MXRoom] paginateBackMessages : is done"); + NSAssert(NO, @"Cannot paginate forwards on a live timeline"); } return operation; @@ -251,7 +267,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync if (self.state.membership == MXMembershipInvite) { // Reset the storage of this room. An initial sync of the room will be done with the provided 'roomSync'. - NSLog(@"[MXRoom] handleJoinedRoomSync: clean invited room from the store (%@).", self.state.roomId); + NSLog(@"[MXEventTimeline] handleJoinedRoomSync: clean invited room from the store (%@).", self.state.roomId); [store deleteRoom:self.state.roomId]; } @@ -369,7 +385,7 @@ - (void)handleMessages:(MXPaginationResponse*)roomMessages // Here direction is MXEventDirectionBackwards or MXEventDirectionSync if (direction == MXEventDirectionForwards) { - NSLog(@"[MXRoom] handleMessages error: forward direction is not supported"); + NSLog(@"[MXEventTimeline] handleMessages error: forward direction is not supported"); return; } @@ -610,5 +626,4 @@ - (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction } } - @end From e0e66dae21db80d69e6e8bf298680bfee321018b Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 11:25:41 +0100 Subject: [PATCH 44/80] Event timeline: MXEventTimeline: Expose [MXEventTimeline initialiseState] --- MatrixSDK/Data/MXEventTimeline.h | 8 +++----- MatrixSDK/Data/MXEventTimeline.m | 13 +++++++++---- MatrixSDK/Data/MXRoom.m | 6 +----- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index 6f8c1fefb3..4a851936bb 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -85,14 +85,12 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom */ - (id)initWithRoom:(MXRoom*)room andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId; - /** - @TODO: Change to initialiseState - Process a state event in order to update the room state. + Initialise the room evenTimeline state. - @param event the state event. + @param stateEvents the state event. */ -- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction; +- (void)initialiseState:(NSArray *)stateEvents; #pragma mark - Pagination diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 27a7481190..9cda28a13b 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -47,6 +47,7 @@ @interface MXEventTimeline () @implementation MXEventTimeline +#pragma mark - Initialisation - (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId { self = [super init]; @@ -68,15 +69,19 @@ - (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NS else { // Live: store events in the session store + _isLiveTimeline = YES; store = room.mxSession.store; } } return self; } -- (BOOL)isLiveTimeline +- (void)initialiseState:(NSArray *)stateEvents { - return !_initialEventId; + for (MXEvent *event in stateEvents) + { + [self handleStateEvent:event direction:MXEventDirectionSync]; + } } @@ -95,7 +100,7 @@ - (BOOL)canPaginate:(MXEventDirection)direction } else { - if (self.isLiveTimeline) + if (_isLiveTimeline) { // Matrix is not yet able to guess the future canPaginate = NO; @@ -239,7 +244,7 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d NSLog(@"[MXEventTimeline] paginate: is done"); } } - else if (!self.isLiveTimeline) + else if (!_isLiveTimeline) { NSAssert(NO, @"TODO: paginate forwards is not yet supported"); } diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index ec8009dad6..fdfaa4a4bb 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -75,11 +75,7 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 { @autoreleasepool { - for (MXEvent *event in stateEvents) - { - [_liveTimeline handleStateEvent:event direction:MXEventDirectionSync]; - } - + [_liveTimeline initialiseState:stateEvents]; _accountData = accountData; } } From 58ebf6be756b8def629f9c8cf24cf96c991419ba Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 11:30:55 +0100 Subject: [PATCH 45/80] Event timeline: MXRoomSync.ephemeral events (typings and read receipts) have to be mananged at the MXRoom layer not MXEventTimeline --- MatrixSDK/Data/MXEventTimeline.m | 39 +++++++++----------------------- MatrixSDK/Data/MXRoom.m | 30 ++++++++++++------------ 2 files changed, 26 insertions(+), 43 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 9cda28a13b..3f1ee3f691 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -533,39 +533,22 @@ Handle an event (message or state) that comes from the events streaming. */ - (void)handleLiveEvent:(MXEvent*)event { - // Handle first typing notifications - if (event.eventType == MXEventTypeTypingNotification) + // Make sure we have not processed this event yet + if (![store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) { - // Typing notifications events are not room messages nor room state events - // They are just volatile information - //MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); - - // Notify listeners - [self notifyListeners:event direction:MXEventDirectionForwards]; - } - else if (event.eventType == MXEventTypeReceipt) - { - //[self handleReceiptEvent:event direction:MXEventDirectionForwards]; - } - else - { - // Make sure we have not processed this event yet - if (![store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) + // Handle here redaction event from live event stream + if (event.eventType == MXEventTypeRoomRedaction) { - // Handle here redaction event from live event stream - if (event.eventType == MXEventTypeRoomRedaction) - { - //[self handleRedaction:event]; - } + //[self handleRedaction:event]; + } - [self handleMessage:event direction:MXEventDirectionForwards]; + [self handleMessage:event direction:MXEventDirectionForwards]; - // Store the event - [store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionForwards]; + // Store the event + [store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionForwards]; - // And notify listeners - [self notifyListeners:event direction:MXEventDirectionForwards]; - } + // And notify listeners + [self notifyListeners:event direction:MXEventDirectionForwards]; } } diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index fdfaa4a4bb..278374426c 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -119,22 +119,22 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // Report the room id in the event as it is skipped in /sync response event.roomId = self.state.roomId; - // Handle first typing notifications - if (event.eventType == MXEventTypeTypingNotification) - { - // Typing notifications events are not room messages nor room state events - // They are just volatile information - MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); - - // Notify listeners - [_liveTimeline notifyListeners:event direction:MXEventDirectionForwards]; - } - else if (event.eventType == MXEventTypeReceipt) - { - [self handleReceiptEvent:event direction:MXEventDirectionForwards]; - } + // Handle first typing notifications + if (event.eventType == MXEventTypeTypingNotification) + { + // Typing notifications events are not room messages nor room state events + // They are just volatile information + MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); + + // Notify listeners + [_liveTimeline notifyListeners:event direction:MXEventDirectionForwards]; + } + else if (event.eventType == MXEventTypeReceipt) + { + [self handleReceiptEvent:event direction:MXEventDirectionForwards]; + } } - + // Handle account data events (if any) [self handleAccounDataEvents:roomSync.accountData.events direction:MXEventDirectionForwards]; } From f102fc0e647ea3bafbc950df3bd2914ab4cbcac5 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 11:34:39 +0100 Subject: [PATCH 46/80] Event timeline: Made redaction work again --- MatrixSDK/Data/MXEventTimeline.m | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 3f1ee3f691..0182a69bd1 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -539,7 +539,7 @@ - (void)handleLiveEvent:(MXEvent*)event // Handle here redaction event from live event stream if (event.eventType == MXEventTypeRoomRedaction) { - //[self handleRedaction:event]; + [self handleRedaction:event]; } [self handleMessage:event direction:MXEventDirectionForwards]; @@ -552,6 +552,24 @@ - (void)handleLiveEvent:(MXEvent*)event } } +- (void)handleRedaction:(MXEvent*)redactionEvent +{ + // Check whether the redacted event has been already processed + MXEvent *redactedEvent = [store eventWithEventId:redactionEvent.redacts inRoom:_state.roomId]; + if (redactedEvent) + { + // Redact the stored event + redactedEvent = [redactedEvent prune]; + redactedEvent.redactedBecause = redactionEvent.JSONDictionary; + + if (redactedEvent.isState) { + // FIXME: The room state must be refreshed here since this redacted event. + } + + // Store the event + [store replaceEvent:redactedEvent inRoom:_state.roomId]; + } +} #pragma mark - Events listeners - (id)listenToEvents:(MXOnRoomEvent)onEvent From fd12a1f3bc331f8fc772aff3dd667a29eb3c6d71 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 11:40:03 +0100 Subject: [PATCH 47/80] Event timeline: Renamed [MXEventTimeline resetBackState] to resetPagination --- MatrixSDK/Data/MXEventTimeline.h | 4 ++-- MatrixSDK/Data/MXEventTimeline.m | 4 ++-- MatrixSDKTests/MXEventTests.m | 2 +- MatrixSDKTests/MXRoomStateDynamicTests.m | 4 ++-- MatrixSDKTests/MXRoomTests.m | 2 +- MatrixSDKTests/MXStoreMemoryStoreTests.m | 12 +++++----- MatrixSDKTests/MXStoreTests.m | 30 ++++++++++++------------ 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index 4a851936bb..dc578cc7d2 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -110,10 +110,10 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom - (BOOL)canPaginate:(MXEventDirection)direction; /** - Reset the back state so that future calls to paginate start over from live or + Reset the pagination so that future calls to paginate start over from live or from the `initialEventId`. */ -- (void)resetBackState; // @TODO: Rename +- (void)resetPagination; /** Get more messages. diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 0182a69bd1..0519484d15 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -116,7 +116,7 @@ - (BOOL)canPaginate:(MXEventDirection)direction #pragma mark - Back pagination -- (void)resetBackState +- (void)resetPagination { // Reset the back state to the current room state backState = [[MXRoomState alloc] initBackStateWith:_state]; @@ -129,7 +129,7 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d { MXHTTPOperation *operation; - NSAssert(nil != backState, @"[MXEventTimeline] paginate: resetBackState must be called before starting the back pagination"); + NSAssert(nil != backState, @"[MXEventTimeline] paginate: resetPagination must be called before starting the back pagination"); if (direction == MXEventDirectionBackwards) { diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index 217d1bc3d8..aaf1aeb867 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -113,7 +113,7 @@ - (void)testIsState }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertGreaterThan(eventCount, 0, "We should have received events in registerEventListenerForTypes"); diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index 4f52c30e30..bdcac964cb 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -158,7 +158,7 @@ - (void)testBackPaginationForScenario1 }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:10 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertGreaterThan(eventCount, 4, @"We must have received events"); @@ -514,7 +514,7 @@ - (void)testBackPaginationForScenario2 }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:2 direction:MXEventDirectionBackwards0 complete:^{ XCTAssertGreaterThan(eventCount, 8, @"We must have received events"); diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index fba6e1fcf5..f72048f0d4 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -276,7 +276,7 @@ - (void)testPaginateBackMessagesCancel }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; MXHTTPOperation *pagination = [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTFail(@"The cancelled operation must not complete"); diff --git a/MatrixSDKTests/MXStoreMemoryStoreTests.m b/MatrixSDKTests/MXStoreMemoryStoreTests.m index 5f941e592d..66fe0b853d 100644 --- a/MatrixSDKTests/MXStoreMemoryStoreTests.m +++ b/MatrixSDKTests/MXStoreMemoryStoreTests.m @@ -199,7 +199,7 @@ - (void)testMXMemoryStorePaginate }]; // First make a call to paginateBackMessages that will make a request to the server - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(firstEventInTheRoom.eventType, MXEventTypeRoomCreate, @"First event in a room is always m.room.create"); @@ -215,7 +215,7 @@ - (void)testMXMemoryStorePaginate firstEventInTheRoom2 = event; }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, eventCount2); @@ -252,7 +252,7 @@ - (void)testMXMemoryStorePaginateAgain [roomEvents addObject:event]; }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:8 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { [room.liveTimeline removeAllListeners]; @@ -283,7 +283,7 @@ - (void)testMXMemoryStorePaginateAgain XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"There is still at least one event to retrieve from the server"); // The several paginations - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:2 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { [room.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { @@ -305,7 +305,7 @@ - (void)testMXMemoryStorePaginateAgain XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We reach the beginning of the history"); - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must be able to paginate again"); [expectation fulfill]; @@ -345,7 +345,7 @@ - (void)testMXMemoryStoreLastMessage { [self doTestWithMXMemoryStore:^(MXRoom *room) { - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:8 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { MXEvent *lastMessage = [room lastMessageWithTypeIn:nil]; diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 08d2661e18..6da416c72a 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -253,7 +253,7 @@ - (void)checkPaginateBack:(MXRoom*)room eventCount++; }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertEqual(eventCount, 5, @"We should get as many messages as requested"); @@ -286,7 +286,7 @@ - (void)checkPaginateBackFilter:(MXRoom*)room }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -318,7 +318,7 @@ - (void)checkPaginateBackOrder:(MXRoom*)room }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertNotEqual(prev_ts, -1, "We should have received events in registerEventListenerForTypes"); @@ -342,7 +342,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room [events addObject:event]; }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -366,7 +366,7 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room [roomEvents addObject:event]; }]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { // Use another MXRoom instance to do pagination in several times @@ -379,7 +379,7 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room }]; // The several paginations - [room2.liveTimeline resetBackState]; + [room2.liveTimeline resetPagination]; if (mxSession.store.isPermanent) { @@ -519,12 +519,12 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room }]; // Take a snapshot of all room history - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ // Messages are now in the cache // Start checking pagination from the cache - [room2.liveTimeline resetBackState]; + [room2.liveTimeline resetPagination]; [room sendTextMessage:@"How is the pagination #1?" success:nil failure:nil]; @@ -537,7 +537,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room - (void)checkCanPaginateFromHomeServer:(MXRoom*)room { - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We can always paginate at the beginning"); [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { @@ -562,7 +562,7 @@ - (void)checkCanPaginateFromHomeServer:(MXRoom*)room - (void)checkCanPaginateFromMXStore:(MXRoom*)room { - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We can always paginate at the beginning"); [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { @@ -582,7 +582,7 @@ - (void)checkLastMessageAfterPaginate:(MXRoom*)room MXEvent *lastMessage = [room lastMessageWithTypeIn:nil]; XCTAssertEqual(lastMessage.eventType, MXEventTypeRoomMessage); - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; MXEvent *lastMessage2 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage2.eventId, lastMessage.eventId, @"The last message should stay the same"); @@ -639,7 +639,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room }]; - [room2.liveTimeline resetBackState]; + [room2.liveTimeline resetPagination]; [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(events.count, 5, "The room should contain only 5 messages (the last message sent while the user is not in the room is not visible)"); @@ -699,14 +699,14 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room }]; // First count how many messages to retrieve - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { // Paginate for the exact number of events in the room NSUInteger pagEnd = eventCount; eventCount = 0; [mxSession.store deleteRoom:room.state.roomId]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:pagEnd direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ @@ -1086,7 +1086,7 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass [mxSession start:^{ MXRoom *room = [mxSession roomWithRoomId:roomId]; - [room.liveTimeline resetBackState]; + [room.liveTimeline resetPagination]; [room.liveTimeline paginate:10 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ NSString *roomPaginationToken = [store paginationTokenOfRoom:roomId]; From 3aa7ead5132ad127594fdc8a5259871e69ac6881 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 11:48:09 +0100 Subject: [PATCH 48/80] MXRoom: Added roomId property as it is boringto get it from room.state.roomId. Moreover, it is sometimes impossible (MXEventTimeLine constructor) --- MatrixSDK/Data/MXEventTimeline.h | 3 +-- MatrixSDK/Data/MXEventTimeline.m | 4 ++-- MatrixSDK/Data/MXRoom.h | 5 +++++ MatrixSDK/Data/MXRoom.m | 3 ++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index dc578cc7d2..b498c6caf2 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -79,11 +79,10 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom Create a timeline instance for a room. @param room the room associated to the timeline - @param roomId @TODO: remove. @param initialEventId the initial event for the timeline. A nil value will create a live timeline. @return a MXEventTimeline instance. */ -- (id)initWithRoom:(MXRoom*)room andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId; +- (id)initWithRoom:(MXRoom*)room andInitialEventId:(NSString*)initialEventId; /** Initialise the room evenTimeline state. diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 0519484d15..040b15d80b 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -48,7 +48,7 @@ @interface MXEventTimeline () @implementation MXEventTimeline #pragma mark - Initialisation -- (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId +- (id)initWithRoom:(MXRoom*)room2 andInitialEventId:(NSString*)initialEventId { self = [super init]; if (self) @@ -57,7 +57,7 @@ - (id)initWithRoom:(MXRoom*)room2 andRoomId:(NSString*)roomId initialEventId:(NS room = room2; eventListeners = [NSMutableArray array]; - _state = [[MXRoomState alloc] initWithRoomId:roomId andMatrixSession:room.mxSession andDirection:YES]; + _state = [[MXRoomState alloc] initWithRoomId:room.roomId andMatrixSession:room.mxSession andDirection:YES]; // Is it a past or live timeline? if (_initialEventId) diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 16c88d9603..e2914233d6 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -52,6 +52,11 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; */ @interface MXRoom : NSObject +/** + The Matrix id of the room. + */ +@property (nonatomic, readonly) NSString *roomId; + /** The related matrix session. */ diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 278374426c..5ea55ed1e8 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -37,9 +37,10 @@ - (id)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)mxSession2 self = [super init]; if (self) { + _roomId = roomId; mxSession = mxSession2; - _liveTimeline = [[MXEventTimeline alloc] initWithRoom:self andRoomId:roomId initialEventId:nil]; + _liveTimeline = [[MXEventTimeline alloc] initWithRoom:self andInitialEventId:nil]; _accountData = [[MXRoomAccountData alloc] init]; From f8c4624100bf8c00a8a212cf54d871af73504d92 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 14:52:32 +0100 Subject: [PATCH 49/80] MXRoom: Removed the dead setReadReceiptToken method. Try to make comment clearer --- MatrixSDK/Data/MXRoom.h | 19 ++++++++----------- MatrixSDK/Data/MXRoom.m | 34 ++++++++-------------------------- 2 files changed, 16 insertions(+), 37 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index e2914233d6..61a25eec30 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -470,10 +470,10 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; - (MXCall*)placeCallWithVideo:(BOOL)video; -#pragma mark - Receipts management +#pragma mark - Read receipts management /** - Handle a receipt event + Handle a receipt event. @param event the event to handle. @param the direction @@ -481,30 +481,27 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; */ - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)direction; -/** - Update the read receipt token. - @param token the new token - @param ts the token ts -@return true if the token is refreshed - */ -- (BOOL)setReadReceiptToken:(NSString*)token ts:(long)ts; - /** Acknowlegde the latest event of type defined in acknowledgableEventTypes. Put sendReceipt YES to send a receipt event if the latest event was not yet acknowledged. + This is will indicate to the homeserver that the user has read up to this event. + @param sendReceipt YES to send a receipt event if required @return true if there is an update */ - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; /** - Returns the receipts list for an event, excluding the receipt from the current user. + Returns the read receipts list for an event, excluding the read receipt from the current user. + @param eventId The event Id. @param sort YES to sort them from the latest to the oldest. @return the receipts for an event in a dedicated room. */ - (NSArray*)getEventReceipts:(NSString*)eventId sorted:(BOOL)sort; + +#pragma mark - Utils /** Comparator to use to order array of rooms by their lastest originServerTs value. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 5ea55ed1e8..ea86638f9a 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -428,7 +428,7 @@ - (MXCall *)placeCallWithVideo:(BOOL)video } -#pragma mark - Receipts management +#pragma mark - Read receipts management - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)direction { @@ -472,26 +472,6 @@ - (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)directio return managedEvents; } -- (BOOL)setReadReceiptToken:(NSString*)token ts:(long)ts -{ - MXReceiptData *data = [[MXReceiptData alloc] init]; - - data.userId = mxSession.myUser.userId; - data.eventId = token; - data.ts = ts; - - if ([mxSession.store storeReceipt:data roomId:self.state.roomId]) - { - if ([mxSession.store respondsToSelector:@selector(commit)]) - { - [mxSession.store commit]; - } - return YES; - } - - return NO; -} - - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; { MXEvent* event =[mxSession.store lastMessageOfRoom:self.state.roomId withTypeIn:_acknowledgableEventTypes]; @@ -527,11 +507,6 @@ - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; return NO; } -- (NSComparisonResult)compareOriginServerTs:(MXRoom *)otherRoom -{ - return [[otherRoom lastMessageWithTypeIn:nil] compareOriginServerTs:[self lastMessageWithTypeIn:nil]]; -} - -(NSArray*) unreadEvents { return [mxSession.store unreadEvents:self.state.roomId withTypeIn:_acknowledgableEventTypes]; @@ -569,6 +544,13 @@ - (NSArray*)getEventReceipts:(NSString*)eventId sorted:(BOOL)sort return receipts; } + +#pragma mark - Utils +- (NSComparisonResult)compareOriginServerTs:(MXRoom *)otherRoom +{ + return [[otherRoom lastMessageWithTypeIn:nil] compareOriginServerTs:[self lastMessageWithTypeIn:nil]]; +} + - (NSString *)description { return [NSString stringWithFormat:@" %@: %@ - %@", self, self.state.roomId, self.state.name, self.state.topic]; From ac280f734252027bbe90f653b6eb6b3c2745cd5d Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 14:56:12 +0100 Subject: [PATCH 50/80] Event timeline: MXEventTimeline: small comment update --- MatrixSDK/Data/MXEventTimeline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index b498c6caf2..218855a349 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -53,7 +53,7 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom - past timelines: they start in the past from an `initialEventId`. They are filled with events on calls of [MXEventTimeline paginate] in backwards or forwards direction. - Events are stored in a in-memory store (MXMemoryStore). So, they are not permanent. + Events are stored in a in-memory store (MXMemoryStore) (@TODO: To be confirmed once they will be implemented). So, they are not permanent. */ @interface MXEventTimeline : NSObject From afef4f5eecd7d92cf7f818e7af656afa4fc2881c Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 23 Feb 2016 16:12:50 +0100 Subject: [PATCH 51/80] SYIOS-208: [MXSession startWithMessagesLimit]: if defined, the limit argument is now passed to /sync requests --- MatrixSDK/MXSession.m | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index c378cb5195..918939c18d 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -46,13 +46,6 @@ #define CLIENT_TIMEOUT_MS 120000 -/** - The number of messages to get at the initialSync. - This number should be big enough to be able to pick at least one message from the downloaded ones - that matches the type requested for `recentsWithTypeIn` but this depends on the app. - */ -#define DEFAULT_INITIALSYNC_MESSAGES_NUMBER 10 - // Block called when MSSession resume is complete typedef void (^MXOnResumeDone)(); @@ -87,9 +80,10 @@ The list of global events listeners (`MXSessionEventListener`). NSMutableArray *globalEventListeners; /** - The limit value to use when doing initialSync. + The limit value to use when doing /sync requests. + -1, the default value, let the homeserver use its default value. */ - NSUInteger initialSyncMessagesLimit; + NSInteger syncMessagesLimit; /** The block to call when MSSession resume is complete. @@ -126,6 +120,7 @@ - (id)initWithMatrixRestClient:(MXRestClient*)mxRestClient users = [NSMutableDictionary dictionary]; oneToOneRooms = [NSMutableDictionary dictionary]; globalEventListeners = [NSMutableArray array]; + syncMessagesLimit = -1; _notificationCenter = [[MXNotificationCenter alloc] initWithMatrixSession:self]; [self setState:MXSessionStateInitialised]; @@ -246,7 +241,7 @@ -(void)setStore:(id)store success:(void (^)())onStoreDataReady failure: - (void)start:(void (^)())onServerSyncDone failure:(void (^)(NSError *error))failure { - [self startWithMessagesLimit:DEFAULT_INITIALSYNC_MESSAGES_NUMBER onServerSyncDone:onServerSyncDone failure:failure]; + [self startWithMessagesLimit:-1 onServerSyncDone:onServerSyncDone failure:failure]; } - (void)startWithMessagesLimit:(NSUInteger)messagesLimit @@ -272,7 +267,7 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit [self setState:MXSessionStateSyncInProgress]; // Store the passed limit to reuse it when initialSyncing per room - initialSyncMessagesLimit = messagesLimit; + syncMessagesLimit = messagesLimit; // Can we resume from data available in the cache if (_store.isPermanent && _store.eventStreamToken && 0 < _store.rooms.count) @@ -480,8 +475,15 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout { NSDate *startDate = [NSDate date]; NSLog(@"[MXSession] Do a server sync"); - - eventStreamRequest = [matrixRestClient syncFromToken:_store.eventStreamToken serverTimeout:serverTimeout clientTimeout:clientTimeout setPresence:setPresence filter:nil success:^(MXSyncResponse *syncResponse) { + + NSString *inlineFilter; + if (-1 != syncMessagesLimit) + { + // If requested by the app, use a limit for /sync. + inlineFilter = [NSString stringWithFormat:@"{\"room\":{\"timeline\":{\"limit\":%tu}}}", syncMessagesLimit]; + } + + eventStreamRequest = [matrixRestClient syncFromToken:_store.eventStreamToken serverTimeout:serverTimeout clientTimeout:clientTimeout setPresence:setPresence filter:inlineFilter success:^(MXSyncResponse *syncResponse) { // Make sure [MXSession close] or [MXSession pause] has not been called before the server response if (!eventStreamRequest) From 7bfbaf02eef70e681831af5181c3b6086013999e Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 24 Feb 2016 08:39:29 +0100 Subject: [PATCH 52/80] Context timelime: Started creation of timeline around a given event. WIP --- MatrixSDK.xcodeproj/project.pbxproj | 4 + MatrixSDK/Data/MXEventTimeline.h | 13 +++ MatrixSDK/Data/MXEventTimeline.m | 24 ++++++ MatrixSDK/Data/MXRoom.h | 30 ++++++- MatrixSDK/Data/MXRoom.m | 18 +++++ .../Data/Store/MXMemoryStore/MXMemoryStore.m | 5 +- MatrixSDKTests/MXEventTimelineTests.m | 80 +++++++++++++++++++ 7 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 MatrixSDKTests/MXEventTimelineTests.m diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 1f5acc01a5..a0b5299e6f 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -53,6 +53,7 @@ 323E0C581A2F6E7D00A31D73 /* MXRoomPowerLevels.m in Sources */ = {isa = PBXBuildFile; fileRef = 323E0C561A2F6E7D00A31D73 /* MXRoomPowerLevels.m */; }; 323E0C5B1A306D7A00A31D73 /* MXEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 323E0C591A306D7A00A31D73 /* MXEvent.h */; }; 323E0C5C1A306D7A00A31D73 /* MXEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 323E0C5A1A306D7A00A31D73 /* MXEvent.m */; }; + 323EF7471C7CB4C7000DC98C /* MXEventTimelineTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 323EF7461C7CB4C7000DC98C /* MXEventTimelineTests.m */; }; 324095221AFA432F00D81C97 /* MXCallStackCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 3240951E1AFA432F00D81C97 /* MXCallStackCall.h */; }; 3245A7501AF7B2930001D8A7 /* MXCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 3245A74C1AF7B2930001D8A7 /* MXCall.h */; }; 3245A7511AF7B2930001D8A7 /* MXCall.m in Sources */ = {isa = PBXBuildFile; fileRef = 3245A74D1AF7B2930001D8A7 /* MXCall.m */; }; @@ -200,6 +201,7 @@ 323E0C561A2F6E7D00A31D73 /* MXRoomPowerLevels.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXRoomPowerLevels.m; sourceTree = ""; }; 323E0C591A306D7A00A31D73 /* MXEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXEvent.h; sourceTree = ""; }; 323E0C5A1A306D7A00A31D73 /* MXEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEvent.m; sourceTree = ""; }; + 323EF7461C7CB4C7000DC98C /* MXEventTimelineTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXEventTimelineTests.m; sourceTree = ""; }; 3240951E1AFA432F00D81C97 /* MXCallStackCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXCallStackCall.h; sourceTree = ""; }; 3245A74C1AF7B2930001D8A7 /* MXCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXCall.h; sourceTree = ""; }; 3245A74D1AF7B2930001D8A7 /* MXCall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXCall.m; sourceTree = ""; }; @@ -520,6 +522,7 @@ 32C6F93919DD814400EA4E9C /* MatrixSDKTests */ = { isa = PBXGroup; children = ( + 323EF7461C7CB4C7000DC98C /* MXEventTimelineTests.m */, 326D1EF41BFC79300030947B /* MXPushRuleTests.m */, 329571941B024D2B00ABB3BA /* Mocks */, 327E37B81A977810007F026F /* MXLoggerTests.m */, @@ -874,6 +877,7 @@ 32FCAB4D19E578860049C555 /* MXRestClientTests.m in Sources */, 329FB17C1A0A963700A5E88E /* MXRoomMemberTests.m in Sources */, 3246BDC51A1A0789000A7D62 /* MXRoomStateDynamicTests.m in Sources */, + 323EF7471C7CB4C7000DC98C /* MXEventTimelineTests.m in Sources */, 32169AA21BD4D1B00077868B /* MXCoreDataStore.xcdatamodeld in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index 218855a349..9069c61eb7 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -91,6 +91,19 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom */ - (void)initialiseState:(NSArray *)stateEvents; +/** + Initialise a timelime by loading the context around its `initialEventId`. + + @param limit the maximum number of messages to return. + + @param success A block object called when the operation succeeds. + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. + */ +- (MXHTTPOperation*)loadContextWithLimit:(NSUInteger)limit + success:(void(^)())success + failure:(void (^)(NSError *error))failure; #pragma mark - Pagination /** diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 040b15d80b..2e6c794037 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -84,6 +84,30 @@ - (void)initialiseState:(NSArray *)stateEvents } } +- (MXHTTPOperation *)loadContextWithLimit:(NSUInteger)limit success:(void (^)())success failure:(void (^)(NSError *))failure +{ + NSAssert(_initialEventId, @"[MXEventTimeline] loadContextWithLimit cannot be called on live timeline"); + + // Get the context around the initial event + return [room.mxSession.matrixRestClient contextOfEvent:_initialEventId inRoom:room.roomId limit:limit success:^(MXEventContext *eventContext) { + + // And fill the timelime with received data + [self initialiseState:eventContext.state]; + + for (MXEvent *event in eventContext.eventsBefore) + { + [self handleMessage:event direction:MXEventDirectionBackwards]; + } + + for (MXEvent *event in eventContext.eventsAfter) + { + [self handleLiveEvent:event]; + } + + success(); + } failure:failure]; +} + #pragma mark - Pagination - (BOOL)canPaginate:(MXEventDirection)direction diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 61a25eec30..2abebcd07d 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -343,7 +343,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; @param typing Use YES if the user is currently typing. @param timeout the length of time until the user should be treated as no longer typing, - in milliseconds. Can be ommited (set to -1) if they are no longer typing. + in milliseconds. Can be ommited (set to -1) if they are no longer typing. @param success A block object called when the operation succeeds. @param failure A block object called when the operation fails. @@ -372,6 +372,34 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; failure:(void (^)(NSError *error))failure; +#pragma mark - Events timeline +/** + Open a new `MXEventTimeline` instance around the passed event. + + @param eventId the id of the event. + @param limit the maximum number of messages to preload. + + @param success A block object called when the operation succeeds. + It passes the newly `MXEventTimeline` created instance. + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. + */ + +- (MXHTTPOperation*)openTimelineOnEvent:(NSString*)eventId + withLimit:(NSUInteger)limit + success:(void(^)(MXEventTimeline *eventTimeline))success + failure:(void (^)(NSError *error))failure; + +/** + Close a `MXEventTimeline` instance. + All attached listeners are unregitered. + + @param eventTimeline the timeline to close. + */ +- (void)closeTimeline:(MXEventTimeline*)eventTimeline; + + #pragma mark - Outgoing events management /** Store into the store an outgoing message event being sent in the room. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index ea86638f9a..9faf91ec17 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -313,6 +313,24 @@ - (MXHTTPOperation*)redactEvent:(NSString*)eventId } +#pragma mark - Events timeline +- (MXHTTPOperation *)openTimelineOnEvent:(NSString *)eventId withLimit:(NSUInteger)limit success:(void (^)(MXEventTimeline *))success failure:(void (^)(NSError *))failure +{ + // Create and preload the event timeline + MXEventTimeline *eventTimeline = [[MXEventTimeline alloc] initWithRoom:self andInitialEventId:eventId]; + [eventTimeline loadContextWithLimit:limit success:^{ + success(eventTimeline); + } failure:failure]; + + return nil; +} + +-(void)closeTimeline:(MXEventTimeline *)eventTimeline +{ + // @TODO +} + + #pragma mark - Outgoing events management - (void)storeOutgoingMessage:(MXEvent*)outgoingMessage { diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m index b167b8f34f..ae49f02cc3 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m @@ -44,7 +44,10 @@ - (void)openWithCredentials:(MXCredentials *)someCredentials onComplete:(void (^ { credentials = someCredentials; // Nothing to do - onComplete(); + if (onComplete) + { + onComplete(); + } } - (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXEventDirection)direction diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m new file mode 100644 index 0000000000..17861bfc74 --- /dev/null +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -0,0 +1,80 @@ +/* + Copyright 2016 OpenMarket Ltd + + 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. + */ + +#import + +#import "MatrixSDKTestsData.h" + +#import "MXSession.h" + +@interface MXEventTimelineTests : XCTestCase +{ + MXSession *mxSession; +} +@end + +@implementation MXEventTimelineTests + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + if (mxSession) + { + [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + mxSession = nil; + } + [super tearDown]; +} + +- (void)testPaginateOnContextTimeline +{ + [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + mxSession = mxSession2; + + // Add 20 messages to the room + [[MatrixSDKTestsData sharedData] for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ + + [room sendTextMessage:@"The initial timelime event" success:^(NSString *eventId) { + + // Add 20 more messages + [[MatrixSDKTestsData sharedData] for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ + + [room openTimelineOnEvent:eventId withLimit:10 success:^(MXEventTimeline *eventTimeline) { + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + }]; + + } failure:^(NSError *error) { + NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + }]; + + }]; + + }]; +} + + +@end From f9127c56b494b59fcf788fc11bbefdc0c32b95ff Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 24 Feb 2016 17:23:54 +0100 Subject: [PATCH 53/80] Tests: Made them independent from each others using a new Alice and a new Bob (user ids) at the beginning of each of them --- MatrixSDKTests/MXMyUserTests.m | 2 +- MatrixSDKTests/MXNotificationCenterTests.m | 4 +- MatrixSDKTests/MXRestClientTests.m | 5 +-- MatrixSDKTests/MXRoomStateTests.m | 4 +- MatrixSDKTests/MXStoreTests.m | 10 ++++- MatrixSDKTests/MatrixSDKTestsData.h | 5 ++- MatrixSDKTests/MatrixSDKTestsData.m | 45 +++++++++------------- 7 files changed, 38 insertions(+), 37 deletions(-) diff --git a/MatrixSDKTests/MXMyUserTests.m b/MatrixSDKTests/MXMyUserTests.m index 104534d8b8..e641dc4725 100644 --- a/MatrixSDKTests/MXMyUserTests.m +++ b/MatrixSDKTests/MXMyUserTests.m @@ -177,7 +177,7 @@ - (void)testIdenticon MXUser *myUser = [mxSession userWithUserId:mxSession.matrixRestClient.credentials.userId]; NSString *identiconURL = [mxSession.matrixRestClient urlOfIdenticon:myUser.userId]; - XCTAssertEqualObjects(identiconURL, @"http://localhost:8080/_matrix/media/v1/identicon/%40mxBob%3Alocalhost%3A8480"); + XCTAssert([identiconURL hasPrefix:@"http://localhost:8080/_matrix/media/v1/identicon/%40mxBob"]); [expectation fulfill]; }]; diff --git a/MatrixSDKTests/MXNotificationCenterTests.m b/MatrixSDKTests/MXNotificationCenterTests.m index 31f38b605c..82fe374900 100644 --- a/MatrixSDKTests/MXNotificationCenterTests.m +++ b/MatrixSDKTests/MXNotificationCenterTests.m @@ -183,14 +183,14 @@ - (void)testDefaultContentCondition MXRoom *room = [mxSession roomWithRoomId:roomId]; [room.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { - NSString *messageFromAlice = @"mxBob: you should be notified for this message"; + NSString *messageFromAlice = [NSString stringWithFormat:@"%@: you should be notified for this message", bobSession.matrixRestClient.credentials.userId]; [bobSession.notificationCenter listenToNotifications:^(MXEvent *event, MXRoomState *roomState, MXPushRule *rule) { // We must be alerted by the default content HS rule on "mxBob" XCTAssertEqual(rule.kind, MXPushRuleKindContent); XCTAssert(rule.isDefault, @"The rule must be the server default rule. Rule: %@", rule); - XCTAssertEqualObjects(rule.pattern, @"mxBob", @"As content rule, the pattern must be define. Rule: %@", rule); + XCTAssert([rule.pattern hasPrefix:@"mxBob"], @"As content rule, the pattern must be define. Rule: %@", rule); // Check the right event has been notified XCTAssertEqualObjects(event.content[@"body"], messageFromAlice, @"The wrong messsage has been caught. event: %@", event); diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index e2b4d01f30..7570cbbf50 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -172,9 +172,7 @@ - (void)testJoinRoomWithRoomAlias { [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - NSString *mxPublicAlias = [NSString stringWithFormat:@"#mxPublic:%@", @"localhost:8480"]; - - [bobRestClient joinRoom:mxPublicAlias success:^(NSString *theRoomId) { + [bobRestClient joinRoom:[MatrixSDKTestsData sharedData].thePublicRoomAlias success:^(NSString *theRoomId) { XCTAssertEqualObjects(roomId, theRoomId); [expectation fulfill]; @@ -971,6 +969,7 @@ - (void)testSearchUniqueTextAcrossRooms XCTAssertNil(roomEventResults.nextBatch, @"The result contains all matching events"); + [mxSession close]; [expectation fulfill]; } failure:^(NSError *error) { diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index 6b4bc19cd3..1caa43321f 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -367,7 +367,7 @@ - (void)testAliases NSString *alias = room.state.aliases[0]; - XCTAssertTrue([alias hasPrefix:@"#mxPublic:"]); + XCTAssertTrue([alias hasPrefix:@"#mxPublic"]); [expectation fulfill]; }]; @@ -381,7 +381,7 @@ - (void)testDisplayName1 mxSession = mxSession2; XCTAssertNotNil(room.state.displayname); - XCTAssertTrue([room.state.displayname hasPrefix:@"MX Public Room test (#mxPublic:"], @"We must retrieve the #mxPublic room settings"); + XCTAssertTrue([room.state.displayname hasPrefix:@"MX Public Room test (#mxPublic"], @"We must retrieve the #mxPublic room settings"); [expectation fulfill]; }]; diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 6da416c72a..718c0a51d0 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -612,6 +612,9 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room __block NSString *aliceTextEventId; + // Make sure bob joins back the room only once + __block BOOL joinedRequestMade = NO; + // Listen for the invitation by Alice [mxSession listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) { @@ -620,10 +623,11 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room XCTAssertNotNil(room2); - if (direction == MXEventDirectionForwards && MXMembershipInvite == room2.state.membership) + if (direction == MXEventDirectionForwards && MXMembershipInvite == room2.state.membership && !joinedRequestMade) { // Join the room on the invitation and check we can paginate all expected text messages // By default the last Alice's message (sent while Bob is not in the room) is not visible. + joinedRequestMade = YES; [room2 join:^{ NSMutableArray *events = [NSMutableArray array]; @@ -643,15 +647,19 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(events.count, 5, "The room should contain only 5 messages (the last message sent while the user is not in the room is not visible)"); + + [mxSession close]; [expectation fulfill]; } failure:^(NSError *error) { XCTFail(@"The request should not fail - NSError: %@", error); + [mxSession close]; [expectation fulfill]; }]; } failure:^(NSError *error) { XCTFail(@"The request should not fail - NSError: %@", error); + [mxSession close]; [expectation fulfill]; }]; } diff --git a/MatrixSDKTests/MatrixSDKTestsData.h b/MatrixSDKTests/MatrixSDKTestsData.h index 207bbd6bbc..6666c3d96e 100644 --- a/MatrixSDKTests/MatrixSDKTestsData.h +++ b/MatrixSDKTests/MatrixSDKTestsData.h @@ -30,7 +30,7 @@ FOUNDATION_EXPORT NSString * const kMXTestsAliceAvatarURL; @interface MatrixSDKTestsData : NSObject -+ (id)sharedData; ++ (MatrixSDKTestsData *)sharedData; #pragma mark - mxBob // Credentials for the user mxBob on the home server located at kMXTestsHomeServerURL @@ -82,6 +82,9 @@ FOUNDATION_EXPORT NSString * const kMXTestsAliceAvatarURL; readyToTest:(void (^)(MXRestClient *aliceRestClient, XCTestExpectation *expectation))readyToTest; #pragma mark - both +// The alias used for the public room created with *ThePublicRoom* methods +@property (nonatomic,readonly) NSString *thePublicRoomAlias; + - (void)doMXRestClientTestWithBobAndAliceInARoom:(XCTestCase*)testCase readyToTest:(void (^)(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString* roomId, XCTestExpectation *expectation))readyToTest; diff --git a/MatrixSDKTests/MatrixSDKTestsData.m b/MatrixSDKTests/MatrixSDKTestsData.m index a38ffad1d2..f0e4486f79 100644 --- a/MatrixSDKTests/MatrixSDKTestsData.m +++ b/MatrixSDKTests/MatrixSDKTestsData.m @@ -85,11 +85,14 @@ - (void)getBobCredentials:(void (^)())success } else { + // Use a different Bob each time so that tests are independent + NSString *bobUniqueUser = [NSString stringWithFormat:@"%@-%@", MXTESTS_BOB, [[NSUUID UUID] UUIDString]]; + // First, try register the user // @TODO: Update the registration code to support r0 registration and // remove this patch that redirects the registration to a deprecated CS API. mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; - [mxRestClient registerWithUser:MXTESTS_BOB andPassword:MXTESTS_BOB_PWD success:^(MXCredentials *credentials) { + [mxRestClient registerWithUser:bobUniqueUser andPassword:MXTESTS_BOB_PWD success:^(MXCredentials *credentials) { _bobCredentials = credentials; success(); @@ -101,7 +104,7 @@ - (void)getBobCredentials:(void (^)())success // The user already exists. This error is normal. // Log Bob in to get his keys mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; - [mxRestClient loginWithUser:MXTESTS_BOB andPassword:MXTESTS_BOB_PWD success:^(MXCredentials *credentials) { + [mxRestClient loginWithUser:bobUniqueUser andPassword:MXTESTS_BOB_PWD success:^(MXCredentials *credentials) { _bobCredentials = credentials; success(); @@ -216,36 +219,21 @@ - (void)doMXRestClientTestWithBobAndThePublicRoom:(XCTestCase*)testCase { [self doMXRestClientTestWithBob:testCase readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - // Create THE allocated public room: #mxPublic + + // Create a public room starting with #mxPublic + _thePublicRoomAlias = [NSString stringWithFormat:@"mxPublic-%@", [[NSUUID UUID] UUIDString]]; + [bobRestClient createRoom:@"MX Public Room test" visibility:kMXRoomVisibilityPublic - roomAlias:@"mxPublic" + roomAlias:_thePublicRoomAlias topic:@"The public room used by SDK tests" success:^(MXCreateRoomResponse *response) { - + + _thePublicRoomAlias = response.roomAlias; readyToTest(bobRestClient, response.roomId, expectation); } failure:^(NSError *error) { - if ([MXError isMXError:error]) - { - // @TODO: Workaround for HS weird behavior: it returns a buggy alias "#mxPublic:localhost:8480" - //NSString *mxPublicAlias = [NSString stringWithFormat:@"#mxPublic:%@", self.bobCredentials.home_server]; - NSString *mxPublicAlias = [NSString stringWithFormat:@"#mxPublic:%@", @"localhost:8480"]; - - // The room may already exist, try to retrieve its room id - [bobRestClient roomIDForRoomAlias:mxPublicAlias success:^(NSString *roomId) { - - readyToTest(bobRestClient, roomId, expectation); - - } failure:^(NSError *error) { - NSAssert(NO, @"Cannot retrieve mxPublic from its alias - error: %@", error); - }]; - } - else - { - NSAssert(NO, @"Cannot create a room - error: %@", error); - } + NSAssert(NO, @"Cannot create the public room - error: %@", error); }]; }]; } @@ -442,11 +430,14 @@ - (void)getAliceCredentials:(void (^)())success } else { + // Use a different Alice each time so that tests are independent + NSString *aliceUniqueUser = [NSString stringWithFormat:@"%@-%@", MXTESTS_ALICE, [[NSUUID UUID] UUIDString]]; + // @TODO: Update the registration code to support r0 registration and // remove this patch that redirects the registration to a deprecated CS API. mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; // First, try register the user - [mxRestClient registerWithUser:MXTESTS_ALICE andPassword:MXTESTS_ALICE_PWD success:^(MXCredentials *credentials) { + [mxRestClient registerWithUser:aliceUniqueUser andPassword:MXTESTS_ALICE_PWD success:^(MXCredentials *credentials) { _aliceCredentials = credentials; success(); @@ -458,7 +449,7 @@ - (void)getAliceCredentials:(void (^)())success // The user already exists. This error is normal. // Log Bob in to get his keys mxRestClient.apiPathPrefix = @"/_matrix/client/api/v1"; - [mxRestClient loginWithUser:MXTESTS_ALICE andPassword:MXTESTS_ALICE_PWD success:^(MXCredentials *credentials) { + [mxRestClient loginWithUser:aliceUniqueUser andPassword:MXTESTS_ALICE_PWD success:^(MXCredentials *credentials) { _aliceCredentials = credentials; success(); From 426d1e306afb86f6e4e4711c8e19f5182d922c80 Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 24 Feb 2016 17:43:40 +0100 Subject: [PATCH 54/80] MXCreateRoomResponse: Fixed parsing of the returned room alias --- MatrixSDK/JSONModels/MXJSONModels.m | 1 + 1 file changed, 1 insertion(+) diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 042357ddf4..0ea1525d86 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -128,6 +128,7 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary if (createRoomResponse) { MXJSONModelSetString(createRoomResponse.roomId, JSONDictionary[@"room_id"]); + MXJSONModelSetString(createRoomResponse.roomAlias, JSONDictionary[@"room_alias"]); } return createRoomResponse; From 70f2714c1bc2a90f8d3e58c6491a99303302f63d Mon Sep 17 00:00:00 2001 From: manuroe Date: Wed, 24 Feb 2016 18:26:14 +0100 Subject: [PATCH 55/80] Tests: Fixed tests with canPaginate. We now need to make call paginate one more time to be sure we reach the end of the history --- MatrixSDKTests/MXStoreMemoryStoreTests.m | 18 ++++++++++++++---- MatrixSDKTests/MXStoreTests.m | 12 ++++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/MatrixSDKTests/MXStoreMemoryStoreTests.m b/MatrixSDKTests/MXStoreMemoryStoreTests.m index 66fe0b853d..b60284ed7d 100644 --- a/MatrixSDKTests/MXStoreMemoryStoreTests.m +++ b/MatrixSDKTests/MXStoreMemoryStoreTests.m @@ -303,12 +303,22 @@ - (void)testMXMemoryStorePaginateAgain XCTAssertTrue([event2.eventId isEqualToString:event.eventId], @"Events mismatch: %@ - %@", event, event2); } - XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We reach the beginning of the history"); + // Do one more round trip so that SDK detect the limit + [room.liveTimeline paginate:1 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ - [room.liveTimeline resetPagination]; - XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must be able to paginate again"); + XCTAssertEqual(roomEvents.count, 8, @"We should have not received more events"); - [expectation fulfill]; + XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We reach the beginning of the history"); + + [room.liveTimeline resetPagination]; + XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must be able to paginate again"); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; } failure:^(NSError *error) { XCTFail(@"The request should not fail - NSError: %@", error); diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 718c0a51d0..52ee984694 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -567,9 +567,17 @@ - (void)checkCanPaginateFromMXStore:(MXRoom*)room [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { - XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must have reached the end of the pagination"); + // Do one more round trip so that SDK detect the limit + [room.liveTimeline paginate:1 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ - [expectation fulfill]; + XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must have reached the end of the pagination"); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; } failure:^(NSError *error) { XCTFail(@"The request should not fail - NSError: %@", error); From bb8bab0b1af530da17d39d65619db4679ebc08c7 Mon Sep 17 00:00:00 2001 From: giomfo Date: Thu, 25 Feb 2016 16:20:45 +0100 Subject: [PATCH 56/80] MXFileStore: Force store refresh. An issue related to invitation handling has been fixed previously. We need to flush the existing store to erase all data corrupted by this issue. --- MatrixSDK/Data/Store/MXFileStore/MXFileStore.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index db79fcc588..1c826ca1e5 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -20,7 +20,7 @@ #import "MXFileStoreMetaData.h" -NSUInteger const kMXFileVersion = 21; +NSUInteger const kMXFileVersion = 22; NSString *const kMXFileStoreFolder = @"MXFileStore"; NSString *const kMXFileStoreMedaDataFile = @"MXFileStore"; From 024478519ae37a8f0b16da65b2313cec84a5438f Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 25 Feb 2016 14:58:18 +0100 Subject: [PATCH 57/80] Tests: Fix: During one test, make sure we use the same Alice and Bob. Use a new MatrixSDKTestsData instance for each test to ensure that. --- MatrixSDKTests/MXEventTests.m | 17 ++-- MatrixSDKTests/MXJSONModelTests.m | 8 +- MatrixSDKTests/MXMyUserTests.m | 17 ++-- MatrixSDKTests/MXNotificationCenterTests.m | 24 +++--- MatrixSDKTests/MXPushRuleTests.m | 2 + MatrixSDKTests/MXRestClientNoAuthAPITests.m | 9 +- MatrixSDKTests/MXRestClientTests.m | 92 +++++++++++---------- MatrixSDKTests/MXRoomMemberTests.m | 10 ++- MatrixSDKTests/MXRoomStateDynamicTests.m | 16 ++-- MatrixSDKTests/MXRoomStateTests.m | 56 +++++++------ MatrixSDKTests/MXRoomTests.m | 30 ++++--- MatrixSDKTests/MXSessionTests.m | 62 +++++++------- MatrixSDKTests/MXStoreTests.m | 37 +++++---- MatrixSDKTests/MXUserTests.m | 10 ++- MatrixSDKTests/MXVoIPTests.m | 12 ++- MatrixSDKTests/MatrixSDKTestsData.h | 5 +- MatrixSDKTests/MatrixSDKTestsData.m | 67 +++++++-------- 17 files changed, 265 insertions(+), 209 deletions(-) diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index aaf1aeb867..55eba1e7d0 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -23,6 +23,8 @@ @interface MXEventTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @@ -30,15 +32,18 @@ @interface MXEventTests : XCTestCase @implementation MXEventTests -- (void)setUp { +- (void)setUp +{ [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + + matrixSDKTestsData =[[MatrixSDKTestsData alloc] init]; } -- (void)tearDown { +- (void)tearDown +{ if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -46,7 +51,7 @@ - (void)tearDown { - (void)doTestWithMXEvents:(void (^)(MXRestClient *bobRestClient, NSString* roomId, NSArray *events, XCTestExpectation *expectation))readyToTest { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient messagesForRoom:roomId from:nil to:nil limit:100 success:^(MXPaginationResponse *paginatedResponse) { @@ -91,7 +96,7 @@ - (void)testAge - (void)testIsState { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; diff --git a/MatrixSDKTests/MXJSONModelTests.m b/MatrixSDKTests/MXJSONModelTests.m index 8899dc1ba2..c479ecfaa8 100644 --- a/MatrixSDKTests/MXJSONModelTests.m +++ b/MatrixSDKTests/MXJSONModelTests.m @@ -54,6 +54,8 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary @interface MXJSONModelTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXHTTPClient *httpClient; } @end @@ -64,6 +66,8 @@ - (void)setUp { [super setUp]; + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; + httpClient = [[MXHTTPClient alloc] initWithBaseURL:[NSString stringWithFormat:@"%@%@", kMXTestsHomeServerURL, kMXAPIPrefixPathR0] andOnUnrecognizedCertificateBlock:nil]; } @@ -77,7 +81,7 @@ - (void)tearDown - (void)testModelFromJSON { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { // Use publicRooms JSON response to check modelFromJSON [httpClient requestWithMethod:@"GET" @@ -103,7 +107,7 @@ - (void)testModelFromJSON - (void)testModelsFromJSON { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { // Use publicRooms JSON response to check modelFromJSON [httpClient requestWithMethod:@"GET" diff --git a/MatrixSDKTests/MXMyUserTests.m b/MatrixSDKTests/MXMyUserTests.m index e641dc4725..22e7136527 100644 --- a/MatrixSDKTests/MXMyUserTests.m +++ b/MatrixSDKTests/MXMyUserTests.m @@ -25,6 +25,8 @@ @interface MXMyUserTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @end @@ -34,13 +36,16 @@ @implementation MXMyUserTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; + matrixSDKTestsData = nil; mxSession = nil; } [super tearDown]; @@ -48,7 +53,7 @@ - (void)tearDown - (void)testMXSessionMyUser { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -63,7 +68,7 @@ - (void)testMXSessionMyUser - (void)testSetDisplayName { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -99,7 +104,7 @@ - (void)testSetDisplayName - (void)testSetAvatarURL { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -134,7 +139,7 @@ - (void)testSetAvatarURL - (void)testSetPresence { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -170,7 +175,7 @@ - (void)testSetPresence - (void)testIdenticon { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; diff --git a/MatrixSDKTests/MXNotificationCenterTests.m b/MatrixSDKTests/MXNotificationCenterTests.m index 82fe374900..18ea138bca 100644 --- a/MatrixSDKTests/MXNotificationCenterTests.m +++ b/MatrixSDKTests/MXNotificationCenterTests.m @@ -26,6 +26,8 @@ @interface MXNotificationCenterTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @@ -36,12 +38,14 @@ @implementation MXNotificationCenterTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -49,7 +53,7 @@ - (void)tearDown { - (void)testNotificationCenterRulesReady { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -75,7 +79,7 @@ - (void)testNotificationCenterRulesReady - (void)testNoNotificationsOnUserEvents { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -102,7 +106,7 @@ - (void)testNoNotificationsOnUserEvents - (void)testNoNotificationsOnPresenceOrTypingEvents { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -140,7 +144,7 @@ - (void)testNoNotificationsOnPresenceOrTypingEvents // While this ticket is not fixed, make sure the SDK workrounds it - (void)testDefaultPushOnAllNonYouMessagesRule { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -176,7 +180,7 @@ - (void)testDefaultPushOnAllNonYouMessagesRule - (void)testDefaultContentCondition { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -219,7 +223,7 @@ - (void)testDefaultContentCondition - (void)testDefaultDisplayNameCondition { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -265,7 +269,7 @@ - (void)testDefaultDisplayNameCondition - (void)testDefaultRoomMemberCountCondition { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -298,7 +302,7 @@ - (void)testDefaultRoomMemberCountCondition - (void)testRemoveListener { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -330,7 +334,7 @@ - (void)testRemoveListener - (void)testRuleMatchingEvent { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; diff --git a/MatrixSDKTests/MXPushRuleTests.m b/MatrixSDKTests/MXPushRuleTests.m index 2b00350381..f275bc0ffa 100644 --- a/MatrixSDKTests/MXPushRuleTests.m +++ b/MatrixSDKTests/MXPushRuleTests.m @@ -38,6 +38,8 @@ - (void)setFlatRules:(NSArray *)newFlatRules @interface MXPushRuleTests : XCTestCase +{ +} @end diff --git a/MatrixSDKTests/MXRestClientNoAuthAPITests.m b/MatrixSDKTests/MXRestClientNoAuthAPITests.m index a4d513fa33..1cc526e357 100644 --- a/MatrixSDKTests/MXRestClientNoAuthAPITests.m +++ b/MatrixSDKTests/MXRestClientNoAuthAPITests.m @@ -27,6 +27,8 @@ @interface MXRestClientNoAuthAPITests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXRestClient *mxRestClient; } @@ -34,9 +36,12 @@ @interface MXRestClientNoAuthAPITests : XCTestCase @implementation MXRestClientNoAuthAPITests -- (void)setUp { +- (void)setUp +{ [super setUp]; + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; + mxRestClient = [[MXRestClient alloc] initWithHomeServer:kMXTestsHomeServerURL andOnUnrecognizedCertificateBlock:nil]; } @@ -333,7 +338,7 @@ - (void)testLoginPasswordBasedWithWrongPassword #pragma mark - Event operations - (void)testPublicRooms { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [mxRestClient publicRooms:^(NSArray *rooms) { diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index 7570cbbf50..d249825abd 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -26,26 +26,32 @@ #pragma clang diagnostic ignored "-Warc-retain-cycles" @interface MXRestClientTests : XCTestCase +{ + MatrixSDKTestsData *matrixSDKTestsData; +} @end @implementation MXRestClientTests -- (void)setUp { +- (void)setUp +{ [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } -- (void)tearDown { +- (void)tearDown +{ // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testInit { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; XCTAssertTrue([bobRestClient.homeserver isEqualToString:kMXTestsHomeServerURL], "bobRestClient.homeserver(%@) is wrong", bobRestClient.homeserver); XCTAssertTrue([bobRestClient.credentials.userId isEqualToString:sharedData.bobCredentials.userId], "bobRestClient.userId(%@) is wrong", bobRestClient.credentials.userId); @@ -59,7 +65,7 @@ - (void)testInit - (void)testSendTextMessage { // This test on sendTextMessage validates sendMessage and sendEvent too - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient sendTextMessageToRoom:roomId text:@"This is text message" success:^(NSString *eventId) { @@ -76,7 +82,7 @@ - (void)testSendTextMessage - (void)testRoomTopic { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { __block MXRestClient *bobRestClient2 = bobRestClient; [bobRestClient setRoomTopic:roomId topic:@"Topic setter and getter functions are tested here" success:^{ @@ -102,7 +108,7 @@ - (void)testRoomTopic - (void)testRoomAvatar { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { __block MXRestClient *bobRestClient2 = bobRestClient; [bobRestClient setRoomAvatar:roomId avatar:@"http://matrix.org/matrix.png" success:^{ @@ -128,7 +134,7 @@ - (void)testRoomAvatar - (void)testRoomName { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { __block MXRestClient *bobRestClient2 = bobRestClient; [bobRestClient setRoomName:roomId name:@"My room name" success:^{ @@ -154,7 +160,7 @@ - (void)testRoomName - (void)testJoinRoomWithRoomId { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient joinRoom:roomId success:^(NSString *theRoomId) { @@ -170,9 +176,9 @@ - (void)testJoinRoomWithRoomId - (void)testJoinRoomWithRoomAlias { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndThePublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient joinRoom:[MatrixSDKTestsData sharedData].thePublicRoomAlias success:^(NSString *theRoomId) { + [bobRestClient joinRoom:matrixSDKTestsData.thePublicRoomAlias success:^(NSString *theRoomId) { XCTAssertEqualObjects(roomId, theRoomId); [expectation fulfill]; @@ -187,7 +193,7 @@ - (void)testJoinRoomWithRoomAlias - (void)testLeaveRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient leaveRoom:roomId success:^{ @@ -203,9 +209,9 @@ - (void)testLeaveRoom - (void)testInviteUserToRoom { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -250,7 +256,7 @@ - (void)testInviteUserToRoom - (void)testKickUserFromRoom { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -292,7 +298,7 @@ - (void)testKickUserFromRoom - (void)testBanUserInRoom { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -334,7 +340,7 @@ - (void)testBanUserInRoom - (void)testCreateRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { // Create a random room with no params [bobRestClient createRoom:nil visibility:nil roomAlias:nil topic:nil success:^(MXCreateRoomResponse *response) { @@ -355,7 +361,7 @@ - (void)testCreateRoom - (void)testMessagesWithNoParams { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient messagesForRoom:roomId from:nil to:nil limit:-1 success:^(MXPaginationResponse *paginatedResponse) { @@ -377,7 +383,7 @@ - (void)testMessagesWithNoParams - (void)testMessagesWithOneParam { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient messagesForRoom:roomId from:nil to:nil limit:100 success:^(MXPaginationResponse *paginatedResponse) { @@ -399,7 +405,7 @@ - (void)testMessagesWithOneParam - (void)testMembers { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient membersOfRoom:roomId success:^(NSArray *roomMemberEvents) { @@ -420,7 +426,7 @@ - (void)testMembers - (void)testStateOfRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient stateOfRoom:roomId success:^(NSDictionary *JSONData) { @@ -450,7 +456,7 @@ - (void)testStateOfRoom - (void)testSendTypingNotification { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient sendTypingNotificationInRoom:roomId typing:YES timeout:30000 success:^{ @@ -472,7 +478,7 @@ - (void)testSendTypingNotification - (void)testRedactEvent { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient sendTextMessageToRoom:roomId text:@"This is text message" success:^(NSString *eventId) { @@ -493,7 +499,7 @@ - (void)testRedactEvent - (void)testInitialSyncOfRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient initialSyncOfRoom:roomId withLimit:3 success:^(MXRoomInitialSync *roomInitialSync) { @@ -529,7 +535,7 @@ - (void)testInitialSyncOfRoom - (void)testContextOfEvent { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient initialSyncOfRoom:roomId withLimit:10 success:^(MXRoomInitialSync *roomInitialSync) { @@ -579,7 +585,7 @@ - (void) removeAgeField:(MXRoomInitialSync*)roomInitialSync - (void)testMXRoomMemberEventContent { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient membersOfRoom:roomId success:^(NSArray *roomMemberEvents) { for (MXEvent *roomMemberEvent in roomMemberEvents) @@ -605,7 +611,7 @@ - (void)testMXRoomMemberEventContent #pragma mark - #pragma mark - Room tags operations - (void)testAddAndRemoveTag { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { // Add a new tag [bobRestClient addTag:@"aTag" withOrder:nil toRoom:roomId success:^{ @@ -648,7 +654,7 @@ - (void)testAddAndRemoveTag #pragma mark - Profile operations - (void)testUserDisplayName { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { __block MXRestClient *aliceRestClient2 = aliceRestClient; @@ -676,15 +682,15 @@ - (void)testUserDisplayName - (void)testOtherUserDisplayName { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { // Set the name __block NSString *newDisplayName = @"mxAlice2"; [aliceRestClient setDisplayName:newDisplayName success:^{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:nil readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBob:nil readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; // Then retrieve it from a Bob restClient [bobRestClient displayNameForUser:sharedData.aliceCredentials.userId success:^(NSString *displayname) { @@ -707,7 +713,7 @@ - (void)testOtherUserDisplayName - (void)testUserNilDisplayName { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { [bobRestClient displayNameForUser:nil success:^(NSString *displayname) { @@ -725,7 +731,7 @@ - (void)testUserNilDisplayName - (void)testUserAvatarUrl { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { __block MXRestClient *aliceRestClient2 = aliceRestClient; @@ -753,15 +759,15 @@ - (void)testUserAvatarUrl - (void)testOtherUserAvatarUrl { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { // Set the avatar url __block NSString *newAvatarUrl = @"http://matrix.org/matrix2.png"; [aliceRestClient setAvatarUrl:newAvatarUrl success:^{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:nil readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBob:nil readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; // Then retrieve it from a Bob restClient [bobRestClient avatarUrlForUser:sharedData.aliceCredentials.userId success:^(NSString *avatarUrl) { @@ -787,7 +793,7 @@ - (void)testOtherUserAvatarUrl - (void)testUserPresence { // Make sure the test is valid once the bug is fixed server side - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { __block MXRestClient *aliceRestClient2 = aliceRestClient; @@ -852,7 +858,7 @@ - (void)testUrlOfContentThumbnail // The test must be updated if those HS default rules change. - (void)testPushRules { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { [bobRestClient pushRules:^(MXPushRulesResponse *pushRules) { @@ -911,7 +917,7 @@ - (void)testPushRules #pragma mark - Search - (void)testSearchText { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient searchMessageText:@"Fake message" inRooms:@[roomId] @@ -943,7 +949,7 @@ - (void)testSearchText - (void)testSearchUniqueTextAcrossRooms { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession, MXRoom *room, XCTestExpectation *expectation) { NSString *message = [[NSProcessInfo processInfo] globallyUniqueString]; __block NSString *messageEventId; @@ -986,10 +992,10 @@ - (void)testSearchUniqueTextAcrossRooms - (void)testSearchPaginate { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { // Add 50 messages to the room - [[MatrixSDKTestsData sharedData] for:bobRestClient andRoom:roomId sendMessages:20 success:^{ + [matrixSDKTestsData for:bobRestClient andRoom:roomId sendMessages:20 success:^{ [bobRestClient searchMessageText:@"Fake message" inRooms:@[roomId] diff --git a/MatrixSDKTests/MXRoomMemberTests.m b/MatrixSDKTests/MXRoomMemberTests.m index 349666c3e3..27267be2bf 100644 --- a/MatrixSDKTests/MXRoomMemberTests.m +++ b/MatrixSDKTests/MXRoomMemberTests.m @@ -22,7 +22,9 @@ #import "MXRoomMember.h" @interface MXRoomMemberTests : XCTestCase - +{ + MatrixSDKTestsData *matrixSDKTestsData; +} @end @implementation MXRoomMemberTests @@ -30,18 +32,18 @@ @implementation MXRoomMemberTests - (void)setUp { [super setUp]; - // Put setup code here. This method is called before the invocation of each test method in the class. + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { - // Put teardown code here. This method is called after the invocation of each test method in the class. [super tearDown]; } - (void)testKickedMember { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index bdcac964cb..a0813a2237 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -23,6 +23,8 @@ @interface MXRoomStateDynamicTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @end @@ -32,13 +34,15 @@ @implementation MXRoomStateDynamicTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -96,7 +100,7 @@ -(void)createScenario1:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId onC - (void)testBackPaginationForScenario1 { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [self createScenario1:bobRestClient inRoom:roomId onComplete:^{ @@ -182,7 +186,7 @@ - (void)testBackPaginationForScenario1 - (void)testLiveEventsForScenario1 { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -291,7 +295,7 @@ - (void)createScenario2:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId on { [bobRestClient sendTextMessageToRoom:roomId text:@"Hello world" success:^(NSString *eventId) { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -356,7 +360,7 @@ - (void)createScenario2:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId on /* - (void)testBackPaginationForScenario2 { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [self createScenario2:bobRestClient inRoom:roomId onComplete:^(MXRestClient *aliceRestClient) { @@ -538,7 +542,7 @@ - (void)testBackPaginationForScenario2 - (void)testLiveEventsForScenario2 { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index 1caa43321f..01ab997a51 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -29,6 +29,8 @@ @interface MXRoomStateTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @end @@ -38,13 +40,15 @@ @implementation MXRoomStateTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -52,7 +56,7 @@ - (void)tearDown - (void)testIsPublic { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -64,7 +68,7 @@ - (void)testIsPublic - (void)testIsPublicForAPrivateRoom { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -76,7 +80,7 @@ - (void)testIsPublicForAPrivateRoom - (void)testRoomTopicProvidedByInitialSync { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { MXRestClient *bobRestClient2 = bobRestClient; @@ -107,7 +111,7 @@ - (void)testRoomTopicProvidedByInitialSync - (void)testRoomTopicLive { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { MXRestClient *bobRestClient2 = bobRestClient; @@ -149,7 +153,7 @@ - (void)testRoomTopicLive - (void)testRoomAvatarProvidedByInitialSync { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { MXRestClient *bobRestClient2 = bobRestClient; @@ -180,7 +184,7 @@ - (void)testRoomAvatarProvidedByInitialSync - (void)testRoomAvatarLive { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { MXRestClient *bobRestClient2 = bobRestClient; @@ -221,7 +225,7 @@ - (void)testRoomAvatarLive - (void)testRoomNameProvidedByInitialSync { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { MXRestClient *bobRestClient2 = bobRestClient; @@ -252,7 +256,7 @@ - (void)testRoomNameProvidedByInitialSync - (void)testRoomNameLive { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { MXRestClient *bobRestClient2 = bobRestClient; @@ -294,7 +298,7 @@ - (void)testRoomNameLive - (void)testMembers { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -325,11 +329,11 @@ - (void)testMembers - (void)testMemberName { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; NSString *bobUserId = sharedData.bobCredentials.userId; NSString *bobMemberName = [room.state memberName:bobUserId]; @@ -345,7 +349,7 @@ - (void)testMemberName - (void)testStateEvents { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -358,7 +362,7 @@ - (void)testStateEvents - (void)testAliases { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -376,7 +380,7 @@ - (void)testAliases // Test the room display name formatting: "roomName (roomAlias)" - (void)testDisplayName1 { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -390,7 +394,7 @@ - (void)testDisplayName1 // Test the room display name formatting: "userID" (self chat) - (void)testDisplayName2 { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -425,7 +429,7 @@ - (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString [bobRestClient setRoomTopic:roomId topic:@"We test room invitation here" success:^{ - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -466,7 +470,7 @@ - (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString - (void)testInviteByOtherInInitialSync { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -515,7 +519,7 @@ - (void)testInviteByOtherInInitialSync - (void)testInviteByOtherInLive { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -580,7 +584,7 @@ - (void)testInviteByOtherInLive - (void)testMXRoomJoin { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -648,7 +652,7 @@ - (void)testMXRoomJoin - (void)testMXSessionJoinOnPublicRoom { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -701,7 +705,7 @@ - (void)testMXSessionJoinOnPublicRoom - (void)testPowerLevels { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -762,7 +766,7 @@ - (void)testPowerLevels // Test for https://matrix.org/jira/browse/SYIOS-105 - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClient { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; [mxSession start:^{ @@ -789,7 +793,7 @@ - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClient }]; // Create a conversation on another MXRestClient. For the current `mxSession`, this other MXRestClient behaves like another device. - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:nil readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:nil readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { newRoomId = roomId; @@ -813,7 +817,7 @@ - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClient // Test for https://matrix.org/jira/browse/SYIOS-105 using notifications - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClientAndNotifications { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; [mxSession start:^{ @@ -851,7 +855,7 @@ - (void)testRoomStateWhenARoomHasBeenJoinedOnAnotherMatrixClientAndNotifications }]; // Create a conversation on another MXRestClient. For the current `mxSession`, this other MXRestClient behaves like another device. - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:nil readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:nil readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { }]; } failure:^(NSError *error) { diff --git a/MatrixSDKTests/MXRoomTests.m b/MatrixSDKTests/MXRoomTests.m index f72048f0d4..4fbc5c385f 100644 --- a/MatrixSDKTests/MXRoomTests.m +++ b/MatrixSDKTests/MXRoomTests.m @@ -27,6 +27,8 @@ @interface MXRoomTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @@ -37,13 +39,15 @@ @implementation MXRoomTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -52,7 +56,7 @@ - (void)tearDown - (void)testListenerForAllLiveEvents { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -85,7 +89,7 @@ - (void)testListenerForAllLiveEvents // Populate a text message in parallel - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndThePublicRoom:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { [bobRestClient sendTextMessageToRoom:roomId text:@"Hello listeners!" success:^(NSString *eventId) { @@ -106,7 +110,7 @@ - (void)testListenerForAllLiveEvents - (void)testListenerForRoomMessageLiveEvents { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndThePublicRoom:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -139,7 +143,7 @@ - (void)testListenerForRoomMessageLiveEvents }]; // Populate a text message in parallel - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndThePublicRoom:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndThePublicRoom:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { [bobRestClient sendTextMessageToRoom:roomId text:@"Hello listeners!" success:^(NSString *eventId) { @@ -159,7 +163,7 @@ - (void)testListenerForRoomMessageLiveEvents - (void)testLeave { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -190,9 +194,9 @@ - (void)testLeave - (void)testJoin { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -231,7 +235,7 @@ - (void)testJoin - (void)testSetPowerLevelOfUser { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -260,7 +264,7 @@ - (void)testSetPowerLevelOfUser - (void)testPaginateBackMessagesCancel { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -300,7 +304,7 @@ - (void)testPaginateBackMessagesCancel - (void)testTypingUsersNotifications { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -332,7 +336,7 @@ - (void)testTypingUsersNotifications - (void)testAddAndRemoveTag { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; NSString *tag = @"aTag"; @@ -378,7 +382,7 @@ - (void)testAddAndRemoveTag - (void)testReplaceTag { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; NSString *tag = @"aTag"; diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index 2311dfe5fd..cc04f5ccbf 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -29,6 +29,8 @@ @interface MXSessionTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @end @@ -38,13 +40,15 @@ @implementation MXSessionTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -53,7 +57,7 @@ - (void)tearDown - (void)testRecents { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -87,7 +91,7 @@ - (void)testRecents - (void)testRecentsOrder { - [[MatrixSDKTestsData sharedData]doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -123,7 +127,7 @@ - (void)testRecentsOrder - (void)testSortRooms { - [[MatrixSDKTestsData sharedData]doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -151,7 +155,7 @@ - (void)testSortRooms - (void)testListenerForAllLiveEvents { - [[MatrixSDKTestsData sharedData]doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -203,7 +207,7 @@ - (void)testListenerForAllLiveEvents // Create a room with messages in parallel [mxSession start:^{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { theRoomId = roomId; @@ -224,7 +228,7 @@ - (void)testListenerForAllLiveEvents - (void)testListenerForRoomMessageOnly { - [[MatrixSDKTestsData sharedData]doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -250,7 +254,7 @@ - (void)testListenerForRoomMessageOnly // Create a room with messages in parallel [mxSession start:^{ - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { }]; } failure:^(NSError *error) { @@ -261,7 +265,7 @@ - (void)testListenerForRoomMessageOnly - (void)testListenerForSyncEvents { - [[MatrixSDKTestsData sharedData]doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -293,7 +297,7 @@ - (void)testListenerForSyncEvents - (void)testListenerForPresence { // Make sure Alice and Bob have activities - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -349,7 +353,7 @@ - (void)testListenerForPresence - (void)testClose { // Make sure Alice and Bob have activities - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -401,7 +405,7 @@ - (void)testClose - (void)testCloseWithMXMemoryStore { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { @@ -446,7 +450,7 @@ - (void)testCloseWithMXMemoryStore - (void)testPauseResume { // Make sure Alice and Bob have activities - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -513,7 +517,7 @@ - (void)testPauseResume - (void)testPauseResumeOnNothingNew { // Make sure Alice and Bob have activities - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -575,7 +579,7 @@ - (void)testPauseResumeOnNothingNew - (void)testState { - [[MatrixSDKTestsData sharedData] doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestInABobRoomAndANewTextMessage:self newTextMessage:@"This is a text message for recents" onReadyToTest:^(MXRestClient *bobRestClient, NSString *roomId, NSString *new_text_message_eventId, XCTestExpectation *expectation) { __block MXSessionState previousSessionState = MXSessionStateInitialised; [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionStateDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { @@ -628,7 +632,7 @@ - (void)testState - (void)testCreateRoom { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBob:self readyToTest:^(MXSession *mxSession2, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBob:self readyToTest:^(MXSession *mxSession2, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -653,7 +657,7 @@ - (void)testCreateRoom - (void)testPrivateOneToOneRoomWithUserId { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -678,9 +682,9 @@ - (void)testPrivateOneToOneRoomWithUserId #pragma mark MXSessionNewRoomNotification tests - (void)testNewRoomNotificationOnInvite { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; [mxSession start:^{ @@ -707,7 +711,7 @@ - (void)testNewRoomNotificationOnInvite - (void)testNewRoomNotificationOnCreatingPublicRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession start:^{ @@ -739,9 +743,9 @@ - (void)testNewRoomNotificationOnCreatingPublicRoom - (void)testNewRoomNotificationOnJoiningPublicRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; [mxSession start:^{ @@ -775,9 +779,9 @@ - (void)testNewRoomNotificationOnJoiningPublicRoom #pragma mark kMXRoomInitialSyncNotification tests - (void)testMXRoomInitialSyncNotificationOnJoiningPublicRoom { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; [mxSession start:^{ @@ -814,7 +818,7 @@ - (void)testMXRoomInitialSyncNotificationOnJoiningPublicRoom #pragma mark rooms tags - (void)doRoomByTagsOrderTest:(XCTestCase*)testCase withOrder1:(NSString*)order1 order2:(NSString*)order2 order3:(NSString*)order3 { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { @@ -904,7 +908,7 @@ - (void)testRoomByTagsOrderWithFloatAndStringTagOrder - (void)testTagRoomsWithSameOrder { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { @@ -953,7 +957,7 @@ - (void)testTagRoomsWithSameOrder - (void)testRoomByTagsAndNoRoomTag { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { @@ -1003,7 +1007,7 @@ - (void)testRoomByTagsAndNoRoomTag - (void)testTagOrderToBeAtIndex { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { @@ -1081,7 +1085,7 @@ - (void)testTagOrderToBeAtIndex - (void)testInvitedRooms { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 52ee984694..0444258f18 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -26,18 +26,27 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-retain-cycles" +@interface MXStoreTests () +{ + MatrixSDKTestsData *matrixSDKTestsData; +} + +@end + @implementation MXStoreTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -53,7 +62,7 @@ - (void)doTestWithStore:(id)store testCase = nil; } - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:testCase readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:testCase readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { if (!expectation) { @@ -89,7 +98,7 @@ - (void)doTestWithTwoUsersAndStore:(id)store testCase = nil; } - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndAliceInARoom:testCase readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation2) { [sharedData for:bobRestClient andRoom:roomId sendMessages:5 success:^{ @@ -130,7 +139,7 @@ - (void)doTestWithStore:(id)store testCase = nil; } - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndARoomWithMessages:testCase readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:testCase readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { if (!expectation) { @@ -178,7 +187,7 @@ - (void)assertNoDuplicate:(NSArray*)events text:(NSString*)text - (void)checkEventExistsWithEventIdOfStore:(id)store { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { @@ -209,7 +218,7 @@ - (void)checkEventExistsWithEventIdOfStore:(id)store - (void)checkEventWithEventIdOfStore:(id)store { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { @@ -609,7 +618,7 @@ - (void)checkLastMessageAfterPaginate:(MXRoom*)room - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { [mxSession.matrixRestClient inviteUser:aliceRestClient.credentials.userId toRoom:room.state.roomId success:^{ @@ -813,7 +822,7 @@ - (void)checkRedactEvent:(MXRoom*)room #pragma mark - Tests on MXStore optional methods - (void)checkUserDisplaynameAndAvatarUrl:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { @@ -877,7 +886,7 @@ - (void)checkUserDisplaynameAndAvatarUrl:(Class)mxStoreClass - (void)checkMXSessionOnStoreDataReady:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { @@ -976,7 +985,7 @@ - (void)checkMXSessionOnStoreDataReady:(Class)mxStoreClass - (void)checkRoomDeletion:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { @@ -1032,7 +1041,7 @@ - (void)checkRoomDeletion:(Class)mxStoreClass // Check that MXEvent.age and MXEvent.ageLocalTs are consistent after being stored. - (void)checkEventAge:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { @@ -1088,7 +1097,7 @@ - (void)checkEventAge:(Class)mxStoreClass // Check the pagination token is valid after reloading the store - (void)checkMXRoomPaginationToken:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { @@ -1145,7 +1154,7 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass - (void)checkMultiAccount:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation2) { @@ -1198,7 +1207,7 @@ - (void)checkMultiAccount:(Class)mxStoreClass - (void)checkRoomAccountDataTags:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; + MatrixSDKTestsData *sharedData = matrixSDKTestsData; [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { diff --git a/MatrixSDKTests/MXUserTests.m b/MatrixSDKTests/MXUserTests.m index 6d752a6115..c6909ea615 100644 --- a/MatrixSDKTests/MXUserTests.m +++ b/MatrixSDKTests/MXUserTests.m @@ -23,6 +23,8 @@ @interface MXUserTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @end @@ -32,13 +34,15 @@ @implementation MXUserTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -47,7 +51,7 @@ - (void)tearDown - (void)doTestWithBobAndAliceActiveInARoom:(void (^)(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString* roomId, XCTestExpectation *expectation))readyToTest { // Make sure Alice and Bob have activities - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { [bobRestClient sendTextMessageToRoom:roomId text:@"Hi Alice!" success:^(NSString *eventId) { @@ -195,7 +199,7 @@ - (void)testOtherUserPresenceUpdate - (void)testMyUserAvailability { - [[MatrixSDKTestsData sharedData] doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; diff --git a/MatrixSDKTests/MXVoIPTests.m b/MatrixSDKTests/MXVoIPTests.m index 6a830a4b0c..6cc12d07ff 100644 --- a/MatrixSDKTests/MXVoIPTests.m +++ b/MatrixSDKTests/MXVoIPTests.m @@ -25,6 +25,8 @@ @interface MXVoIPTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @@ -35,13 +37,15 @@ @implementation MXVoIPTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; } [super tearDown]; @@ -51,7 +55,7 @@ - (void)tearDown #pragma mark - Tests with no call stack - (void)testNoVoIPStackMXRoomCall { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; MXRoom *room = [mxSession roomWithRoomId:roomId]; @@ -69,7 +73,7 @@ - (void)testNoVoIPStackMXRoomCall - (void)testNoVoIPStackOnCallInvite { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; @@ -109,7 +113,7 @@ - (void)testNoVoIPStackOnCallInvite #pragma mark - Tests with a call stack mock - (void)testMXRoomCall { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; MXRoom *room = [mxSession roomWithRoomId:roomId]; diff --git a/MatrixSDKTests/MatrixSDKTestsData.h b/MatrixSDKTests/MatrixSDKTestsData.h index 6666c3d96e..326e77215d 100644 --- a/MatrixSDKTests/MatrixSDKTestsData.h +++ b/MatrixSDKTests/MatrixSDKTestsData.h @@ -30,8 +30,6 @@ FOUNDATION_EXPORT NSString * const kMXTestsAliceAvatarURL; @interface MatrixSDKTestsData : NSObject -+ (MatrixSDKTestsData *)sharedData; - #pragma mark - mxBob // Credentials for the user mxBob on the home server located at kMXTestsHomeServerURL @property (nonatomic, readonly) MXCredentials *bobCredentials; @@ -82,7 +80,8 @@ FOUNDATION_EXPORT NSString * const kMXTestsAliceAvatarURL; readyToTest:(void (^)(MXRestClient *aliceRestClient, XCTestExpectation *expectation))readyToTest; #pragma mark - both -// The alias used for the public room created with *ThePublicRoom* methods +// The id and alias used for the public room created with *ThePublicRoom* methods +@property (nonatomic,readonly) NSString *thePublicRoomId; @property (nonatomic,readonly) NSString *thePublicRoomAlias; - (void)doMXRestClientTestWithBobAndAliceInARoom:(XCTestCase*)testCase diff --git a/MatrixSDKTests/MatrixSDKTestsData.m b/MatrixSDKTests/MatrixSDKTestsData.m index f0e4486f79..c867521033 100644 --- a/MatrixSDKTests/MatrixSDKTestsData.m +++ b/MatrixSDKTests/MatrixSDKTestsData.m @@ -65,17 +65,6 @@ - (id)init return self; } -+ (id)sharedData -{ - static MatrixSDKTestsData *sharedData = nil; - @synchronized(self) { - if (sharedData == nil) - sharedData = [[self alloc] init]; - } - return sharedData; -} - - - (void)getBobCredentials:(void (^)())success { if (self.bobCredentials) @@ -143,10 +132,8 @@ - (void)doMXRestClientTestWithBob:(XCTestCase*)testCase { expectation = [testCase expectationWithDescription:@"asyncTest"]; } - - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; - - [sharedData getBobCredentials:^{ + + [self getBobCredentials:^{ MXRestClient *restClient = [[MXRestClient alloc] initWithCredentials:self.bobCredentials andOnUnrecognizedCertificateBlock:nil]; @@ -217,24 +204,32 @@ - (void)doMXRestClientTestWithBobAndAPublicRoom:(XCTestCase*)testCase - (void)doMXRestClientTestWithBobAndThePublicRoom:(XCTestCase*)testCase readyToTest:(void (^)(MXRestClient *bobRestClient, NSString* roomId, XCTestExpectation *expectation))readyToTest { - [self doMXRestClientTestWithBob:testCase - readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - // Create a public room starting with #mxPublic - _thePublicRoomAlias = [NSString stringWithFormat:@"mxPublic-%@", [[NSUUID UUID] UUIDString]]; + [self doMXRestClientTestWithBob:testCase readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - [bobRestClient createRoom:@"MX Public Room test" - visibility:kMXRoomVisibilityPublic - roomAlias:_thePublicRoomAlias - topic:@"The public room used by SDK tests" - success:^(MXCreateRoomResponse *response) { + if (_thePublicRoomId) + { + readyToTest(bobRestClient, _thePublicRoomId, expectation); + } + else + { + // Create a public room starting with #mxPublic + _thePublicRoomAlias = [NSString stringWithFormat:@"mxPublic-%@", [[NSUUID UUID] UUIDString]]; + + [bobRestClient createRoom:@"MX Public Room test" + visibility:kMXRoomVisibilityPublic + roomAlias:_thePublicRoomAlias + topic:@"The public room used by SDK tests" + success:^(MXCreateRoomResponse *response) { + + _thePublicRoomId = response.roomId; + _thePublicRoomAlias = response.roomAlias; + readyToTest(bobRestClient, response.roomId, expectation); + + } failure:^(NSError *error) { + NSAssert(NO, @"Cannot create the public room - error: %@", error); + }]; + } - _thePublicRoomAlias = response.roomAlias; - readyToTest(bobRestClient, response.roomId, expectation); - - } failure:^(NSError *error) { - NSAssert(NO, @"Cannot create the public room - error: %@", error); - }]; }]; } @@ -247,10 +242,8 @@ - (void)doMXRestClientTestInABobRoomAndANewTextMessage:(XCTestCase*)testCase { expectation = [testCase expectationWithDescription:@"asyncTest"]; } - - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; - [sharedData getBobMXRestClient:^(MXRestClient *bobRestClient) { + [self getBobMXRestClient:^(MXRestClient *bobRestClient) { // Create a random room to use [bobRestClient createRoom:nil visibility:kMXRoomVisibilityPrivate roomAlias:nil topic:nil success:^(MXCreateRoomResponse *response) { @@ -300,12 +293,10 @@ - (void)doMXRestClientTestWihBobAndSeveralRoomsAndMessages:(XCTestCase*)testCase expectation = [testCase expectationWithDescription:@"asyncTest"]; } - MatrixSDKTestsData *sharedData = [MatrixSDKTestsData sharedData]; - - [sharedData getBobMXRestClient:^(MXRestClient *bobRestClient) { + [self getBobMXRestClient:^(MXRestClient *bobRestClient) { // Fill Bob's account with 5 rooms of 3 messages - [sharedData for:bobRestClient createRooms:5 withMessages:3 success:^{ + [self for:bobRestClient createRooms:5 withMessages:3 success:^{ readyToTest(bobRestClient, expectation); }]; }]; From 601cf4844a9bb034f9923133dbe2bb59bb979563 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 25 Feb 2016 15:07:14 +0100 Subject: [PATCH 58/80] Tests: "MatrixSDKTestsData *sharedData" has no more meaning now --- MatrixSDKTests/MXRestClientTests.m | 46 +++++++----------- MatrixSDKTests/MXRoomMemberTests.m | 10 ++-- MatrixSDKTests/MXRoomStateDynamicTests.m | 16 +++---- MatrixSDKTests/MXRoomStateTests.m | 34 +++++--------- MatrixSDKTests/MXSessionTests.m | 24 +++------- MatrixSDKTests/MXStoreTests.m | 59 ++++++++---------------- 6 files changed, 64 insertions(+), 125 deletions(-) diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index d249825abd..c213813814 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -50,12 +50,10 @@ - (void)tearDown - (void)testInit { [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - + XCTAssertTrue([bobRestClient.homeserver isEqualToString:kMXTestsHomeServerURL], "bobRestClient.homeserver(%@) is wrong", bobRestClient.homeserver); - XCTAssertTrue([bobRestClient.credentials.userId isEqualToString:sharedData.bobCredentials.userId], "bobRestClient.userId(%@) is wrong", bobRestClient.credentials.userId); - XCTAssertTrue([bobRestClient.credentials.accessToken isEqualToString:sharedData.bobCredentials.accessToken], "bobRestClient.accessToken(%@) is wrong", bobRestClient.credentials.accessToken); + XCTAssertTrue([bobRestClient.credentials.userId isEqualToString:matrixSDKTestsData.bobCredentials.userId], "bobRestClient.userId(%@) is wrong", bobRestClient.credentials.userId); + XCTAssertTrue([bobRestClient.credentials.accessToken isEqualToString:matrixSDKTestsData.bobCredentials.accessToken], "bobRestClient.accessToken(%@) is wrong", bobRestClient.credentials.accessToken); [expectation fulfill]; }]; @@ -209,14 +207,12 @@ - (void)testLeaveRoom - (void)testInviteUserToRoom { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { // Do the test - [bobRestClient inviteUser:sharedData.aliceCredentials.userId toRoom:roomId success:^{ + [bobRestClient inviteUser:matrixSDKTestsData.aliceCredentials.userId toRoom:roomId success:^{ // Check room actual members [bobRestClient membersOfRoom:roomId success:^(NSArray *roomMemberEvents) { @@ -227,14 +223,14 @@ - (void)testInviteUserToRoom { MXRoomMember *member = [[MXRoomMember alloc] initWithMXEvent:roomMemberEvent]; - if ([member.userId isEqualToString:sharedData.aliceCredentials.userId]) + if ([member.userId isEqualToString:matrixSDKTestsData.aliceCredentials.userId]) { XCTAssertEqual(member.membership, MXMembershipInvite, @"A invited user membership is invite, not %tu", member.membership); } else { // The other user is Bob - XCTAssert([member.userId isEqualToString:sharedData.bobCredentials.userId], @"Unexpected member: %@", member); + XCTAssert([member.userId isEqualToString:matrixSDKTestsData.bobCredentials.userId], @"Unexpected member: %@", member); } } @@ -256,11 +252,9 @@ - (void)testInviteUserToRoom - (void)testKickUserFromRoom { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient kickUser:sharedData.aliceCredentials.userId fromRoom:roomId reason:@"No particular reason" success:^{ + [bobRestClient kickUser:matrixSDKTestsData.aliceCredentials.userId fromRoom:roomId reason:@"No particular reason" success:^{ // Check room actual members [bobRestClient membersOfRoom:roomId success:^(NSArray *roomMemberEvents) { @@ -271,14 +265,14 @@ - (void)testKickUserFromRoom { MXRoomMember *member = [[MXRoomMember alloc] initWithMXEvent:roomMemberEvent]; - if ([member.userId isEqualToString:sharedData.aliceCredentials.userId]) + if ([member.userId isEqualToString:matrixSDKTestsData.aliceCredentials.userId]) { XCTAssertEqual(member.membership, MXMembershipLeave, @"A kicked user membership is leave, not %tu", member.membership); } else { // The other user is Bob - XCTAssert([member.userId isEqualToString:sharedData.bobCredentials.userId], @"Unexpected member: %@", member); + XCTAssert([member.userId isEqualToString:matrixSDKTestsData.bobCredentials.userId], @"Unexpected member: %@", member); } } @@ -298,11 +292,9 @@ - (void)testKickUserFromRoom - (void)testBanUserInRoom { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient banUser:sharedData.aliceCredentials.userId inRoom:roomId reason:@"No particular reason" success:^{ + [bobRestClient banUser:matrixSDKTestsData.aliceCredentials.userId inRoom:roomId reason:@"No particular reason" success:^{ // Check room actual members [bobRestClient membersOfRoom:roomId success:^(NSArray *roomMemberEvents) { @@ -313,14 +305,14 @@ - (void)testBanUserInRoom { MXRoomMember *member = [[MXRoomMember alloc] initWithMXEvent:roomMemberEvent]; - if ([member.userId isEqualToString:sharedData.aliceCredentials.userId]) + if ([member.userId isEqualToString:matrixSDKTestsData.aliceCredentials.userId]) { XCTAssertEqual(member.membership, MXMembershipBan, @"A banned user membership is ban, not %tu", member.membership); } else { // The other user is Bob - XCTAssert([member.userId isEqualToString:sharedData.bobCredentials.userId], @"Unexpected member: %@", member); + XCTAssert([member.userId isEqualToString:matrixSDKTestsData.bobCredentials.userId], @"Unexpected member: %@", member); } } @@ -690,10 +682,8 @@ - (void)testOtherUserDisplayName [matrixSDKTestsData doMXRestClientTestWithBob:nil readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - // Then retrieve it from a Bob restClient - [bobRestClient displayNameForUser:sharedData.aliceCredentials.userId success:^(NSString *displayname) { + [bobRestClient displayNameForUser:matrixSDKTestsData.aliceCredentials.userId success:^(NSString *displayname) { XCTAssertTrue([displayname isEqualToString:newDisplayName], @"Must retrieved the set string: %@ - %@", displayname, newDisplayName); [expectation fulfill]; @@ -767,10 +757,8 @@ - (void)testOtherUserAvatarUrl [matrixSDKTestsData doMXRestClientTestWithBob:nil readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - // Then retrieve it from a Bob restClient - [bobRestClient avatarUrlForUser:sharedData.aliceCredentials.userId success:^(NSString *avatarUrl) { + [bobRestClient avatarUrlForUser:matrixSDKTestsData.aliceCredentials.userId success:^(NSString *avatarUrl) { XCTAssertTrue([avatarUrl isEqualToString:newAvatarUrl], @"Must retrieved the set string: %@ - %@", avatarUrl, newAvatarUrl); [expectation fulfill]; diff --git a/MatrixSDKTests/MXRoomMemberTests.m b/MatrixSDKTests/MXRoomMemberTests.m index 27267be2bf..7142f572aa 100644 --- a/MatrixSDKTests/MXRoomMemberTests.m +++ b/MatrixSDKTests/MXRoomMemberTests.m @@ -43,11 +43,9 @@ - (void)tearDown - (void)testKickedMember { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient kickUser:sharedData.aliceCredentials.userId fromRoom:roomId reason:@"No particular reason" success:^{ + [bobRestClient kickUser:matrixSDKTestsData.aliceCredentials.userId fromRoom:roomId reason:@"No particular reason" success:^{ // Check room actual members [bobRestClient membersOfRoom:roomId success:^(NSArray *roomMemberEvents) { @@ -56,13 +54,13 @@ - (void)testKickedMember { MXRoomMember *member = [[MXRoomMember alloc] initWithMXEvent:roomMemberEvent]; - if ([member.userId isEqualToString:sharedData.aliceCredentials.userId]) + if ([member.userId isEqualToString:matrixSDKTestsData.aliceCredentials.userId]) { XCTAssertEqual(member.membership, MXMembershipLeave, @"A kicked user membership is leave, not %tu", member.membership); // rooms//members does not return prev-content anymore - we comment the related test //XCTAssertEqual(member.prevMembership, MXMembershipJoin, @"The previous membership of a kicked user must be join, not %tu", member.prevMembership); - XCTAssert([member.originUserId isEqualToString:sharedData.bobCredentials.userId], @"This is Bob who kicked Alice, not %@", member.originUserId); + XCTAssert([member.originUserId isEqualToString:matrixSDKTestsData.bobCredentials.userId], @"This is Bob who kicked Alice, not %@", member.originUserId); } } diff --git a/MatrixSDKTests/MXRoomStateDynamicTests.m b/MatrixSDKTests/MXRoomStateDynamicTests.m index a0813a2237..186d0cbeab 100644 --- a/MatrixSDKTests/MXRoomStateDynamicTests.m +++ b/MatrixSDKTests/MXRoomStateDynamicTests.m @@ -294,12 +294,10 @@ - (void)testLiveEventsForScenario1 - (void)createScenario2:(MXRestClient*)bobRestClient inRoom:(NSString*)roomId onComplete:(void(^)(MXRestClient *aliceRestClient))onComplete { [bobRestClient sendTextMessageToRoom:roomId text:@"Hello world" success:^(NSString *eventId) { - - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { - [bobRestClient inviteUser:sharedData.aliceCredentials.userId toRoom:roomId success:^{ + [bobRestClient inviteUser:matrixSDKTestsData.aliceCredentials.userId toRoom:roomId success:^{ [bobRestClient sendTextMessageToRoom:roomId text:@"I wait for Alice" success:^(NSString *eventId) { @@ -542,9 +540,7 @@ - (void)testBackPaginationForScenario2 - (void)testLiveEventsForScenario2 { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; @@ -555,8 +551,8 @@ - (void)testLiveEventsForScenario2 __block NSUInteger eventCount = 0; [room listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { - MXRoomMember *beforeEventAliceMember = [roomState memberWithUserId:sharedData.aliceCredentials.userId]; - MXRoomMember *aliceMember = [room.state memberWithUserId:sharedData.aliceCredentials.userId]; + MXRoomMember *beforeEventAliceMember = [roomState memberWithUserId:matrixSDKTestsData.aliceCredentials.userId]; + MXRoomMember *aliceMember = [room.state memberWithUserId:matrixSDKTestsData.aliceCredentials.userId]; // Check each expected event and their roomState contect // Events are live. Then comes in order diff --git a/MatrixSDKTests/MXRoomStateTests.m b/MatrixSDKTests/MXRoomStateTests.m index 01ab997a51..ede17665cd 100644 --- a/MatrixSDKTests/MXRoomStateTests.m +++ b/MatrixSDKTests/MXRoomStateTests.m @@ -333,9 +333,7 @@ - (void)testMemberName mxSession = mxSession2; - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - NSString *bobUserId = sharedData.bobCredentials.userId; + NSString *bobUserId = matrixSDKTestsData.bobCredentials.userId; NSString *bobMemberName = [room.state memberName:bobUserId]; XCTAssertNotNil(bobMemberName); @@ -429,13 +427,11 @@ - (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString [bobRestClient setRoomTopic:roomId topic:@"We test room invitation here" success:^{ - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { if (inviteAlice) { - [bobRestClient2 inviteUser:sharedData.aliceCredentials.userId toRoom:roomId success:^{ + [bobRestClient2 inviteUser:matrixSDKTestsData.aliceCredentials.userId toRoom:roomId success:^{ [bobRestClient2 sendTextMessageToRoom:roomId text:@"I wait for Alice" success:^(NSString *eventId) { @@ -470,13 +466,11 @@ - (void)createInviteByUserScenario:(MXRestClient*)bobRestClient inRoom:(NSString - (void)testInviteByOtherInInitialSync { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES onComplete:^{ - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -519,11 +513,9 @@ - (void)testInviteByOtherInInitialSync - (void)testInviteByOtherInLive { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -584,13 +576,11 @@ - (void)testInviteByOtherInLive - (void)testMXRoomJoin { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:YES onComplete:^{ - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; @@ -652,13 +642,11 @@ - (void)testMXRoomJoin - (void)testMXSessionJoinOnPublicRoom { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAPublicRoom:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { [self createInviteByUserScenario:bobRestClient inRoom:roomId inviteAlice:NO onComplete:^{ - [sharedData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:nil readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { mxSession = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index cc04f5ccbf..5a6de5d6da 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -405,9 +405,7 @@ - (void)testClose - (void)testCloseWithMXMemoryStore { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { MXMemoryStore *store = [[MXMemoryStore alloc] init]; @@ -818,9 +816,7 @@ - (void)testMXRoomInitialSyncNotificationOnJoiningPublicRoom #pragma mark rooms tags - (void)doRoomByTagsOrderTest:(XCTestCase*)testCase withOrder1:(NSString*)order1 order2:(NSString*)order2 order3:(NSString*)order3 { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { // Create rooms with the same tag but with the passed orders // Use the room topic to define the expected order @@ -908,9 +904,7 @@ - (void)testRoomByTagsOrderWithFloatAndStringTagOrder - (void)testTagRoomsWithSameOrder { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { // Create 2 rooms with the same tag and same order NSString *tag = [[NSProcessInfo processInfo] globallyUniqueString]; @@ -957,9 +951,7 @@ - (void)testTagRoomsWithSameOrder - (void)testRoomByTagsAndNoRoomTag { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { // Create a tagged room [bobRestClient createRoom:nil visibility:kMXRoomVisibilityPrivate roomAlias:nil topic:@"Tagged" success:^(MXCreateRoomResponse *response) { @@ -1007,9 +999,7 @@ - (void)testRoomByTagsAndNoRoomTag - (void)testTagOrderToBeAtIndex { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { // Create 2 rooms with the same tag but different order NSString *tag = [[NSProcessInfo processInfo] globallyUniqueString]; @@ -1085,9 +1075,7 @@ - (void)testTagOrderToBeAtIndex - (void)testInvitedRooms { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndAliceInARoom:self readyToTest:^(MXSession *bobSession, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation) { mxSession = bobSession; diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 0444258f18..1c11fff334 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -98,10 +98,9 @@ - (void)doTestWithTwoUsersAndStore:(id)store testCase = nil; } - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - [sharedData doMXRestClientTestWithBobAndAliceInARoom:testCase readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:testCase readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation2) { - [sharedData for:bobRestClient andRoom:roomId sendMessages:5 success:^{ + [matrixSDKTestsData for:bobRestClient andRoom:roomId sendMessages:5 success:^{ if (!expectation) { @@ -187,9 +186,7 @@ - (void)assertNoDuplicate:(NSArray*)events text:(NSString*)text - (void)checkEventExistsWithEventIdOfStore:(id)store { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { expectation = expectation2; @@ -218,9 +215,7 @@ - (void)checkEventExistsWithEventIdOfStore:(id)store - (void)checkEventWithEventIdOfStore:(id)store { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { expectation = expectation2; @@ -822,14 +817,12 @@ - (void)checkRedactEvent:(MXRoom*)room #pragma mark - Tests on MXStore optional methods - (void)checkUserDisplaynameAndAvatarUrl:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithAlice:self readyToTest:^(MXRestClient *aliceRestClient, XCTestExpectation *expectation2) { expectation = expectation2; id store = [[mxStoreClass alloc] init]; - [store openWithCredentials:sharedData.aliceCredentials onComplete:^{ + [store openWithCredentials:matrixSDKTestsData.aliceCredentials onComplete:^{ [store deleteAllData]; @@ -856,7 +849,7 @@ - (void)checkUserDisplaynameAndAvatarUrl:(Class)mxStoreClass // Check user information is permanent id store2 = [[mxStoreClass alloc] init]; - [store2 openWithCredentials:sharedData.aliceCredentials onComplete:^{ + [store2 openWithCredentials:matrixSDKTestsData.aliceCredentials onComplete:^{ XCTAssertEqualObjects(store2.userDisplayname, kMXTestsAliceDisplayName); XCTAssertEqualObjects(store2.userAvatarUrl, kMXTestsAliceAvatarURL); @@ -886,15 +879,13 @@ - (void)checkUserDisplaynameAndAvatarUrl:(Class)mxStoreClass - (void)checkMXSessionOnStoreDataReady:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { expectation = expectation2; id store = [[mxStoreClass alloc] init]; - [store openWithCredentials:sharedData.bobCredentials onComplete:^{ + [store openWithCredentials:matrixSDKTestsData.bobCredentials onComplete:^{ // Make sure to start from an empty store [store deleteAllData]; @@ -985,9 +976,7 @@ - (void)checkMXSessionOnStoreDataReady:(Class)mxStoreClass - (void)checkRoomDeletion:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { expectation = expectation2; @@ -1009,7 +998,7 @@ - (void)checkRoomDeletion:(Class)mxStoreClass // Reload the store, to be sure the room is no more here id store2 = [[mxStoreClass alloc] init]; - [store2 openWithCredentials:sharedData.bobCredentials onComplete:^{ + [store2 openWithCredentials:matrixSDKTestsData.bobCredentials onComplete:^{ XCTAssertEqual(NSNotFound, [store2.rooms indexOfObject:roomId], @"The room %@ must be no more in the store", roomId); @@ -1041,9 +1030,7 @@ - (void)checkRoomDeletion:(Class)mxStoreClass // Check that MXEvent.age and MXEvent.ageLocalTs are consistent after being stored. - (void)checkEventAge:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { expectation = expectation2; @@ -1065,7 +1052,7 @@ - (void)checkEventAge:(Class)mxStoreClass [store close]; } - [store openWithCredentials:sharedData.bobCredentials onComplete:^{ + [store openWithCredentials:matrixSDKTestsData.bobCredentials onComplete:^{ MXEvent *sameEvent = [store eventWithEventId:event.eventId inRoom:roomId]; XCTAssertNotNil(sameEvent); @@ -1097,9 +1084,7 @@ - (void)checkEventAge:(Class)mxStoreClass // Check the pagination token is valid after reloading the store - (void)checkMXRoomPaginationToken:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { expectation = expectation2; @@ -1154,9 +1139,7 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass - (void)checkMultiAccount:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBobAndAliceInARoom:self readyToTest:^(MXRestClient *bobRestClient, MXRestClient *aliceRestClient, NSString *roomId, XCTestExpectation *expectation2) { expectation = expectation2; @@ -1170,13 +1153,13 @@ - (void)checkMultiAccount:(Class)mxStoreClass mxSession = nil; id bobStore2 = [[mxStoreClass alloc] init]; - [bobStore2 openWithCredentials:sharedData.bobCredentials onComplete:^{ + [bobStore2 openWithCredentials:matrixSDKTestsData.bobCredentials onComplete:^{ id aliceStore = [[mxStoreClass alloc] init]; - [aliceStore openWithCredentials:sharedData.aliceCredentials onComplete:^{ + [aliceStore openWithCredentials:matrixSDKTestsData.aliceCredentials onComplete:^{ id bobStore3 = [[mxStoreClass alloc] init]; - [bobStore3 openWithCredentials:sharedData.bobCredentials onComplete:^{ + [bobStore3 openWithCredentials:matrixSDKTestsData.bobCredentials onComplete:^{ XCTAssertEqual(bobStore2.rooms.count, bobStore3.rooms.count); @@ -1207,9 +1190,7 @@ - (void)checkMultiAccount:(Class)mxStoreClass - (void)checkRoomAccountDataTags:(Class)mxStoreClass { - MatrixSDKTestsData *sharedData = matrixSDKTestsData; - - [sharedData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { + [matrixSDKTestsData doMXRestClientTestWithBob:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation2) { expectation = expectation2; @@ -1232,7 +1213,7 @@ - (void)checkRoomAccountDataTags:(Class)mxStoreClass // Do the test id store = [[mxStoreClass alloc] init]; - [store openWithCredentials:sharedData.bobCredentials onComplete:^{ + [store openWithCredentials:matrixSDKTestsData.bobCredentials onComplete:^{ // Make sure to start from an empty store [store deleteAllData]; From 5e37b8018887f1e6720e337a14f0dcda284622ee Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 25 Feb 2016 15:24:38 +0100 Subject: [PATCH 59/80] Tests: Fixed [MXStoreTests checkMXRoomPaginationToken] --- MatrixSDKTests/MXStoreTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index 1c11fff334..ed5f1a2ccb 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -1093,7 +1093,7 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass // Do a 1st [mxSession start] to fill the store mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; [mxSession setStore:store success:^{ - [mxSession start:^{ + [mxSession startWithMessagesLimit:5 onServerSyncDone:^{ MXRoom *room = [mxSession roomWithRoomId:roomId]; [room.liveTimeline resetPagination]; From 09cc2e73bad3cb213c24672d31649dc258f5dafc Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 25 Feb 2016 16:27:50 +0100 Subject: [PATCH 60/80] Tests: Made testListenerForAllLiveEvents work again --- MatrixSDKTests/MXSessionTests.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index 5a6de5d6da..c337bc9a6a 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -162,7 +162,7 @@ - (void)testListenerForAllLiveEvents // The listener must catch at least these events __block NSMutableArray *expectedEvents = [NSMutableArray arrayWithArray:@[ - kMXEventTypeStringRoomCreate, + //kMXEventTypeStringRoomCreate, // TODO: To fix. Why we do not receive it in the timeline? kMXEventTypeStringRoomMember, // Expect the 5 text messages created by doMXRestClientTestWithBobAndARoomWithMessages @@ -205,7 +205,8 @@ - (void)testListenerForAllLiveEvents // Create a room with messages in parallel - [mxSession start:^{ + // Use a 0 limit to avoid to get older messages from /sync + [mxSession startWithMessagesLimit:0 onServerSyncDone:^{ [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:nil readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation2) { From f195b3ff18cc329848ef0dc09dc453c59e0f2407 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 25 Feb 2016 16:39:16 +0100 Subject: [PATCH 61/80] Tests: Updated [MXStoreTests checkPaginateWhenJoiningAgainAfterLeft] because default hs room visibility has changed --- MatrixSDKTests/MXStoreTests.m | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/MatrixSDKTests/MXStoreTests.m b/MatrixSDKTests/MXStoreTests.m index ed5f1a2ccb..c0d1df0605 100644 --- a/MatrixSDKTests/MXStoreTests.m +++ b/MatrixSDKTests/MXStoreTests.m @@ -638,27 +638,30 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room if (direction == MXEventDirectionForwards && MXMembershipInvite == room2.state.membership && !joinedRequestMade) { // Join the room on the invitation and check we can paginate all expected text messages - // By default the last Alice's message (sent while Bob is not in the room) is not visible. + // By default the last Alice's message (sent while Bob is not in the room) must be visible. joinedRequestMade = YES; [room2 join:^{ NSMutableArray *events = [NSMutableArray array]; [room2.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { - if (0 == events.count) + if (direction == MXEventDirectionBackwards) { - // The most recent message must not be "Hi bob" sent by Alice - XCTAssertNotEqualObjects(aliceTextEventId, event.eventId); - } + if (0 == events.count) + { + // The most recent message must be "Hi bob" sent by Alice + XCTAssertEqualObjects(aliceTextEventId, event.eventId); + } - [events addObject:event]; + [events addObject:event]; + } }]; [room2.liveTimeline resetPagination]; [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ - XCTAssertEqual(events.count, 5, "The room should contain only 5 messages (the last message sent while the user is not in the room is not visible)"); + XCTAssertEqual(events.count, 6, "The room should contain only 6 messages (the last message sent while the user is not in the room must be visible)"); [mxSession close]; [expectation fulfill]; From dbf49aae986b2a6f90d2b031d2141ebc37efa10b Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 25 Feb 2016 16:43:21 +0100 Subject: [PATCH 62/80] Tests: Repair testOtherUserLastActiveUpdate --- MatrixSDKTests/MXUserTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDKTests/MXUserTests.m b/MatrixSDKTests/MXUserTests.m index c6909ea615..07798aa98b 100644 --- a/MatrixSDKTests/MXUserTests.m +++ b/MatrixSDKTests/MXUserTests.m @@ -135,7 +135,7 @@ - (void)testOtherUserLastActiveUpdate }]; - [aliceRestClient sendTextMessageToRoom:roomId text:@"A message to update my last active ago" success:^(NSString *eventId) { + [aliceRestClient setPresence:MXPresenceOnline andStatusMessage:@"" success:^{ } failure:^(NSError *error) { NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); From 44cd5cec188fcb19a2e30e4e6e98564894b9bff6 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 26 Feb 2016 11:58:05 +0100 Subject: [PATCH 63/80] MXEventDirectionSync: Removed MXEventDirectionSync (SYIOS-207). Refactored MXEventTimeline code to remove the notion of MXEventDirectionSync --- MatrixSDK/Data/MXEventTimeline.m | 246 ++++++++++++------------------- MatrixSDK/JSONModels/MXEvent.h | 8 +- MatrixSDK/MXSession.m | 4 +- 3 files changed, 98 insertions(+), 160 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 040b15d80b..405e97824d 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -80,7 +80,7 @@ - (void)initialiseState:(NSArray *)stateEvents { for (MXEvent *event in stateEvents) { - [self handleStateEvent:event direction:MXEventDirectionSync]; + [self handleStateEvent:event direction:MXEventDirectionForwards]; } } @@ -152,7 +152,7 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) { MXEvent *event = messagesFromStore[i]; - [self handleMessage:event direction:MXEventDirectionBackwards]; + [self addEvent:event direction:MXEventDirectionBackwards fromStore:YES notify:YES]; } numItems -= messagesFromStoreCount; @@ -184,31 +184,14 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d limit:numItems success:^(MXPaginationResponse *paginatedResponse) { - @autoreleasepool - { - NSLog(@"[MXEventTimeline] paginate : get %tu messages from the server", paginatedResponse.chunk.count); - - // Check pagination end - @see SPEC-319 ticket - if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) - { - // We run out of items - [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; - } - - // Process received events and update pagination tokens - [self handleMessages:paginatedResponse direction:MXEventDirectionBackwards isTimeOrdered:NO]; - - // Commit store changes - if ([store respondsToSelector:@selector(commit)]) - { - [store commit]; - } + NSLog(@"[MXEventTimeline] paginate : get %tu messages from the server", paginatedResponse.chunk.count); - // Inform the method caller - complete(); - - NSLog(@"[MXEventTimeline] paginate: is done"); - } + [self handlePaginationResponse:paginatedResponse]; + + // Inform the method caller + complete(); + + NSLog(@"[MXEventTimeline] paginate: is done"); } failure:^(NSError *error) { // Check whether the pagination end is reached @@ -262,7 +245,7 @@ - (NSUInteger)remainingMessagesForBackPaginationInStore } -#pragma mark - Server sync +#pragma mark - Homeserver responses handling - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync { // Is it an initial sync for this room? @@ -283,7 +266,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - [self handleStateEvent:event direction:MXEventDirectionSync]; + [self handleStateEvent:event direction:MXEventDirectionForwards]; } // Update store with new room state when all state event have been processed @@ -303,7 +286,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync event.roomId = _state.roomId; // Make room data digest the live event - [self handleLiveEvent:event]; + [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; } // Check whether we got all history from the home server @@ -329,7 +312,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync event.roomId = _state.roomId; // Make room data digest the live event - [self handleLiveEvent:event]; + [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; } } @@ -370,112 +353,119 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - [self handleLiveEvent:event]; + [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; } } +- (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse +{ + // Check pagination end - @see SPEC-319 ticket + if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) + { + // We run out of items + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + } + + // Process received events + for (MXEvent *event in paginatedResponse.chunk) + { + // Make sure we have not processed this event yet + [self addEvent:event direction:MXEventDirectionBackwards fromStore:NO notify:YES]; + } + + // And update pagination tokens + [store storePaginationTokenOfRoom:_state.roomId andToken:paginatedResponse.end]; + + // Commit store changes + if ([store respondsToSelector:@selector(commit)]) + { + [store commit]; + } +} -#pragma mark - Messages handling -/** - Handle bunch of events received in case of back pagination, global initial sync or room initial sync. - @param roomMessages the response in which events are stored. - @param direction the process direction: MXEventDirectionBackwards or MXEventDirectionSync. MXEventDirectionForwards is not supported here. - @param isTimeOrdered tell whether the events are in chronological order. +#pragma mark - Timeline events +/** + Add an event to the timeline. + + @param event the event to add. + @param direction the direction indicates if the event must added to the start or to the end of the timeline. + @param fromStore YES if the messages have been loaded from the store. In this case, there is no need to store + it again in the store + @param notify YES to notify listeners. */ -- (void)handleMessages:(MXPaginationResponse*)roomMessages - direction:(MXEventDirection)direction - isTimeOrdered:(BOOL)isTimeOrdered +- (void)addEvent:(MXEvent*)event direction:(MXEventDirection)direction fromStore:(BOOL)fromStore notify:(BOOL)notify { - // Here direction is MXEventDirectionBackwards or MXEventDirectionSync - if (direction == MXEventDirectionForwards) + // Make sure we have not processed this event yet + if (fromStore == NO && [store eventExistsWithEventId:event.eventId inRoom:room.roomId]) { - NSLog(@"[MXEventTimeline] handleMessages error: forward direction is not supported"); return; } - NSArray *events = roomMessages.chunk; - - // Handles messages according to their time order - if (NO == isTimeOrdered) + // State event updates the timeline room state + if (event.isState) { - // [MXRestClient messages] returns messages in reverse chronological order - for (MXEvent *event in events) { + [self cloneState:direction]; - // Make sure we have not processed this event yet - if (![store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) - { - [self handleMessage:event direction:direction]; + [self handleStateEvent:event direction:direction]; - // Store the event - [store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionBackwards]; - } + // The store keeps only the most recent state of the room + if (direction == MXEventDirectionForwards && [store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) + { + [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; } - - // Store how far back we've paginated - [store storePaginationTokenOfRoom:_state.roomId andToken:roomMessages.end]; } - else + + // Handle here redaction event from live event stream + if (direction == MXEventDirectionForwards) { - // InitialSync returns messages in chronological order - // We have to read them in reverse to fill the store from the beginning. - for (NSInteger i = events.count - 1; i >= 0; i--) + if (event.eventType == MXEventTypeRoomRedaction) { - MXEvent *event = events[i]; + [self handleRedaction:event]; + } - // Make sure we have not processed this event yet - MXEvent *storedEvent = [store eventWithEventId:event.eventId inRoom:_state.roomId]; - if (!storedEvent) - { - [self handleMessage:event direction:direction]; + if (_isLiveTimeline) + { + // Consider that a message sent by a user has been read by him + MXReceiptData* data = [[MXReceiptData alloc] init]; + data.userId = event.sender; + data.eventId = event.eventId; + data.ts = event.originServerTs; - // Store the event - [store storeEventForRoom:_state.roomId event:event direction:direction]; - } + [store storeReceipt:data roomId:_state.roomId]; } - - // Store where to start pagination - [store storePaginationTokenOfRoom:_state.roomId andToken:roomMessages.start]; } -} -- (void)handleMessage:(MXEvent*)event direction:(MXEventDirection)direction -{ - if (event.isState) + // Store the event + if (!fromStore) { - // Consider here state event (except during initial sync) - if (direction != MXEventDirectionSync) - { - [self cloneState:direction]; - - [self handleStateEvent:event direction:direction]; - - // Update store with new room state once a live event has been processed - if (direction == MXEventDirectionForwards) - { - if ([store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) - { - [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; - } - } - } + [store storeEventForRoom:_state.roomId event:event direction:direction]; } - // Notify listener only for past events here - // Live events are already notified from handleLiveEvent - if (MXEventDirectionForwards != direction) + // Notify listeners + if (notify) { [self notifyListeners:event direction:direction]; } - else +} + +#pragma mark - Specific events Handling +- (void)handleRedaction:(MXEvent*)redactionEvent +{ + // Check whether the redacted event has been already processed + MXEvent *redactedEvent = [store eventWithEventId:redactionEvent.redacts inRoom:_state.roomId]; + if (redactedEvent) { - MXReceiptData* data = [[MXReceiptData alloc] init]; - data.userId = event.sender; - data.eventId = event.eventId; - data.ts = event.originServerTs; + // Redact the stored event + redactedEvent = [redactedEvent prune]; + redactedEvent.redactedBecause = redactionEvent.JSONDictionary; + + if (redactedEvent.isState) { + // FIXME: The room state must be refreshed here since this redacted event. + } - [store storeReceipt:data roomId:_state.roomId]; - // notifyListeners call is performed in the calling method. + // Store the event + [store replaceEvent:redactedEvent inRoom:_state.roomId]; } } @@ -525,52 +515,6 @@ - (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction } -#pragma mark - Handle live event -/** - Handle an event (message or state) that comes from the events streaming. - - @param event the event to handle. - */ -- (void)handleLiveEvent:(MXEvent*)event -{ - // Make sure we have not processed this event yet - if (![store eventExistsWithEventId:event.eventId inRoom:_state.roomId]) - { - // Handle here redaction event from live event stream - if (event.eventType == MXEventTypeRoomRedaction) - { - [self handleRedaction:event]; - } - - [self handleMessage:event direction:MXEventDirectionForwards]; - - // Store the event - [store storeEventForRoom:_state.roomId event:event direction:MXEventDirectionForwards]; - - // And notify listeners - [self notifyListeners:event direction:MXEventDirectionForwards]; - } -} - -- (void)handleRedaction:(MXEvent*)redactionEvent -{ - // Check whether the redacted event has been already processed - MXEvent *redactedEvent = [store eventWithEventId:redactionEvent.redacts inRoom:_state.roomId]; - if (redactedEvent) - { - // Redact the stored event - redactedEvent = [redactedEvent prune]; - redactedEvent.redactedBecause = redactionEvent.JSONDictionary; - - if (redactedEvent.isState) { - // FIXME: The room state must be refreshed here since this redacted event. - } - - // Store the event - [store replaceEvent:redactedEvent inRoom:_state.roomId]; - } -} - #pragma mark - Events listeners - (id)listenToEvents:(MXOnRoomEvent)onEvent { diff --git a/MatrixSDK/JSONModels/MXEvent.h b/MatrixSDK/JSONModels/MXEvent.h index a7377be3c2..8cb7f3d648 100644 --- a/MatrixSDK/JSONModels/MXEvent.h +++ b/MatrixSDK/JSONModels/MXEvent.h @@ -131,13 +131,7 @@ typedef enum : NSUInteger MXEventDirectionForwards, // Backwards for old events requested through pagination - MXEventDirectionBackwards, - - // Sync for events coming from an initialSync API request to the home server - // The SDK internally makes such requests when the app call [MXSession start], - // [MXSession joinRoom] and [MXRoom join]. - MXEventDirectionSync - + MXEventDirectionBackwards } MXEventDirection; diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 918939c18d..33040303a7 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -602,7 +602,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout // Handle presence of other users for (MXEvent *presenceEvent in syncResponse.presence.events) { - [self handlePresenceEvent:presenceEvent direction:MXEventDirectionSync]; + [self handlePresenceEvent:presenceEvent direction:MXEventDirectionForwards]; } // Update live event stream token @@ -1276,7 +1276,7 @@ - (BOOL)removeInvitedRoom:(MXRoom*)roomToRemove // 2 - perform an initial sync when the join method call the success callback // 3 - receive the join event in the live stream -> this method is not called because the event has already been stored in the step 2 // so, we need to manage the sync direction - if ((MXEventDirectionForwards == direction) || (MXEventDirectionSync == direction)) + if (MXEventDirectionForwards == direction) { BOOL notify = NO; MXRoomState *roomPrevState = (MXRoomState *)customObject; From 87ecf86123ee263d0f76fbe9e0575a907febdef2 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 26 Feb 2016 11:58:38 +0100 Subject: [PATCH 64/80] MXEventDirectionSync: Removed testListenerForSyncEvents test --- MatrixSDKTests/MXSessionTests.m | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/MatrixSDKTests/MXSessionTests.m b/MatrixSDKTests/MXSessionTests.m index c337bc9a6a..638b4bb708 100644 --- a/MatrixSDKTests/MXSessionTests.m +++ b/MatrixSDKTests/MXSessionTests.m @@ -264,35 +264,6 @@ - (void)testListenerForRoomMessageOnly }]; } -- (void)testListenerForSyncEvents -{ - [matrixSDKTestsData doMXRestClientTestWihBobAndSeveralRoomsAndMessages:self readyToTest:^(MXRestClient *bobRestClient, XCTestExpectation *expectation) { - - mxSession = [[MXSession alloc] initWithMatrixRestClient:bobRestClient]; - - __block NSUInteger eventCount = 0; - - // Listen to events received during rooms state sync - [mxSession listenToEvents:^(MXEvent *event, MXEventDirection direction, id customObject) { - - eventCount++; - - XCTAssertEqual(direction, MXEventDirectionSync); - - }]; - - - // Create a room with messages in parallel - [mxSession startWithMessagesLimit:0 onServerSyncDone:^{ - - XCTAssertGreaterThan(eventCount, 0); - [expectation fulfill]; - - } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); - }]; - }]; -} /* Disabled as lastActiveAgo events sent by the HS are less accurate than before - (void)testListenerForPresence From a238726c026053654f07ae3a09f881e24b3cce18 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 26 Feb 2016 15:10:24 +0100 Subject: [PATCH 65/80] MXEventDirectionSync: MXEventTimeline: improved comments as the term live event is a lie since /sync v2 --- MatrixSDK/Data/MXEventTimeline.m | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 405e97824d..1369a07e0e 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -278,14 +278,12 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // Handle now timeline.events, the room state is updated during this step too (Note: timeline events are in chronological order) if (isRoomInitialSync) { - // Here the events are handled in forward direction (see [handleLiveEvent:]). - // They will be added at the end of the stored events, so we keep the chronologinal order. for (MXEvent *event in roomSync.timeline.events) { // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - // Make room data digest the live event + // Add the event to the end of the timeline [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; } @@ -304,14 +302,12 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync [store deleteAllMessagesInRoom:_state.roomId]; } - // Here the events are handled in forward direction (see [handleLiveEvent:]). - // They will be added at the end of the stored events, so we keep the chronologinal order. for (MXEvent *event in roomSync.timeline.events) { // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - // Make room data digest the live event + // Add the event to the end of the timeline [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; } } @@ -341,7 +337,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync { - // Handle the state events as live events (the room state will be updated, and the listeners (if any) will be notified). + // Handle the state events forwardly (the room state will be updated, and the listeners (if any) will be notified). for (MXEvent *event in invitedRoomSync.inviteState.events) { // Add a fake event id if none in order to be able to store the event @@ -416,24 +412,23 @@ - (void)addEvent:(MXEvent*)event direction:(MXEventDirection)direction fromStore } } - // Handle here redaction event from live event stream - if (direction == MXEventDirectionForwards) + // Events going forwards on the live timeline come from /sync. + // They are assimilated to live events. + if (_isLiveTimeline && direction == MXEventDirectionForwards) { + // Handle here live redaction if (event.eventType == MXEventTypeRoomRedaction) { [self handleRedaction:event]; } - if (_isLiveTimeline) - { - // Consider that a message sent by a user has been read by him - MXReceiptData* data = [[MXReceiptData alloc] init]; - data.userId = event.sender; - data.eventId = event.eventId; - data.ts = event.originServerTs; + // Consider that a message sent by a user has been read by him + MXReceiptData* data = [[MXReceiptData alloc] init]; + data.userId = event.sender; + data.eventId = event.eventId; + data.ts = event.originServerTs; - [store storeReceipt:data roomId:_state.roomId]; - } + [store storeReceipt:data roomId:_state.roomId]; } // Store the event From cd5cb4916a10b7fab206f886a217c8c8252c6db1 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 26 Feb 2016 15:24:01 +0100 Subject: [PATCH 66/80] MXEventDirectionSync: Renamed MXEventDirection into MXTimelineDirection --- MatrixSDK/Data/MXEventListener.h | 5 +- MatrixSDK/Data/MXEventListener.m | 2 +- MatrixSDK/Data/MXEventTimeline.h | 30 ++++-- MatrixSDK/Data/MXEventTimeline.m | 40 ++++---- MatrixSDK/Data/MXRoom.h | 2 +- MatrixSDK/Data/MXRoom.m | 12 +-- MatrixSDK/Data/MXSessionEventListener.h | 2 +- MatrixSDK/Data/MXSessionEventListener.m | 2 +- .../Store/MXCoreDataStore/MXCoreDataRoom.h | 2 +- .../Store/MXCoreDataStore/MXCoreDataRoom.m | 4 +- .../Store/MXCoreDataStore/MXCoreDataStore.m | 2 +- .../Data/Store/MXFileStore/MXFileStore.m | 2 +- .../Store/MXMemoryStore/MXMemoryRoomStore.h | 2 +- .../Store/MXMemoryStore/MXMemoryRoomStore.m | 4 +- .../Data/Store/MXMemoryStore/MXMemoryStore.m | 2 +- MatrixSDK/Data/Store/MXNoStore/MXNoStore.m | 4 +- MatrixSDK/Data/Store/MXStore.h | 3 +- MatrixSDK/JSONModels/MXEvent.h | 13 --- MatrixSDK/MXSession.m | 12 +-- .../NotificationCenter/MXNotificationCenter.m | 4 +- MatrixSDK/VoIP/MXCallManager.m | 4 +- MatrixSDKTests/MXEventTests.m | 4 +- MatrixSDKTests/MXNotificationCenterTests.m | 8 +- MatrixSDKTests/MXRestClientTests.m | 2 +- MatrixSDKTests/MXRoomStateDynamicTests.m | 12 +-- MatrixSDKTests/MXRoomStateTests.m | 20 ++-- MatrixSDKTests/MXRoomTests.m | 22 ++--- MatrixSDKTests/MXSessionTests.m | 24 ++--- MatrixSDKTests/MXStoreMemoryStoreTests.m | 38 ++++---- MatrixSDKTests/MXStoreTests.m | 92 +++++++++---------- MatrixSDKTests/MXVoIPTests.m | 2 +- 31 files changed, 189 insertions(+), 188 deletions(-) diff --git a/MatrixSDK/Data/MXEventListener.h b/MatrixSDK/Data/MXEventListener.h index 81d98099f6..16075e3121 100644 --- a/MatrixSDK/Data/MXEventListener.h +++ b/MatrixSDK/Data/MXEventListener.h @@ -17,6 +17,7 @@ #import #import "MXEvent.h" +#import "MXEventTimeline.h" /** Block called when an event of the registered types has been handled by the Matrix SDK. @@ -26,7 +27,7 @@ @param customObject additional contect for the event. In case of room event, customObject is a RoomState instance. */ -typedef void (^MXOnEvent)(MXEvent *event, MXEventDirection direction, id customObject); +typedef void (^MXOnEvent)(MXEvent *event, MXTimelineDirection direction, id customObject); /** The `MXEventListener` class stores information about a listener to MXEvents that @@ -46,7 +47,7 @@ typedef void (^MXOnEvent)(MXEvent *event, MXEventDirection direction, id customO @param event the new event. @param direction the origin of the event. */ -- (void)notify:(MXEvent*)event direction:(MXEventDirection)direction andCustomObject:(id)customObject; +- (void)notify:(MXEvent*)event direction:(MXTimelineDirection)direction andCustomObject:(id)customObject; @property (nonatomic, readonly) id sender; @property (nonatomic, readonly) NSArray* eventTypes; diff --git a/MatrixSDK/Data/MXEventListener.m b/MatrixSDK/Data/MXEventListener.m index ceb7b7007b..33282bfd35 100644 --- a/MatrixSDK/Data/MXEventListener.m +++ b/MatrixSDK/Data/MXEventListener.m @@ -37,7 +37,7 @@ -(instancetype)initWithSender:(id)sender return self; } -- (void)notify:(MXEvent*)event direction:(MXEventDirection)direction andCustomObject:(id)customObject +- (void)notify:(MXEvent*)event direction:(MXTimelineDirection)direction andCustomObject:(id)customObject { // Check if the event match with eventTypes BOOL match = NO; diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index 218855a349..b7e0493eb5 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -18,11 +18,23 @@ #import "MXEvent.h" #import "MXJSONModels.h" -#import "MXRoomMember.h" -#import "MXEventListener.h" #import "MXRoomState.h" #import "MXHTTPOperation.h" +/** + The direction of an event in the timeline. + */ +typedef enum : NSUInteger +{ + // Forwards when the event is added to the end of the timeline. + // These events come from the /sync stream or from forwards pagination. + MXTimelineDirectionForwards, + + // Backwards when the event is added to the start of the timeline. + // These events come from a back pagination. + MXTimelineDirectionBackwards +} MXTimelineDirection; + /** Prefix used to build fake invite event. */ @@ -36,7 +48,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomInviteStateEventIdPrefix; @param direction the origin of the event. @param roomState the room state right before the event. */ -typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoomState *roomState); +typedef void (^MXOnRoomEvent)(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState); @class MXRoom; @@ -102,11 +114,11 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom canPaginate in forward direction has no meaning for a live timeline. - @param direction MXEventDirectionBackwards to check if we can paginate backwards. - MXEventDirectionForwards to check if we can go forwards. + @param direction MXTimelineDirectionBackwards to check if we can paginate backwards. + MXTimelineDirectionForwards to check if we can go forwards. @return true if we can paginate in the given direction. */ -- (BOOL)canPaginate:(MXEventDirection)direction; +- (BOOL)canPaginate:(MXTimelineDirection)direction; /** Reset the pagination so that future calls to paginate start over from live or @@ -121,7 +133,7 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom It is not possible to paginate forwards on a live timeline. @param numItems the number of items to get. - @param direction `MXEventDirectionForwards` or `MXEventDirectionBackwards` + @param direction `MXTimelineDirectionForwards` or `MXTimelineDirectionBackwards` @param onlyFromStore if YES, return available events from the store, do not make a pagination request to the homeserver. @@ -132,7 +144,7 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom to the homeserver is required. */ - (MXHTTPOperation*)paginate:(NSUInteger)numItems - direction:(MXEventDirection)direction + direction:(MXTimelineDirection)direction onlyFromStore:(BOOL)onlyFromStore complete:(void (^)())complete failure:(void (^)(NSError *error))failure; @@ -198,6 +210,6 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXEventDirection direction, MXRoom @param event the event to notify. @param the event direction. */ -- (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction; +- (void)notifyListeners:(MXEvent*)event direction:(MXTimelineDirection)direction; @end diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 1369a07e0e..b7a6fcdc54 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -80,17 +80,17 @@ - (void)initialiseState:(NSArray *)stateEvents { for (MXEvent *event in stateEvents) { - [self handleStateEvent:event direction:MXEventDirectionForwards]; + [self handleStateEvent:event direction:MXTimelineDirectionForwards]; } } #pragma mark - Pagination -- (BOOL)canPaginate:(MXEventDirection)direction +- (BOOL)canPaginate:(MXTimelineDirection)direction { BOOL canPaginate = NO; - if (direction == MXEventDirectionBackwards) + if (direction == MXTimelineDirectionBackwards) { // canPaginate depends on two things: // - did we end to paginate from the MXStore? @@ -125,13 +125,13 @@ - (void)resetPagination [store resetPaginationOfRoom:_state.roomId]; } -- (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)direction onlyFromStore:(BOOL)onlyFromStore complete:(void (^)())complete failure:(void (^)(NSError *))failure +- (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirection)direction onlyFromStore:(BOOL)onlyFromStore complete:(void (^)())complete failure:(void (^)(NSError *))failure { MXHTTPOperation *operation; NSAssert(nil != backState, @"[MXEventTimeline] paginate: resetPagination must be called before starting the back pagination"); - if (direction == MXEventDirectionBackwards) + if (direction == MXTimelineDirectionBackwards) { // Return messages from the store first NSUInteger messagesFromStoreCount = 0; @@ -152,7 +152,7 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXEventDirection)d for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) { MXEvent *event = messagesFromStore[i]; - [self addEvent:event direction:MXEventDirectionBackwards fromStore:YES notify:YES]; + [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:YES notify:YES]; } numItems -= messagesFromStoreCount; @@ -266,7 +266,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - [self handleStateEvent:event direction:MXEventDirectionForwards]; + [self handleStateEvent:event direction:MXTimelineDirectionForwards]; } // Update store with new room state when all state event have been processed @@ -284,7 +284,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync event.roomId = _state.roomId; // Add the event to the end of the timeline - [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; } // Check whether we got all history from the home server @@ -308,7 +308,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync event.roomId = _state.roomId; // Add the event to the end of the timeline - [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; } } @@ -349,7 +349,7 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - [self addEvent:event direction:MXEventDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; } } @@ -366,7 +366,7 @@ - (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse for (MXEvent *event in paginatedResponse.chunk) { // Make sure we have not processed this event yet - [self addEvent:event direction:MXEventDirectionBackwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO notify:YES]; } // And update pagination tokens @@ -390,7 +390,7 @@ - (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse it again in the store @param notify YES to notify listeners. */ -- (void)addEvent:(MXEvent*)event direction:(MXEventDirection)direction fromStore:(BOOL)fromStore notify:(BOOL)notify +- (void)addEvent:(MXEvent*)event direction:(MXTimelineDirection)direction fromStore:(BOOL)fromStore notify:(BOOL)notify { // Make sure we have not processed this event yet if (fromStore == NO && [store eventExistsWithEventId:event.eventId inRoom:room.roomId]) @@ -406,7 +406,7 @@ - (void)addEvent:(MXEvent*)event direction:(MXEventDirection)direction fromStore [self handleStateEvent:event direction:direction]; // The store keeps only the most recent state of the room - if (direction == MXEventDirectionForwards && [store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) + if (direction == MXTimelineDirectionForwards && [store respondsToSelector:@selector(storeStateForRoom:stateEvents:)]) { [store storeStateForRoom:_state.roomId stateEvents:_state.stateEvents]; } @@ -414,7 +414,7 @@ - (void)addEvent:(MXEvent*)event direction:(MXEventDirection)direction fromStore // Events going forwards on the live timeline come from /sync. // They are assimilated to live events. - if (_isLiveTimeline && direction == MXEventDirectionForwards) + if (_isLiveTimeline && direction == MXTimelineDirectionForwards) { // Handle here live redaction if (event.eventType == MXEventTypeRoomRedaction) @@ -466,10 +466,10 @@ - (void)handleRedaction:(MXEvent*)redactionEvent #pragma mark - State events handling -- (void)cloneState:(MXEventDirection)direction +- (void)cloneState:(MXTimelineDirection)direction { // create a new instance of the state - if (MXEventDirectionBackwards == direction) + if (MXTimelineDirectionBackwards == direction) { backState = [backState copy]; } @@ -482,10 +482,10 @@ - (void)cloneState:(MXEventDirection)direction } } -- (void)handleStateEvent:(MXEvent*)event direction:(MXEventDirection)direction +- (void)handleStateEvent:(MXEvent*)event direction:(MXTimelineDirection)direction { // Update the room state - if (MXEventDirectionBackwards == direction) + if (MXTimelineDirectionBackwards == direction) { [backState handleStateEvent:event]; } @@ -535,11 +535,11 @@ - (void)removeAllListeners [eventListeners removeAllObjects]; } -- (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction +- (void)notifyListeners:(MXEvent*)event direction:(MXTimelineDirection)direction { MXRoomState * roomState; - if (MXEventDirectionBackwards == direction) + if (MXTimelineDirectionBackwards == direction) { roomState = backState; } diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 61a25eec30..242cf334e6 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -479,7 +479,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; @param the direction @param */ -- (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)direction; +- (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXTimelineDirection)direction; /** Acknowlegde the latest event of type defined in acknowledgableEventTypes. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index ea86638f9a..67b4d8c1ea 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -128,16 +128,16 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync MXJSONModelSetArray(_typingUsers, event.content[@"user_ids"]); // Notify listeners - [_liveTimeline notifyListeners:event direction:MXEventDirectionForwards]; + [_liveTimeline notifyListeners:event direction:MXTimelineDirectionForwards]; } else if (event.eventType == MXEventTypeReceipt) { - [self handleReceiptEvent:event direction:MXEventDirectionForwards]; + [self handleReceiptEvent:event direction:MXTimelineDirectionForwards]; } } // Handle account data events (if any) - [self handleAccounDataEvents:roomSync.accountData.events direction:MXEventDirectionForwards]; + [self handleAccounDataEvents:roomSync.accountData.events direction:MXTimelineDirectionForwards]; } - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync @@ -152,9 +152,9 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync Handle private user data events. @param accounDataEvents the events to handle. - @param direction the process direction: MXEventDirectionSync or MXEventDirectionForwards. MXEventDirectionBackwards is not applicable here. + @param direction the process direction: MXTimelineDirectionSync or MXTimelineDirectionForwards. MXTimelineDirectionBackwards is not applicable here. */ -- (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(MXEventDirection)direction +- (void)handleAccounDataEvents:(NSArray*)accounDataEvents direction:(MXTimelineDirection)direction { for (MXEvent *event in accounDataEvents) { @@ -430,7 +430,7 @@ - (MXCall *)placeCallWithVideo:(BOOL)video #pragma mark - Read receipts management -- (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXEventDirection)direction +- (BOOL)handleReceiptEvent:(MXEvent *)event direction:(MXTimelineDirection)direction { BOOL managedEvents = false; diff --git a/MatrixSDK/Data/MXSessionEventListener.h b/MatrixSDK/Data/MXSessionEventListener.h index 3d004bc8a8..db9ed8812a 100644 --- a/MatrixSDK/Data/MXSessionEventListener.h +++ b/MatrixSDK/Data/MXSessionEventListener.h @@ -30,7 +30,7 @@ @param customObject additional contect for the event. In case of room event, customObject is a RoomState instance. In the case of a presence, customObject is nil. */ -typedef void (^MXOnSessionEvent)(MXEvent *event, MXEventDirection direction, id customObject); +typedef void (^MXOnSessionEvent)(MXEvent *event, MXTimelineDirection direction, id customObject); /** The `MXSessionEventListener` class stores information about a listener to MXSession events diff --git a/MatrixSDK/Data/MXSessionEventListener.m b/MatrixSDK/Data/MXSessionEventListener.m index c4afa704b4..da6bca5dda 100644 --- a/MatrixSDK/Data/MXSessionEventListener.m +++ b/MatrixSDK/Data/MXSessionEventListener.m @@ -45,7 +45,7 @@ - (void)addRoomToSpy:(MXRoom*)room if (![roomEventListeners objectForKey:room.state.roomId]) { roomEventListeners[room.state.roomId] = - [room.liveTimeline listenToEventsOfTypes:self.eventTypes onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:self.eventTypes onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { self.listenerBlock(event, direction, roomState); }]; } diff --git a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.h b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.h index 6f48d9ca5b..b922e11996 100644 --- a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.h +++ b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.h @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN @param event the MXEvent object to store. @param direction the origin of the event. Live or past events. */ -- (void)storeEvent:(MXEvent*)event direction:(MXEventDirection)direction; +- (void)storeEvent:(MXEvent*)event direction:(MXTimelineDirection)direction; /** Replace room event (used in case of redaction for example). diff --git a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.m b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.m index 36d7eed0d3..35398c11e3 100644 --- a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.m +++ b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataRoom.m @@ -40,7 +40,7 @@ - (instancetype)init return self; } -- (void)storeEvent:(MXEvent *)event direction:(MXEventDirection)direction +- (void)storeEvent:(MXEvent *)event direction:(MXTimelineDirection)direction { // Convert Mantle MXEvent object to MXCoreDataEvent MXCoreDataEvent *cdEvent = [self coreDataEventFromEvent:event]; @@ -50,7 +50,7 @@ - (void)storeEvent:(MXEvent *)event direction:(MXEventDirection)direction // from working //cdEvent.room = self; - if (MXEventDirectionForwards == direction) + if (MXTimelineDirectionForwards == direction) { [self addMessagesObject:cdEvent]; } diff --git a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m index f217f23768..0bee43e0ba 100644 --- a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m +++ b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m @@ -183,7 +183,7 @@ - (void)openWithCredentials:(MXCredentials*)credentials onComplete:(void (^)())o #pragma mark - MXStore -- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXEventDirection)direction +- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXTimelineDirection)direction { //NSDate *startDate = [NSDate date]; diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index 1c826ca1e5..5a1b19c695 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -230,7 +230,7 @@ - (NSUInteger)diskUsage #pragma mark - MXStore -- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXEventDirection)direction +- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXTimelineDirection)direction { [super storeEventForRoom:roomId event:event direction:direction]; diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h index 02a18324df..c35981f0e5 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.h @@ -40,7 +40,7 @@ @param event the MXEvent object to store. @param direction the origin of the event. Live or past events. */ -- (void)storeEvent:(MXEvent*)event direction:(MXEventDirection)direction; +- (void)storeEvent:(MXEvent*)event direction:(MXTimelineDirection)direction; /** Replace room event (used in case of redaction for example). diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m index 539c72778a..0421574090 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryRoomStore.m @@ -39,9 +39,9 @@ - (instancetype)init return self; } -- (void)storeEvent:(MXEvent *)event direction:(MXEventDirection)direction +- (void)storeEvent:(MXEvent *)event direction:(MXTimelineDirection)direction { - if (MXEventDirectionForwards == direction) + if (MXTimelineDirectionForwards == direction) { [messages addObject:event]; } diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m index b167b8f34f..4c22c54587 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m @@ -47,7 +47,7 @@ - (void)openWithCredentials:(MXCredentials *)someCredentials onComplete:(void (^ onComplete(); } -- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXEventDirection)direction +- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXTimelineDirection)direction { MXMemoryRoomStore *roomStore = [self getOrCreateRoomStore:roomId]; [roomStore storeEvent:event direction:direction]; diff --git a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m index b10061e51a..bffad45296 100644 --- a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m +++ b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m @@ -57,7 +57,7 @@ - (void)openWithCredentials:(MXCredentials *)credentials onComplete:(void (^)()) onComplete(); } -- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXEventDirection)direction +- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXTimelineDirection)direction { // Store nothing in the MXNoStore except the last message if (nil == lastMessages[roomId]) @@ -65,7 +65,7 @@ - (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXE // If there not yet a last message, store anything lastMessages[roomId] = event; } - else if (MXEventDirectionForwards == direction) + else if (MXTimelineDirectionForwards == direction) { // Else keep always the latest one lastMessages[roomId] = event; diff --git a/MatrixSDK/Data/Store/MXStore.h b/MatrixSDK/Data/Store/MXStore.h index e9cd71955a..092aab5fc7 100644 --- a/MatrixSDK/Data/Store/MXStore.h +++ b/MatrixSDK/Data/Store/MXStore.h @@ -16,6 +16,7 @@ #import "MXJSONModels.h" #import "MXEvent.h" +#import "MXEventTimeline.h" #import "MXReceiptData.h" #import "MXRoomAccountData.h" @@ -49,7 +50,7 @@ @param event the MXEvent object to store. @param direction the origin of the event. Live or past events. */ -- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXEventDirection)direction; +- (void)storeEventForRoom:(NSString*)roomId event:(MXEvent*)event direction:(MXTimelineDirection)direction; /** Replace a room event (in case of redaction for example). diff --git a/MatrixSDK/JSONModels/MXEvent.h b/MatrixSDK/JSONModels/MXEvent.h index 8cb7f3d648..0e614dd794 100644 --- a/MatrixSDK/JSONModels/MXEvent.h +++ b/MatrixSDK/JSONModels/MXEvent.h @@ -122,19 +122,6 @@ FOUNDATION_EXPORT NSString *const kMXMembershipStringBan; FOUNDATION_EXPORT uint64_t const kMXUndefinedTimestamp; -/** - The direction from which an incoming event is considered. - */ -typedef enum : NSUInteger -{ - // Forwards for events coming down the live event stream - MXEventDirectionForwards, - - // Backwards for old events requested through pagination - MXEventDirectionBackwards -} MXEventDirection; - - /** `MXEvent` is the generic model of events received from the home server. diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 33040303a7..7bbed4c2cc 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -315,7 +315,7 @@ - (void)startWithMessagesLimit:(NSUInteger)messagesLimit } } -- (void)handlePresenceEvent:(MXEvent *)event direction:(MXEventDirection)direction +- (void)handlePresenceEvent:(MXEvent *)event direction:(MXTimelineDirection)direction { // Update MXUser with presence data NSString *userId = event.sender; @@ -602,7 +602,7 @@ - (void)serverSyncWithServerTimeout:(NSUInteger)serverTimeout // Handle presence of other users for (MXEvent *presenceEvent in syncResponse.presence.events) { - [self handlePresenceEvent:presenceEvent direction:MXEventDirectionForwards]; + [self handlePresenceEvent:presenceEvent direction:MXTimelineDirectionForwards]; } // Update live event stream token @@ -1262,9 +1262,9 @@ - (BOOL)removeInvitedRoom:(MXRoom*)roomToRemove [invitedRooms sortUsingSelector:@selector(compareOriginServerTs:)]; // Add a listener in order to update the app about invitation list change - [self listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) { + [self listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) { - // in some race conditions the oneself join event is received during the sync instead of MXEventDirectionSync + // in some race conditions the oneself join event is received during the sync instead of MXTimelineDirectionSync // // standard case // 1 - send a join request @@ -1276,7 +1276,7 @@ - (BOOL)removeInvitedRoom:(MXRoom*)roomToRemove // 2 - perform an initial sync when the join method call the success callback // 3 - receive the join event in the live stream -> this method is not called because the event has already been stored in the step 2 // so, we need to manage the sync direction - if (MXEventDirectionForwards == direction) + if (MXTimelineDirectionForwards == direction) { BOOL notify = NO; MXRoomState *roomPrevState = (MXRoomState *)customObject; @@ -1539,7 +1539,7 @@ - (void)removeAllListeners } } -- (void)notifyListeners:(MXEvent*)event direction:(MXEventDirection)direction +- (void)notifyListeners:(MXEvent*)event direction:(MXTimelineDirection)direction { // Notify all listeners // The SDK client may remove a listener while calling them by enumeration diff --git a/MatrixSDK/NotificationCenter/MXNotificationCenter.m b/MatrixSDK/NotificationCenter/MXNotificationCenter.m index 6267b68992..49bd596b39 100644 --- a/MatrixSDK/NotificationCenter/MXNotificationCenter.m +++ b/MatrixSDK/NotificationCenter/MXNotificationCenter.m @@ -88,9 +88,9 @@ - (instancetype)initWithMatrixSession:(MXSession *)mxSession2 // Catch all live events sent from other users to check if we need to notify them - [mxSession listenToEvents:^(MXEvent *event, MXEventDirection direction, id customObject) { + [mxSession listenToEvents:^(MXEvent *event, MXTimelineDirection direction, id customObject) { - if (MXEventDirectionForwards == direction + if (MXTimelineDirectionForwards == direction && NO == [event.sender isEqualToString:mxSession.matrixRestClient.credentials.userId]) { [self shouldNotify:event roomState:customObject]; diff --git a/MatrixSDK/VoIP/MXCallManager.m b/MatrixSDK/VoIP/MXCallManager.m index f3c3cec146..516e85ff2f 100644 --- a/MatrixSDK/VoIP/MXCallManager.m +++ b/MatrixSDK/VoIP/MXCallManager.m @@ -65,9 +65,9 @@ - (instancetype)initWithMatrixSession:(MXSession *)mxSession andCallStack:(id)store @"user_id": @"userId:" }]; - [store storeEventForRoom:@"roomId" event:event direction:MXEventDirectionForwards]; + [store storeEventForRoom:@"roomId" event:event direction:MXTimelineDirectionForwards]; BOOL exists = [store eventExistsWithEventId:@"anID" inRoom:@"roomId"]; @@ -227,7 +227,7 @@ - (void)checkEventWithEventIdOfStore:(id)store @"user_id": @"userId:" }]; - [store storeEventForRoom:@"roomId" event:event direction:MXEventDirectionForwards]; + [store storeEventForRoom:@"roomId" event:event direction:MXTimelineDirectionForwards]; MXEvent *storedEvent = [store eventWithEventId:@"anID" inRoom:@"roomId"]; @@ -252,13 +252,13 @@ - (void)checkPaginateBack:(MXRoom*)room ]; __block NSUInteger eventCount = 0; - [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { eventCount++; }]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:5 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertEqual(eventCount, 5, @"We should get as many messages as requested"); @@ -280,7 +280,7 @@ - (void)checkPaginateBackFilter:(MXRoom*)room ]; __block NSUInteger eventCount = 0; - [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { eventCount++; @@ -291,7 +291,7 @@ - (void)checkPaginateBackFilter:(MXRoom*)room }]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -313,7 +313,7 @@ - (void)checkPaginateBackOrder:(MXRoom*)room ]; __block uint64_t prev_ts = -1; - [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:eventsFilterForMessages onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { XCTAssert(event.originServerTs, @"The event should have an attempt: %@", event); @@ -323,7 +323,7 @@ - (void)checkPaginateBackOrder:(MXRoom*)room }]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { XCTAssertNotEqual(prev_ts, -1, "We should have received events in registerEventListenerForTypes"); @@ -339,7 +339,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room { __block NSUInteger eventCount = 0; __block NSMutableArray *events = [NSMutableArray array]; - [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { eventCount++; @@ -347,7 +347,7 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room }]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { XCTAssert(eventCount, "We should have received events in registerEventListenerForTypes"); @@ -365,19 +365,19 @@ - (void)checkPaginateBackDuplicates:(MXRoom*)room - (void)checkSeveralPaginateBacks:(MXRoom*)room { __block NSMutableArray *roomEvents = [NSMutableArray array]; - [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { [roomEvents addObject:event]; }]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { // Use another MXRoom instance to do pagination in several times MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room2.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { [room2Events addObject:event]; }]; @@ -390,16 +390,16 @@ - (void)checkSeveralPaginateBacks:(MXRoom*)room XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 7); } - [room2.liveTimeline paginate:2 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:2 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { if (mxSession.store.isPermanent) { XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 5); } - [room2.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:5 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { - [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { [self assertNoDuplicate:room2Events text:@"events got one by one with testSeveralPaginateBacks"]; @@ -447,18 +447,18 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room MXRoom *room2 = [[MXRoom alloc] initWithRoomId:room.state.roomId andMatrixSession:mxSession]; __block NSMutableArray *room2Events = [NSMutableArray array]; - [room2.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { - if (MXEventDirectionForwards != direction) + if (MXTimelineDirectionForwards != direction) { [room2Events addObject:event]; } }]; __block NSUInteger liveEvents = 0; - [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEventsOfTypes:nil onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { - if (MXEventDirectionForwards == direction) + if (MXTimelineDirectionForwards == direction) { // Do some paginations after receiving live events liveEvents++; @@ -469,7 +469,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room XCTAssertGreaterThanOrEqual(room2.liveTimeline.remainingMessagesForBackPaginationInStore, 7); } - [room2.liveTimeline paginate:2 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:2 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { if (mxSession.store.isPermanent) { @@ -487,9 +487,9 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room } else if (3 == liveEvents) - [room2.liveTimeline paginate:5 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:5 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { - [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room2.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { [self assertNoDuplicate:room2Events text:@"events got one by one with testSeveralPaginateBacks"]; @@ -524,7 +524,7 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room // Take a snapshot of all room history [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ // Messages are now in the cache // Start checking pagination from the cache @@ -542,14 +542,14 @@ - (void)checkPaginateWithLiveEvents:(MXRoom*)room - (void)checkCanPaginateFromHomeServer:(MXRoom*)room { [room.liveTimeline resetPagination]; - XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We can always paginate at the beginning"); + XCTAssertTrue([room.liveTimeline canPaginate:MXTimelineDirectionBackwards], @"We can always paginate at the beginning"); - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { // Due to SPEC-319, we need to paginate twice to be sure to hit the limit - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { - XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must have reached the end of the pagination"); + XCTAssertFalse([room.liveTimeline canPaginate:MXTimelineDirectionBackwards], @"We must have reached the end of the pagination"); [expectation fulfill]; @@ -567,14 +567,14 @@ - (void)checkCanPaginateFromHomeServer:(MXRoom*)room - (void)checkCanPaginateFromMXStore:(MXRoom*)room { [room.liveTimeline resetPagination]; - XCTAssertTrue([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We can always paginate at the beginning"); + XCTAssertTrue([room.liveTimeline canPaginate:MXTimelineDirectionBackwards], @"We can always paginate at the beginning"); - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { // Do one more round trip so that SDK detect the limit - [room.liveTimeline paginate:1 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:1 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ - XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"We must have reached the end of the pagination"); + XCTAssertFalse([room.liveTimeline canPaginate:MXTimelineDirectionBackwards], @"We must have reached the end of the pagination"); [expectation fulfill]; @@ -598,7 +598,7 @@ - (void)checkLastMessageAfterPaginate:(MXRoom*)room MXEvent *lastMessage2 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage2.eventId, lastMessage.eventId, @"The last message should stay the same"); - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { MXEvent *lastMessage3 = [room lastMessageWithTypeIn:nil]; XCTAssertEqualObjects(lastMessage3.eventId, lastMessage.eventId, @"The last message should stay the same"); @@ -628,14 +628,14 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room __block BOOL joinedRequestMade = NO; // Listen for the invitation by Alice - [mxSession listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) { + [mxSession listenToEventsOfTypes:@[kMXEventTypeStringRoomMember] onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) { // Join the room again MXRoom *room2 = [mxSession roomWithRoomId:roomId]; XCTAssertNotNil(room2); - if (direction == MXEventDirectionForwards && MXMembershipInvite == room2.state.membership && !joinedRequestMade) + if (direction == MXTimelineDirectionForwards && MXMembershipInvite == room2.state.membership && !joinedRequestMade) { // Join the room on the invitation and check we can paginate all expected text messages // By default the last Alice's message (sent while Bob is not in the room) must be visible. @@ -643,9 +643,9 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room [room2 join:^{ NSMutableArray *events = [NSMutableArray array]; - [room2.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room2.liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { - if (direction == MXEventDirectionBackwards) + if (direction == MXTimelineDirectionBackwards) { if (0 == events.count) { @@ -659,7 +659,7 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room }]; [room2.liveTimeline resetPagination]; - [room2.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ + [room2.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(events.count, 6, "The room should contain only 6 messages (the last message sent while the user is not in the room must be visible)"); @@ -716,14 +716,14 @@ - (void)checkPaginateWhenJoiningAgainAfterLeft:(MXRoom*)room - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room { __block NSUInteger eventCount = 0; - [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { eventCount++; }]; // First count how many messages to retrieve [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:100 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^() { + [room.liveTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^() { // Paginate for the exact number of events in the room NSUInteger pagEnd = eventCount; @@ -731,18 +731,18 @@ - (void)checkPaginateWhenReachingTheExactBeginningOfTheRoom:(MXRoom*)room [mxSession.store deleteRoom:room.state.roomId]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:pagEnd direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:pagEnd direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, pagEnd, @"We should get as many messages as requested"); - XCTAssert([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"At this point the SDK cannot know it reaches the beginning of the history"); + XCTAssert([room.liveTimeline canPaginate:MXTimelineDirectionBackwards], @"At this point the SDK cannot know it reaches the beginning of the history"); // Try to load more messages eventCount = 0; - [room.liveTimeline paginate:1 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:1 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ XCTAssertEqual(eventCount, 0, @"There must be no more event"); - XCTAssertFalse([room.liveTimeline canPaginate:MXEventDirectionBackwards], @"SDK must now indicate there is no more event to paginate"); + XCTAssertFalse([room.liveTimeline canPaginate:MXTimelineDirectionBackwards], @"SDK must now indicate there is no more event to paginate"); [expectation fulfill]; @@ -766,7 +766,7 @@ - (void)checkRedactEvent:(MXRoom*)room { __block NSString *messageEventId; - [room.liveTimeline listenToEvents:^(MXEvent *event, MXEventDirection direction, MXRoomState *roomState) { + [room.liveTimeline listenToEvents:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { if (MXEventTypeRoomMessage == event.eventType) { @@ -1100,7 +1100,7 @@ - (void)checkMXRoomPaginationToken:(Class)mxStoreClass MXRoom *room = [mxSession roomWithRoomId:roomId]; [room.liveTimeline resetPagination]; - [room.liveTimeline paginate:10 direction:MXEventDirectionBackwards onlyFromStore:NO complete:^{ + [room.liveTimeline paginate:10 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ NSString *roomPaginationToken = [store paginationTokenOfRoom:roomId]; XCTAssert(roomPaginationToken, @"The room must have a pagination after a pagination"); diff --git a/MatrixSDKTests/MXVoIPTests.m b/MatrixSDKTests/MXVoIPTests.m index 6cc12d07ff..b6fb31c432 100644 --- a/MatrixSDKTests/MXVoIPTests.m +++ b/MatrixSDKTests/MXVoIPTests.m @@ -95,7 +95,7 @@ - (void)testNoVoIPStackOnCallInvite }; - [mxSession listenToEventsOfTypes:@[kMXEventTypeStringCallInvite] onEvent:^(MXEvent *event, MXEventDirection direction, id customObject) { + [mxSession listenToEventsOfTypes:@[kMXEventTypeStringCallInvite] onEvent:^(MXEvent *event, MXTimelineDirection direction, id customObject) { MXCall *call = [mxSession.callManager callWithCallId:callId]; From 667750a5161c1747a8cff5c8e0c9f8018f8cbd12 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 26 Feb 2016 17:54:00 +0100 Subject: [PATCH 67/80] Event timeline: Added the undocumented 'event' to MXEventContext --- MatrixSDK/JSONModels/MXJSONModels.h | 7 ++++++- MatrixSDK/JSONModels/MXJSONModels.m | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index 08a369302f..fa459bb782 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -615,10 +615,15 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; #pragma mark - Context #pragma mark - /** - `MXEventContext` represents to the response to the /context request. + `MXEventContext` represents the response to the /context request. */ @interface MXEventContext : MXJSONModel + /** + The event on which /context has been requested. + */ + @property (nonatomic) MXEvent *event; + /** A token that can be used to paginate backwards with. */ diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 0ea1525d86..deeccf50fb 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -582,6 +582,7 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary MXEventContext *eventContext = [[MXEventContext alloc] init]; if (eventContext) { + MXJSONModelSetMXJSONModel(eventContext.event, MXEvent, JSONDictionary[@"event"]); MXJSONModelSetString(eventContext.start, JSONDictionary[@"start"]); MXJSONModelSetMXJSONModelArray(eventContext.eventsBefore, MXEvent, JSONDictionary[@"events_before"]); MXJSONModelSetMXJSONModelArray(eventContext.eventsAfter, MXEvent, JSONDictionary[@"events_after"]); From 641f0c1dd9ec9ad1da77e7017761755885123352 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 26 Feb 2016 19:12:13 +0100 Subject: [PATCH 68/80] Event timeline: [MXEventTimeline loadContextWithLimit] starts to work --- MatrixSDK/Data/MXEventTimeline.m | 8 +++++-- MatrixSDKTests/MXEventTimelineTests.m | 30 ++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index ef6d21fb5a..e871ccf457 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -94,16 +94,20 @@ - (MXHTTPOperation *)loadContextWithLimit:(NSUInteger)limit success:(void (^)()) // And fill the timelime with received data [self initialiseState:eventContext.state]; + [self addEvent:eventContext.event direction:MXTimelineDirectionForwards fromStore:NO notify:NO]; + for (MXEvent *event in eventContext.eventsBefore) { - [self handleMessage:event direction:MXEventDirectionBackwards]; + [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO notify:NO]; } for (MXEvent *event in eventContext.eventsAfter) { - [self handleLiveEvent:event]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:NO]; } + [store storePaginationTokenOfRoom:room.roomId andToken:eventContext.start]; + success(); } failure:failure]; } diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index 17861bfc74..e2ffc6e904 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -22,6 +22,8 @@ @interface MXEventTimelineTests : XCTestCase { + MatrixSDKTestsData *matrixSDKTestsData; + MXSession *mxSession; } @end @@ -31,34 +33,52 @@ @implementation MXEventTimelineTests - (void)setUp { [super setUp]; + + matrixSDKTestsData = [[MatrixSDKTestsData alloc] init]; } - (void)tearDown { if (mxSession) { - [[MatrixSDKTestsData sharedData] closeMXSession:mxSession]; + [matrixSDKTestsData closeMXSession:mxSession]; mxSession = nil; + matrixSDKTestsData = nil; } [super tearDown]; } - (void)testPaginateOnContextTimeline { - [[MatrixSDKTestsData sharedData] doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { + [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; // Add 20 messages to the room - [[MatrixSDKTestsData sharedData] for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ + [matrixSDKTestsData for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ [room sendTextMessage:@"The initial timelime event" success:^(NSString *eventId) { // Add 20 more messages - [[MatrixSDKTestsData sharedData] for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ + [matrixSDKTestsData for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ [room openTimelineOnEvent:eventId withLimit:10 success:^(MXEventTimeline *eventTimeline) { - [expectation fulfill]; + [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + + NSLog(@"### %@", event); + + }]; + + [eventTimeline resetPagination]; + [eventTimeline paginate:1 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ + + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; } failure:^(NSError *error) { XCTFail(@"The operation should not fail - NSError: %@", error); From 0ec3fa057e580175e81b4011f0e51a735b1aab51 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 29 Feb 2016 08:56:14 +0100 Subject: [PATCH 69/80] Event timeline: Renamed [MXEventTimeline loadContextWithLimit] into [MXEventTimeline resetPaginationAroundInitialEventWithLimit]. It resets the pagination but around the initial events. It sends all received events to the sdk user --- MatrixSDK/Data/MXEventTimeline.h | 34 ++++++++------- MatrixSDK/Data/MXEventTimeline.m | 62 ++++++++++++++------------- MatrixSDK/Data/MXRoom.h | 14 +----- MatrixSDK/Data/MXRoom.m | 10 +---- MatrixSDKTests/MXEventTimelineTests.m | 36 ++++++++++------ 5 files changed, 77 insertions(+), 79 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index e1f3916d16..cb8f619157 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -103,19 +103,6 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXTimelineDirection direction, MXR */ - (void)initialiseState:(NSArray *)stateEvents; -/** - Initialise a timelime by loading the context around its `initialEventId`. - - @param limit the maximum number of messages to return. - - @param success A block object called when the operation succeeds. - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. - */ -- (MXHTTPOperation*)loadContextWithLimit:(NSUInteger)limit - success:(void(^)())success - failure:(void (^)(NSError *error))failure; #pragma mark - Pagination /** @@ -134,16 +121,31 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXTimelineDirection direction, MXR - (BOOL)canPaginate:(MXTimelineDirection)direction; /** - Reset the pagination so that future calls to paginate start over from live or - from the `initialEventId`. + Reset the pagination so that future calls to paginate start from the most recent + event of the timeline. */ - (void)resetPagination; +/** + Reset the pagination timelime and start loading the context around its `initialEventId`. + The retrieved (backwards and forwards) events will be sent to registered listeners. + + @param limit the maximum number of messages to get around the initial event. + + @param success A block object called when the operation succeeds. + @param failure A block object called when the operation fails. + + @return a MXHTTPOperation instance. + */ +- (MXHTTPOperation*)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limit + success:(void(^)())success + failure:(void (^)(NSError *error))failure; + /** Get more messages. The retrieved events will be sent to registered listeners. - It is not possible to paginate forwards on a live timeline. + Note it is not possible to paginate forwards on a live timeline. @param numItems the number of items to get. @param direction `MXTimelineDirectionForwards` or `MXTimelineDirectionBackwards` diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index e871ccf457..0dc22d820c 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -84,34 +84,6 @@ - (void)initialiseState:(NSArray *)stateEvents } } -- (MXHTTPOperation *)loadContextWithLimit:(NSUInteger)limit success:(void (^)())success failure:(void (^)(NSError *))failure -{ - NSAssert(_initialEventId, @"[MXEventTimeline] loadContextWithLimit cannot be called on live timeline"); - - // Get the context around the initial event - return [room.mxSession.matrixRestClient contextOfEvent:_initialEventId inRoom:room.roomId limit:limit success:^(MXEventContext *eventContext) { - - // And fill the timelime with received data - [self initialiseState:eventContext.state]; - - [self addEvent:eventContext.event direction:MXTimelineDirectionForwards fromStore:NO notify:NO]; - - for (MXEvent *event in eventContext.eventsBefore) - { - [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO notify:NO]; - } - - for (MXEvent *event in eventContext.eventsAfter) - { - [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:NO]; - } - - [store storePaginationTokenOfRoom:room.roomId andToken:eventContext.start]; - - success(); - } failure:failure]; -} - #pragma mark - Pagination - (BOOL)canPaginate:(MXTimelineDirection)direction @@ -142,8 +114,6 @@ - (BOOL)canPaginate:(MXTimelineDirection)direction return canPaginate; } - -#pragma mark - Back pagination - (void)resetPagination { // Reset the back state to the current room state @@ -153,6 +123,38 @@ - (void)resetPagination [store resetPaginationOfRoom:_state.roomId]; } +- (MXHTTPOperation *)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limit success:(void (^)())success failure:(void (^)(NSError *))failure +{ + NSAssert(_initialEventId, @"[MXEventTimeline] resetPaginationAroundInitialEventWithLimit cannot be called on live timeline"); + + // Reset the store + [store deleteAllData]; + + // Get the context around the initial event + return [room.mxSession.matrixRestClient contextOfEvent:_initialEventId inRoom:room.roomId limit:limit success:^(MXEventContext *eventContext) { + + // And fill the timelime with received data + [self initialiseState:eventContext.state]; + + [self addEvent:eventContext.event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + + for (MXEvent *event in eventContext.eventsBefore) + { + [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO notify:YES]; + } + + for (MXEvent *event in eventContext.eventsAfter) + { + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + } + + [store storePaginationTokenOfRoom:room.roomId andToken:eventContext.start]; + + success(); + } failure:failure]; +} + + - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirection)direction onlyFromStore:(BOOL)onlyFromStore complete:(void (^)())complete failure:(void (^)(NSError *))failure { MXHTTPOperation *operation; diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 1b95349cfd..f803d10039 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -377,19 +377,9 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; Open a new `MXEventTimeline` instance around the passed event. @param eventId the id of the event. - @param limit the maximum number of messages to preload. - - @param success A block object called when the operation succeeds. - It passes the newly `MXEventTimeline` created instance. - @param failure A block object called when the operation fails. - - @return a MXHTTPOperation instance. + @return a new `MXEventTimeline` instance. */ - -- (MXHTTPOperation*)openTimelineOnEvent:(NSString*)eventId - withLimit:(NSUInteger)limit - success:(void(^)(MXEventTimeline *eventTimeline))success - failure:(void (^)(NSError *error))failure; +- (MXEventTimeline*)openTimelineOnEvent:(NSString*)eventId; /** Close a `MXEventTimeline` instance. diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index e69f021984..2ffd401d97 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -314,15 +314,9 @@ - (MXHTTPOperation*)redactEvent:(NSString*)eventId #pragma mark - Events timeline -- (MXHTTPOperation *)openTimelineOnEvent:(NSString *)eventId withLimit:(NSUInteger)limit success:(void (^)(MXEventTimeline *))success failure:(void (^)(NSError *))failure +- (MXEventTimeline*)openTimelineOnEvent:(NSString*)eventId; { - // Create and preload the event timeline - MXEventTimeline *eventTimeline = [[MXEventTimeline alloc] initWithRoom:self andInitialEventId:eventId]; - [eventTimeline loadContextWithLimit:limit success:^{ - success(eventTimeline); - } failure:failure]; - - return nil; + return [[MXEventTimeline alloc] initWithRoom:self andInitialEventId:eventId]; } -(void)closeTimeline:(MXEventTimeline *)eventTimeline diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index e2ffc6e904..93f8e8ce1a 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -56,35 +56,45 @@ - (void)testPaginateOnContextTimeline // Add 20 messages to the room [matrixSDKTestsData for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ - [room sendTextMessage:@"The initial timelime event" success:^(NSString *eventId) { + NSString *theMessage = @"The initial timelime event"; + [room sendTextMessage:theMessage success:^(NSString *eventId) { // Add 20 more messages [matrixSDKTestsData for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ - [room openTimelineOnEvent:eventId withLimit:10 success:^(MXEventTimeline *eventTimeline) { + MXEventTimeline *eventTimeline = [room openTimelineOnEvent:eventId]; - [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + NSMutableArray *events = [NSMutableArray array]; + [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { - NSLog(@"### %@", event); + if (events.count == 0) + { + XCTAssertEqualObjects(event.content[@"body"], theMessage, @"The first returned event must be the initial event"); + } - }]; + if (direction == MXTimelineDirectionForwards) + { + [events addObject:event]; + } + else + { + [events insertObject:event atIndex:0]; + } + NSLog(@"### %@", event); - [eventTimeline resetPagination]; - [eventTimeline paginate:1 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ + }]; + [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ - [expectation fulfill]; + XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); - } failure:^(NSError *error) { - XCTFail(@"The operation should not fail - NSError: %@", error); - [expectation fulfill]; - }]; + [expectation fulfill]; } failure:^(NSError *error) { XCTFail(@"The operation should not fail - NSError: %@", error); [expectation fulfill]; }]; - + }]; } failure:^(NSError *error) { From 11690947343ea4818e3d9df574bfda141cbbc14d Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 29 Feb 2016 10:19:05 +0100 Subject: [PATCH 70/80] Event timeline: tests: testResetPaginationAroundInitialEventWithLimit is now ready --- MatrixSDKTests/MXEventTimelineTests.m | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index 93f8e8ce1a..c870fb30d2 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -48,7 +48,7 @@ - (void)tearDown [super tearDown]; } -- (void)testPaginateOnContextTimeline +- (void)testResetPaginationAroundInitialEventWithLimit { [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -80,7 +80,6 @@ - (void)testPaginateOnContextTimeline { [events insertObject:event atIndex:0]; } - NSLog(@"### %@", event); }]; @@ -88,6 +87,19 @@ - (void)testPaginateOnContextTimeline XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertNotNil(event.eventId, @"The event must have an eventId to be valid"); + + if (event.originServerTs) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } + } + [expectation fulfill]; } failure:^(NSError *error) { From 52fb02d5c67bb0f785ad090c8d6b26264852f3e8 Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 29 Feb 2016 13:58:29 +0100 Subject: [PATCH 71/80] Event timeline: Fixed back pagination on past timeline --- MatrixSDK/Data/MXEventTimeline.m | 3 + MatrixSDKTests/MXEventTimelineTests.m | 224 ++++++++++++++++++++++---- 2 files changed, 192 insertions(+), 35 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 0dc22d820c..e1fadf055e 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -136,6 +136,9 @@ - (MXHTTPOperation *)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limi // And fill the timelime with received data [self initialiseState:eventContext.state]; + // Reset pagination state from here + [self resetPagination]; + [self addEvent:eventContext.event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; for (MXEvent *event in eventContext.eventsBefore) diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index c870fb30d2..7b4cd9c897 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -28,6 +28,8 @@ @interface MXEventTimelineTests : XCTestCase } @end +NSString *theInitialEventMessage = @"The initial timelime event"; + @implementation MXEventTimelineTests - (void)setUp @@ -48,7 +50,7 @@ - (void)tearDown [super tearDown]; } -- (void)testResetPaginationAroundInitialEventWithLimit +- (void)doTestWithARoomOf41Messages:(XCTestCase*)testCase readyToTest:(void (^)(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId))readyToTest { [matrixSDKTestsData doMXSessionTestWithBobAndARoomWithMessages:self readyToTest:^(MXSession *mxSession2, MXRoom *room, XCTestExpectation *expectation) { mxSession = mxSession2; @@ -56,49 +58,193 @@ - (void)testResetPaginationAroundInitialEventWithLimit // Add 20 messages to the room [matrixSDKTestsData for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ - NSString *theMessage = @"The initial timelime event"; - [room sendTextMessage:theMessage success:^(NSString *eventId) { + // Add a text message that will be used as initial event + [room sendTextMessage:theInitialEventMessage success:^(NSString *eventId) { // Add 20 more messages [matrixSDKTestsData for:mxSession.matrixRestClient andRoom:room.roomId sendMessages:20 success:^{ - MXEventTimeline *eventTimeline = [room openTimelineOnEvent:eventId]; + readyToTest(room, expectation, eventId); - NSMutableArray *events = [NSMutableArray array]; - [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + }]; - if (events.count == 0) - { - XCTAssertEqualObjects(event.content[@"body"], theMessage, @"The first returned event must be the initial event"); - } + } failure:^(NSError *error) { + NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + }]; + }]; + }]; +} - if (direction == MXTimelineDirectionForwards) - { - [events addObject:event]; - } - else - { - [events insertObject:event atIndex:0]; - } +- (void)testResetPaginationAroundInitialEventWithLimit +{ + [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { - }]; + MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + + NSMutableArray *events = [NSMutableArray array]; + [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + + if (events.count == 0) + { + XCTAssertEqualObjects(event.eventId, initialEventId, @"The first returned event must be the initial event"); + XCTAssertEqualObjects(event.content[@"body"], theInitialEventMessage); + } + + if (direction == MXTimelineDirectionForwards) + { + [events addObject:event]; + } + else + { + [events insertObject:event atIndex:0]; + } + + }]; + + [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ + + XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } + + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); + // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + }]; +} + +- (void)testDoubleResetPaginationAroundInitialEventWithLimit +{ + [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { + + MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + + NSMutableArray *events = [NSMutableArray array]; + [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + + if (events.count == 0) + { + XCTAssertEqualObjects(event.eventId, initialEventId, @"The first returned event must be the initial event"); + XCTAssertEqualObjects(event.content[@"body"], theInitialEventMessage); + } + + if (direction == MXTimelineDirectionForwards) + { + [events addObject:event]; + } + else + { + [events insertObject:event atIndex:0]; + } + + }]; + + [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ + + XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + + [events removeAllObjects]; + + [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ + + XCTAssertEqual(events.count, 11, @"1 + 10 = 11. Calling resetPaginationAroundInitialEventWithLimit must lead to the same reset state"); + + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } + + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); + // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + }]; +} + +- (void)testBackPaginationOnPastTimeline +{ + [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { + + MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + + NSMutableArray *events = [NSMutableArray array]; + [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + + if (events.count == 0) + { + XCTAssertEqualObjects(event.eventId, initialEventId, @"The first returned event must be the initial event"); + XCTAssertEqualObjects(event.content[@"body"], theInitialEventMessage); + } + + if (direction == MXTimelineDirectionForwards) + { + [events addObject:event]; + } + else + { + [events insertObject:event atIndex:0]; + } + + }]; + + [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ + + XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); - [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ + // Get some messages in the past + [eventTimeline paginate:10 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ - XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + // @TODO: Note: this test fails because of https://matrix.org/jira/browse/SYN-641 + //XCTAssertEqual(events.count, 21, @"1 + 10 + 10 = 21"); - // Check events order - uint64_t prev_ts = 0; - for (MXEvent *event in events) - { - XCTAssertNotNil(event.eventId, @"The event must have an eventId to be valid"); + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } - if (event.originServerTs) - { - XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); - prev_ts = event.originServerTs; - } - } + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); + // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + + // Get all past messages + [eventTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ + + XCTAssertEqual(events.count, 31, @"1 + 20 + 10 = 31"); + + // Do one more request to test end + [eventTimeline paginate:1 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ + + XCTAssertFalse([eventTimeline canPaginate:MXTimelineDirectionBackwards]); + // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO [expectation fulfill]; @@ -106,16 +252,24 @@ - (void)testResetPaginationAroundInitialEventWithLimit XCTFail(@"The operation should not fail - NSError: %@", error); [expectation fulfill]; }]; - + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; }]; - + } failure:^(NSError *error) { - NSAssert(NO, @"Cannot set up intial test conditions - error: %@", error); + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; }]; + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; }]; }]; + } From cf984d789e73f1ad6851372dbcb9d411b6bd831a Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 29 Feb 2016 15:27:22 +0100 Subject: [PATCH 72/80] MXRestClient: the messagesForRoom method has been updated to conform r0 C-S API. The "to" parameter has been removed. The "direction" parameter has been added. --- MatrixSDK/MXRestClient.h | 7 ++++--- MatrixSDK/MXRestClient.m | 17 ++++++++--------- MatrixSDKTests/MXEventTests.m | 2 +- MatrixSDKTests/MXRestClientTests.m | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/MatrixSDK/MXRestClient.h b/MatrixSDK/MXRestClient.h index 390cf0ac9d..6028a55ad5 100644 --- a/MatrixSDK/MXRestClient.h +++ b/MatrixSDK/MXRestClient.h @@ -19,6 +19,7 @@ #import "MXHTTPClient.h" #import "MXEvent.h" +#import "MXEventTimeline.h" #import "MXJSONModels.h" @@ -670,8 +671,8 @@ typedef enum : NSUInteger Get a list of messages for this room. @param roomId the id of the room. - @param from (optional) the token to start getting results from. - @param to (optional)the token to stop getting results at. + @param from the token to start getting results from. + @param direction `MXTimelineDirectionForwards` or `MXTimelineDirectionBackwards` @param limit (optional, use -1 to not defined this value) the maximum nuber of messages to return. @param success A block object called when the operation succeeds. It provides a `MXPaginationResponse` object. @@ -681,7 +682,7 @@ typedef enum : NSUInteger */ - (MXHTTPOperation*)messagesForRoom:(NSString*)roomId from:(NSString*)from - to:(NSString*)to + direction:(MXTimelineDirection)direction limit:(NSUInteger)limit success:(void (^)(MXPaginationResponse *paginatedResponse))success failure:(void (^)(NSError *error))failure; diff --git a/MatrixSDK/MXRestClient.m b/MatrixSDK/MXRestClient.m index f7795ddad3..5adc1d531a 100644 --- a/MatrixSDK/MXRestClient.m +++ b/MatrixSDK/MXRestClient.m @@ -1226,7 +1226,7 @@ - (MXHTTPOperation*)createRoom:(NSString*)name - (MXHTTPOperation*)messagesForRoom:(NSString*)roomId from:(NSString*)from - to:(NSString*)to + direction:(MXTimelineDirection)direction limit:(NSUInteger)limit success:(void (^)(MXPaginationResponse *paginatedResponse))success failure:(void (^)(NSError *error))failure @@ -1235,23 +1235,22 @@ - (MXHTTPOperation*)messagesForRoom:(NSString*)roomId // All query parameters are optional. Fill the request parameters on demand NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; - - if (from) + + parameters[@"from"] = from; + + if (direction == MXTimelineDirectionForwards) { - parameters[@"from"] = from; + parameters[@"dir"] = @"f"; } - if (to) + else { - parameters[@"to"] = to; + parameters[@"dir"] = @"b"; } if (-1 != limit) { parameters[@"limit"] = [NSNumber numberWithUnsignedInteger:limit]; } - // List messages in backward order to make the API answer - parameters[@"dir"] = @"b"; - return [httpClient requestWithMethod:@"GET" path:path parameters:parameters diff --git a/MatrixSDKTests/MXEventTests.m b/MatrixSDKTests/MXEventTests.m index 46d60a0189..849f0a7887 100644 --- a/MatrixSDKTests/MXEventTests.m +++ b/MatrixSDKTests/MXEventTests.m @@ -53,7 +53,7 @@ - (void)doTestWithMXEvents:(void (^)(MXRestClient *bobRestClient, NSString* room { [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient messagesForRoom:roomId from:nil to:nil limit:100 success:^(MXPaginationResponse *paginatedResponse) { + [bobRestClient messagesForRoom:roomId from:nil direction:MXTimelineDirectionBackwards limit:100 success:^(MXPaginationResponse *paginatedResponse) { NSAssert(0 < paginatedResponse.chunk.count, @"Cannot set up intial test conditions"); diff --git a/MatrixSDKTests/MXRestClientTests.m b/MatrixSDKTests/MXRestClientTests.m index 2c0f1fbebb..7dcb2373fc 100644 --- a/MatrixSDKTests/MXRestClientTests.m +++ b/MatrixSDKTests/MXRestClientTests.m @@ -355,7 +355,7 @@ - (void)testMessagesWithNoParams { [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient messagesForRoom:roomId from:nil to:nil limit:-1 success:^(MXPaginationResponse *paginatedResponse) { + [bobRestClient messagesForRoom:roomId from:nil direction:MXTimelineDirectionBackwards limit:-1 success:^(MXPaginationResponse *paginatedResponse) { XCTAssertNotNil(paginatedResponse); XCTAssertNotNil(paginatedResponse.start); @@ -377,7 +377,7 @@ - (void)testMessagesWithOneParam { [matrixSDKTestsData doMXRestClientTestWithBobAndARoomWithMessages:self readyToTest:^(MXRestClient *bobRestClient, NSString *roomId, XCTestExpectation *expectation) { - [bobRestClient messagesForRoom:roomId from:nil to:nil limit:100 success:^(MXPaginationResponse *paginatedResponse) { + [bobRestClient messagesForRoom:roomId from:nil direction:MXTimelineDirectionBackwards limit:100 success:^(MXPaginationResponse *paginatedResponse) { XCTAssertNotNil(paginatedResponse); XCTAssertNotNil(paginatedResponse.start); From 5edf4540b0038379430f7817de98c3fa52a18bac Mon Sep 17 00:00:00 2001 From: manuroe Date: Mon, 29 Feb 2016 16:19:43 +0100 Subject: [PATCH 73/80] Event timeline: Implemented forward pagination --- MatrixSDK/Data/MXEventTimeline.m | 162 +++++++++++++++----------- MatrixSDKTests/MXEventTimelineTests.m | 119 +++++++++++++++++-- 2 files changed, 205 insertions(+), 76 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index e1fadf055e..1183b2cd8f 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -42,6 +42,11 @@ @interface MXEventTimeline () // The store to store events, id store; + + // MXStore does only back pagination. So, the forward pagination token for + // past timelines is managed locally. + NSString *forwardsPaginationToken; + BOOL hasReachedHomeServerForwardsPaginationEnd; } @end @@ -107,7 +112,7 @@ - (BOOL)canPaginate:(MXTimelineDirection)direction } else { - NSAssert(NO, @"TODO: canPaginate forwards is not yet supported"); + canPaginate = !hasReachedHomeServerForwardsPaginationEnd; } } @@ -130,6 +135,9 @@ - (MXHTTPOperation *)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limi // Reset the store [store deleteAllData]; + forwardsPaginationToken = nil; + hasReachedHomeServerForwardsPaginationEnd = NO; + // Get the context around the initial event return [room.mxSession.matrixRestClient contextOfEvent:_initialEventId inRoom:room.roomId limit:limit success:^(MXEventContext *eventContext) { @@ -152,6 +160,7 @@ - (MXHTTPOperation *)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limi } [store storePaginationTokenOfRoom:room.roomId andToken:eventContext.start]; + forwardsPaginationToken = eventContext.end; success(); } failure:failure]; @@ -162,12 +171,15 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio { MXHTTPOperation *operation; - NSAssert(nil != backState, @"[MXEventTimeline] paginate: resetPagination must be called before starting the back pagination"); + NSAssert(nil != backState, @"[MXEventTimeline] paginate: resetPagination or resetPaginationAroundInitialEventWithLimit must be called before starting the back pagination"); + + NSAssert(!(_isLiveTimeline && direction == MXTimelineDirectionForwards), @"Cannot paginate forwards on a live timeline"); + + NSUInteger messagesFromStoreCount = 0; if (direction == MXTimelineDirectionBackwards) { - // Return messages from the store first - NSUInteger messagesFromStoreCount = 0; + // For back pagination, try to get messages from the store first NSArray *messagesFromStore = [store paginateRoom:_state.roomId numMessages:numItems]; if (messagesFromStore) { @@ -200,73 +212,77 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio return nil; } - if (0 < numItems && NO == [store hasReachedHomeServerPaginationEndForRoom:_state.roomId]) - { - // Not enough messages: make a pagination request to the home server - // from last known token - NSString *paginationToken = [store paginationTokenOfRoom:_state.roomId]; - if (nil == paginationToken) { - paginationToken = @"END"; - } - - NSLog(@"[MXEventTimeline] paginate : request %tu messages from the server", numItems); - - operation = [room.mxSession.matrixRestClient messagesForRoom:_state.roomId - from:paginationToken - to:nil - limit:numItems - success:^(MXPaginationResponse *paginatedResponse) { - - NSLog(@"[MXEventTimeline] paginate : get %tu messages from the server", paginatedResponse.chunk.count); - - [self handlePaginationResponse:paginatedResponse]; - - // Inform the method caller - complete(); - - NSLog(@"[MXEventTimeline] paginate: is done"); - - } failure:^(NSError *error) { - // Check whether the pagination end is reached - MXError *mxError = [[MXError alloc] initWithNSError:error]; - if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) - { - // We run out of items - [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; - - NSLog(@"[MXEventTimeline] paginate: pagination end has been reached"); - - // Ignore the error - complete(); - return; - } - - NSLog(@"[MXEventTimeline] paginate error: %@", error); - failure(error); - }]; - - if (messagesFromStoreCount) - { - // Disable retry to let the caller handle messages from store without delay. - // The caller will trigger a new pagination if need. - operation.maxNumberOfTries = 1; - } - } - else + if (0 == numItems || YES == [store hasReachedHomeServerPaginationEndForRoom:_state.roomId]) { // Nothing more to do complete(); - + NSLog(@"[MXEventTimeline] paginate: is done"); + return nil; } } - else if (!_isLiveTimeline) + + // Not enough messages: make a pagination request to the home server + // from last known token + NSString *paginationToken; + + if (direction == MXTimelineDirectionBackwards) { - NSAssert(NO, @"TODO: paginate forwards is not yet supported"); + paginationToken = [store paginationTokenOfRoom:_state.roomId]; + if (nil == paginationToken) + { + paginationToken = @"END"; + } } else { - NSAssert(NO, @"Cannot paginate forwards on a live timeline"); + paginationToken = forwardsPaginationToken; + } + + NSLog(@"[MXEventTimeline] paginate : request %tu messages from the server", numItems); + + operation = [room.mxSession.matrixRestClient messagesForRoom:_state.roomId from:paginationToken direction:direction limit:numItems success:^(MXPaginationResponse *paginatedResponse) { + + NSLog(@"[MXEventTimeline] paginate : get %tu messages from the server", paginatedResponse.chunk.count); + + [self handlePaginationResponse:paginatedResponse direction:direction]; + + // Inform the method caller + complete(); + + NSLog(@"[MXEventTimeline] paginate: is done"); + + } failure:^(NSError *error) { + // Check whether the pagination end is reached + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && [mxError.error isEqualToString:kMXErrorStringInvalidToken]) + { + // Store the fact we run out of items + if (direction == MXTimelineDirectionBackwards) + { + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + } + else + { + hasReachedHomeServerForwardsPaginationEnd = YES; + } + + NSLog(@"[MXEventTimeline] paginate: pagination end has been reached"); + + // Ignore the error + complete(); + return; + } + + NSLog(@"[MXEventTimeline] paginate error: %@", error); + failure(error); + }]; + + if (messagesFromStoreCount) + { + // Disable retry to let the caller handle messages from store without delay. + // The caller will trigger a new pagination if need. + operation.maxNumberOfTries = 1; } return operation; @@ -386,24 +402,38 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync } } -- (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse +- (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse direction:(MXTimelineDirection)direction { // Check pagination end - @see SPEC-319 ticket if (paginatedResponse.chunk.count == 0 && [paginatedResponse.start isEqualToString:paginatedResponse.end]) { - // We run out of items - [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + // Store the fact we run out of items + if (direction == MXTimelineDirectionBackwards) + { + [store storeHasReachedHomeServerPaginationEndForRoom:_state.roomId andValue:YES]; + } + else + { + hasReachedHomeServerForwardsPaginationEnd = YES; + } } // Process received events for (MXEvent *event in paginatedResponse.chunk) { // Make sure we have not processed this event yet - [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO notify:YES]; + [self addEvent:event direction:direction fromStore:NO notify:YES]; } // And update pagination tokens - [store storePaginationTokenOfRoom:_state.roomId andToken:paginatedResponse.end]; + if (direction == MXTimelineDirectionBackwards) + { + [store storePaginationTokenOfRoom:_state.roomId andToken:paginatedResponse.end]; + } + else + { + forwardsPaginationToken = paginatedResponse.end; + } // Commit store changes if ([store respondsToSelector:@selector(commit)]) diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index 7b4cd9c897..2539a574a4 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -103,7 +103,7 @@ - (void)testResetPaginationAroundInitialEventWithLimit [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ - XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + XCTAssertEqual(events.count, 11, @"5 + 1 + 5 = 11"); // Check events order uint64_t prev_ts = 0; @@ -114,7 +114,7 @@ - (void)testResetPaginationAroundInitialEventWithLimit } XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); - // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); [expectation fulfill]; @@ -154,13 +154,13 @@ - (void)testDoubleResetPaginationAroundInitialEventWithLimit [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ - XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + XCTAssertEqual(events.count, 11, @"5 + 1 + 5 = 11"); [events removeAllObjects]; [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ - XCTAssertEqual(events.count, 11, @"1 + 10 = 11. Calling resetPaginationAroundInitialEventWithLimit must lead to the same reset state"); + XCTAssertEqual(events.count, 11, @"5 + 1 + 5 = 11. Calling resetPaginationAroundInitialEventWithLimit must lead to the same reset state"); // Check events order uint64_t prev_ts = 0; @@ -171,7 +171,7 @@ - (void)testDoubleResetPaginationAroundInitialEventWithLimit } XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); - // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); [expectation fulfill]; @@ -216,13 +216,13 @@ - (void)testBackPaginationOnPastTimeline [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ - XCTAssertEqual(events.count, 11, @"1 + 10 = 11"); + XCTAssertEqual(events.count, 11, @"5 + 1 + 5 = 11"); // Get some messages in the past [eventTimeline paginate:10 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ // @TODO: Note: this test fails because of https://matrix.org/jira/browse/SYN-641 - //XCTAssertEqual(events.count, 21, @"1 + 10 + 10 = 21"); + XCTAssertEqual(events.count, 21, @"10 + 5 + 1 + 5 = 21"); // Check events order uint64_t prev_ts = 0; @@ -233,18 +233,27 @@ - (void)testBackPaginationOnPastTimeline } XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); - // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // Get all past messages [eventTimeline paginate:100 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ - XCTAssertEqual(events.count, 31, @"1 + 20 + 10 = 31"); + // @TODO: Note: this test fails because of https://matrix.org/jira/browse/SYN-641 + XCTAssertEqual(events.count, 26, @"20 + 1 + 5 = 26"); // Do one more request to test end [eventTimeline paginate:1 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } + XCTAssertFalse([eventTimeline canPaginate:MXTimelineDirectionBackwards]); - // XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); // @TODO + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); [expectation fulfill]; @@ -272,5 +281,95 @@ - (void)testBackPaginationOnPastTimeline } +- (void)testForwardPaginationOnPastTimeline +{ + [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { + + MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + + NSMutableArray *events = [NSMutableArray array]; + [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + + if (events.count == 0) + { + XCTAssertEqualObjects(event.eventId, initialEventId, @"The first returned event must be the initial event"); + XCTAssertEqualObjects(event.content[@"body"], theInitialEventMessage); + } + + if (direction == MXTimelineDirectionForwards) + { + [events addObject:event]; + } + else + { + [events insertObject:event atIndex:0]; + } + + }]; + + [eventTimeline resetPaginationAroundInitialEventWithLimit:10 success:^{ + + XCTAssertEqual(events.count, 11, @"5 + 1 + 5 = 11"); + + // Get some messages in the past + [eventTimeline paginate:10 direction:MXTimelineDirectionForwards onlyFromStore:NO complete:^{ + + XCTAssertEqual(events.count, 21, @"5 + 1 + 5 + 10 = 21"); + + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } + + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionForwards]); + + // Get all past messages + [eventTimeline paginate:100 direction:MXTimelineDirectionForwards onlyFromStore:NO complete:^{ + + XCTAssertEqual(events.count, 26, @"5 + 1 + 20 = 26"); + + // Do one more request to test end + [eventTimeline paginate:1 direction:MXTimelineDirectionForwards onlyFromStore:NO complete:^{ + + // Check events order + uint64_t prev_ts = 0; + for (MXEvent *event in events) + { + XCTAssertGreaterThanOrEqual(event.originServerTs, prev_ts, @"The events order is wrong"); + prev_ts = event.originServerTs; + } + + XCTAssert([eventTimeline canPaginate:MXTimelineDirectionBackwards]); + XCTAssertFalse([eventTimeline canPaginate:MXTimelineDirectionForwards]); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"The operation should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + }]; + +} @end From 3bd9406fb1e159f52021c22544d0f0f91ecefb37 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 1 Mar 2016 08:33:13 +0100 Subject: [PATCH 74/80] Event timeline: the notify param of the addEvent method is no more useful. The SDK notify its user about all events it gets for the timeline --- MatrixSDK/Data/MXEventTimeline.m | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 1183b2cd8f..429f25fe43 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -147,16 +147,16 @@ - (MXHTTPOperation *)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limi // Reset pagination state from here [self resetPagination]; - [self addEvent:eventContext.event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + [self addEvent:eventContext.event direction:MXTimelineDirectionForwards fromStore:NO]; for (MXEvent *event in eventContext.eventsBefore) { - [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:NO]; } for (MXEvent *event in eventContext.eventsAfter) { - [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO]; } [store storePaginationTokenOfRoom:room.roomId andToken:eventContext.start]; @@ -197,7 +197,7 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio for (NSInteger i = messagesFromStoreCount - 1; i >= 0; i--) { MXEvent *event = messagesFromStore[i]; - [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:YES notify:YES]; + [self addEvent:event direction:MXTimelineDirectionBackwards fromStore:YES]; } numItems -= messagesFromStoreCount; @@ -333,7 +333,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync event.roomId = _state.roomId; // Add the event to the end of the timeline - [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO]; } // Check whether we got all history from the home server @@ -357,7 +357,7 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync event.roomId = _state.roomId; // Add the event to the end of the timeline - [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO]; } } @@ -398,7 +398,7 @@ - (void)handleInvitedRoomSync:(MXInvitedRoomSync *)invitedRoomSync // Report the room id in the event as it is skipped in /sync response event.roomId = _state.roomId; - [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO notify:YES]; + [self addEvent:event direction:MXTimelineDirectionForwards fromStore:NO]; } } @@ -422,7 +422,7 @@ - (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse direct for (MXEvent *event in paginatedResponse.chunk) { // Make sure we have not processed this event yet - [self addEvent:event direction:direction fromStore:NO notify:YES]; + [self addEvent:event direction:direction fromStore:NO]; } // And update pagination tokens @@ -451,9 +451,8 @@ - (void)handlePaginationResponse:(MXPaginationResponse*)paginatedResponse direct @param direction the direction indicates if the event must added to the start or to the end of the timeline. @param fromStore YES if the messages have been loaded from the store. In this case, there is no need to store it again in the store - @param notify YES to notify listeners. */ -- (void)addEvent:(MXEvent*)event direction:(MXTimelineDirection)direction fromStore:(BOOL)fromStore notify:(BOOL)notify +- (void)addEvent:(MXEvent*)event direction:(MXTimelineDirection)direction fromStore:(BOOL)fromStore { // Make sure we have not processed this event yet if (fromStore == NO && [store eventExistsWithEventId:event.eventId inRoom:room.roomId]) @@ -501,10 +500,7 @@ - (void)addEvent:(MXEvent*)event direction:(MXTimelineDirection)direction fromSt } // Notify listeners - if (notify) - { - [self notifyListeners:event direction:direction]; - } + [self notifyListeners:event direction:direction]; } #pragma mark - Specific events Handling From 42a460acfb15df032c645e5a6c29c4d939c3373c Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 1 Mar 2016 08:56:44 +0100 Subject: [PATCH 75/80] Event timeline: Added destroy method. Renamed [MXRoom openTimelineOnEvent] to [MXRoom timelineOnEvent] --- MatrixSDK/Data/MXEventTimeline.h | 5 +++++ MatrixSDK/Data/MXEventTimeline.m | 9 +++++++++ MatrixSDK/Data/MXRoom.h | 10 +--------- MatrixSDK/Data/MXRoom.m | 7 +------ MatrixSDKTests/MXEventTimelineTests.m | 8 ++++---- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/MatrixSDK/Data/MXEventTimeline.h b/MatrixSDK/Data/MXEventTimeline.h index cb8f619157..4055a504f1 100644 --- a/MatrixSDK/Data/MXEventTimeline.h +++ b/MatrixSDK/Data/MXEventTimeline.h @@ -103,6 +103,11 @@ typedef void (^MXOnRoomEvent)(MXEvent *event, MXTimelineDirection direction, MXR */ - (void)initialiseState:(NSArray *)stateEvents; +/** + Release RAM memory used by the timeline. + */ +- (void)destroy; + #pragma mark - Pagination /** diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 429f25fe43..071f44bc90 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -89,6 +89,15 @@ - (void)initialiseState:(NSArray *)stateEvents } } +- (void)destroy +{ + if (!_isLiveTimeline) + { + // Release past timeline events stored in memory + [store deleteAllData]; + } +} + #pragma mark - Pagination - (BOOL)canPaginate:(MXTimelineDirection)direction diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index f803d10039..69cfa57e43 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -379,15 +379,7 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; @param eventId the id of the event. @return a new `MXEventTimeline` instance. */ -- (MXEventTimeline*)openTimelineOnEvent:(NSString*)eventId; - -/** - Close a `MXEventTimeline` instance. - All attached listeners are unregitered. - - @param eventTimeline the timeline to close. - */ -- (void)closeTimeline:(MXEventTimeline*)eventTimeline; +- (MXEventTimeline*)timelineOnEvent:(NSString*)eventId; #pragma mark - Outgoing events management diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 2ffd401d97..163a2788cf 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -314,16 +314,11 @@ - (MXHTTPOperation*)redactEvent:(NSString*)eventId #pragma mark - Events timeline -- (MXEventTimeline*)openTimelineOnEvent:(NSString*)eventId; +- (MXEventTimeline*)timelineOnEvent:(NSString*)eventId; { return [[MXEventTimeline alloc] initWithRoom:self andInitialEventId:eventId]; } --(void)closeTimeline:(MXEventTimeline *)eventTimeline -{ - // @TODO -} - #pragma mark - Outgoing events management - (void)storeOutgoingMessage:(MXEvent*)outgoingMessage diff --git a/MatrixSDKTests/MXEventTimelineTests.m b/MatrixSDKTests/MXEventTimelineTests.m index 2539a574a4..fca83e57f9 100644 --- a/MatrixSDKTests/MXEventTimelineTests.m +++ b/MatrixSDKTests/MXEventTimelineTests.m @@ -79,7 +79,7 @@ - (void)testResetPaginationAroundInitialEventWithLimit { [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { - MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + MXEventTimeline *eventTimeline = [room timelineOnEvent:initialEventId]; NSMutableArray *events = [NSMutableArray array]; [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { @@ -130,7 +130,7 @@ - (void)testDoubleResetPaginationAroundInitialEventWithLimit { [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { - MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + MXEventTimeline *eventTimeline = [room timelineOnEvent:initialEventId]; NSMutableArray *events = [NSMutableArray array]; [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { @@ -192,7 +192,7 @@ - (void)testBackPaginationOnPastTimeline { [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { - MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + MXEventTimeline *eventTimeline = [room timelineOnEvent:initialEventId]; NSMutableArray *events = [NSMutableArray array]; [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { @@ -285,7 +285,7 @@ - (void)testForwardPaginationOnPastTimeline { [self doTestWithARoomOf41Messages:self readyToTest:^(MXRoom *room, XCTestExpectation *expectation, NSString *initialEventId) { - MXEventTimeline *eventTimeline = [room openTimelineOnEvent:initialEventId]; + MXEventTimeline *eventTimeline = [room timelineOnEvent:initialEventId]; NSMutableArray *events = [NSMutableArray array]; [eventTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { From 4909c9fc04d7b758262f575125ef7511723c129d Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 1 Mar 2016 10:15:41 +0100 Subject: [PATCH 76/80] Event timeline: Update after code review. The main change is do not try to paginate forward if end has been reached --- MatrixSDK/Data/MXEventTimeline.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 071f44bc90..69a19a028b 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -139,6 +139,7 @@ - (void)resetPagination - (MXHTTPOperation *)resetPaginationAroundInitialEventWithLimit:(NSUInteger)limit success:(void (^)())success failure:(void (^)(NSError *))failure { + NSParameterAssert(success); NSAssert(_initialEventId, @"[MXEventTimeline] resetPaginationAroundInitialEventWithLimit cannot be called on live timeline"); // Reset the store @@ -231,6 +232,16 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio } } + // Do not try to paginate forward if end has been reached + if (direction == MXTimelineDirectionForwards && YES == hasReachedHomeServerForwardsPaginationEnd) + { + // Nothing more to do + complete(); + + NSLog(@"[MXEventTimeline] paginate: is done"); + return nil; + } + // Not enough messages: make a pagination request to the home server // from last known token NSString *paginationToken; From 74cb653b0e3562eceda834091d827e3eca1b336e Mon Sep 17 00:00:00 2001 From: giomfo Date: Thu, 3 Mar 2016 09:14:23 +0100 Subject: [PATCH 77/80] BugFix SYIOS-202: IOS should no longer reset badge count on launch. --- MatrixSDK/Data/MXRoom.h | 18 ++++++++++++--- MatrixSDK/Data/MXRoom.m | 14 ++++++++++-- .../Store/MXCoreDataStore/MXCoreDataStore.m | 4 ++-- .../Data/Store/MXMemoryStore/MXMemoryStore.m | 10 ++++----- MatrixSDK/Data/Store/MXNoStore/MXNoStore.m | 16 ++------------ MatrixSDK/Data/Store/MXStore.h | 6 ++--- MatrixSDK/JSONModels/MXJSONModels.h | 22 +++++++++++++++++++ MatrixSDK/JSONModels/MXJSONModels.m | 16 ++++++++++++++ 8 files changed, 77 insertions(+), 29 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.h b/MatrixSDK/Data/MXRoom.h index 69cfa57e43..d7e94a4421 100644 --- a/MatrixSDK/Data/MXRoom.h +++ b/MatrixSDK/Data/MXRoom.h @@ -99,10 +99,22 @@ FOUNDATION_EXPORT NSString *const kMXRoomSyncWithLimitedTimelineNotification; - (MXEvent*)lastMessageWithTypeIn:(NSArray*)type; /** - The unread events. - They are filtered by acknowledgableEventTypes. + Tell whether the room has unread events. + This value depends on acknowledgableEventTypes. */ -@property (nonatomic, readonly) NSArray* unreadEvents; +@property (nonatomic, readonly) BOOL hasUnreadEvents; + +/** + The number of unread messages that match the push notification rules. + It is based on the notificationCount field in /sync response. + */ +@property (nonatomic, readonly) NSUInteger notificationCount; + +/** + The number of highlighted unread messages (subset of notifications). + It is based on the notificationCount field in /sync response. + */ +@property (nonatomic, readonly) NSUInteger highlightCount; /** * An array of event types strings (MXEventTypeString). diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index 163a2788cf..f8467967b2 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -135,6 +135,10 @@ - (void)handleJoinedRoomSync:(MXRoomSync *)roomSync [self handleReceiptEvent:event direction:MXTimelineDirectionForwards]; } } + + // Update bing counts from the notificationCount field in /sync response + _notificationCount = roomSync.unreadNotifications.notificationCount; + _highlightCount = roomSync.unreadNotifications.highlightCount; // Handle account data events (if any) [self handleAccounDataEvents:roomSync.accountData.events direction:MXTimelineDirectionForwards]; @@ -514,9 +518,15 @@ - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; return NO; } --(NSArray*) unreadEvents +- (BOOL)hasUnreadEvents { - return [mxSession.store unreadEvents:self.state.roomId withTypeIn:_acknowledgableEventTypes]; + if (_notificationCount) + { + return YES; + } + + // Else check for unread events in store + return [mxSession.store hasUnreadEvents:self.state.roomId withTypeIn:_acknowledgableEventTypes]; } - (NSArray*)getEventReceipts:(NSString*)eventId sorted:(BOOL)sort diff --git a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m index 0bee43e0ba..e04a0cd6ba 100644 --- a/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m +++ b/MatrixSDK/Data/Store/MXCoreDataStore/MXCoreDataStore.m @@ -336,10 +336,10 @@ - (BOOL)storeReceipt:(MXReceiptData*)receipt roomId:(NSString*)roomId return NO; } -- (NSArray*)unreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types +- (BOOL)hasUnreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types { // TODO - return nil; + return NO; } - (BOOL)isPermanent diff --git a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m index d9aed012c7..077cd0fbf2 100644 --- a/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m +++ b/MatrixSDK/Data/Store/MXMemoryStore/MXMemoryStore.m @@ -220,7 +220,7 @@ - (BOOL)storeReceipt:(MXReceiptData*)receipt roomId:(NSString*)roomId return false; } -- (NSArray*)unreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types +- (BOOL)hasUnreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types { MXMemoryRoomStore* store = [roomStores valueForKey:roomId]; NSMutableDictionary* receipsByUserId = [receiptsByRoomId objectForKey:roomId]; @@ -231,13 +231,13 @@ - (NSArray*)unreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types if (data) { - // ignore oneself events - // assume you read what you wrote - return [store eventsAfter:data.eventId except:credentials.userId withTypeIn:[NSSet setWithArray:types]]; + // Check the current stored events (by ignoring oneself events) + NSArray *array = [store eventsAfter:data.eventId except:credentials.userId withTypeIn:[NSSet setWithArray:types]]; + return (array.count != 0); } } - return nil; + return NO; } - (BOOL)isPermanent diff --git a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m index bffad45296..c163af8ff3 100644 --- a/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m +++ b/MatrixSDK/Data/Store/MXNoStore/MXNoStore.m @@ -211,26 +211,14 @@ - (NSArray*)getEventReceipts:(NSString*)roomId eventId:(NSString*)eventId sorted return nil; } -/** - * Store the receipt for an user in a room - * @param receipt The event - * @param roomId The roomId - * @return true if the receipt has been stored - */ - (BOOL)storeReceipt:(MXReceiptData*)receipt roomId:(NSString*)roomId { return NO; } -/** - * Provides the unread events list. - * @param roomId the room id. - * @param types an array of event types strings (MXEventTypeString). - * @return the unread events list. - */ -- (NSArray*)unreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types +- (BOOL)hasUnreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types { - return nil; + return NO; } diff --git a/MatrixSDK/Data/Store/MXStore.h b/MatrixSDK/Data/Store/MXStore.h index 092aab5fc7..94daae3a0e 100644 --- a/MatrixSDK/Data/Store/MXStore.h +++ b/MatrixSDK/Data/Store/MXStore.h @@ -190,12 +190,12 @@ - (BOOL)storeReceipt:(MXReceiptData*)receipt roomId:(NSString*)roomId; /** - * Provides the unread events list. + * Check whether a room has some unread events. * @param roomId the room id. * @param types an array of event types strings (MXEventTypeString). - * @return the unread events list. + * @return YES if at least one stored event has its type listed in provided array. */ -- (NSArray*)unreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types; +- (BOOL)hasUnreadEvents:(NSString*)roomId withTypeIn:(NSArray*)types; /** Indicate if the MXStore implementation stores data permanently. diff --git a/MatrixSDK/JSONModels/MXJSONModels.h b/MatrixSDK/JSONModels/MXJSONModels.h index fa459bb782..139822cb20 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.h +++ b/MatrixSDK/JSONModels/MXJSONModels.h @@ -955,6 +955,23 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; @end +/** + `MXRoomSyncUnreadNotifications` represents the unread counts for a room. + */ +@interface MXRoomSyncUnreadNotifications : MXJSONModel + + /** + The number of unread messages that match the push notification rules. + */ + @property (nonatomic) NSUInteger notificationCount; + + /** + The number of highlighted unread messages (subset of notifications). + */ + @property (nonatomic) NSUInteger highlightCount; + +@end + /** `MXRoomSync` represents the response for a room during server sync. */ @@ -980,6 +997,11 @@ FOUNDATION_EXPORT NSString *const kMXPushRuleScopeStringDevice; */ @property (nonatomic) MXRoomSyncAccountData *accountData; + /** + The notification counts for the room. + */ + @property (nonatomic) MXRoomSyncUnreadNotifications *unreadNotifications; + @end /** diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index deeccf50fb..357e1972a7 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -857,6 +857,21 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary @end +@implementation MXRoomSyncUnreadNotifications + ++ (id)modelFromJSON:(NSDictionary *)JSONDictionary +{ + MXRoomSyncUnreadNotifications *roomSyncUnreadNotifications = [[MXRoomSyncUnreadNotifications alloc] init]; + if (roomSyncUnreadNotifications) + { + MXJSONModelSetUInteger(roomSyncUnreadNotifications.notificationCount, JSONDictionary[@"notification_count"]); + MXJSONModelSetUInteger(roomSyncUnreadNotifications.highlightCount, JSONDictionary[@"highlight_count"]); + } + return roomSyncUnreadNotifications; +} + +@end + @implementation MXRoomSync + (id)modelFromJSON:(NSDictionary *)JSONDictionary @@ -868,6 +883,7 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary MXJSONModelSetMXJSONModel(roomSync.timeline, MXRoomSyncTimeline, JSONDictionary[@"timeline"]); MXJSONModelSetMXJSONModel(roomSync.ephemeral, MXRoomSyncEphemeral, JSONDictionary[@"ephemeral"]); MXJSONModelSetMXJSONModel(roomSync.accountData, MXRoomSyncAccountData, JSONDictionary[@"account_data"]); + MXJSONModelSetMXJSONModel(roomSync.unreadNotifications, MXRoomSyncUnreadNotifications, JSONDictionary[@"unread_notifications"]); } return roomSync; } From df037e8aa7e39373c8b216c316860446a1ac07ee Mon Sep 17 00:00:00 2001 From: giomfo Date: Fri, 4 Mar 2016 14:46:30 +0100 Subject: [PATCH 78/80] BugFix: Corrupted unread status in Recents. On Matrix console, some one to one room are displayed as unread whereas all messages are read. --- MatrixSDK/Data/MXRoom.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index f8467967b2..c35b247ab3 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -520,12 +520,7 @@ - (BOOL)acknowledgeLatestEvent:(BOOL)sendReceipt; - (BOOL)hasUnreadEvents { - if (_notificationCount) - { - return YES; - } - - // Else check for unread events in store + // Check for unread events in store return [mxSession.store hasUnreadEvents:self.state.roomId withTypeIn:_acknowledgableEventTypes]; } From d243d6ee33b82212c1f030e97280b947b3ebea85 Mon Sep 17 00:00:00 2001 From: giomfo Date: Mon, 7 Mar 2016 10:22:21 +0100 Subject: [PATCH 79/80] Bug Fix: iOS Console crashes on incoming call --- MatrixSDK/JSONModels/MXJSONModels.m | 11 +++++++++++ MatrixSDK/VoIP/MXCall.m | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/MatrixSDK/JSONModels/MXJSONModels.m b/MatrixSDK/JSONModels/MXJSONModels.m index 357e1972a7..c551e1b6a2 100644 --- a/MatrixSDK/JSONModels/MXJSONModels.m +++ b/MatrixSDK/JSONModels/MXJSONModels.m @@ -1024,6 +1024,17 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary return callCandidate; } +- (NSDictionary *)JSONDictionary +{ + NSMutableDictionary *JSONDictionary = [NSMutableDictionary dictionary]; + + JSONDictionary[@"sdpMid"] = _sdpMid; + JSONDictionary[@"sdpMLineIndex"] = @(_sdpMLineIndex); + JSONDictionary[@"candidate"] = _candidate; + + return JSONDictionary; +} + @end @implementation MXCallCandidatesEventContent diff --git a/MatrixSDK/VoIP/MXCall.m b/MatrixSDK/VoIP/MXCall.m index 3a7bdb592a..9d9fa923a3 100644 --- a/MatrixSDK/VoIP/MXCall.m +++ b/MatrixSDK/VoIP/MXCall.m @@ -181,9 +181,9 @@ - (void)handleCallEvent:(MXEvent *)event MXCallCandidatesEventContent *content = [MXCallCandidatesEventContent modelFromJSON:event.content]; NSLog(@"[MXCall] handleCallCandidates: %@", content.candidates); - for (NSDictionary *canditate in content.candidates) + for (MXCallCandidate *canditate in content.candidates) { - [callStackCall handleRemoteCandidate:canditate]; + [callStackCall handleRemoteCandidate:canditate.JSONDictionary]; } break; } From e4f492911f0ae63e88941bc47b9d55c5ab313f41 Mon Sep 17 00:00:00 2001 From: giomfo Date: Mon, 7 Mar 2016 17:09:43 +0100 Subject: [PATCH 80/80] Prepare matrix-ios-sdk release v0.6.3 --- CHANGES.rst | 20 ++++++++++++++++++++ MatrixSDK.podspec | 4 ++-- MatrixSDK/MXSession.m | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c0d3387659..03b624f6de 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,23 @@ +Changes in Matrix iOS SDK in 0.6.3 (2016-03-07) +=============================================== + +Improvements: + * Moving to r0 API: Replace calls to v1 and v2_alpha apis by r0, which is configurable via MXRestClient.apiPathPrefix. + * MXEventContext: Add C-S API to handle event context. + * MXEventTimeline: Created MXEventTimeline to manage a list of continuous events. MXRoom has now a liveTimeline property that manages live events and state of the room. MXEventTimeline is able to manage live events and events that will come from the event context API. + * MXEventDirection* has been renamed to MXTimelineDirection*. + * MXEventTimeline: Support backward/forward pagination around a past event. + * MXRestClient: the messagesForRoom method has been updated to conform r0 C-S API. The "to" parameter has been replaced by the "direction" parameter. + * MXRoom: Replace the inaccurate 'unreadEvents' array with a boolean flag 'hasUnreadEvents'. + * MXRoom: Add 'notificationCount' and 'highlightCount' based on the notificationCount field in /sync response. + * SDK Tests: Update and fix tests. + +Bug fixes: + * Support email login. + * Room ordering: a tagged room with no order value must have higher priority than the tagged rooms with order value. + * SYIOS-208: [MXSession startWithMessagesLimit]: if defined, the limit argument is now passed to /sync request. + * SYIOS-207: Removed MXEventDirectionSync which became useless. + Changes in Matrix iOS SDK in 0.6.2 (2016-02-09) =============================================== diff --git a/MatrixSDK.podspec b/MatrixSDK.podspec index 369b2114ec..dc2a5f0a99 100644 --- a/MatrixSDK.podspec +++ b/MatrixSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixSDK" - s.version = "0.6.2" + s.version = "0.6.3" s.summary = "The iOS SDK to build apps compatible with Matrix (http://www.matrix.org)" s.description = <<-DESC @@ -19,7 +19,7 @@ Pod::Spec.new do |s| s.platform = :ios, "7.0" - s.source = { :git => "https://github.com/matrix-org/matrix-ios-sdk.git", :tag => "v0.6.2" } + s.source = { :git => "https://github.com/matrix-org/matrix-ios-sdk.git", :tag => "v0.6.3" } s.source_files = "MatrixSDK", "MatrixSDK/**/*.{h,m}" s.resources = "MatrixSDK/Data/Store/MXCoreDataStore/*.xcdatamodeld" diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index 7bbed4c2cc..6922e27b1b 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -28,7 +28,7 @@ #pragma mark - Constants definitions -const NSString *MatrixSDKVersion = @"0.6.2"; +const NSString *MatrixSDKVersion = @"0.6.3"; NSString *const kMXSessionStateDidChangeNotification = @"kMXSessionStateDidChangeNotification"; NSString *const kMXSessionNewRoomNotification = @"kMXSessionNewRoomNotification"; NSString *const kMXSessionWillLeaveRoomNotification = @"kMXSessionWillLeaveRoomNotification";