From f191868209de5bb8fb177d528221a00a8f788f5e Mon Sep 17 00:00:00 2001 From: Andrew Heard Date: Wed, 30 Aug 2023 11:44:09 -0400 Subject: [PATCH] Add `GACAppCheckTokenResult` type (#18) --- AppCheckCore/Sources/Core/GACAppCheck.m | 2 - .../Sources/Core/GACAppCheckTokenResult.m | 51 ++++++++++ .../Public/AppCheckCore/AppCheckCore.h | 1 + .../AppCheckCore/GACAppCheckTokenResult.h | 43 +++++++++ .../Unit/Core/GACAppCheckTokenResultTests.m | 93 +++++++++++++++++++ 5 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 AppCheckCore/Sources/Core/GACAppCheckTokenResult.m create mode 100644 AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckTokenResult.h create mode 100644 AppCheckCore/Tests/Unit/Core/GACAppCheckTokenResultTests.m diff --git a/AppCheckCore/Sources/Core/GACAppCheck.m b/AppCheckCore/Sources/Core/GACAppCheck.m index f05333c..7f5b5cc 100644 --- a/AppCheckCore/Sources/Core/GACAppCheck.m +++ b/AppCheckCore/Sources/Core/GACAppCheck.m @@ -38,8 +38,6 @@ static const NSTimeInterval kTokenExpirationThreshold = 5 * 60; // 5 min. -static NSString *const kDummyFACTokenValue = @"eyJlcnJvciI6IlVOS05PV05fRVJST1IifQ=="; - typedef void (^GACAppCheckTokenHandler)(id _Nullable token, NSError *_Nullable error); diff --git a/AppCheckCore/Sources/Core/GACAppCheckTokenResult.m b/AppCheckCore/Sources/Core/GACAppCheckTokenResult.m new file mode 100644 index 0000000..4bb86df --- /dev/null +++ b/AppCheckCore/Sources/Core/GACAppCheckTokenResult.m @@ -0,0 +1,51 @@ +/* + * Copyright 2023 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 "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckTokenResult.h" + +#import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckToken.h" + +/// Placeholder value that indicates failure. +/// This value is `{"error":"UNKNOWN_ERROR"}` encoded as base64. +static NSString *const kPlaceholderTokenValue = @"eyJlcnJvciI6IlVOS05PV05fRVJST1IifQ=="; + +@implementation GACAppCheckTokenResult + +- (instancetype)initWithToken:(GACAppCheckToken *)token error:(NSError *)error { + if (self = [super init]) { + _token = token; + _error = error; + } + + return self; +} + +- (instancetype)initWithToken:(GACAppCheckToken *)token { + return [self initWithToken:token error:nil]; +} + +- (instancetype)initWithError:(NSError *)error { + return [self initWithToken:[[self class] placeholderToken] error:error]; +} + +#pragma mark - Internal + ++ (GACAppCheckToken *)placeholderToken { + return [[GACAppCheckToken alloc] initWithToken:kPlaceholderTokenValue + expirationDate:[NSDate distantPast]]; +} + +@end diff --git a/AppCheckCore/Sources/Public/AppCheckCore/AppCheckCore.h b/AppCheckCore/Sources/Public/AppCheckCore/AppCheckCore.h index e55dfbb..a075215 100644 --- a/AppCheckCore/Sources/Public/AppCheckCore/AppCheckCore.h +++ b/AppCheckCore/Sources/Public/AppCheckCore/AppCheckCore.h @@ -21,6 +21,7 @@ #import "GACAppCheckSettings.h" #import "GACAppCheckToken.h" #import "GACAppCheckTokenDelegate.h" +#import "GACAppCheckTokenResult.h" // Debug provider #import "GACAppCheckDebugProvider.h" diff --git a/AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckTokenResult.h b/AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckTokenResult.h new file mode 100644 index 0000000..8673396 --- /dev/null +++ b/AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckTokenResult.h @@ -0,0 +1,43 @@ +/* + * Copyright 2023 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 + +NS_ASSUME_NONNULL_BEGIN + +@class GACAppCheckToken; + +NS_SWIFT_NAME(AppCheckCoreTokenResult) +@interface GACAppCheckTokenResult : NSObject + +/// An App Check token in the case of success or a placeholder token in the case of a failure. +@property(nonatomic, readonly) GACAppCheckToken *token; + +/// A token fetch error in the case of a failure or `nil` in the case of success. +@property(nonatomic, readonly, nullable) NSError *error; + +- (instancetype)initWithToken:(GACAppCheckToken *)token; + +- (instancetype)initWithError:(NSError *)error; + +- (instancetype)initWithToken:(GACAppCheckToken *)token + error:(nullable NSError *)error NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/AppCheckCore/Tests/Unit/Core/GACAppCheckTokenResultTests.m b/AppCheckCore/Tests/Unit/Core/GACAppCheckTokenResultTests.m new file mode 100644 index 0000000..37198d0 --- /dev/null +++ b/AppCheckCore/Tests/Unit/Core/GACAppCheckTokenResultTests.m @@ -0,0 +1,93 @@ +/* + * Copyright 2023 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 XCTest; + +#import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckToken.h" +#import "AppCheckCore/Sources/Public/AppCheckCore/GACAppCheckTokenResult.h" + +static NSString *const kTestTokenValue = @"test-token"; +/// Placeholder value that indicates failure: `{"error":"UNKNOWN_ERROR"}` encoded as base64 +static NSString *const kPlaceholderTokenValue = @"eyJlcnJvciI6IlVOS05PV05fRVJST1IifQ=="; +static NSString *const kTestErrorDomain = @"TestErrorDomain"; +static NSInteger const kTestErrorCode = 42; + +@interface GACAppCheckTokenResult (Tests) + ++ (GACAppCheckToken *)placeholderToken; + +@end + +@interface GACAppCheckTokenResultTests : XCTestCase +@end + +@implementation GACAppCheckTokenResultTests + +- (void)testInitWithToken { + NSDate *expectedExpirationDate = [NSDate dateWithTimeIntervalSince1970:1693314000.0]; + NSDate *expectedReceivedAtDate = [NSDate dateWithTimeIntervalSince1970:1693317600.0]; + GACAppCheckToken *expectedToken = [[GACAppCheckToken alloc] initWithToken:kTestTokenValue + expirationDate:expectedExpirationDate + receivedAtDate:expectedReceivedAtDate]; + + GACAppCheckTokenResult *tokenResult = + [[GACAppCheckTokenResult alloc] initWithToken:expectedToken]; + + XCTAssertEqualObjects(tokenResult.token, expectedToken); + XCTAssertNil(tokenResult.error); +} + +- (void)testInitWithError { + NSError *expectedError = [NSError errorWithDomain:kTestErrorDomain + code:kTestErrorCode + userInfo:nil]; + + GACAppCheckTokenResult *tokenResult = + [[GACAppCheckTokenResult alloc] initWithError:expectedError]; + + XCTAssertEqualObjects(tokenResult.token.token, kPlaceholderTokenValue); + XCTAssertNotNil(tokenResult.error); + XCTAssertEqualObjects(tokenResult.error, expectedError); +} + +- (void)testInitWithTokenAndError { + GACAppCheckToken *placeholderToken = [GACAppCheckTokenResult placeholderToken]; + NSError *expectedError = [NSError errorWithDomain:kTestErrorDomain + code:kTestErrorCode + userInfo:nil]; + + GACAppCheckTokenResult *tokenResult = + [[GACAppCheckTokenResult alloc] initWithToken:placeholderToken error:expectedError]; + + XCTAssertEqualObjects(tokenResult.token, placeholderToken); + XCTAssertNotNil(tokenResult.error); + XCTAssertEqualObjects(tokenResult.error, expectedError); +} + +- (void)testPlaceholderToken { + NSDate *expectedExpirationDate = [NSDate distantPast]; + NSDate *expectedReceivedAtDate = [NSDate date]; // Current time + + GACAppCheckToken *placeholderToken = [GACAppCheckTokenResult placeholderToken]; + + XCTAssertEqualObjects(placeholderToken.token, kPlaceholderTokenValue); + // Verify that the placeholder token's received at time is approximately equal to current time. + XCTAssertEqualWithAccuracy( + [placeholderToken.receivedAtDate timeIntervalSinceDate:expectedReceivedAtDate], 0, 5.0); + XCTAssertEqualObjects(placeholderToken.expirationDate, expectedExpirationDate); +} + +@end