Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions AppAuth.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@
2D93865224B38840009A12D7 /* OIDTVServiceConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D47AADA249A87010059B5A4 /* OIDTVServiceConfiguration.m */; };
2DEB065624CA1D9300DF47E7 /* OIDTVTokenRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DEB065424CA1D9300DF47E7 /* OIDTVTokenRequest.h */; };
2DEB065724CA1D9300DF47E7 /* OIDTVTokenRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DEB065524CA1D9300DF47E7 /* OIDTVTokenRequest.m */; };
2DEB066124CF5CE000DF47E7 /* OIDTVTokenRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DEB066024CF5CE000DF47E7 /* OIDTVTokenRequestTests.m */; };
2DEB066224CF5CFB00DF47E7 /* OIDTVTokenRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DEB066024CF5CE000DF47E7 /* OIDTVTokenRequestTests.m */; };
340DAE571D5821A100EC285B /* OIDAuthorizationService+Mac.m in Sources */ = {isa = PBXBuildFile; fileRef = 340DAE261D581FE700EC285B /* OIDAuthorizationService+Mac.m */; };
340DAE581D5821A100EC285B /* OIDExternalUserAgentMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 340DAE281D581FE700EC285B /* OIDExternalUserAgentMac.m */; };
340DAE591D5821A100EC285B /* OIDAuthState+Mac.m in Sources */ = {isa = PBXBuildFile; fileRef = 340DAE2A1D581FE700EC285B /* OIDAuthState+Mac.m */; };
Expand Down Expand Up @@ -774,6 +776,8 @@
2D9385BA24B37CAD009A12D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2DEB065424CA1D9300DF47E7 /* OIDTVTokenRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OIDTVTokenRequest.h; sourceTree = "<group>"; };
2DEB065524CA1D9300DF47E7 /* OIDTVTokenRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OIDTVTokenRequest.m; sourceTree = "<group>"; };
2DEB065F24CF5CDF00DF47E7 /* OIDTVTokenRequestTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OIDTVTokenRequestTests.h; sourceTree = "<group>"; };
2DEB066024CF5CE000DF47E7 /* OIDTVTokenRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OIDTVTokenRequestTests.m; sourceTree = "<group>"; };
340DAE251D581FE700EC285B /* OIDAuthorizationService+Mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OIDAuthorizationService+Mac.h"; sourceTree = "<group>"; };
340DAE261D581FE700EC285B /* OIDAuthorizationService+Mac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OIDAuthorizationService+Mac.m"; sourceTree = "<group>"; };
340DAE271D581FE700EC285B /* OIDExternalUserAgentMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OIDExternalUserAgentMac.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1092,6 +1096,8 @@
children = (
2D81120324C1036700984DA7 /* OIDTVAuthorizationRequestTests.h */,
2D81120024C1036700984DA7 /* OIDTVAuthorizationRequestTests.m */,
2DEB065F24CF5CDF00DF47E7 /* OIDTVTokenRequestTests.h */,
2DEB066024CF5CE000DF47E7 /* OIDTVTokenRequestTests.m */,
);
path = AppAuthTV;
sourceTree = "<group>";
Expand Down Expand Up @@ -2184,6 +2190,7 @@
files = (
2D81120C24C103F300984DA7 /* OIDScopesTests.m in Sources */,
2D81121224C103F300984DA7 /* OIDURLQueryComponentTests.m in Sources */,
2DEB066224CF5CFB00DF47E7 /* OIDTVTokenRequestTests.m in Sources */,
2D81120D24C103F300984DA7 /* OIDServiceConfigurationTests.m in Sources */,
2D81121324C103F300984DA7 /* OIDURLQueryComponentTestsIOS7.m in Sources */,
2D81121524C103F300984DA7 /* OIDRegistrationResponseTests.m in Sources */,
Expand Down Expand Up @@ -2340,6 +2347,7 @@
340DAECB1D582DE100EC285B /* OIDAuthorizationService+IOS.m in Sources */,
341741E31C5D8243000EF209 /* OIDResponseTypes.m in Sources */,
341741E41C5D8243000EF209 /* OIDScopes.m in Sources */,
2DEB066124CF5CE000DF47E7 /* OIDTVTokenRequestTests.m in Sources */,
341741E71C5D8243000EF209 /* OIDServiceDiscovery.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
51 changes: 51 additions & 0 deletions UnitTests/AppAuthTV/OIDTVTokenRequestTests.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*! @file OIDTVTokenRequestTests.h
@brief AppAuth iOS SDK
@copyright
Copyright 2020 Google Inc. All Rights Reserved.
@copydetails
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/XCTest.h>

@class OIDTVTokenRequest;

NS_ASSUME_NONNULL_BEGIN

/*! @brief Unit tests for @c OIDTVTokenRequest.
*/
@interface OIDTVTokenRequestTests : XCTestCase

/*! @brief Tests the initializer
*/
- (void)testInitializer;

/*! @brief Tests the @c NSCopying implementation by round-tripping an instance through the copying
* process and checking to make sure the source and destination both contain the @c deviceCode.
*/
- (void)testCopying;

/*! @brief Tests the @c NSSecureCoding implementation by round-tripping an instance through the
* coding process and checking to make sure the source and destination both contain the
* @c deviceCode
*/
- (void)testSecureCoding;

/*! @brief Tests the @c URLRequest method to verify that the body parameters include the correct
* grant type, device code and additional parameters.
*/
- (void)testURLRequest;

@end

NS_ASSUME_NONNULL_END
194 changes: 194 additions & 0 deletions UnitTests/AppAuthTV/OIDTVTokenRequestTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*! @file OIDTVTokenRequestTests.m
@brief AppAuth iOS SDK
@copyright
Copyright 2020 Google Inc. All Rights Reserved.
@copydetails
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 "OIDTVTokenRequestTests.h"

#if SWIFT_PACKAGE
@import AppAuthTV;
#else
#import "Source/AppAuthCore/OIDScopeUtilities.h"
#import "Source/AppAuthTV/OIDTVAuthorizationRequest.h"
#import "Source/AppAuthTV/OIDTVAuthorizationResponse.h"
#import "Source/AppAuthTV/OIDTVServiceConfiguration.h"
#import "Source/AppAuthTV/OIDTVTokenRequest.h"
#endif

// Ignore warnings about "Use of GNU statement expression extension" which is
// raised by our use of the XCTAssert___ macros.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wgnu"

/*! @brief Test value for the @c TVAuthorizationEndpoint property.
*/
static NSString *const kTestTVAuthorizationEndpoint =
@"https://www.example.com/device/code";

/*! @brief Test value for the @c tokenEndpoint property.
*/
static NSString *const kTestTokenEndpoint = @"https://www.example.com/token";

/*! @brief Test key for the @c additionalParameters property.
*/
static NSString *const kTestAdditionalParameterKey = @"A";

/*! @brief Test value for the @c additionalParameters property.
*/
static NSString *const kTestAdditionalParameterValue = @"1";

/*! @brief Test key for the @c clientID parameter in the HTTP request.
*/
static NSString *const kTestClientIDKey = @"client_id";

/*! @brief Test value for the @c clientID property.
*/
static NSString *const kTestClientID = @"ClientID";

/*! @brief Test value for the @c clientSecret property.
*/
static NSString *const kTestClientSecret = @"ClientSecret";

/*! @brief Key for the @c deviceCode property for @c NSSecureCoding and the HTTP request body.
*/
static NSString *const kDeviceCodeKey = @"device_code";

/*! @brief Value for the @c deviceCode key in the HTTP request body.
*/
static NSString *const kDeviceCodeValue = @"DeviceCode";

/*! @brief Key for the @c grantType property for @c NSSecureCoding and the HTTP request body.
*/
static NSString *const kGrantTypeKey = @"grant_type";

/*! @brief Value for the @c grant_type key in the HTTP request body
* @see https://tools.ietf.org/html/rfc8628#section-3.4
*/
static NSString *const kOIDTVDeviceTokenGrantType =
@"urn:ietf:params:oauth:grant-type:device_code";

@implementation OIDTVTokenRequestTests

- (NSDictionary<NSString *, NSString *> *)bodyParametersFromURLRequest:
(NSURLRequest *)URLRequest {
NSString *bodyString = [[NSString alloc] initWithData:URLRequest.HTTPBody
encoding:NSUTF8StringEncoding];
NSArray<NSString *> *bodyParameterStrings =
[bodyString componentsSeparatedByString:@"&"];

NSMutableDictionary<NSString *, NSString *> *bodyParameters =
[[NSMutableDictionary alloc] init];

for (NSString *paramString in bodyParameterStrings) {
NSArray<NSString *> *components =
[paramString componentsSeparatedByString:@"="];

if (components.count == 2) {
bodyParameters[components[0]] = components[1];
}
}

return bodyParameters;
}

- (OIDTVServiceConfiguration *)testServiceConfiguration {
NSURL *tokenEndpoint = [NSURL URLWithString:kTestTokenEndpoint];
NSURL *TVAuthorizationEndpoint = [NSURL URLWithString:kTestTVAuthorizationEndpoint];

// Pass in an empty authorizationEndpoint since only the
// TVAuthorizationEndpoint and tokenEndpoint are used for the TV
// authentication flow.
OIDTVServiceConfiguration *configuration = [[OIDTVServiceConfiguration alloc]
initWithAuthorizationEndpoint:[[NSURL alloc] initWithString:@""]
TVAuthorizationEndpoint:TVAuthorizationEndpoint
tokenEndpoint:tokenEndpoint];
return configuration;
}

- (OIDTVTokenRequest *)testTokenRequest {
OIDTVServiceConfiguration *service = [self testServiceConfiguration];
return [[OIDTVTokenRequest alloc]
initWithConfiguration:service
deviceCode:kDeviceCodeValue
clientID:kTestClientID
clientSecret:kTestClientSecret
additionalParameters:@{kTestAdditionalParameterKey : kTestAdditionalParameterValue}];
}

/*! @brief Tests the initializer
*/
- (void)testInitializer {
OIDTVTokenRequest *request = [self testTokenRequest];
NSURL *requestTVAuthorizationEndpoint =
((OIDTVServiceConfiguration *)request.configuration).TVAuthorizationEndpoint;

XCTAssertEqualObjects(requestTVAuthorizationEndpoint,
[self testServiceConfiguration].TVAuthorizationEndpoint);
XCTAssertEqualObjects(request.deviceCode, kDeviceCodeValue);
XCTAssertEqualObjects(request.grantType, kOIDTVDeviceTokenGrantType);
XCTAssertEqualObjects(request.clientID, kTestClientID);
XCTAssertEqualObjects(request.clientSecret, kTestClientSecret);
XCTAssertEqualObjects(request.additionalParameters,
@{kTestAdditionalParameterKey:kTestAdditionalParameterValue});
}

/*! @brief Tests the @c NSCopying implementation by round-tripping an instance through the copying
* process and checking to make sure the source and destination both contain the @c deviceCode.
*/
- (void)testCopying {
OIDTVTokenRequest *request = [self testTokenRequest];
OIDTVTokenRequest *requestCopy = [request copy];

XCTAssertEqualObjects(requestCopy.deviceCode, request.deviceCode);
}

/*! @brief Tests the @c NSSecureCoding implementation by round-tripping an instance through the
* coding process and checking to make sure the source and destination both contain the
* @c deviceCode
*/
- (void)testSecureCoding {
OIDTVTokenRequest *request = [self testTokenRequest];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:request];
OIDTVTokenRequest *requestDecoded = [NSKeyedUnarchiver unarchiveObjectWithData:data];
XCTAssertEqualObjects(requestDecoded.deviceCode, request.deviceCode);
}

/*! @brief Tests the @c URLRequest method to verify that the body parameters include the correct
* grant type, device code and additional parameters.
*/
- (void)testURLRequest {
OIDTVTokenRequest *request = [self testTokenRequest];

NSURLRequest *URLRequest = [request URLRequest];

NSDictionary<NSString *, NSString *> *bodyParameters =
[self bodyParametersFromURLRequest:URLRequest];

// Since clientSecret is present, we will not need to check for client_id
// as that will be passed in using HTTP Basic Authentication

NSDictionary<NSString *, NSString *> *expectedParameters = @{
kGrantTypeKey : kOIDTVDeviceTokenGrantType,
kDeviceCodeKey : kDeviceCodeValue,
kTestAdditionalParameterKey : kTestAdditionalParameterValue
};

XCTAssertEqualObjects(bodyParameters, expectedParameters);
}

@end

#pragma GCC diagnostic pop