16
16
17
17
#import < XCTest/XCTest.h>
18
18
19
+ #import < OCMock/OCMock.h>
20
+
21
+ #import " FIRTestsAssertionHandler.h"
22
+ #import " XCTestCase+FIRMessagingRmqManagerTests.h"
23
+
19
24
#import " Firebase/Messaging/FIRMessagingPersistentSyncMessage.h"
20
25
#import " Firebase/Messaging/FIRMessagingRmqManager.h"
21
26
#import " Firebase/Messaging/FIRMessagingUtilities.h"
28
33
@interface FIRMessagingRmqManager (ExposedForTest)
29
34
30
35
- (void )removeDatabase ;
36
+ - (dispatch_queue_t )databaseOperationQueue ;
31
37
32
38
@end
33
39
34
40
@interface FIRMessagingRmqManagerTest : XCTestCase
35
41
36
42
@property (nonatomic , readwrite , strong ) FIRMessagingRmqManager *rmqManager;
43
+ @property (nonatomic , strong ) id assertionHandlerMock;
44
+ @property (nonatomic , strong ) FIRTestsAssertionHandler *testAssertionHandler;
37
45
38
46
@end
39
47
40
48
@implementation FIRMessagingRmqManagerTest
41
49
42
50
- (void )setUp {
43
51
[super setUp ];
52
+
53
+ self.testAssertionHandler = [[FIRTestsAssertionHandler alloc ] init ];
54
+ self.assertionHandlerMock = OCMClassMock ([NSAssertionHandler class ]);
55
+ OCMStub ([self .assertionHandlerMock currentHandler ]).andReturn (self.testAssertionHandler );
56
+
44
57
// Make sure we start off with a clean state each time
45
58
_rmqManager = [[FIRMessagingRmqManager alloc ] initWithDatabaseName: kRmqDatabaseName ];
46
-
47
59
}
48
60
49
61
- (void )tearDown {
50
62
[self .rmqManager removeDatabase ];
63
+ [self waitForDrainDatabaseQueueForRmqManager: self .rmqManager];
64
+
65
+ [self .assertionHandlerMock stopMocking ];
66
+ self.assertionHandlerMock = nil ;
67
+ self.testAssertionHandler = nil ;
68
+
51
69
[super tearDown ];
52
70
}
53
71
@@ -302,6 +320,40 @@ - (void)testDeleteSyncMessage {
302
320
XCTAssertNil ([self .rmqManager querySyncMessageWithRmqID: rmqID]);
303
321
}
304
322
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
+
305
357
#pragma mark - Private Helpers
306
358
307
359
- (GtalkDataMessageStanza *)dataMessageWithMessageID : (NSString *)messageID
@@ -323,4 +375,24 @@ - (GtalkDataMessageStanza *)dataMessageWithMessageID:(NSString *)messageID
323
375
return stanza;
324
376
}
325
377
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
+
326
398
@end
0 commit comments