/* * 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 #import #import "FirebaseInAppMessaging/Sources/Private/Data/FIRIAMFetchResponseParser.h" #import "FirebaseInAppMessaging/Sources/Private/Data/FIRIAMMessageContentDataWithImageURL.h" #import "FirebaseInAppMessaging/Sources/Private/Data/FIRIAMMessageDefinition.h" #import "FirebaseInAppMessaging/Sources/Private/DisplayTrigger/FIRIAMDisplayTriggerDefinition.h" #import "FirebaseInAppMessaging/Sources/Private/Util/FIRIAMTimeFetcher.h" #import "FirebaseInAppMessaging/Sources/Util/UIColor+FIRIAMHexString.h" @interface FIRIAMFetchResponseParserTests : XCTestCase @property(nonatomic, copy) NSString *jsonResponse; @property(nonatomic) FIRIAMFetchResponseParser *parser; @property(nonatomic) id mockTimeFetcher; @end @implementation FIRIAMFetchResponseParserTests - (void)setUp { [super setUp]; self.mockTimeFetcher = OCMProtocolMock(@protocol(FIRIAMTimeFetcher)); self.parser = [[FIRIAMFetchResponseParser alloc] initWithTimeFetcher:self.mockTimeFetcher]; } - (void)tearDown { [super tearDown]; } - (void)testRegularConversion { NSString *testJsonDataFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestJsonDataFromFetch" ofType:@"txt"]; NSTimeInterval currentMoment = 100000000; OCMStub([self.mockTimeFetcher currentTimestampInSeconds]).andReturn(currentMoment); self.jsonResponse = [[NSString alloc] initWithContentsOfFile:testJsonDataFilePath encoding:NSUTF8StringEncoding error:nil]; NSData *data = [self.jsonResponse dataUsingEncoding:NSUTF8StringEncoding]; NSError *errorJson = nil; NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&errorJson]; NSInteger discardCount; NSNumber *fetchWaitTime; NSArray *results = [self.parser parseAPIResponseDictionary:responseDict discardedMsgCount:&discardCount fetchWaitTimeInSeconds:&fetchWaitTime]; double nextFetchEpochTimeInResponse = [responseDict[@"expirationEpochTimestampMillis"] doubleValue]; // Fetch wait time should be (next fetch epoch time - current moment). XCTAssertEqualWithAccuracy([fetchWaitTime doubleValue], nextFetchEpochTimeInResponse / 1000 - currentMoment, 0.1); XCTAssertEqual(7, [results count]); XCTAssertEqual(0, discardCount); FIRIAMMessageDefinition *first = results[0]; XCTAssertEqualObjects(@"13313766398414028800", first.renderData.messageID); XCTAssertEqualObjects(@"first campaign", first.renderData.name); XCTAssertEqualObjects(@"I heard you like In-App Messages", first.renderData.contentData.titleText); XCTAssertEqualObjects(@"This is message body", first.renderData.contentData.bodyText); XCTAssertEqual(FIRIAMRenderAsModalView, first.renderData.renderingEffectSettings.viewMode); XCTAssertEqualWithAccuracy(1523986039, first.startTime, 0.1); XCTAssertEqualWithAccuracy(1526986039, first.endTime, 0.1); XCTAssertNotNil(first.renderData.renderingEffectSettings.textColor); XCTAssertEqualObjects(first.renderData.renderingEffectSettings.displayBGColor, [UIColor firiam_colorWithHexString:@"#fffff8"]); XCTAssertEqualObjects(first.renderData.renderingEffectSettings.btnBGColor, [UIColor firiam_colorWithHexString:@"#000000"]); XCTAssertEqualObjects(first.renderData.contentData.actionURL.absoluteString, @"https://www.google.com"); XCTAssertEqual(FIRIAMRenderTriggerOnAppForeground, first.renderTriggers[0].triggerType); XCTAssertEqual(first.appData.count, 2); XCTAssertEqualObjects(first.appData[@"a"], @"b"); XCTAssertEqualObjects(first.appData[@"c"], @"d"); FIRIAMMessageDefinition *second = results[1]; XCTAssertEqualObjects(@"9350598726327992320", second.renderData.messageID); XCTAssertEqualObjects(@"Inception1", second.renderData.name); XCTAssertEqualObjects(@"Test 2", second.renderData.contentData.titleText); XCTAssertNil(second.renderData.contentData.bodyText); XCTAssertNil(second.appData); XCTAssertEqual(FIRIAMRenderAsModalView, second.renderData.renderingEffectSettings.viewMode); XCTAssertEqual(2, second.renderTriggers.count); XCTAssertEqualObjects(second.renderData.renderingEffectSettings.displayBGColor, [UIColor firiam_colorWithHexString:@"#ffffff"]); // Third message is a banner view message based on an analytics event trigger. FIRIAMMessageDefinition *third = results[2]; XCTAssertEqualObjects(@"14819094573862617088", third.renderData.messageID); XCTAssertEqual(FIRIAMRenderAsBannerView, third.renderData.renderingEffectSettings.viewMode); XCTAssertEqual(1, third.renderTriggers.count); XCTAssertEqualObjects(@"jackpot", third.renderTriggers[0].firebaseEventName); // Fifth message is a card view message based on an analytics event trigger. FIRIAMMessageDefinition *fifth = results[4]; XCTAssertEqualObjects(@"5432869654332221", fifth.renderData.messageID); XCTAssertEqual(FIRIAMRenderAsCardView, fifth.renderData.renderingEffectSettings.viewMode); XCTAssertEqual(1, fifth.renderTriggers.count); XCTAssertEqual(FIRIAMRenderTriggerOnAppForeground, fifth.renderTriggers[0].triggerType); XCTAssertEqualObjects(@"Super Bowl LIV", fifth.renderData.name); XCTAssertEqualObjects(@"Eagles are going to win", fifth.renderData.contentData.titleText); XCTAssertEqualObjects(@"Start of a dynasty.", fifth.renderData.contentData.bodyText); XCTAssertEqualObjects(@"https://image.com/birds.png", fifth.renderData.contentData.imageURL.absoluteString); XCTAssertEqualObjects(@"https://image.com/ls_birds.png", fifth.renderData.contentData.landscapeImageURL.absoluteString); XCTAssertEqualObjects(@"https://www.google.com", fifth.renderData.contentData.actionURL.absoluteString); XCTAssertEqualObjects(@"Win Super Bowl LIV", fifth.renderData.contentData.actionButtonText); XCTAssertEqualObjects(@"https://www.google.com", fifth.renderData.contentData.secondaryActionURL.absoluteString); XCTAssertEqualObjects(@"Win Super Bowl LV", fifth.renderData.contentData.secondaryActionButtonText); FIRIAMMessageDefinition *sixth = results[5]; XCTAssertEqualObjects(@"687787988989", sixth.renderData.messageID); XCTAssertEqualObjects(@"Super Bowl LV", sixth.renderData.name); XCTAssertEqualObjects(@"Eagles are going to win", sixth.renderData.contentData.titleText); XCTAssertEqualObjects(sixth.renderData.renderingEffectSettings.btnTextColor, [UIColor firiam_colorWithHexString:@"#1a0dab"]); XCTAssertNil(sixth.renderData.contentData.bodyText); XCTAssertNil(sixth.appData); XCTAssertNotNil(sixth.experimentPayload); XCTAssertEqual(FIRIAMRenderAsModalView, sixth.renderData.renderingEffectSettings.viewMode); XCTAssertEqual(1, sixth.renderTriggers.count); FIRIAMMessageDefinition *seventh = results[6]; XCTAssertEqualObjects(@"https://example.com/recoverable_image_url", seventh.renderData.contentData.imageURL.absoluteString); XCTAssertEqualObjects(nil, seventh.renderData.contentData.landscapeImageURL.absoluteString); XCTAssertEqualObjects(@"http://example.com/recoverable_action_url_without_https", seventh.renderData.contentData.actionURL.absoluteString); XCTAssertEqualObjects(nil, seventh.renderData.contentData.secondaryActionURL.absoluteString); } - (void)testParsingTestMessage { NSString *testJsonDataFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"TestJsonDataWithTestMessageFromFetch" ofType:@"txt"]; self.jsonResponse = [[NSString alloc] initWithContentsOfFile:testJsonDataFilePath encoding:NSUTF8StringEncoding error:nil]; NSData *data = [self.jsonResponse dataUsingEncoding:NSUTF8StringEncoding]; NSError *errorJson = nil; NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&errorJson]; NSInteger discardCount; NSNumber *fetchWaitTime; NSArray *results = [self.parser parseAPIResponseDictionary:responseDict discardedMsgCount:&discardCount fetchWaitTimeInSeconds:&fetchWaitTime]; // In our fixture file used in this test, there is no fetch expiration time XCTAssertNil(fetchWaitTime); XCTAssertEqual(3, [results count]); XCTAssertEqual(0, discardCount); // First is a test message and the second one is not. XCTAssertTrue(results[0].isTestMessage); XCTAssertTrue(results[0].renderData.renderingEffectSettings.isTestMessage); XCTAssertNil(results[0].appData); XCTAssertFalse(results[1].isTestMessage); XCTAssertFalse(results[1].renderData.renderingEffectSettings.isTestMessage); XCTAssertTrue(results[2].isTestMessage); XCTAssertTrue(results[2].renderData.renderingEffectSettings.isTestMessage); XCTAssertEqual(results[2].appData.count, 2); XCTAssertEqualObjects(results[2].appData[@"a"], @"b"); XCTAssertEqualObjects(results[2].appData[@"c"], @"d"); } - (void)testParsingInvalidTestMessageNodes { NSString *testJsonDataFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"JsonDataWithInvalidMessagesFromFetch" ofType:@"txt"]; self.jsonResponse = [[NSString alloc] initWithContentsOfFile:testJsonDataFilePath encoding:NSUTF8StringEncoding error:nil]; NSData *data = [self.jsonResponse dataUsingEncoding:NSUTF8StringEncoding]; NSError *errorJson = nil; NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&errorJson]; NSInteger discardCount; NSNumber *fetchWaitTime; NSArray *results = [self.parser parseAPIResponseDictionary:responseDict discardedMsgCount:&discardCount fetchWaitTimeInSeconds:&fetchWaitTime]; XCTAssertEqual(0, [results count]); // First node missing title, second one missig triggering conditions and the third one // contains invalid type node. XCTAssertEqual(3, discardCount); } @end