diff --git a/Tests/ARTRealtimePresenceTest.m b/Tests/ARTRealtimePresenceTest.m index 86d697df4..db2435951 100644 --- a/Tests/ARTRealtimePresenceTest.m +++ b/Tests/ARTRealtimePresenceTest.m @@ -230,16 +230,19 @@ - (void)testEnterLeaveSimple { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence leave:presenceLeave callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } if(message.action == ARTPresenceLeave) { XCTAssertEqualObjects([message data], presenceLeave); - [expectation fulfill]; + partialExpectationFulfill(); } }]; @@ -269,16 +272,19 @@ - (void)testEnterEnter { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence enter:secondEnter callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceUpdate) { XCTAssertEqualObjects([message data], secondEnter); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [realtime.connection on:^(ARTConnectionStateChange *stateChange) { @@ -307,16 +313,19 @@ - (void)testEnterUpdateSimple { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence update:update callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceUpdate) { XCTAssertEqualObjects([message data], update); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [realtime.connection on:^(ARTConnectionStateChange *stateChange) { @@ -344,16 +353,19 @@ - (void)testUpdateNull { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence update:nil callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceUpdate) { XCTAssertEqualObjects([message data], nil); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [realtime.connection on:^(ARTConnectionStateChange *stateChange) { @@ -383,16 +395,19 @@ - (void)testEnterLeaveWithoutData { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:channelName]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if (message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], presenceEnter); [channel.presence leave:@"" callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } if (message.action == ARTPresenceLeave) { XCTAssertEqualObjects([message data], presenceEnter); - [expectation fulfill]; + partialExpectationFulfill(); } }]; @@ -574,16 +589,19 @@ - (void)testLeaveNoData { __weak XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"%s", __FUNCTION__]]; ARTRealtime *realtime = [[ARTRealtime alloc] initWithOptions:options]; ARTRealtimeChannel *channel = [realtime.channels get:@"testEnterLeaveNoData"]; + void(^partialExpectationFulfill)(void) = [ARTTestUtil splitFulfillFrom:self expectation:expectation in:2]; [channel.presence subscribe:^(ARTPresenceMessage *message) { if(message.action == ARTPresenceEnter) { XCTAssertEqualObjects([message data], enter); [channel.presence leave:@"" callback:^(ARTErrorInfo *errorInfo) { XCTAssertNil(errorInfo); + // Should wait for the publishing acknowledgement + partialExpectationFulfill(); }]; } else if(message.action == ARTPresenceLeave) { XCTAssertEqualObjects([message data], enter); - [expectation fulfill]; + partialExpectationFulfill(); } }]; [channel attach]; diff --git a/Tests/ARTTestUtil.h b/Tests/ARTTestUtil.h index 3c437d935..b6bcf2d07 100644 --- a/Tests/ARTTestUtil.h +++ b/Tests/ARTTestUtil.h @@ -73,6 +73,8 @@ typedef void (^ARTRealtimeConstructorCb)(ARTRealtime *realtime); + (void)waitForWithTimeout:(NSUInteger *_Nonnull)counter list:(NSArray *)list timeout:(NSTimeInterval)timeout; + (void)delay:(NSTimeInterval)timeout block:(dispatch_block_t)block; ++ (void(^)())splitFulfillFrom:(XCTestCase *)testCase expectation:(XCTestExpectation *)expectation in:(NSInteger)howMany; + @end ART_ASSUME_NONNULL_END diff --git a/Tests/ARTTestUtil.m b/Tests/ARTTestUtil.m index f93388a62..78b7516f1 100644 --- a/Tests/ARTTestUtil.m +++ b/Tests/ARTTestUtil.m @@ -316,4 +316,16 @@ + (ARTClientOptions *)newSandboxApp:(XCTestCase *)testCase withDescription:(cons return options; } ++ (void(^)())splitFulfillFrom:(XCTestCase *)testCase expectation:(XCTestExpectation *)expectation in:(NSInteger)howMany { + __block NSInteger left = howMany; + return ^{ + left--; + if (left == 0) { + [expectation fulfill]; + } else if (left < 0) { + _XCTPrimitiveFail(testCase, @"%s called more than the expected %ld times", __FUNCTION__, (long)howMany); + } + }; +} + @end