|
|
@@ -16,6 +16,11 @@
|
|
|
|
|
|
#import <XCTest/XCTest.h>
|
|
|
|
|
|
+#import <OCMock/OCMock.h>
|
|
|
+
|
|
|
+#import "FIRTestsAssertionHandler.h"
|
|
|
+#import "XCTestCase+FIRMessagingRmqManagerTests.h"
|
|
|
+
|
|
|
#import "Firebase/Messaging/FIRMessagingPersistentSyncMessage.h"
|
|
|
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
|
|
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
|
|
@@ -28,12 +33,15 @@ static const NSTimeInterval kAsyncTestTimout = 0.5;
|
|
|
@interface FIRMessagingRmqManager (ExposedForTest)
|
|
|
|
|
|
- (void)removeDatabase;
|
|
|
+- (dispatch_queue_t)databaseOperationQueue;
|
|
|
|
|
|
@end
|
|
|
|
|
|
@interface FIRMessagingRmqManagerTest : XCTestCase
|
|
|
|
|
|
@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmqManager;
|
|
|
+@property(nonatomic, strong) id assertionHandlerMock;
|
|
|
+@property(nonatomic, strong) FIRTestsAssertionHandler *testAssertionHandler;
|
|
|
|
|
|
@end
|
|
|
|
|
|
@@ -41,13 +49,23 @@ static const NSTimeInterval kAsyncTestTimout = 0.5;
|
|
|
|
|
|
- (void)setUp {
|
|
|
[super setUp];
|
|
|
+
|
|
|
+ self.testAssertionHandler = [[FIRTestsAssertionHandler alloc] init];
|
|
|
+ self.assertionHandlerMock = OCMClassMock([NSAssertionHandler class]);
|
|
|
+ OCMStub([self.assertionHandlerMock currentHandler]).andReturn(self.testAssertionHandler);
|
|
|
+
|
|
|
// Make sure we start off with a clean state each time
|
|
|
_rmqManager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:kRmqDatabaseName];
|
|
|
-
|
|
|
}
|
|
|
|
|
|
- (void)tearDown {
|
|
|
[self.rmqManager removeDatabase];
|
|
|
+ [self waitForDrainDatabaseQueueForRmqManager:self.rmqManager];
|
|
|
+
|
|
|
+ [self.assertionHandlerMock stopMocking];
|
|
|
+ self.assertionHandlerMock = nil;
|
|
|
+ self.testAssertionHandler = nil;
|
|
|
+
|
|
|
[super tearDown];
|
|
|
}
|
|
|
|
|
|
@@ -302,6 +320,40 @@ static const NSTimeInterval kAsyncTestTimout = 0.5;
|
|
|
XCTAssertNil([self.rmqManager querySyncMessageWithRmqID:rmqID]);
|
|
|
}
|
|
|
|
|
|
+- (void)testInitWhenDatabaseIsBrokenThenDatabaseIsDeleted {
|
|
|
+ NSString *databaseName = @"invalid-database-file";
|
|
|
+ NSString *databasePath = [self createBrokenDatabaseWithName:databaseName];
|
|
|
+ XCTAssert([[NSFileManager defaultManager] fileExistsAtPath:databasePath]);
|
|
|
+
|
|
|
+ // Expect for at least one assertion.
|
|
|
+ XCTestExpectation *assertionFailureExpectation = [self expectationWithDescription:@"assertionFailureExpectation"];
|
|
|
+ assertionFailureExpectation.assertForOverFulfill = NO;
|
|
|
+
|
|
|
+// The flag FIR_MESSAGING_ASSERTIONS_BLOCKED can be set by blaze when running tests from google3.
|
|
|
+#ifndef FIR_MESSAGING_ASSERTIONS_BLOCKED
|
|
|
+ [self.testAssertionHandler setMethodFailureHandlerForClass:[FIRMessagingRmqManager class]
|
|
|
+ handler:^(id object, NSString *fileName, NSInteger lineNumber) {
|
|
|
+ [assertionFailureExpectation fulfill];
|
|
|
+ }];
|
|
|
+#else
|
|
|
+ // If FIR_MESSAGING_ASSERTIONS_BLOCKED is defined, then no assertion handlers will be called,
|
|
|
+ // so don't wait for it.
|
|
|
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
|
+ [assertionFailureExpectation fulfill];
|
|
|
+ });
|
|
|
+#endif // FIR_MESSAGING_ASSERTIONS_BLOCKED
|
|
|
+
|
|
|
+ // Create `FIRMessagingRmqManager` instance with a broken database.
|
|
|
+ FIRMessagingRmqManager *manager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:databaseName];
|
|
|
+
|
|
|
+ [self waitForExpectations:@[ assertionFailureExpectation ] timeout:0.5];
|
|
|
+
|
|
|
+ [self waitForDrainDatabaseQueueForRmqManager:manager];
|
|
|
+
|
|
|
+ // Check that the file was deleted.
|
|
|
+ XCTAssertFalse([[NSFileManager defaultManager] fileExistsAtPath:databasePath]);
|
|
|
+}
|
|
|
+
|
|
|
#pragma mark - Private Helpers
|
|
|
|
|
|
- (GtalkDataMessageStanza *)dataMessageWithMessageID:(NSString *)messageID
|
|
|
@@ -323,4 +375,24 @@ static const NSTimeInterval kAsyncTestTimout = 0.5;
|
|
|
return stanza;
|
|
|
}
|
|
|
|
|
|
+- (NSString *)createBrokenDatabaseWithName:(NSString *)name {
|
|
|
+ NSString *databasePath = [FIRMessagingRmqManager pathForDatabaseWithName:name];
|
|
|
+ NSMutableArray *pathComponents = [[databasePath pathComponents] mutableCopy];
|
|
|
+ [pathComponents removeLastObject];
|
|
|
+ NSString *directoryPath = [NSString pathWithComponents:pathComponents];
|
|
|
+
|
|
|
+ // Create directory if doesn't exist.
|
|
|
+ [[NSFileManager defaultManager] createDirectoryAtPath:directoryPath withIntermediateDirectories:YES attributes:nil error:NULL];
|
|
|
+ // Remove the file if exists.
|
|
|
+ [[NSFileManager defaultManager] removeItemAtPath:databasePath error:NULL];
|
|
|
+
|
|
|
+ NSData *brokenDBFileContent = [@"not a valid DB" dataUsingEncoding:NSUTF8StringEncoding];
|
|
|
+ [brokenDBFileContent writeToFile:databasePath atomically:YES];
|
|
|
+
|
|
|
+ XCTAssertEqualObjects([NSData dataWithContentsOfFile:databasePath], brokenDBFileContent);
|
|
|
+ return databasePath;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
@end
|