FIRMessagingSyncMessageManagerTest.m 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Copyright 2017 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <XCTest/XCTest.h>
  17. #import "XCTestCase+FIRMessagingRmqManagerTests.h"
  18. #import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
  19. #import "FirebaseMessaging/Sources/FIRMessagingPersistentSyncMessage.h"
  20. #import "FirebaseMessaging/Sources/FIRMessagingRmqManager.h"
  21. #import "FirebaseMessaging/Sources/FIRMessagingSyncMessageManager.h"
  22. #import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
  23. static NSString *const kRmqSqliteFilename = @"rmq-sync-manager-test";
  24. @interface FIRMessagingRmqManager (ExposedForTest)
  25. - (void)removeDatabase;
  26. @end
  27. @interface FIRMessagingSyncMessageManagerTest : XCTestCase
  28. @property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmqManager;
  29. @property(nonatomic, readwrite, strong) FIRMessagingSyncMessageManager *syncMessageManager;
  30. @end
  31. @implementation FIRMessagingSyncMessageManagerTest
  32. - (void)setUp {
  33. [super setUp];
  34. // Make sure the db state is clean before we begin.
  35. _rmqManager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:kRmqSqliteFilename];
  36. self.syncMessageManager =
  37. [[FIRMessagingSyncMessageManager alloc] initWithRmqManager:self.rmqManager];
  38. }
  39. - (void)tearDown {
  40. [_rmqManager removeDatabase];
  41. [self waitForDrainDatabaseQueueForRmqManager:_rmqManager];
  42. [super tearDown];
  43. }
  44. /**
  45. * Test receiving a new sync message via APNS should be added to SYNC_RMQ.
  46. */
  47. - (void)testNewAPNSMessage {
  48. int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 86400; // 1 day in future
  49. NSDictionary *oldMessage = @{
  50. kFIRMessagingMessageIDKey : @"fake-rmq-1",
  51. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  52. @"hello" : @"world",
  53. };
  54. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:oldMessage]);
  55. NSDictionary *newMessage = @{
  56. kFIRMessagingMessageIDKey : @"fake-rmq-2",
  57. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  58. @"hello" : @"world",
  59. };
  60. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:newMessage]);
  61. }
  62. /**
  63. * Test receiving a new sync message via MCS should be added to SYNC_RMQ.
  64. */
  65. - (void)testNewMCSMessage {
  66. int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 86400; // 1 day in future
  67. NSDictionary *oldMessage = @{
  68. kFIRMessagingMessageIDKey : @"fake-rmq-1",
  69. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  70. @"hello" : @"world",
  71. };
  72. XCTAssertFalse([self.syncMessageManager didReceiveMCSSyncMessage:oldMessage]);
  73. NSDictionary *newMessage = @{
  74. kFIRMessagingMessageIDKey : @"fake-rmq-2",
  75. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  76. @"hello" : @"world",
  77. };
  78. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:newMessage]);
  79. }
  80. /**
  81. * Test receiving a duplicate message via APNS.
  82. */
  83. - (void)testDuplicateAPNSMessage {
  84. NSString *messageID = @"fake-rmq-1";
  85. int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 86400; // 1 day in future
  86. NSDictionary *newMessage = @{
  87. kFIRMessagingMessageIDKey : messageID,
  88. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  89. @"hello" : @"world",
  90. };
  91. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:newMessage]);
  92. // The message is a duplicate
  93. XCTAssertTrue([self.syncMessageManager didReceiveAPNSSyncMessage:newMessage]);
  94. FIRMessagingPersistentSyncMessage *persistentMessage =
  95. [self.rmqManager querySyncMessageWithRmqID:messageID];
  96. XCTAssertTrue(persistentMessage.apnsReceived);
  97. XCTAssertFalse(persistentMessage.mcsReceived);
  98. }
  99. /**
  100. * Test receiving a duplicate message via MCS.
  101. */
  102. - (void)testDuplicateMCSMessage {
  103. NSString *messageID = @"fake-rmq-1";
  104. int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 86400; // 1 day in future
  105. NSDictionary *newMessage = @{
  106. kFIRMessagingMessageIDKey : messageID,
  107. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  108. @"hello" : @"world",
  109. };
  110. XCTAssertFalse([self.syncMessageManager didReceiveMCSSyncMessage:newMessage]);
  111. // The message is a duplicate
  112. XCTAssertTrue([self.syncMessageManager didReceiveMCSSyncMessage:newMessage]);
  113. FIRMessagingPersistentSyncMessage *persistentMessage =
  114. [self.rmqManager querySyncMessageWithRmqID:messageID];
  115. XCTAssertFalse(persistentMessage.apnsReceived);
  116. XCTAssertTrue(persistentMessage.mcsReceived);
  117. }
  118. /**
  119. * Test receiving a sync message both via APNS and MCS.
  120. */
  121. - (void)testMessageReceivedBothViaAPNSAndMCS {
  122. NSString *messageID = @"fake-rmq-1";
  123. int64_t expirationTime = FIRMessagingCurrentTimestampInSeconds() + 86400; // 1 day in future
  124. NSDictionary *newMessage = @{
  125. kFIRMessagingMessageIDKey : messageID,
  126. kFIRMessagingMessageSyncViaMCSKey : @(expirationTime),
  127. @"hello" : @"world",
  128. };
  129. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:newMessage]);
  130. // Duplicate of the above received APNS message
  131. XCTAssertTrue([self.syncMessageManager didReceiveMCSSyncMessage:newMessage]);
  132. // Since we've received both APNS and MCS messages we should have deleted them from SYNC_RMQ
  133. FIRMessagingPersistentSyncMessage *persistentMessage =
  134. [self.rmqManager querySyncMessageWithRmqID:messageID];
  135. XCTAssertNil(persistentMessage);
  136. }
  137. - (void)testDeletingExpiredMessages {
  138. NSString *unexpiredMessageID = @"fake-not-expired-rmqID";
  139. int64_t futureExpirationTime = 86400; // 1 day in future
  140. NSDictionary *unexpiredMessage = @{
  141. kFIRMessagingMessageIDKey : unexpiredMessageID,
  142. kFIRMessagingMessageSyncMessageTTLKey : @(futureExpirationTime),
  143. @"hello" : @"world",
  144. };
  145. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:unexpiredMessage]);
  146. NSString *expiredMessageID = @"fake-expired-rmqID";
  147. int64_t past = -86400; // 1 day in past
  148. NSDictionary *expiredMessage = @{
  149. kFIRMessagingMessageIDKey : expiredMessageID,
  150. kFIRMessagingMessageSyncMessageTTLKey : @(past),
  151. @"hello" : @"world",
  152. };
  153. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:expiredMessage]);
  154. NSString *noTTLMessageID = @"no-ttl-rmqID"; // no TTL specified should be 4 weeks
  155. NSDictionary *noTTLMessage = @{
  156. kFIRMessagingMessageIDKey : noTTLMessageID,
  157. @"hello" : @"world",
  158. };
  159. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:noTTLMessage]);
  160. [self.syncMessageManager removeExpiredSyncMessages];
  161. XCTAssertNotNil([self.rmqManager querySyncMessageWithRmqID:unexpiredMessageID]);
  162. XCTAssertNil([self.rmqManager querySyncMessageWithRmqID:expiredMessageID]);
  163. XCTAssertNotNil([self.rmqManager querySyncMessageWithRmqID:noTTLMessageID]);
  164. }
  165. - (void)testDeleteFinishedMessages {
  166. NSString *unexpiredMessageID = @"fake-not-expired-rmqID";
  167. int64_t futureExpirationTime = 86400; // 1 day in future
  168. NSDictionary *unexpiredMessage = @{
  169. kFIRMessagingMessageIDKey : unexpiredMessageID,
  170. kFIRMessagingMessageSyncMessageTTLKey : @(futureExpirationTime),
  171. @"hello" : @"world",
  172. };
  173. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:unexpiredMessage]);
  174. NSString *noTTLMessageID = @"no-ttl-rmqID"; // no TTL specified should be 4 weeks
  175. NSDictionary *noTTLMessage = @{
  176. kFIRMessagingMessageIDKey : noTTLMessageID,
  177. @"hello" : @"world",
  178. };
  179. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:noTTLMessage]);
  180. // Mark the no-TTL message as received via MCS too
  181. [self.rmqManager updateSyncMessageViaMCSWithRmqID:noTTLMessageID];
  182. [self.syncMessageManager removeExpiredSyncMessages];
  183. XCTAssertNotNil([self.rmqManager querySyncMessageWithRmqID:unexpiredMessageID]);
  184. XCTAssertNil([self.rmqManager querySyncMessageWithRmqID:noTTLMessageID]);
  185. }
  186. - (void)testDeleteFinishedAndExpiredMessages {
  187. NSString *unexpiredMessageID = @"fake-not-expired-rmqID";
  188. int64_t futureExpirationTime = 86400; // 1 day in future
  189. NSDictionary *unexpiredMessage = @{
  190. kFIRMessagingMessageIDKey : unexpiredMessageID,
  191. kFIRMessagingMessageSyncMessageTTLKey : @(futureExpirationTime),
  192. @"hello" : @"world",
  193. };
  194. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:unexpiredMessage]);
  195. NSString *expiredMessageID = @"fake-expired-rmqID";
  196. int64_t past = -86400; // 1 day in past
  197. NSDictionary *expiredMessage = @{
  198. kFIRMessagingMessageIDKey : expiredMessageID,
  199. kFIRMessagingMessageSyncMessageTTLKey : @(past),
  200. @"hello" : @"world",
  201. };
  202. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:expiredMessage]);
  203. NSString *noTTLMessageID = @"no-ttl-rmqID"; // no TTL specified should be 4 weeks
  204. NSDictionary *noTTLMessage = @{
  205. kFIRMessagingMessageIDKey : noTTLMessageID,
  206. @"hello" : @"world",
  207. };
  208. XCTAssertFalse([self.syncMessageManager didReceiveAPNSSyncMessage:noTTLMessage]);
  209. // Mark the no-TTL message as received via MCS too
  210. [self.rmqManager updateSyncMessageViaMCSWithRmqID:noTTLMessageID];
  211. // Remove expired or finished sync messages.
  212. [self.syncMessageManager removeExpiredSyncMessages];
  213. XCTAssertNotNil([self.rmqManager querySyncMessageWithRmqID:unexpiredMessageID]);
  214. XCTAssertNil([self.rmqManager querySyncMessageWithRmqID:expiredMessageID]);
  215. XCTAssertNil([self.rmqManager querySyncMessageWithRmqID:noTTLMessageID]);
  216. }
  217. @end