1616
1717#import < XCTest/XCTest.h>
1818
19+ #import < OCMock/OCMock.h>
20+
21+ #import " FIRTestsAssertionHandler.h"
22+ #import " XCTestCase+FIRMessagingRmqManagerTests.h"
23+
1924#import " Firebase/Messaging/FIRMessagingPersistentSyncMessage.h"
2025#import " Firebase/Messaging/FIRMessagingRmqManager.h"
2126#import " Firebase/Messaging/FIRMessagingUtilities.h"
2833@interface FIRMessagingRmqManager (ExposedForTest)
2934
3035- (void )removeDatabase ;
36+ - (dispatch_queue_t )databaseOperationQueue ;
3137
3238@end
3339
3440@interface FIRMessagingRmqManagerTest : XCTestCase
3541
3642@property (nonatomic , readwrite , strong ) FIRMessagingRmqManager *rmqManager;
43+ @property (nonatomic , strong ) id assertionHandlerMock;
44+ @property (nonatomic , strong ) FIRTestsAssertionHandler *testAssertionHandler;
3745
3846@end
3947
4048@implementation FIRMessagingRmqManagerTest
4149
4250- (void )setUp {
4351 [super setUp ];
52+
53+ self.testAssertionHandler = [[FIRTestsAssertionHandler alloc ] init ];
54+ self.assertionHandlerMock = OCMClassMock ([NSAssertionHandler class ]);
55+ OCMStub ([self .assertionHandlerMock currentHandler ]).andReturn (self.testAssertionHandler );
56+
4457 // Make sure we start off with a clean state each time
4558 _rmqManager = [[FIRMessagingRmqManager alloc ] initWithDatabaseName: kRmqDatabaseName ];
46-
4759}
4860
4961- (void )tearDown {
5062 [self .rmqManager removeDatabase ];
63+ [self waitForDrainDatabaseQueueForRmqManager: self .rmqManager];
64+
65+ [self .assertionHandlerMock stopMocking ];
66+ self.assertionHandlerMock = nil ;
67+ self.testAssertionHandler = nil ;
68+
5169 [super tearDown ];
5270}
5371
@@ -302,6 +320,40 @@ - (void)testDeleteSyncMessage {
302320 XCTAssertNil ([self .rmqManager querySyncMessageWithRmqID: rmqID]);
303321}
304322
323+ - (void )testInitWhenDatabaseIsBrokenThenDatabaseIsDeleted {
324+ NSString *databaseName = @" invalid-database-file" ;
325+ NSString *databasePath = [self createBrokenDatabaseWithName: databaseName];
326+ XCTAssert ([[NSFileManager defaultManager ] fileExistsAtPath: databasePath]);
327+
328+ // Expect for at least one assertion.
329+ XCTestExpectation *assertionFailureExpectation = [self expectationWithDescription: @" assertionFailureExpectation" ];
330+ assertionFailureExpectation.assertForOverFulfill = NO ;
331+
332+ // The flag FIR_MESSAGING_ASSERTIONS_BLOCKED can be set by blaze when running tests from google3.
333+ #ifndef FIR_MESSAGING_ASSERTIONS_BLOCKED
334+ [self .testAssertionHandler setMethodFailureHandlerForClass: [FIRMessagingRmqManager class ]
335+ handler: ^(id object, NSString *fileName, NSInteger lineNumber) {
336+ [assertionFailureExpectation fulfill ];
337+ }];
338+ #else
339+ // If FIR_MESSAGING_ASSERTIONS_BLOCKED is defined, then no assertion handlers will be called,
340+ // so don't wait for it.
341+ dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t )(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^{
342+ [assertionFailureExpectation fulfill ];
343+ });
344+ #endif // FIR_MESSAGING_ASSERTIONS_BLOCKED
345+
346+ // Create `FIRMessagingRmqManager` instance with a broken database.
347+ FIRMessagingRmqManager *manager = [[FIRMessagingRmqManager alloc ] initWithDatabaseName: databaseName];
348+
349+ [self waitForExpectations: @[ assertionFailureExpectation ] timeout: 0.5 ];
350+
351+ [self waitForDrainDatabaseQueueForRmqManager: manager];
352+
353+ // Check that the file was deleted.
354+ XCTAssertFalse ([[NSFileManager defaultManager ] fileExistsAtPath: databasePath]);
355+ }
356+
305357#pragma mark - Private Helpers
306358
307359- (GtalkDataMessageStanza *)dataMessageWithMessageID : (NSString *)messageID
@@ -323,4 +375,24 @@ - (GtalkDataMessageStanza *)dataMessageWithMessageID:(NSString *)messageID
323375 return stanza;
324376}
325377
378+ - (NSString *)createBrokenDatabaseWithName : (NSString *)name {
379+ NSString *databasePath = [FIRMessagingRmqManager pathForDatabaseWithName: name];
380+ NSMutableArray *pathComponents = [[databasePath pathComponents ] mutableCopy ];
381+ [pathComponents removeLastObject ];
382+ NSString *directoryPath = [NSString pathWithComponents: pathComponents];
383+
384+ // Create directory if doesn't exist.
385+ [[NSFileManager defaultManager ] createDirectoryAtPath: directoryPath withIntermediateDirectories: YES attributes: nil error: NULL ];
386+ // Remove the file if exists.
387+ [[NSFileManager defaultManager ] removeItemAtPath: databasePath error: NULL ];
388+
389+ NSData *brokenDBFileContent = [@" not a valid DB" dataUsingEncoding: NSUTF8StringEncoding];
390+ [brokenDBFileContent writeToFile: databasePath atomically: YES ];
391+
392+ XCTAssertEqualObjects ([NSData dataWithContentsOfFile: databasePath], brokenDBFileContent);
393+ return databasePath;
394+ }
395+
396+
397+
326398@end
0 commit comments