diff --git a/GoogleSignIn/Sources/GIDEMMSupport.h b/GoogleSignIn/Sources/GIDEMMSupport.h index f57a6af7..61f445a4 100644 --- a/GoogleSignIn/Sources/GIDEMMSupport.h +++ b/GoogleSignIn/Sources/GIDEMMSupport.h @@ -34,12 +34,13 @@ NS_ASSUME_NONNULL_BEGIN completion:(void (^)(NSError *_Nullable))completion; /// Gets a new set of URL parameters that contains updated EMM-related URL parameters if needed. -+ (NSDictionary *)updatedEMMParametersWithParameters:(NSDictionary *)parameters; ++ (NSDictionary *)updatedEMMParametersWithParameters: + (NSDictionary *)parameters; /// Gets a new set of URL parameters that also contains EMM-related URL parameters if needed. -+ (NSDictionary *)parametersWithParameters:(NSDictionary *)parameters - emmSupport:(nullable NSString *)emmSupport - isPasscodeInfoRequired:(BOOL)isPasscodeInfoRequired; ++ (NSDictionary *)parametersWithParameters:(NSDictionary *)parameters + emmSupport:(nullable NSString *)emmSupport + isPasscodeInfoRequired:(BOOL)isPasscodeInfoRequired; @end diff --git a/GoogleSignIn/Sources/GIDEMMSupport.m b/GoogleSignIn/Sources/GIDEMMSupport.m index 0e7b0369..0914d841 100644 --- a/GoogleSignIn/Sources/GIDEMMSupport.m +++ b/GoogleSignIn/Sources/GIDEMMSupport.m @@ -84,16 +84,16 @@ + (void)handleTokenFetchEMMError:(nullable NSError *)error } } -+ (NSDictionary *)updatedEMMParametersWithParameters:(NSDictionary *)parameters { ++ (NSDictionary *)updatedEMMParametersWithParameters: + (NSDictionary *)parameters { return [self parametersWithParameters:parameters emmSupport:parameters[kEMMSupportParameterName] isPasscodeInfoRequired:parameters[kEMMPasscodeInfoParameterName] != nil]; } - -+ (NSDictionary *)parametersWithParameters:(NSDictionary *)parameters - emmSupport:(nullable NSString *)emmSupport - isPasscodeInfoRequired:(BOOL)isPasscodeInfoRequired { ++ (NSDictionary *)parametersWithParameters:(NSDictionary *)parameters + emmSupport:(nullable NSString *)emmSupport + isPasscodeInfoRequired:(BOOL)isPasscodeInfoRequired { if (!emmSupport) { return parameters; } @@ -109,7 +109,7 @@ + (NSDictionary *)parametersWithParameters:(NSDictionary *)parameters if (isPasscodeInfoRequired) { allParameters[kEMMPasscodeInfoParameterName] = [GIDMDMPasscodeState passcodeState].info; } - return allParameters; + return [GIDEMMSupport dictionaryWithStringValuesFromDictionary:allParameters]; } #pragma mark - GTMAuthSessionDelegate @@ -128,6 +128,30 @@ - (void)updateErrorForAuthSession:(GTMAuthSession *)authSession }]; } +#pragma mark - Private Helpers + ++ (NSDictionary *) + dictionaryWithStringValuesFromDictionary:(NSDictionary *)originalDictionary { + NSMutableDictionary *stringifiedDictionary = + [NSMutableDictionary dictionaryWithCapacity:originalDictionary.count]; + + [originalDictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { + if ([value isKindOfClass:[NSString class]]) { + stringifiedDictionary[key] = value; + return; + } + if ([value isKindOfClass:[NSNumber class]]) { + if (CFGetTypeID((__bridge CFTypeRef)value) == CFBooleanGetTypeID()) { + stringifiedDictionary[key] = [value boolValue] ? @"true" : @"false"; + } else { + stringifiedDictionary[key] = [value stringValue]; + } + return; + } + }]; + return stringifiedDictionary; +} + @end NS_ASSUME_NONNULL_END diff --git a/GoogleSignIn/Tests/Unit/GIDEMMSupportTest.m b/GoogleSignIn/Tests/Unit/GIDEMMSupportTest.m index 990aa733..9aece13b 100644 --- a/GoogleSignIn/Tests/Unit/GIDEMMSupportTest.m +++ b/GoogleSignIn/Tests/Unit/GIDEMMSupportTest.m @@ -274,6 +274,86 @@ - (void)testHandleTokenFetchEMMError_errorIsNotEMM { [self waitForExpectations:@[ called ] timeout:1]; } +# pragma mark - String Conversion Tests + +- (void)testParametersWithParameters_withAnyNumber_isConvertedToString { + NSDictionary *inputParameters = @{ @"number_key": @12345 }; + + NSDictionary *stringifiedParameters = [GIDEMMSupport parametersWithParameters:inputParameters + emmSupport:@"1" + isPasscodeInfoRequired:NO]; + + XCTAssertEqualObjects(stringifiedParameters[@"number_key"], @"12345", + @"The NSNumber should be converted to a string."); + XCTAssertTrue([stringifiedParameters[@"number_key"] isKindOfClass:[NSString class]], + @"The final value should be of a NSString type."); +} + +- (void)testParametersWithParameters_withNumberOne_isConvertedToString { + NSDictionary *inputParameters = @{ @"number_key": @1 }; + + NSDictionary *stringifiedParameters = [GIDEMMSupport parametersWithParameters:inputParameters + emmSupport:@"1" + isPasscodeInfoRequired:NO]; + + XCTAssertEqualObjects(stringifiedParameters[@"number_key"], @"1", + @"The NSNumber should be converted to a string."); + XCTAssertTrue([stringifiedParameters[@"number_key"] isKindOfClass:[NSString class]], + @"The final value should be of a NSString type."); +} + +- (void)testParametersWithParameters_withNumberZero_isConvertedToString { + NSDictionary *inputParameters = @{ @"number_key": @0}; + + NSDictionary *stringifiedParameters = [GIDEMMSupport parametersWithParameters:inputParameters + emmSupport:@"1" + isPasscodeInfoRequired:NO]; + + XCTAssertEqualObjects(stringifiedParameters[@"number_key"], @"0", + @"The NSNumber should be converted to a string."); + XCTAssertTrue([stringifiedParameters[@"number_key"] isKindOfClass:[NSString class]], + @"The final value should be of a NSString type."); +} + +- (void)testParametersWithParameters_withBooleanYes_isConvertedToTrueString { + NSDictionary *inputParameters = @{ @"bool_key": @YES }; + + NSDictionary *stringifiedParameters = [GIDEMMSupport parametersWithParameters:inputParameters + emmSupport:@"1" + isPasscodeInfoRequired:NO]; + + XCTAssertEqualObjects(stringifiedParameters[@"bool_key"], @"true", + @"The boolean YES should be converted to the string 'true'."); + XCTAssertTrue([stringifiedParameters[@"bool_key"] isKindOfClass:[NSString class]], + @"The final value should be of a NSString type."); +} + +- (void)testParametersWithParameters_withBooleanNo_isConvertedToFalseString { + NSDictionary *inputParameters = @{ @"bool_key": @NO }; + + NSDictionary *stringifiedParameters = [GIDEMMSupport parametersWithParameters:inputParameters + emmSupport:@"1" + isPasscodeInfoRequired:NO]; + + XCTAssertEqualObjects(stringifiedParameters[@"bool_key"], @"false", + @"The boolean NO should be converted to the string 'false'."); + XCTAssertTrue([stringifiedParameters[@"bool_key"] isKindOfClass:[NSString class]], + @"The final value should be of a NSString type."); +} + +- (void)testParametersWithParameters_withString_remainsUnchanged { + NSDictionary *inputParameters = @{ @"string_key": @"hello" }; + + NSDictionary *stringifiedParameters = [GIDEMMSupport parametersWithParameters:inputParameters + emmSupport:@"1" + isPasscodeInfoRequired:NO]; + + XCTAssertEqualObjects(stringifiedParameters[@"string_key"], @"hello", + @"The original string value should be preserved."); + XCTAssertTrue([stringifiedParameters[@"string_key"] isKindOfClass:[NSString class]], + @"The final value should be of a NSString type."); +} + # pragma mark - Helpers - (NSString *)systemVersion {