Files
firebase-ios-sdk/Example/Messaging/Tests/FIRMessagingRmqManagerTest.m
T
Paul Beusterien 06d36108d8 Add test_spec for FCM (#3088)
* Add test_spec for FCM
* FIRMessagingRemoteNotificationsProxyTest - don't use OCMPartialMock([UIApplication sharedApplication]) to avoid crashing tests on iOS 8 (#3094)
2019-05-28 11:36:31 -07:00

333 lines
13 KiB
Objective-C

/*
* 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/XCTest.h>
#import "Protos/GtalkCore.pbobjc.h"
#import "FIRMessagingPersistentSyncMessage.h"
#import "FIRMessagingRmqManager.h"
#import "FIRMessagingUtilities.h"
static NSString *const kRmqDatabaseName = @"rmq-test-db";
static NSString *const kRmqDataMessageCategory = @"com.google.gcm-rmq-test";
@interface FIRMessagingRmqManagerTest : XCTestCase
@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmqManager;
@end
@implementation FIRMessagingRmqManagerTest
- (void)setUp {
[super setUp];
// Make sure we start off with a clean state each time
[FIRMessagingRmqManager removeDatabaseWithName:kRmqDatabaseName];
_rmqManager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:kRmqDatabaseName];
}
- (void)tearDown {
[super tearDown];
[FIRMessagingRmqManager removeDatabaseWithName:kRmqDatabaseName];
}
/**
* Add s2d messages with different RMQ-ID's to the RMQ. Fetch the messages
* and verify that all messages were successfully saved.
*/
- (void)testSavingS2dMessages {
NSArray *messageIDs = @[ @"message1", @"message2", @"123456" ];
for (NSString *messageID in messageIDs) {
[self.rmqManager saveS2dMessageWithRmqId:messageID];
}
NSArray *rmqMessages = [self.rmqManager unackedS2dRmqIds];
XCTAssertEqual(messageIDs.count, rmqMessages.count);
for (NSString *messageID in rmqMessages) {
XCTAssertTrue([messageIDs containsObject:messageID]);
}
}
/**
* Add s2d messages with different RMQ-ID's to the RMQ. Delete some of the
* messages stored, assuming we received a server ACK for them. The remaining
* messages should be fetched successfully.
*/
- (void)testDeletingS2dMessages {
NSArray *addMessages = @[ @"message1", @"message2", @"message3", @"message4"];
for (NSString *messageID in addMessages) {
[self.rmqManager saveS2dMessageWithRmqId:messageID];
}
NSArray *removeMessages = @[ addMessages[1], addMessages[3] ];
[self.rmqManager removeS2dIds:removeMessages];
NSArray *remainingMessages = [self.rmqManager unackedS2dRmqIds];
XCTAssertEqual(2, remainingMessages.count);
XCTAssertTrue([remainingMessages containsObject:addMessages[0]]);
XCTAssertTrue([remainingMessages containsObject:addMessages[2]]);
}
/**
* Test deleting a s2d message that is not in the persistent store. This shouldn't
* crash or alter the valid contents of the RMQ store.
*/
- (void)testDeletingInvalidS2dMessage {
NSString *validMessageID = @"validMessage123";
[self.rmqManager saveS2dMessageWithRmqId:validMessageID];
NSString *invalidMessageID = @"invalidMessage123";
[self.rmqManager removeS2dIds:@[invalidMessageID]];
NSArray *remainingMessages = [self.rmqManager unackedS2dRmqIds];
XCTAssertEqual(1, remainingMessages.count);
XCTAssertEqualObjects(validMessageID, remainingMessages[0]);
}
/**
* Test loading the RMQ-ID for d2s messages when there are no outgoing messages in the RMQ.
*/
- (void)testLoadRmqIDWithNoD2sMessages {
[self.rmqManager loadRmqId];
XCTAssertEqual(-1, [self maxRmqIDInRmqStoreForD2SMessages]);
}
/**
* Test that outgoing RMQ messages are correctly saved
*/
- (void)testOutgoingRmqWithValidMessages {
NSString *from = @"rmq-test";
[self.rmqManager loadRmqId];
GtalkDataMessageStanza *message1 = [self dataMessageWithMessageID:@"message1"
from:from
data:nil];
NSError *error = nil;
// should successfully save the message to RMQ
XCTAssertTrue([self.rmqManager saveRmqMessage:message1 error:&error]);
XCTAssertNil(error);
GtalkDataMessageStanza *message2 = [self dataMessageWithMessageID:@"message2"
from:from
data:nil];
// should successfully save the second message to RMQ
XCTAssertTrue([self.rmqManager saveRmqMessage:message2 error:&error]);
XCTAssertNil(error);
// message1 should have RMQ-ID = 2, message2 = 3
XCTAssertEqual(3, [self maxRmqIDInRmqStoreForD2SMessages]);
[self.rmqManager scanWithRmqMessageHandler:nil
dataMessageHandler:^(int64_t rmqId, GtalkDataMessageStanza *stanza) {
if (rmqId == 2) {
XCTAssertEqualObjects(@"message1", stanza.id_p);
} else if (rmqId == 3) {
XCTAssertEqualObjects(@"message2", stanza.id_p);
} else {
XCTFail(@"Invalid RmqID %lld for s2d message", rmqId);
}
}];
}
/**
* Test that an outgoing message with different properties is correctly saved to the RMQ.
*/
- (void)testOutgoingDataMessageIsCorrectlySaved {
NSString *from = @"rmq-test";
NSString *messageID = @"message123";
NSString *to = @"to-senderID-123";
int32_t ttl = 2400;
NSString *registrationToken = @"registration-token";
NSDictionary *data = @{
@"hello" : @"world",
@"count" : @"2",
};
[self.rmqManager loadRmqId];
GtalkDataMessageStanza *message = [self dataMessageWithMessageID:messageID
from:from
data:data];
[message setTo:to];
[message setTtl:ttl];
[message setRegId:registrationToken];
NSError *error = nil;
// should successfully save the message to RMQ
XCTAssertTrue([self.rmqManager saveRmqMessage:message error:&error]);
XCTAssertNil(error);
[self.rmqManager scanWithRmqMessageHandler:nil
dataMessageHandler:^(int64_t rmqId, GtalkDataMessageStanza *stanza) {
XCTAssertEqualObjects(from, stanza.from);
XCTAssertEqualObjects(messageID, stanza.id_p);
XCTAssertEqualObjects(to, stanza.to);
XCTAssertEqualObjects(registrationToken, stanza.regId);
XCTAssertEqual(ttl, stanza.ttl);
NSMutableDictionary *d = [NSMutableDictionary dictionary];
for (GtalkAppData *appData in stanza.appDataArray) {
d[appData.key] = appData.value;
}
XCTAssertTrue([data isEqualToDictionary:d]);
}];
}
/**
* Test D2S messages being deleted from RMQ.
*/
- (void)testDeletingD2SMessagesFromRMQ {
NSString *message1 = @"message123";
NSString *ackedMessage = @"message234";
NSString *from = @"from-rmq-test";
GtalkDataMessageStanza *stanza1 = [self dataMessageWithMessageID:message1 from:from data:nil];
GtalkDataMessageStanza *stanza2 = [self dataMessageWithMessageID:ackedMessage
from:from
data:nil];
NSError *error = nil;
XCTAssertTrue([self.rmqManager saveRmqMessage:stanza1 error:&error]);
XCTAssertNil(error);
XCTAssertTrue([self.rmqManager saveRmqMessage:stanza2 error:&error]);
XCTAssertNil(error);
__block int64_t ackedMessageRmqID = -1;
[self.rmqManager scanWithRmqMessageHandler:nil
dataMessageHandler:^(int64_t rmqId, GtalkDataMessageStanza *stanza) {
if ([stanza.id_p isEqualToString:ackedMessage]) {
ackedMessageRmqID = rmqId;
}
}];
// should be a valid RMQ ID
XCTAssertTrue(ackedMessageRmqID > 0);
// delete the acked message
NSString *rmqIDString = [NSString stringWithFormat:@"%lld", ackedMessageRmqID];
XCTAssertEqual(1, [self.rmqManager removeRmqMessagesWithRmqId:rmqIDString]);
// should only have one message in the d2s RMQ
[self.rmqManager scanWithRmqMessageHandler:nil
dataMessageHandler:^(int64_t rmqId, GtalkDataMessageStanza *stanza) {
// the acked message was queued later so should have
// rmqID = ackedMessageRMQID - 1
XCTAssertEqual(ackedMessageRmqID - 1, rmqId);
XCTAssertEqual(message1, stanza2.id_p);
}];
}
/**
* Test saving a sync message to SYNC_RMQ.
*/
- (void)testSavingSyncMessage {
NSString *rmqID = @"fake-rmq-id-1";
int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 1;
XCTAssertTrue([self.rmqManager saveSyncMessageWithRmqID:rmqID
expirationTime:expirationTime
apnsReceived:YES
mcsReceived:NO
error:nil]);
FIRMessagingPersistentSyncMessage *persistentMessage = [self.rmqManager querySyncMessageWithRmqID:rmqID];
XCTAssertEqual(persistentMessage.expirationTime, expirationTime);
XCTAssertTrue(persistentMessage.apnsReceived);
XCTAssertFalse(persistentMessage.mcsReceived);
}
/**
* Test updating a sync message initially received via MCS, now being received via APNS.
*/
- (void)testUpdateMessageReceivedViaAPNS {
NSString *rmqID = @"fake-rmq-id-1";
int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 1;
XCTAssertTrue([self.rmqManager saveSyncMessageWithRmqID:rmqID
expirationTime:expirationTime
apnsReceived:NO
mcsReceived:YES
error:nil]);
// Message was now received via APNS
XCTAssertTrue([self.rmqManager updateSyncMessageViaAPNSWithRmqID:rmqID error:nil]);
FIRMessagingPersistentSyncMessage *persistentMessage = [self.rmqManager querySyncMessageWithRmqID:rmqID];
XCTAssertTrue(persistentMessage.apnsReceived);
XCTAssertTrue(persistentMessage.mcsReceived);
}
/**
* Test updating a sync message initially received via APNS, now being received via MCS.
*/
- (void)testUpdateMessageReceivedViaMCS {
NSString *rmqID = @"fake-rmq-id-1";
int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 1;
XCTAssertTrue([self.rmqManager saveSyncMessageWithRmqID:rmqID
expirationTime:expirationTime
apnsReceived:YES
mcsReceived:NO
error:nil]);
// Message was now received via APNS
XCTAssertTrue([self.rmqManager updateSyncMessageViaMCSWithRmqID:rmqID error:nil]);
FIRMessagingPersistentSyncMessage *persistentMessage = [self.rmqManager querySyncMessageWithRmqID:rmqID];
XCTAssertTrue(persistentMessage.apnsReceived);
XCTAssertTrue(persistentMessage.mcsReceived);
}
/**
* Test deleting sync messages from SYNC_RMQ.
*/
- (void)testDeleteSyncMessage {
NSString *rmqID = @"fake-rmq-id-1";
int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 1;
XCTAssertTrue([self.rmqManager saveSyncMessageWithRmqID:rmqID
expirationTime:expirationTime
apnsReceived:YES
mcsReceived:NO
error:nil]);
XCTAssertNotNil([self.rmqManager querySyncMessageWithRmqID:rmqID]);
// should successfully delete the message
XCTAssertTrue([self.rmqManager deleteSyncMessageWithRmqID:rmqID]);
XCTAssertNil([self.rmqManager querySyncMessageWithRmqID:rmqID]);
}
#pragma mark - Private Helpers
- (GtalkDataMessageStanza *)dataMessageWithMessageID:(NSString *)messageID
from:(NSString *)from
data:(NSDictionary *)data {
GtalkDataMessageStanza *stanza = [[GtalkDataMessageStanza alloc] init];
[stanza setId_p:messageID];
[stanza setFrom:from];
[stanza setCategory:kRmqDataMessageCategory];
for (NSString *key in data) {
NSString *val = data[key];
GtalkAppData *appData = [[GtalkAppData alloc] init];
[appData setKey:key];
[appData setValue:val];
[[stanza appDataArray] addObject:appData];
}
return stanza;
}
- (int64_t)maxRmqIDInRmqStoreForD2SMessages {
__block int64_t maxRmqID = -1;
[self.rmqManager scanWithRmqMessageHandler:^(int64_t rmqId, int8_t tag, NSData *data) {
if (rmqId > maxRmqID) {
maxRmqID = rmqId;
}
}
dataMessageHandler:nil];
return maxRmqID;
}
@end