mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-11 22:55:59 +05:45
* Adding error handling and returning correct error codes * * Handling auth cancellation a few other error cases * Adding some logging for EAP (Using NSLogs temporarily. DONOT MERGE) * Add in a setter for clientID to allow overrides (#5514) * Add in a setter for clientID to allow overrides * Update styling * Adding some result parsing logs * Fixing code hash logging * Add FirebaseAppDistribution to ZipBuilder * * Making sure keychain is accesible after first unlock even if app is backgrounded (#5563) * Fix auth persistence logging and invalid type casting (#5631) * Logging app id requesting releases (#5655) * AppDistribution keychain access fixes (#5683) * Using the GULKeychainUtils instead of custom keychain utility. Also added better logging * Updating keychain name and fixing tests * Code review feedback updates * Making serviceID unique per app * Adding gmp app id to the keychain along with the bundle id * Moving Keychain Utility functions in the AuthPersistence class and deleting the utility class * Lazy initialize auth state (#5755) * Lazy initialize auth state * Making sure we dont log an error is auth state is not persisted in the keychain * Switch from NSLog to FIRFADLogger (#5756) * Add FIRLogger * Switch from NSLog to FIRFADLogger * * Use FIS Auth for authenticating the tester * Remove AppAuth and start wiring up interceptor to do sign in * Extracting registration flow UI in interceptor * Adding support for iOS 9 and 10 * Create app distribution api service to handle tester api calls. (#6060) * Pull out calls to the FAD API to make them reuseable * Fix tests and run styl updates * Uncomment FIRFADLog Statements * Use [] accessor rather than . accessor * Re-running style updates * Trying to get these checks to pass the first time around * App distribution signin persist (#6063) * Pull out calls to the FAD API to make them reuseable * Fix tests and run styl updates * Add in UserDefaults storage after a tester has signed in * Add testing for the main AppDistribution file * Ran style.sh * Remove FIRFADLocalStorage and call GULUserDefaults directly. Update tests to stop mocking on teardown. * Add support for dynamic url schemes and fix two crashes (#6081) * Add support for dynamic url schemes and fix two crashes * Add support for dynamic url schemes in the format appdistribution-<app id without colons> * Fix crash when launching an app directly via a URL scheme * Fix a crash on iOS 10 simulator caused by calling NSLogv twice * Remove uses of NSLog * Fix warnings * Switch encodedAppId to be a class method * Fix styles * Create changelog and readme in preparation for release. (#6095) Just changing markdown files so will not wait for gha checks. * Change slices property from copy to strong (#6097) Fix lint warning * Change error handlers to return bool values instead of void (#6101) * Mapping sign in flow errors to app distribution errors. Also renaming AppDelegateInterceptor to FIRAppDistributionUIService (#6099) * Add github action for App Distribution (#6094) * Updating app distribution deployment target to iOS 9 (#6118) * Making sure we return granular errors during sign in persistence. Also fixing some naming and comment issues (#6117) * Encoding colons to dashes in the app id (#6119) * Move Internal headers to Sources (#6106) * Move Internal headers to Sources/ folder * PR feedback * Remove appDistribution from zip builder * Respond to code review feedback (#6138) * Initializing UIWindow using initWithWindowScene for ios 13 and removing UI code from main FIRAppDistribution.m (#6144) * Initializing UIWindow using initWithWindowScene for ios 13. Also making sure we only reset window in the App delegate if a registration flow is in progress. * Remove UI code from main class, add unit tests, and clean up UIService * stylish * Remove defines in favor of solely 'if (@available(iOS 13.0, *))' * Respond to code review feedback Co-authored-by: Cleo Schneider <cleoschneider@google.com> Co-authored-by: Pranav Rajgopal <pranavrajgopal@google.com> Co-authored-by: Cleo Schneider <cleoschneider@google.com>
488 lines
20 KiB
Objective-C
488 lines
20 KiB
Objective-C
//
|
|
// Copyright 2020 Google LLC
|
|
//
|
|
// 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 <Foundation/Foundation.h>
|
|
#import <OCMock/OCMock.h>
|
|
#import <XCTest/XCTest.h>
|
|
|
|
#import "FirebaseAppDistribution/Sources/FIRFADApiService.h"
|
|
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
|
|
#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h"
|
|
|
|
NSString *const kFakeErrorDomain = @"test.failure.domain";
|
|
|
|
@interface FIRFADApiServiceTests : XCTestCase
|
|
@end
|
|
|
|
@implementation FIRFADApiServiceTests {
|
|
id _mockFIRAppClass;
|
|
id _mockURLSession;
|
|
id _mockFIRInstallations;
|
|
id _mockInstallationToken;
|
|
NSString *_mockAuthToken;
|
|
NSString *_mockInstallationId;
|
|
NSDictionary *_mockReleases;
|
|
}
|
|
|
|
- (void)setUp {
|
|
[super setUp];
|
|
_mockFIRAppClass = OCMClassMock([FIRApp class]);
|
|
_mockURLSession = OCMClassMock([NSURLSession class]);
|
|
_mockFIRInstallations = OCMClassMock([FIRInstallations class]);
|
|
_mockInstallationToken = OCMClassMock([FIRInstallationsAuthTokenResult class]);
|
|
_mockAuthToken = @"this-is-an-auth-token";
|
|
OCMStub([_mockFIRAppClass defaultApp]).andReturn(_mockFIRAppClass);
|
|
OCMStub([_mockURLSession sharedSession]).andReturn(_mockURLSession);
|
|
OCMStub([_mockFIRInstallations installations]).andReturn(_mockFIRInstallations);
|
|
OCMStub([_mockInstallationToken authToken]).andReturn(_mockAuthToken);
|
|
|
|
_mockInstallationId = @"this-id-is-fake-ccccc";
|
|
_mockReleases = @{
|
|
@"releases" : @[
|
|
@{
|
|
@"displayVersion" : @"1.0.0",
|
|
@"buildVersion" : @"111",
|
|
@"releaseNotes" : @"This is a release",
|
|
@"downloadURL" : @"http://faketyfakefake.download"
|
|
},
|
|
@{
|
|
@"latest" : @YES,
|
|
@"displayVersion" : @"1.0.1",
|
|
@"buildVersion" : @"112",
|
|
@"releaseNotes" : @"This is a release too",
|
|
@"downloadURL" : @"http://faketyfakefake.download"
|
|
}
|
|
]
|
|
};
|
|
}
|
|
|
|
- (void)tearDown {
|
|
[super tearDown];
|
|
[_mockFIRAppClass stopMocking];
|
|
[_mockFIRInstallations stopMocking];
|
|
[_mockInstallationToken stopMocking];
|
|
[_mockURLSession stopMocking];
|
|
}
|
|
|
|
- (void)mockInstallationAuthCompletion:(FIRInstallationsAuthTokenResult *_Nullable)token
|
|
error:(NSError *_Nullable)error {
|
|
[OCMStub([_mockFIRInstallations authTokenWithCompletion:OCMOCK_ANY])
|
|
andDo:^(NSInvocation *invocation) {
|
|
void (^handler)(FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
|
|
NSError *_Nullable error);
|
|
[invocation getArgument:&handler atIndex:2];
|
|
handler(token, error);
|
|
}];
|
|
}
|
|
|
|
- (void)verifyInstallationAuthCompletion {
|
|
OCMVerify([_mockFIRInstallations authTokenWithCompletion:[OCMArg isNotNil]]);
|
|
}
|
|
|
|
- (void)rejectInstallationAuthCompletion {
|
|
OCMReject([_mockFIRInstallations authTokenWithCompletion:[OCMArg isNotNil]]);
|
|
}
|
|
|
|
- (void)mockInstallationIdCompletion:(NSString *_Nullable)identifier
|
|
error:(NSError *_Nullable)error {
|
|
[OCMStub([_mockFIRInstallations installationIDWithCompletion:OCMOCK_ANY])
|
|
andDo:^(NSInvocation *invocation) {
|
|
void (^handler)(NSString *identifier, NSError *_Nullable error);
|
|
[invocation getArgument:&handler atIndex:2];
|
|
handler(identifier, error);
|
|
}];
|
|
}
|
|
|
|
- (void)verifyInstallationIdCompletion {
|
|
OCMVerify([_mockFIRInstallations installationIDWithCompletion:[OCMArg isNotNil]]);
|
|
}
|
|
|
|
- (void)rejectInstallationIdCompletion {
|
|
OCMReject([_mockFIRInstallations installationIDWithCompletion:[OCMArg isNotNil]]);
|
|
}
|
|
|
|
- (void)mockUrlSessionResponse:(NSDictionary *)dictionary
|
|
response:(NSURLResponse *)response
|
|
error:(NSError *)error {
|
|
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
|
|
[self mockUrlSessionResponseWithData:data response:response error:error];
|
|
}
|
|
|
|
- (void)mockUrlSessionResponseWithData:(NSData *)data
|
|
response:(NSURLResponse *)response
|
|
error:(NSError *)error {
|
|
[OCMStub([_mockURLSession dataTaskWithRequest:[OCMArg any]
|
|
completionHandler:[OCMArg any]]) andDo:^(NSInvocation *invocation) {
|
|
void (^handler)(NSData *data, NSURLResponse *response, NSError *error);
|
|
[invocation getArgument:&handler atIndex:3];
|
|
handler(data, response, error);
|
|
}];
|
|
}
|
|
|
|
- (void)verifyUrlSessionResponseWithData {
|
|
OCMVerify([_mockURLSession dataTaskWithRequest:[OCMArg isNotNil]
|
|
completionHandler:[OCMArg isNotNil]]);
|
|
}
|
|
|
|
- (void)rejectUrlSessionResponseWithData {
|
|
OCMReject([_mockURLSession dataTaskWithRequest:[OCMArg isNotNil]
|
|
completionHandler:[OCMArg isNotNil]]);
|
|
}
|
|
|
|
- (void)testGenerateAuthTokenWithCompletionSuccess {
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Generate auth token succeeds."];
|
|
|
|
[FIRFADApiService
|
|
generateAuthTokenWithCompletion:^(NSString *_Nullable identifier,
|
|
FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNotNil(authTokenResult);
|
|
XCTAssertNotNil(identifier);
|
|
XCTAssertNil(error);
|
|
XCTAssertEqual(identifier, self->_mockInstallationId);
|
|
XCTAssertEqual([authTokenResult authToken], self -> _mockAuthToken);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
}
|
|
|
|
- (void)testGenerateAuthTokenWithCompletionAuthTokenFailure {
|
|
[self mockInstallationAuthCompletion:nil
|
|
error:[NSError errorWithDomain:kFakeErrorDomain
|
|
code:1
|
|
userInfo:@{}]];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Generate auth token fails to generate auth token."];
|
|
|
|
[FIRFADApiService
|
|
generateAuthTokenWithCompletion:^(NSString *_Nullable identifier,
|
|
FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNil(identifier);
|
|
XCTAssertNil(authTokenResult);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual(error.code, FIRFADApiTokenGenerationFailure);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self rejectInstallationIdCompletion];
|
|
}
|
|
|
|
- (void)testGenerateAuthTokenWithCompletionIDFailure {
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:nil
|
|
error:[NSError errorWithDomain:kFakeErrorDomain
|
|
code:1
|
|
userInfo:@{}]];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Generate auth token fails to find ID."];
|
|
|
|
[FIRFADApiService
|
|
generateAuthTokenWithCompletion:^(NSString *_Nullable identifier,
|
|
FIRInstallationsAuthTokenResult *_Nullable authTokenResult,
|
|
NSError *_Nullable error) {
|
|
XCTAssertNil(identifier);
|
|
XCTAssertNil(authTokenResult);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRFADApiInstallationIdentifierError);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionSuccess {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(200);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases succeeds with two releases."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(error);
|
|
XCTAssertNotNil(releases);
|
|
XCTAssertEqual([releases count], 2);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionUnknownFailure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(200);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases
|
|
response:fakeResponse
|
|
error:[NSError errorWithDomain:kFakeErrorDomain code:1 userInfo:@{}]];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases fails with unknown error."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual(error.code, FIRApiErrorUnknownFailure);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionUnauthenticatedFailure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(401);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases fails with unknown error."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual(error.code, FIRFADApiErrorUnauthenticated);
|
|
[expectation fulfill];
|
|
}];
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionUnauthorized400Failure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(400);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a 400."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRFADApiErrorUnauthorized);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionUnauthorized403Failure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(403);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a 403."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRFADApiErrorUnauthorized);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionUnauthorized404Failure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(404);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a 404."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRFADApiErrorUnauthorized);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionTimeout408Failure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(408);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with 408."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRFADApiErrorTimeout);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionTimeout504Failure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(504);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a 504."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRFADApiErrorTimeout);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionUnknownStatusCodeFailure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(500);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:_mockReleases response:fakeResponse error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a 500."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRApiErrorUnknownFailure);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionNoReleasesFoundSuccess {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(200);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self mockUrlSessionResponse:@{@"releases" : @[]} response:fakeResponse error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a not found exception."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNotNil(releases);
|
|
XCTAssertNil(error);
|
|
XCTAssertEqual([releases count], 0);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
- (void)testFetchReleasesWithCompletionParsingFailure {
|
|
NSHTTPURLResponse *fakeResponse = OCMClassMock([NSHTTPURLResponse class]);
|
|
OCMStub([fakeResponse statusCode]).andReturn(200);
|
|
[self mockInstallationAuthCompletion:_mockInstallationToken error:nil];
|
|
[self mockInstallationIdCompletion:_mockInstallationId error:nil];
|
|
[self
|
|
mockUrlSessionResponseWithData:[@"malformed{json[data" dataUsingEncoding:NSUTF8StringEncoding]
|
|
response:fakeResponse
|
|
error:nil];
|
|
XCTestExpectation *expectation =
|
|
[self expectationWithDescription:@"Fetch releases rejects with a parsing failure."];
|
|
|
|
[FIRFADApiService
|
|
fetchReleasesWithCompletion:^(NSArray *_Nullable releases, NSError *_Nullable error) {
|
|
XCTAssertNil(releases);
|
|
XCTAssertNotNil(error);
|
|
XCTAssertEqual([error code], FIRApiErrorParseFailure);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
[self waitForExpectations:@[ expectation ] timeout:5.0];
|
|
[self verifyInstallationAuthCompletion];
|
|
[self verifyInstallationIdCompletion];
|
|
[self verifyUrlSessionResponseWithData];
|
|
OCMVerify([fakeResponse statusCode]);
|
|
}
|
|
|
|
@end
|