| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*
- * 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 <OCMock/OCMock.h>
- #import <XCTest/XCTest.h>
- #import "FirebaseInAppMessaging/Sources/Private/Data/FIRIAMMessageDefinition.h"
- #import "FirebaseInAppMessaging/Sources/Private/Flows/FIRIAMMsgFetcherUsingRestful.h"
- #import "FirebaseInAppMessaging/Sources/Private/Runtime/FIRIAMFetchFlow.h"
- static NSString *serverHost = @"myhost";
- static NSString *projectNumber = @"My-project-number";
- static NSString *appId = @"My-app-id";
- static NSString *apiKey = @"Api-key";
- @interface FIRIAMMsgFetcherUsingRestfulTests : XCTestCase
- @property NSURLSession *mockedNSURLSession;
- @property FIRIAMClientInfoFetcher *mockclientInfoFetcher;
- @property FIRIAMMsgFetcherUsingRestful *fetcher;
- @end
- @implementation FIRIAMMsgFetcherUsingRestfulTests
- - (void)setUp {
- [super setUp];
- // Put setup code here. This method is called before the invocation of each test method in the
- // class.
- self.mockedNSURLSession = OCMClassMock([NSURLSession class]);
- self.mockclientInfoFetcher = OCMClassMock([FIRIAMClientInfoFetcher class]);
- FIRIAMFetchResponseParser *parser =
- [[FIRIAMFetchResponseParser alloc] initWithTimeFetcher:[[FIRIAMTimerWithNSDate alloc] init]];
- self.fetcher =
- [[FIRIAMMsgFetcherUsingRestful alloc] initWithHost:serverHost
- HTTPProtocol:@"https"
- project:projectNumber
- firebaseApp:appId
- APIKey:apiKey
- fetchStorage:[[FIRIAMServerMsgFetchStorage alloc] init]
- instanceIDFetcher:_mockclientInfoFetcher
- usingURLSession:_mockedNSURLSession
- responseParser:parser];
- }
- - (void)tearDown {
- // Put teardown code here. This method is called after the invocation of each test method in the
- // class.
- [super tearDown];
- }
- - (void)testRequestConstructionWithoutImpressionData {
- // This is an example of a functional test case.
- // Use XCTAssert and related functions to verify your tests produce the correct results.
- __block NSURLRequest *capturedNSURLRequest;
- OCMStub([self.mockedNSURLSession
- dataTaskWithRequest:[OCMArg checkWithBlock:^BOOL(NSURLRequest *request) {
- capturedNSURLRequest = request;
- return YES;
- }]
- completionHandler:[OCMArg any] // second parameter is the callback which we don't care in
- // this unit testing
- ]);
- NSString *FIDValue = @"my FID";
- NSString *FISToken = @"my FIS token";
- OCMStub([self.mockclientInfoFetcher
- fetchFirebaseInstallationDataWithProjectNumber:[OCMArg any]
- withCompletion:([OCMArg
- invokeBlockWithArgs:FIDValue, FISToken,
- [NSNull null], nil])]);
- NSString *osVersion = @"OS Version";
- OCMStub([self.mockclientInfoFetcher getOSVersion]).andReturn(osVersion);
- NSString *appVersion = @"App Version";
- OCMStub([self.mockclientInfoFetcher getAppVersion]).andReturn(appVersion);
- NSString *deviceLanguage = @"Language";
- OCMStub([self.mockclientInfoFetcher getDeviceLanguageCode]).andReturn(deviceLanguage);
- NSString *timezone = @"time zone";
- OCMStub([self.mockclientInfoFetcher getTimezone]).andReturn(timezone);
- [self.fetcher
- fetchMessagesWithImpressionList:@[]
- withCompletion:^(NSArray<FIRIAMMessageDefinition *> *_Nullable messages,
- NSNumber *nextFetchWaitTime, NSInteger discardCount,
- NSError *_Nullable error){
- // blank on purpose: it won't get triggered
- }];
- // verify that the dataTaskWithRequest:completionHandler: is triggered for NSURLSession object
- OCMVerify([self.mockedNSURLSession dataTaskWithRequest:[OCMArg any]
- completionHandler:[OCMArg any]]);
- XCTAssertEqualObjects(@"POST", capturedNSURLRequest.HTTPMethod);
- NSDictionary<NSString *, NSString *> *requestHeaders = capturedNSURLRequest.allHTTPHeaderFields;
- // verifying some request header fields
- XCTAssertEqualObjects([NSBundle mainBundle].bundleIdentifier,
- requestHeaders[@"X-Ios-Bundle-Identifier"]);
- XCTAssertEqualObjects(@"application/json", requestHeaders[@"Content-Type"]);
- XCTAssertEqualObjects(@"application/json", requestHeaders[@"Accept"]);
- // verify that the request contains the desired api key
- NSString *s = [NSString stringWithFormat:@"key=%@", apiKey];
- XCTAssertTrue([capturedNSURLRequest.URL.absoluteString containsString:s]);
- XCTAssertTrue([capturedNSURLRequest.URL.absoluteString containsString:projectNumber]);
- // verify that we the request body contains desired iid data
- NSError *errorJson = nil;
- NSDictionary *requestBodyDict =
- [NSJSONSerialization JSONObjectWithData:capturedNSURLRequest.HTTPBody
- options:kNilOptions
- error:&errorJson];
- XCTAssertEqualObjects(appId, requestBodyDict[@"requesting_client_app"][@"gmp_app_id"]);
- XCTAssertEqualObjects(FIDValue, requestBodyDict[@"requesting_client_app"][@"app_instance_id"]);
- XCTAssertEqualObjects(FISToken,
- requestBodyDict[@"requesting_client_app"][@"app_instance_id_token"]);
- XCTAssertEqualObjects(osVersion, requestBodyDict[@"client_signals"][@"platform_version"]);
- XCTAssertEqualObjects(appVersion, requestBodyDict[@"client_signals"][@"app_version"]);
- XCTAssertEqualObjects(deviceLanguage, requestBodyDict[@"client_signals"][@"language_code"]);
- XCTAssertEqualObjects(timezone, requestBodyDict[@"client_signals"][@"time_zone"]);
- }
- - (void)testRequestConstructionWithImpressionData {
- __block NSURLRequest *capturedNSURLRequest;
- OCMStub([self.mockedNSURLSession
- dataTaskWithRequest:[OCMArg checkWithBlock:^BOOL(NSURLRequest *request) {
- capturedNSURLRequest = request;
- return YES;
- }]
- completionHandler:[OCMArg any] // second parameter is the callback which we don't care in
- // this unit testing
- ]);
- NSString *FIDValue = @"my FID";
- NSString *FISToken = @"my FIS token";
- OCMStub([self.mockclientInfoFetcher
- fetchFirebaseInstallationDataWithProjectNumber:[OCMArg any]
- withCompletion:([OCMArg
- invokeBlockWithArgs:FIDValue, FISToken,
- [NSNull null], nil])]);
- // this is to test the case that only partial client signal fields are available
- NSString *osVersion = @"OS Version";
- OCMStub([self.mockclientInfoFetcher getOSVersion]).andReturn(osVersion);
- NSString *appVersion = @"App Version";
- OCMStub([self.mockclientInfoFetcher getAppVersion]).andReturn(appVersion);
- long impression1Timestamp = 12345;
- FIRIAMImpressionRecord *impression1 =
- [[FIRIAMImpressionRecord alloc] initWithMessageID:@"impression 1"
- impressionTimeInSeconds:impression1Timestamp];
- long impression2Timestamp = 45678;
- FIRIAMImpressionRecord *impression2 =
- [[FIRIAMImpressionRecord alloc] initWithMessageID:@"impression 2"
- impressionTimeInSeconds:impression2Timestamp];
- [self.fetcher
- fetchMessagesWithImpressionList:@[ impression1, impression2 ]
- withCompletion:^(NSArray<FIRIAMMessageDefinition *> *_Nullable messages,
- NSNumber *_Nullable nextFetchWaitTime,
- NSInteger discardCount, NSError *_Nullable error){
- // blank on purpose: it won't get triggered
- }];
- // verify that the captured nsurl request has expected body
- NSError *errorJson = nil;
- NSDictionary *requestBodyDict =
- [NSJSONSerialization JSONObjectWithData:capturedNSURLRequest.HTTPBody
- options:kNilOptions
- error:&errorJson];
- XCTAssertEqualObjects(impression1.messageID,
- requestBodyDict[@"already_seen_campaigns"][0][@"campaign_id"]);
- XCTAssertEqualWithAccuracy(
- impression1Timestamp * 1000,
- ((NSNumber *)requestBodyDict[@"already_seen_campaigns"][0][@"impression_timestamp_millis"])
- .longValue,
- 0.1);
- XCTAssertEqualObjects(impression2.messageID,
- requestBodyDict[@"already_seen_campaigns"][1][@"campaign_id"]);
- XCTAssertEqualWithAccuracy(
- impression2Timestamp * 1000,
- ((NSNumber *)requestBodyDict[@"already_seen_campaigns"][1][@"impression_timestamp_millis"])
- .longValue,
- 0.1);
- XCTAssertEqualObjects(osVersion, requestBodyDict[@"client_signals"][@"platform_version"]);
- XCTAssertEqualObjects(appVersion, requestBodyDict[@"client_signals"][@"app_version"]);
- // not expecting language signal since it's not mocked on mockclientInfoFetcher
- XCTAssertNil(requestBodyDict[@"client_signals"][@"language_code"]);
- }
- - (void)testBailoutOnFIDError {
- // in this test, the attempt to fetch iid data failed and as a result, we expect the whole
- // fetch operation attempt to fail with that error
- NSError *FIDError = [[NSError alloc] initWithDomain:@"Error Domain" code:100 userInfo:nil];
- OCMStub([self.mockclientInfoFetcher
- fetchFirebaseInstallationDataWithProjectNumber:[OCMArg any]
- withCompletion:([OCMArg invokeBlockWithArgs:[NSNull null],
- [NSNull null],
- FIDError, nil])]);
- XCTestExpectation *expectation =
- [self expectationWithDescription:@"fetch callback block triggered."];
- [self.fetcher
- fetchMessagesWithImpressionList:@[]
- withCompletion:^(NSArray<FIRIAMMessageDefinition *> *_Nullable messages,
- NSNumber *_Nullable nextFetchWaitTime,
- NSInteger discardCount, NSError *_Nullable error) {
- // expecting triggering the completion callback with error
- XCTAssertNil(messages);
- XCTAssertEqualObjects(FIDError, error);
- [expectation fulfill];
- }];
- [self waitForExpectationsWithTimeout:5.0 handler:nil];
- }
- @end
|