| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661 |
- /*
- * Copyright 2017 Google
- *
- * 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 XCTest;
- #import <OCMock/OCMock.h>
- #import "Protos/GtalkCore.pbobjc.h"
- #import "FIRMessaging.h"
- #import "FIRMessagingClient.h"
- #import "FIRMessagingConnection.h"
- #import "FIRMessagingDataMessageManager.h"
- #import "FIRMessagingReceiver.h"
- #import "FIRMessagingRmqManager.h"
- #import "FIRMessagingSyncMessageManager.h"
- #import "FIRMessagingUtilities.h"
- #import "FIRMessaging_Private.h"
- #import "FIRMessagingConstants.h"
- #import "FIRMessagingDefines.h"
- #import "NSError+FIRMessaging.h"
- static NSString *const kFIRMessagingUserDefaultsSuite = @"FIRMessagingClientTestUserDefaultsSuite";
- static NSString *const kFIRMessagingAppIDToken = @"1234abcdef789";
- static NSString *const kMessagePersistentID = @"abcdef123";
- static NSString *const kMessageFrom = @"com.example.gcm";
- static NSString *const kMessageTo = @"123456789";
- static NSString *const kCollapseKey = @"collapse-1";
- static NSString *const kAppDataItemKey = @"hello";
- static NSString *const kAppDataItemValue = @"world";
- static NSString *const kAppDataItemInvalidKey = @"google.hello";
- static NSString *const kRmqDatabaseName = @"gcm-dmm-test";
- @interface FIRMessagingDataMessageManager()
- @property(nonatomic, readwrite, weak) FIRMessagingRmqManager *rmq2Manager;
- - (NSString *)categoryForUpstreamMessages;
- @end
- @interface FIRMessagingDataMessageManagerTest : XCTestCase
- @property(nonatomic, readwrite, strong) id mockClient;
- @property(nonatomic, readwrite, strong) id mockRmqManager;
- @property(nonatomic, readwrite, strong) id mockReceiver;
- @property(nonatomic, readwrite, strong) id mockSyncMessageManager;
- @property(nonatomic, readwrite, strong) FIRMessagingDataMessageManager *dataMessageManager;
- @property(nonatomic, readwrite, strong) id mockDataMessageManager;
- @end
- @implementation FIRMessagingDataMessageManagerTest
- - (void)setUp {
- [super setUp];
- _mockClient = OCMClassMock([FIRMessagingClient class]);
- _mockReceiver = OCMClassMock([FIRMessagingReceiver class]);
- _mockRmqManager = OCMClassMock([FIRMessagingRmqManager class]);
- _mockSyncMessageManager = OCMClassMock([FIRMessagingSyncMessageManager class]);
- _dataMessageManager = [[FIRMessagingDataMessageManager alloc]
- initWithDelegate:_mockReceiver
- client:_mockClient
- rmq2Manager:_mockRmqManager
- syncMessageManager:_mockSyncMessageManager];
- [_dataMessageManager refreshDelayedMessages];
- _mockDataMessageManager = OCMPartialMock(_dataMessageManager);
- }
- - (void)testSendValidMessage_withNoConnection {
- // mock no connection initially
- NSString *messageID = @"1";
- BOOL mockConnectionActive = NO;
- [[[self.mockClient stub] andDo:^(NSInvocation *invocation) {
- NSValue *returnValue = [NSValue valueWithBytes:&mockConnectionActive
- objCType:@encode(BOOL)];
- [invocation setReturnValue:&returnValue];
- }] isConnectionActive];
- BOOL(^isValidStanza)(id obj) = ^BOOL(id obj) {
- if ([obj isKindOfClass:[GtalkDataMessageStanza class]]) {
- GtalkDataMessageStanza *message = (GtalkDataMessageStanza *)obj;
- return ([message.id_p isEqualToString:messageID] && [message.to isEqualToString:kMessageTo]);
- }
- return NO;
- };
- OCMExpect([self.mockReceiver willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg isNil]]);
- [[[self.mockRmqManager stub] andReturnValue:@YES]
- saveRmqMessage:[OCMArg checkWithBlock:isValidStanza]
- error:[OCMArg anyObjectRef]];
- // should be logged into the service
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- // try to send messages with no connection should be queued into RMQ
- NSMutableDictionary *message = [self upstreamMessageWithID:messageID ttl:-1 delay:0];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockReceiver);
- OCMVerifyAll(self.mockRmqManager);
- }
- - (void)testSendValidMessage_withoutCheckinAuthentication {
- NSString *messageID = @"1";
- NSMutableDictionary *message = [self standardFIRMessagingMessageWithMessageID:messageID];
- OCMExpect([self.mockReceiver
- willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[NSError class]]) {
- NSError *error = (NSError *)obj;
- return error.code == kFIRMessagingErrorCodeMissingDeviceID;
- }
- return NO;
- }]]);
- // do not log into checkin service
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockReceiver);
- }
- - (void)testSendInvalidMessage_withNoTo {
- NSString *messageID = @"1";
- NSMutableDictionary *message =
- [FIRMessaging createFIRMessagingMessageWithMessage:@{ kAppDataItemKey : kAppDataItemValue}
- to:@""
- withID:messageID
- timeToLive:-1
- delay:0];
- OCMExpect([self.mockReceiver
- willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[NSError class]]) {
- NSError *error = (NSError *)obj;
- return error.code == kFIRMessagingErrorMissingTo;
- }
- return NO;
- }]]);
- // should be logged into the service
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockReceiver);
- }
- - (void)testSendInvalidMessage_withSizeExceeded {
- NSString *messageID = @"1";
- NSString *veryLargeString = [@"a" stringByPaddingToLength:4 * 1024 // 4kB
- withString:@"b"
- startingAtIndex:0];
- NSMutableDictionary *message =
- [FIRMessaging createFIRMessagingMessageWithMessage:@{ kAppDataItemKey : veryLargeString }
- to:kMessageTo
- withID:messageID
- timeToLive:-1
- delay:0];
- OCMExpect([self.mockReceiver
- willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[NSError class]]) {
- NSError *error = (NSError *)obj;
- return error.code == kFIRMessagingErrorSizeExceeded;
- }
- return NO;
- }]]);
- [self addFakeFIRMessagingRegistrationToken];
- // should be logged into the service
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockReceiver);
- }
- // TODO: Add test with rawData exceeding 4KB in size
- - (void)testSendValidMessage_withRmqSaveError {
- NSString *messageID = @"1";
- NSMutableDictionary *message = [self standardFIRMessagingMessageWithMessageID:messageID];
- [[[self.mockRmqManager stub] andReturnValue:@NO]
- saveRmqMessage:[OCMArg any] error:[OCMArg anyObjectRef]];
- OCMExpect([self.mockReceiver
- willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[NSError class]]) {
- NSError *error = (NSError *)obj;
- return error.code == kFIRMessagingErrorSave;
- }
- return NO;
- }]]);
- // should be logged into the service
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockReceiver);
- }
- - (void)testSendValidMessage_withTTL0 {
- // simulate a valid connection
- [[[self.mockClient stub] andReturnValue:@YES] isConnectionActive];
- NSString *messageID = @"1";
- NSMutableDictionary *message = [self upstreamMessageWithID:messageID ttl:0 delay:0];
- BOOL(^isValidStanza)(id obj) = ^BOOL(id obj) {
- if ([obj isKindOfClass:[GtalkDataMessageStanza class]]) {
- GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)obj;
- return ([stanza.id_p isEqualToString:messageID] &&
- [stanza.to isEqualToString:kMessageTo] &&
- stanza.ttl == 0);
- }
- return NO;
- };
- OCMExpect([self.mockClient sendMessage:[OCMArg checkWithBlock:isValidStanza]]);
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockClient);
- }
- // TODO: This is failing on simulator 7.1 & 8.2, take this out temporarily
- - (void)XXX_testSendValidMessage_withTTL0AndNoFIRMessagingConnection {
- // simulate a invalid connection
- [[[self.mockClient stub] andReturnValue:@NO] isConnectionActive];
- // simulate network reachability
- FIRMessaging *service = [FIRMessaging messaging];
- id mockService = OCMPartialMock(service);
- [[[mockService stub] andReturnValue:@YES] isNetworkAvailable];
- NSString *messageID = @"1";
- NSMutableDictionary *message = [self upstreamMessageWithID:messageID ttl:0 delay:0];
- BOOL(^isValidStanza)(id obj) = ^BOOL(id obj) {
- if ([obj isKindOfClass:[GtalkDataMessageStanza class]]) {
- GtalkDataMessageStanza *stanza = (GtalkDataMessageStanza *)obj;
- return ([stanza.id_p isEqualToString:messageID] &&
- [stanza.to isEqualToString:kMessageTo] &&
- stanza.ttl == 0);
- }
- return NO;
- };
- // should save the message to be sent when we reconnect the next time
- OCMExpect([self.mockClient sendOnConnectOrDrop:[OCMArg checkWithBlock:isValidStanza]]);
- // should also try to reconnect immediately
- OCMExpect([self.mockClient retryConnectionImmediately:[OCMArg isEqual:@YES]]);
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockClient);
- }
- // TODO: Investigate why this test is flaky
- - (void)xxx_testSendValidMessage_withTTL0AndNoNetwork {
- // simulate a invalid connection
- [[[self.mockClient stub] andReturnValue:@NO] isConnectionActive];
- NSString *messageID = @"1";
- NSMutableDictionary *message = [self upstreamMessageWithID:messageID ttl:0 delay:0];
- // should drop the message since there is no network
- OCMExpect([self.mockReceiver willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg checkWithBlock:^BOOL(id obj) {
- if ([obj isKindOfClass:[NSError class]]) {
- NSError *error = (NSError *)obj;
- return error.code == kFIRMessagingErrorCodeNetwork;
- }
- return NO;
- }]]);
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockReceiver);
- }
- // TODO: This failed on simulator 7.1 & 8.2, take this out temporarily
- - (void)XXX_testDelayedMessagesBeingResentOnReconnect {
- static BOOL isConnectionActive = NO;
- OCMStub([self.mockClient isConnectionActive]).andDo(^(NSInvocation *invocation) {
- [invocation setReturnValue:&isConnectionActive];
- });
- // message that lives for 2 seconds
- NSString *messageID = @"1";
- int ttl = 2;
- NSMutableDictionary *message = [self upstreamMessageWithID:messageID ttl:ttl delay:1];
- __block GtalkDataMessageStanza *firstMessageStanza;
- OCMStub([self.mockRmqManager saveRmqMessage:[OCMArg any]
- error:[OCMArg anyObjectRef]]).andReturn(YES);
- OCMExpect([self.mockReceiver willSendDataMessageWithID:[OCMArg isEqual:messageID]
- error:[OCMArg isNil]]);
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager sendDataMessageStanza:message];
- __block FIRMessagingDataMessageHandler dataMessageHandler;
- [[[self.mockRmqManager stub] andDo:^(NSInvocation *invocation) {
- dataMessageHandler([FIRMessagingGetRmq2Id(firstMessageStanza) longLongValue],
- firstMessageStanza);
- }]
- scanWithRmqMessageHandler:[OCMArg isNil]
- dataMessageHandler:[OCMArg checkWithBlock:^BOOL(id obj) {
- dataMessageHandler = obj;
- return YES;
- }]];
- // expect both 1 and 2 messages to be sent once we regain connection
- __block BOOL firstMessageSent = NO;
- __block BOOL secondMessageSent = NO;
- XCTestExpectation *didSendAllMessages =
- [self expectationWithDescription:@"Did send all messages"];
- OCMExpect([self.mockClient sendMessage:[OCMArg checkWithBlock:^BOOL(id obj) {
- // [didSendAllMessages fulfill];
- if ([obj isKindOfClass:[GtalkDataMessageStanza class]]) {
- GtalkDataMessageStanza *message = (GtalkDataMessageStanza *)obj;
- if ([@"1" isEqualToString:message.id_p]) {
- firstMessageSent = YES;
- } else if ([@"2" isEqualToString:message.id_p]) {
- secondMessageSent = YES;
- }
- if (firstMessageSent && secondMessageSent) {
- [didSendAllMessages fulfill];
- }
- return firstMessageSent || secondMessageSent;
- }
- return NO;
- }]]);
- // send the second message after some delay
- [NSThread sleepForTimeInterval:2.0];
- isConnectionActive = YES;
- // simulate active connection
- NSString *newMessageID = @"2";
- NSMutableDictionary *newMessage = [self upstreamMessageWithID:newMessageID
- ttl:0
- delay:0];
- // send another message to resend not sent messages
- [self.dataMessageManager sendDataMessageStanza:newMessage];
- [self waitForExpectationsWithTimeout:5.0 handler:^(NSError *error) {
- XCTAssertNil(error);
- OCMVerifyAll(self.mockClient);
- OCMVerifyAll(self.mockReceiver);
- }];
- }
- - (void)testSendDelayedMessage_shouldNotSend {
- // should not send a delayed message even with an active connection
- // simulate active connection
- [[[self.mockClient stub] andReturnValue:OCMOCK_VALUE(YES)] isConnectionActive];
- [[self.mockClient reject] sendMessage:[OCMArg any]];
- [[self.mockReceiver reject] didSendDataMessageWithID:[OCMArg any]];
- // delayed message
- NSString *messageID = @"1";
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- NSMutableDictionary *message = [self upstreamMessageWithID:messageID ttl:0 delay:1];
- [self.dataMessageManager sendDataMessageStanza:message];
- OCMVerifyAll(self.mockClient);
- OCMVerifyAll(self.mockReceiver);
- }
- - (void)testProcessPacket_withValidPacket {
- GtalkDataMessageStanza *message = [self validDataMessagePacket];
- NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message];
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingFromKey], message.from);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingCollapseKey], message.token);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingMessageIDKey], kMessagePersistentID);
- XCTAssertEqualObjects(parsedMessage[kAppDataItemKey], kAppDataItemValue);
- XCTAssertEqual(4, parsedMessage.count);
- }
- - (void)testProcessPacket_withOnlyFrom {
- GtalkDataMessageStanza *message = [self validDataMessageWithOnlyFrom];
- NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message];
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingFromKey], message.from);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingMessageIDKey], kMessagePersistentID);
- XCTAssertEqual(2, parsedMessage.count);
- }
- - (void)testProcessPacket_withInvalidPacket {
- GtalkDataMessageStanza *message = [self invalidDataMessageUsingReservedKeyword];
- NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message];
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingFromKey], message.from);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingMessageIDKey], kMessagePersistentID);
- XCTAssertEqual(2, parsedMessage.count);
- }
- /**
- * Test parsing a duplex message.
- */
- - (void)testProcessPacket_withDuplexMessage {
- GtalkDataMessageStanza *stanza = [self validDuplexmessage];
- NSDictionary *parsedMessage = [self.dataMessageManager processPacket:stanza];
- XCTAssertEqual(5, parsedMessage.count);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingFromKey], stanza.from);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingCollapseKey], stanza.token);
- XCTAssertEqualObjects(parsedMessage[kFIRMessagingMessageIDKey], kMessagePersistentID);
- XCTAssertEqualObjects(parsedMessage[kAppDataItemKey], kAppDataItemValue);
- XCTAssertTrue([parsedMessage[kFIRMessagingMessageSyncViaMCSKey] boolValue]);
- }
- - (void)testReceivingParsedMessage {
- NSDictionary *message = @{ @"hello" : @"world" };
- OCMStub([self.mockReceiver didReceiveMessage:[OCMArg isEqual:message] withIdentifier:[OCMArg any]]);
- [self.dataMessageManager didReceiveParsedMessage:message];
- OCMVerify([self.mockReceiver didReceiveMessage:message withIdentifier:[OCMArg any]]);
- }
- /**
- * Test receiving a new duplex message notifies the receiver callback.
- */
- - (void)testReceivingNewDuplexMessage {
- GtalkDataMessageStanza *message = [self validDuplexmessage];
- NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message];
- [[[self.mockSyncMessageManager stub] andReturnValue:@(NO)]
- didReceiveMCSSyncMessage:parsedMessage];
- OCMStub([self.mockReceiver didReceiveMessage:[OCMArg isEqual:message] withIdentifier:[OCMArg any]]);
- [self.dataMessageManager didReceiveParsedMessage:parsedMessage];
- OCMVerify([self.mockReceiver didReceiveMessage:[OCMArg any] withIdentifier:[OCMArg any]]);
- }
- /**
- * Test receiving a duplicated duplex message does not notify the receiver callback.
- */
- - (void)testReceivingDuplicateDuplexMessage {
- GtalkDataMessageStanza *message = [self validDuplexmessage];
- NSDictionary *parsedMessage = [self.dataMessageManager processPacket:message];
- [[[self.mockSyncMessageManager stub] andReturnValue:@(YES)]
- didReceiveMCSSyncMessage:parsedMessage];
- [[self.mockReceiver reject] didReceiveMessage:[OCMArg any] withIdentifier:[OCMArg any]];
- [self.dataMessageManager didReceiveParsedMessage:parsedMessage];
- }
- /**
- * In this test we simulate a real RMQ manager and send messages simulating no
- * active connection. Then we simulate a new connection being established and
- * the client receives a Streaming ACK which should result in resending RMQ messages.
- */
- - (void)testResendSavedMessages {
- static BOOL isClientConnected = NO;
- [[[self.mockClient stub] andDo:^(NSInvocation *invocation) {
- [invocation setReturnValue:&isClientConnected];
- }] isConnectionActive];
- // Set a fake, valid bundle identifier
- [[[self.mockDataMessageManager stub] andReturn:@"gcm-dmm-test"] categoryForUpstreamMessages];
- [FIRMessagingRmqManager removeDatabaseWithName:kRmqDatabaseName];
- FIRMessagingRmqManager *newRmqManager =
- [[FIRMessagingRmqManager alloc] initWithDatabaseName:kRmqDatabaseName];
- [newRmqManager loadRmqId];
- // have a real RMQ store
- [self.dataMessageManager setRmq2Manager:newRmqManager];
- [self addFakeFIRMessagingRegistrationToken];
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- // send a couple of message with no connection should be saved to RMQ
- [self.dataMessageManager sendDataMessageStanza:
- [self upstreamMessageWithID:@"1" ttl:20000 delay:0]];
- [self.dataMessageManager sendDataMessageStanza:
- [self upstreamMessageWithID:@"2" ttl:20000 delay:0]];
- [NSThread sleepForTimeInterval:1.0];
- isClientConnected = YES;
- // after the usual version, login assertion we would receive a SelectiveAck
- // assuming we we weren't able to send any messages we won't delete anything
- // from the RMQ but try to resend whatever is there
- __block int didRecieveMessages = 0;
- id mockConnection = OCMClassMock([FIRMessagingConnection class]);
- BOOL (^resendMessageBlock)(id obj) = ^BOOL(id obj) {
- if ([obj isKindOfClass:[GtalkDataMessageStanza class]]) {
- GtalkDataMessageStanza *message = (GtalkDataMessageStanza *)obj;
- NSLog(@"hello resending %@, %d", message.id_p, didRecieveMessages);
- if ([@"1" isEqualToString:message.id_p]) {
- didRecieveMessages |= 1; // right most bit for 1st message
- return YES;
- } else if ([@"2" isEqualToString:message.id_p]) {
- didRecieveMessages |= (1<<1); // second from RMB for 2nd message
- return YES;
- }
- }
- return NO;
- };
- [[[mockConnection stub] andDo:^(NSInvocation *invocation) {
- // pass
- }] sendProto:[OCMArg checkWithBlock:resendMessageBlock]];
- [self.dataMessageManager resendMessagesWithConnection:mockConnection];
- // should send both messages
- XCTAssert(didRecieveMessages == 3);
- OCMVerifyAll(mockConnection);
- }
- - (void)testResendingExpiredMessagesFails {
- // TODO: Test that expired messages should not be sent on resend
- static BOOL isClientConnected = NO;
- [[[self.mockClient stub] andDo:^(NSInvocation *invocation) {
- [invocation setReturnValue:&isClientConnected];
- }] isConnectionActive];
- // Set a fake, valid bundle identifier
- [[[self.mockDataMessageManager stub] andReturn:@"gcm-dmm-test"] categoryForUpstreamMessages];
- [FIRMessagingRmqManager removeDatabaseWithName:kRmqDatabaseName];
- FIRMessagingRmqManager *newRmqManager =
- [[FIRMessagingRmqManager alloc] initWithDatabaseName:kRmqDatabaseName];
- [newRmqManager loadRmqId];
- // have a real RMQ store
- [self.dataMessageManager setRmq2Manager:newRmqManager];
- [self.dataMessageManager setDeviceAuthID:@"auth-id" secretToken:@"secret-token"];
- // send a message that expires in 1 sec
- [self.dataMessageManager sendDataMessageStanza:
- [self upstreamMessageWithID:@"1" ttl:1 delay:0]];
- // wait for 2 seconds (let the above message expire)
- [NSThread sleepForTimeInterval:2.0];
- isClientConnected = YES;
- id mockConnection = OCMClassMock([FIRMessagingConnection class]);
- [[mockConnection reject] sendProto:[OCMArg any]];
- [self.dataMessageManager resendMessagesWithConnection:mockConnection];
- // rmq should not have any pending messages
- [newRmqManager scanWithRmqMessageHandler:^(int64_t rmqId, int8_t tag, NSData *data) {
- XCTFail(@"RMQ should not have any message");
- }
- dataMessageHandler:nil];
- }
- #pragma mark - Private
- - (void)addFakeFIRMessagingRegistrationToken {
- // [[FIRMessagingDefaultsManager sharedInstance] saveAppIDToken:kFIRMessagingAppIDToken];
- }
- #pragma mark - Create Packet
- - (GtalkDataMessageStanza *)validDataMessagePacket {
- GtalkDataMessageStanza *message = [[GtalkDataMessageStanza alloc] init];
- message.from = kMessageFrom;
- message.token = kCollapseKey;
- message.persistentId = kMessagePersistentID;
- GtalkAppData *item = [[GtalkAppData alloc] init];
- item.key = kAppDataItemKey;
- item.value = kAppDataItemValue;
- message.appDataArray = [NSMutableArray arrayWithObject:item];
- return message;
- }
- - (GtalkDataMessageStanza *)validDataMessageWithOnlyFrom {
- GtalkDataMessageStanza *message = [[GtalkDataMessageStanza alloc] init];
- message.from = kMessageFrom;
- message.persistentId = kMessagePersistentID;
- return message;
- }
- - (GtalkDataMessageStanza *)invalidDataMessageUsingReservedKeyword {
- GtalkDataMessageStanza *message = [[GtalkDataMessageStanza alloc] init];
- message.from = kMessageFrom;
- message.persistentId = kMessagePersistentID;
- GtalkAppData *item = [[GtalkAppData alloc] init];
- item.key = kAppDataItemInvalidKey;
- item.value = kAppDataItemValue;
- message.appDataArray = [NSMutableArray arrayWithObject:item];
- return message;
- }
- - (GtalkDataMessageStanza *)validDataMessageForFIRMessaging {
- GtalkDataMessageStanza *message = [[GtalkDataMessageStanza alloc] init];
- message.from = kMessageFrom;
- message.token = @"com.google.gcm";
- return message;
- }
- - (GtalkDataMessageStanza *)validDuplexmessage {
- GtalkDataMessageStanza *message = [[GtalkDataMessageStanza alloc] init];
- message.from = kMessageFrom;
- message.token = kCollapseKey;
- message.persistentId = kMessagePersistentID;
- GtalkAppData *item = [[GtalkAppData alloc] init];
- item.key = kAppDataItemKey;
- item.value = kAppDataItemValue;
- GtalkAppData *duplexItem = [[GtalkAppData alloc] init];
- duplexItem.key = @"gcm.duplex";
- duplexItem.value = @"1";
- message.appDataArray = [NSMutableArray arrayWithObjects:item, duplexItem, nil];
- return message;
- }
- #pragma mark - Create Message
- - (NSMutableDictionary *)standardFIRMessagingMessageWithMessageID:(NSString *)messageID {
- NSDictionary *message = @{ kAppDataItemKey : kAppDataItemValue };
- return [FIRMessaging createFIRMessagingMessageWithMessage:message
- to:kMessageTo
- withID:messageID
- timeToLive:-1
- delay:0];
- }
- - (NSMutableDictionary *)upstreamMessageWithID:(NSString *)messageID
- ttl:(int64_t)ttl
- delay:(int)delay {
- NSDictionary *message = @{ kAppDataItemInvalidKey : kAppDataItemValue };
- return [FIRMessaging createFIRMessagingMessageWithMessage:message
- to:kMessageTo
- withID:messageID
- timeToLive:ttl
- delay:delay];
- }
- @end
|