diff --git a/CHANGES.rst b/CHANGES.rst index 7074d03520..8228ab40b2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -13,6 +13,7 @@ Improvements: Bug fix: * MXEvent: Move `invite_room_state` to the correct place in the client-server API (vector-im/riot-ios/issues/2010). * MXRoomSummaryUpdater: Fix minor issue in updateSummaryAvatar method. +* Left room is still displayed as "Empty room" in rooms list (vector-im/riot-ios/issues/2082). Changes in Matrix iOS SDK in 0.11.5 (2018-10-05) =============================================== diff --git a/MatrixSDK/Data/MXEventTimeline.m b/MatrixSDK/Data/MXEventTimeline.m index 7e078a38b0..577eabe9a4 100644 --- a/MatrixSDK/Data/MXEventTimeline.m +++ b/MatrixSDK/Data/MXEventTimeline.m @@ -331,7 +331,11 @@ - (MXHTTPOperation *)paginate:(NSUInteger)numItems direction:(MXTimelineDirectio NSLog(@"[MXEventTimeline] paginate : got %tu messages from the server", paginatedResponse.chunk.count); - [self handlePaginationResponse:paginatedResponse direction:direction]; + // Check if the room has not been left while waiting for the response + if ([self->room.mxSession hasRoomWithRoomId:self->room.roomId]) + { + [self handlePaginationResponse:paginatedResponse direction:direction]; + } // Inform the method caller complete(); diff --git a/MatrixSDK/Data/MXRoom.m b/MatrixSDK/Data/MXRoom.m index e51a1ce12b..78d7345045 100644 --- a/MatrixSDK/Data/MXRoom.m +++ b/MatrixSDK/Data/MXRoom.m @@ -270,12 +270,16 @@ - (MXHTTPOperation*)members:(void (^)(MXRoomMembers *members))success } roomMemberEvents = updatedRoomMemberEvents; - [liveTimeline handleLazyLoadedStateEvents:roomMemberEvents]; - - [self.mxSession.store storeHasLoadedAllRoomMembersForRoom:self.roomId andValue:YES]; - if ([self.mxSession.store respondsToSelector:@selector(commit)]) + // Check if the room has not been left while waiting for the response + if ([self.mxSession hasRoomWithRoomId:self.roomId]) { - [self.mxSession.store commit]; + [liveTimeline handleLazyLoadedStateEvents:roomMemberEvents]; + + [self.mxSession.store storeHasLoadedAllRoomMembersForRoom:self.roomId andValue:YES]; + if ([self.mxSession.store respondsToSelector:@selector(commit)]) + { + [self.mxSession.store commit]; + } } // Provide the timelime to pending requesters diff --git a/MatrixSDK/MXSession.h b/MatrixSDK/MXSession.h index d0db5e93a3..0d8dc78da9 100644 --- a/MatrixSDK/MXSession.h +++ b/MatrixSDK/MXSession.h @@ -749,6 +749,15 @@ typedef void (^MXOnBackgroundSyncFail)(NSError *error); #pragma mark - The user's rooms +/** + Check if the user is in a room + + @param roomId The room id to the room. + + @return YES if they are. + */ +- (BOOL)hasRoomWithRoomId:(NSString*)roomId; + /** Get the MXRoom instance of a room. diff --git a/MatrixSDK/MXSession.m b/MatrixSDK/MXSession.m index cf39889165..54fbcde30f 100644 --- a/MatrixSDK/MXSession.m +++ b/MatrixSDK/MXSession.m @@ -1867,6 +1867,11 @@ - (MXHTTPOperation*)leaveRoom:(NSString*)roomId #pragma mark - The user's rooms +- (BOOL)hasRoomWithRoomId:(NSString*)roomId +{ + return (rooms[roomId] != nil); +} + - (MXRoom *)roomWithRoomId:(NSString *)roomId { // sanity check diff --git a/MatrixSDKTests/MXLazyLoadingTests.m b/MatrixSDKTests/MXLazyLoadingTests.m index 6a714a0554..e4b453e56e 100644 --- a/MatrixSDKTests/MXLazyLoadingTests.m +++ b/MatrixSDKTests/MXLazyLoadingTests.m @@ -20,6 +20,7 @@ #import "MXSDKOptions.h" #import "MXHTTPClient_Private.h" +#import "MXFileStore.h" // Do not bother with retain cycles warnings in tests #pragma clang diagnostic push @@ -790,6 +791,143 @@ - (void)testRoomAfterLeavingFromAnotherDeviceWithLazyLoadingOFF } +// Complementary test to testRoomAfterLeavingFromAnotherDevice to check +// the regression described at https://github.com/vector-im/riot-ios/issues/2082: +// - Run the scenario +// - Restart Alice session with a permanent store (MXFileStore) +// - Alice requests all members from the HS +// - and make a pagination request, because there is a bug here too +// - Meanwhile, Alice leaves the room +// - Close and reopen Alice session +// -> Alice must not know the room anymore +- (void)checkRoomAfterLeavingWithLazyLoading:(BOOL)lazyLoading +{ + // - Run the scenario + [self createScenarioWithLazyLoading:lazyLoading readyToTest:^(MXSession *aliceSession, MXSession *bobSession, MXSession *charlieSession, NSString *roomId, XCTestExpectation *expectation) { + + MXRoom *room = [aliceSession roomWithRoomId:roomId]; + MXRoomSummary *summary = [aliceSession roomSummaryWithRoomId:roomId]; + XCTAssertNotNil(room); + XCTAssertNotNil(summary); + + // - Restart Alice session with a permanent store (MXFileStore) + MXRestClient *aliceRestClient = aliceSession.matrixRestClient; + [aliceSession close]; + aliceSession = nil; + + MXFileStore *store = [[MXFileStore alloc] init]; + __block MXSession *aliceSession2 = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; + [aliceSession2 setStore:store success:^{ + [aliceSession2 start:^{ + + MXRoom *room2 = [aliceSession2 roomWithRoomId:roomId]; + MXRoomSummary *summary2 = [aliceSession2 roomSummaryWithRoomId:roomId]; + XCTAssertNotNil(room2); + XCTAssertNotNil(summary2); + + [room2 liveTimeline:^(MXEventTimeline *liveTimeline) { + + // - Alice requests all members from the HS + // Force [MXRoom members:] to make a request + [aliceSession2.store storeHasLoadedAllRoomMembersForRoom:roomId andValue:NO]; + + [MXHTTPClient setDelay:1000 toRequestsContainingString:@"/members"]; + [room2 members:^(MXRoomMembers *members) { + + MXRoom *room2a = [aliceSession2 roomWithRoomId:roomId]; + MXRoomSummary *summary2a = [aliceSession2 roomSummaryWithRoomId:roomId]; + XCTAssertNil(room2a); + XCTAssertNil(summary2a); + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + + + // - and a pagination request, because there is a bug here too + [MXHTTPClient setDelay:1000 toRequestsContainingString:@"/messages"]; + [liveTimeline resetPagination]; + [liveTimeline paginate:30 direction:MXTimelineDirectionBackwards onlyFromStore:NO complete:^{ + + MXRoom *room2a = [aliceSession2 roomWithRoomId:roomId]; + MXRoomSummary *summary2a = [aliceSession2 roomSummaryWithRoomId:roomId]; + XCTAssertNil(room2a); + XCTAssertNil(summary2a); + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + + + // - Meanwhile, she leaves the room + [room2 leave:^{ + + // Let time for the pagination to complete + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2000 * USEC_PER_SEC), dispatch_get_main_queue(), ^{ + + // Keep a ref to room2 so that requests on it can complete + NSLog(@"%@", room2); + + MXRoom *room2b = [aliceSession2 roomWithRoomId:roomId]; + MXRoomSummary *summary2b = [aliceSession2 roomSummaryWithRoomId:roomId]; + XCTAssertNil(room2b); + XCTAssertNil(summary2b); + + // - Close and reopen Alice session + [aliceSession2 close]; + aliceSession2 = nil; + + MXFileStore *store = [[MXFileStore alloc] init]; + MXSession *aliceSession3 = [[MXSession alloc] initWithMatrixRestClient:aliceRestClient]; + [aliceSession3 setStore:store success:^{ + [aliceSession3 start:^{ + + // -> Alice must not know the room anymore + MXRoom *room3 = [aliceSession3 roomWithRoomId:roomId]; + MXRoomSummary *summary3 = [aliceSession3 roomSummaryWithRoomId:roomId]; + XCTAssertNil(room3); + XCTAssertNil(summary3); + + [expectation fulfill]; + + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + }); + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + }]; + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + } failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + }]; +} + +- (void)testRoomAfterLeaving +{ + [self checkRoomAfterLeavingWithLazyLoading:YES]; +} + +- (void)testRoomAfterLeavingWithLazyLoadingOFF +{ + [self checkRoomAfterLeavingWithLazyLoading:NO]; +} + + // roomSummary.membersCount must be right in both cases - (void)checkRoomSummaryMembersCountWithLazyLoading:(BOOL)lazyLoading {