From b2d5f81af540dfcf77edfa7d93c108ab4dece91d Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 14 Jul 2021 18:09:55 -0700 Subject: [PATCH 1/8] [google_sign_in] Add iOS unit tests --- .../google_sign_in/CHANGELOG.md | 1 + .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../ios/Runner.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/xcschemes/Runner.xcscheme | 3 +- .../ios/RunnerTests/GoogleSignInTests.m | 439 +++++++++++++++--- .../ios/Classes/FLTGoogleSignInPlugin.m | 14 +- 6 files changed, 399 insertions(+), 64 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index cb4a65f42fa2..4aad80dbb352 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,6 +1,7 @@ ## NEXT * Add iOS unit and UI integration test targets. +* Add iOS unit tests. * Exclude arm64 simulators in example app. ## 5.0.4 diff --git a/packages/google_sign_in/google_sign_in/example/ios/Flutter/AppFrameworkInfo.plist b/packages/google_sign_in/google_sign_in/example/ios/Flutter/AppFrameworkInfo.plist index 6c2de8086bcd..3a9c234f96d4 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/google_sign_in/google_sign_in/example/ios/Flutter/AppFrameworkInfo.plist @@ -25,6 +25,6 @@ arm64 MinimumOSVersion - 8.0 + 9.0 diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj index 0c3cc430d23e..06857ed2bd59 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj @@ -539,7 +539,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -589,7 +589,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index f85273f21768..c6684a7fbf98 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,7 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES" + codeCoverageEnabled = "YES"> *mockBinaryMessenger; @property(strong, nonatomic) NSObject *mockPluginRegistrar; @property(strong, nonatomic) FLTGoogleSignInPlugin *plugin; -@property(strong, nonatomic) GIDSignIn *mockSharedInstance; +@property(strong, nonatomic) id mockSharedInstance; @end @@ -26,79 +26,416 @@ - (void)setUp { [super setUp]; self.mockBinaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); self.mockPluginRegistrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); - self.mockSharedInstance = [OCMockObject partialMockForObject:[GIDSignIn sharedInstance]]; + + id mockSharedInstance = OCMClassMock([GIDSignIn class]); + OCMStub([mockSharedInstance sharedInstance]).andReturn(mockSharedInstance); + self.mockSharedInstance = mockSharedInstance; + OCMStub(self.mockPluginRegistrar.messenger).andReturn(self.mockBinaryMessenger); self.plugin = [[FLTGoogleSignInPlugin alloc] init]; [FLTGoogleSignInPlugin registerWithRegistrar:self.mockPluginRegistrar]; } - (void)tearDown { - [((OCMockObject *)self.mockSharedInstance) stopMocking]; + [self.mockSharedInstance stopMocking]; [super tearDown]; } +- (void)testUnimplementedMethod { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"bogus" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(id result) { + XCTAssertEqualObjects(result, FlutterMethodNotImplemented); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testSignOut { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"signOut" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(id result) { + XCTAssertNil(result); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + OCMVerify([self.mockSharedInstance signOut]); +} + +- (void)testDisconnect { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"disconnect" + arguments:nil]; + + [self.plugin handleMethodCall:methodCall result:^(id result) {}]; + OCMVerify([self.mockSharedInstance disconnect]); +} + +- (void)testClearAuthCache { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"clearAuthCache" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(id result) { + XCTAssertNil(result); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +#pragma mark - Init + +- (void)testInitGamesSignInUnsupported { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"init" + arguments:@{@"signInOption" : @"SignInOption.games"}]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"unsupported-options"); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testInitGoogleServiceInfoPlist { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"init" + arguments:@{@"scopes" : @[ @"mockScope1" ], @"hostedDomain" : @"example.com"}]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(id result) { + XCTAssertNil(result); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + + id mockSharedInstance = self.mockSharedInstance; + OCMVerify([mockSharedInstance setScopes:@[ @"mockScope1" ]]); + OCMVerify([mockSharedInstance setHostedDomain:@"example.com"]); + + // Set in example app GoogleService-Info.plist. + OCMVerify([mockSharedInstance setClientID:@"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com"]); + OCMVerify([mockSharedInstance setServerClientID:@"YOUR_SERVER_CLIENT_ID"]); +} + +- (void)testInitNullDomain { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"init" + arguments:@{@"hostedDomain" : [NSNull null]}]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(id r) { + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + OCMVerify([self.mockSharedInstance setHostedDomain:nil]); +} + +- (void)testInitDynamicClientId { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"init" + arguments:@{@"clientId" : @"mockClientId"}]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall result:^(id r) { + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; + OCMVerify([self.mockSharedInstance setClientID:@"mockClientId"]); +} + +#pragma mark - Is signed in + +- (void)testIsNotSignedIn { + OCMStub([self.mockSharedInstance hasPreviousSignIn]).andReturn(NO); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"isSignedIn" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(NSNumber *result) { + XCTAssertFalse(result.boolValue); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testIsSignedIn { + OCMStub([self.mockSharedInstance hasPreviousSignIn]).andReturn(YES); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"isSignedIn" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(NSNumber *result) { + XCTAssertTrue(result.boolValue); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +#pragma mark - Sign in silently + +- (void)testSignInSilently { + OCMExpect([self.mockSharedInstance restorePreviousSignIn]); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"signInSilently" + arguments:nil]; + + [self.plugin handleMethodCall:methodCall + result:^(id result) {}]; + OCMVerifyAll(self.mockSharedInstance); +} + +- (void)testSignInSilentlyFailsConcurrently { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"signInSilently" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + + OCMExpect([self.mockSharedInstance restorePreviousSignIn]).andDo(^(NSInvocation *invocation) { + // Simulate calling the same method while the previous one is in flight. + [self.plugin handleMethodCall:methodCall + result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"concurrent-requests"); + [expectation fulfill]; + }]; + }); + + [self.plugin handleMethodCall:methodCall + result:^(id result) {}]; + + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +#pragma mark - Sign in + +- (void)testSignIn { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"signIn" + arguments:nil]; + + [self.plugin handleMethodCall:methodCall + result:^(NSNumber *result) {}]; + + id mockSharedInstance = self.mockSharedInstance; + OCMVerify([mockSharedInstance setPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]]); + OCMVerify([mockSharedInstance signIn]); +} + +- (void)testSignInExecption { + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"signIn" + arguments:nil]; + OCMExpect([self.mockSharedInstance signIn]).andThrow([NSException exceptionWithName:@"MockName" reason:@"MockReason" userInfo:nil]); + + __block FlutterError *error; + XCTAssertThrows( + [self.plugin handleMethodCall:methodCall + result:^(FlutterError *result) { + error = result; + }]); + + + XCTAssertEqualObjects(error.code, @"google_sign_in"); + XCTAssertEqualObjects(error.message, @"MockReason"); + XCTAssertEqualObjects(error.details, @"MockName"); +} + +#pragma mark - Get tokens + +- (void)testGetTokens { + id mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + + id mockAuthentication = OCMClassMock([GIDAuthentication class]); + OCMStub([mockAuthentication idToken]).andReturn(@"mockIdToken"); + OCMStub([mockAuthentication accessToken]).andReturn(@"mockAccessToken"); + [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:mockAuthentication, [NSNull null], nil]]; + OCMStub([mockUser authentication]).andReturn(mockAuthentication); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(NSDictionary *result) { + XCTAssertEqualObjects(result[@"idToken"], @"mockIdToken"); + XCTAssertEqualObjects(result[@"accessToken"], @"mockAccessToken"); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testGetTokensNoAuthKeychainError { + id mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + + id mockAuthentication = OCMClassMock([GIDAuthentication class]); + NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain code:kGIDSignInErrorCodeHasNoAuthInKeychain userInfo:nil]; + [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + OCMStub([mockUser authentication]).andReturn(mockAuthentication); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"sign_in_required"); + XCTAssertEqualObjects(result.message, kGIDSignInErrorDomain); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testGetTokensCancelledError { + id mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + + id mockAuthentication = OCMClassMock([GIDAuthentication class]); + NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain code:kGIDSignInErrorCodeCanceled userInfo:nil]; + [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + OCMStub([mockUser authentication]).andReturn(mockAuthentication); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"sign_in_canceled"); + XCTAssertEqualObjects(result.message, kGIDSignInErrorDomain); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testGetTokensURLError { + id mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + + id mockAuthentication = OCMClassMock([GIDAuthentication class]); + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:nil]; + [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + OCMStub([mockUser authentication]).andReturn(mockAuthentication); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"network_error"); + XCTAssertEqualObjects(result.message, NSURLErrorDomain); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +- (void)testGetTokensUnknownError { + id mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + + id mockAuthentication = OCMClassMock([GIDAuthentication class]); + NSError *error = [NSError errorWithDomain:@"BogusDomain" code:42 userInfo:nil]; + [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + OCMStub([mockUser authentication]).andReturn(mockAuthentication); + + FlutterMethodCall *methodCall = + [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; + + XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; + [self.plugin handleMethodCall:methodCall + result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"sign_in_failed"); + XCTAssertEqualObjects(result.message, @"BogusDomain"); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + +#pragma mark - Request scopes + - (void)testRequestScopesResultErrorIfNotSignedIn { - OCMStub(self.mockSharedInstance.currentUser).andReturn(nil); + OCMStub([self.mockSharedInstance currentUser]).andReturn(nil); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : @[ @"mockScope1" ]}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : @[ @"mockScope1" ]}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; - __block id result; [self.plugin handleMethodCall:methodCall - result:^(id r) { - [expectation fulfill]; - result = r; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertEqualObjects([((FlutterError *)result) code], @"sign_in_required"); + result:^(FlutterError *result) { + XCTAssertEqualObjects(result.code, @"sign_in_required"); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; } - (void)testRequestScopesIfNoMissingScope { // Mock Google Signin internal calls - GIDGoogleUser *mockUser = OCMClassMock(GIDGoogleUser.class); - OCMStub(self.mockSharedInstance.currentUser).andReturn(mockUser); + GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(requestedScopes); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; - __block id result; [self.plugin handleMethodCall:methodCall - result:^(id r) { - [expectation fulfill]; - result = r; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertTrue([result boolValue]); + result:^(NSNumber *result) { + XCTAssertTrue(result.boolValue); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; } - (void)testRequestScopesRequestsIfNotGranted { // Mock Google Signin internal calls - GIDGoogleUser *mockUser = OCMClassMock(GIDGoogleUser.class); - OCMStub(self.mockSharedInstance.currentUser).andReturn(mockUser); + GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(@[]); + id mockSharedInstance = self.mockSharedInstance; + OCMStub([mockSharedInstance scopes]).andReturn(@[]); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; [self.plugin handleMethodCall:methodCall result:^(id r){ - }]; + }]; - XCTAssertTrue([self.mockSharedInstance.scopes containsObject:@"mockScope1"]); - OCMVerify([self.mockSharedInstance signIn]); + OCMVerify([mockSharedInstance setScopes:@[ @"mockScope1" ]]); + OCMVerify([mockSharedInstance signIn]); } - (void)testRequestScopesReturnsFalseIfNotGranted { // Mock Google Signin internal calls - GIDGoogleUser *mockUser = OCMClassMock(GIDGoogleUser.class); - OCMStub(self.mockSharedInstance.currentUser).andReturn(mockUser); + GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(@[]); @@ -109,24 +446,22 @@ - (void)testRequestScopesReturnsFalseIfNotGranted { }); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns false"]; - __block id result; [self.plugin handleMethodCall:methodCall - result:^(id r) { - [expectation fulfill]; - result = r; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertFalse([result boolValue]); + result:^(NSNumber *result) { + XCTAssertFalse(result.boolValue); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; } - (void)testRequestScopesReturnsTrueIfGranted { // Mock Google Signin internal calls - GIDGoogleUser *mockUser = OCMClassMock(GIDGoogleUser.class); - OCMStub(self.mockSharedInstance.currentUser).andReturn(mockUser); + GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); + OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; NSMutableArray *availableScopes = [NSMutableArray new]; OCMStub(mockUser.grantedScopes).andReturn(availableScopes); @@ -139,18 +474,16 @@ - (void)testRequestScopesReturnsTrueIfGranted { }); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; - __block id result; [self.plugin handleMethodCall:methodCall - result:^(id r) { - [expectation fulfill]; - result = r; - }]; - [self waitForExpectations:@[ expectation ] timeout:5]; - XCTAssertTrue([result boolValue]); + result:^(NSNumber *result) { + XCTAssertTrue(result.boolValue); + [expectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @end diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 578f64d5a41c..3abdc8c39034 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -39,7 +39,7 @@ @interface FLTGoogleSignInPlugin () @implementation FLTGoogleSignInPlugin { FlutterResult _accountRequest; - NSArray *_additionalScopesRequest; + NSArray *_additionalScopesRequest; } + (void)registerWithRegistrar:(NSObject *)registrar { @@ -76,7 +76,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSString *path = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; if (path) { - NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; + NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; BOOL hasDynamicClientId = [[call.arguments valueForKey:@"clientId"] isKindOfClass:[NSString class]]; @@ -146,9 +146,9 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result return; } - NSArray *currentScopes = [GIDSignIn sharedInstance].scopes; - NSArray *scopes = call.arguments[@"scopes"]; - NSArray *missingScopes = [scopes + NSArray *currentScopes = [GIDSignIn sharedInstance].scopes; + NSArray *scopes = call.arguments[@"scopes"]; + NSArray *missingScopes = [scopes filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id scope, NSDictionary *bindings) { return ![user.grantedScopes containsObject:scope]; @@ -187,7 +187,7 @@ - (BOOL)setAccountRequest:(FlutterResult)request { return YES; } -- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { return [[GIDSignIn sharedInstance] handleURL:url]; } @@ -251,7 +251,7 @@ - (void)signIn:(GIDSignIn *)signIn #pragma mark - private methods -- (void)respondWithAccount:(id)account error:(NSError *)error { +- (void)respondWithAccount:(NSDictionary *)account error:(NSError *)error { FlutterResult result = _accountRequest; _accountRequest = nil; result(error != nil ? getFlutterError(error) : account); From 4d908264bdb664f9e70e4266f35350271957f40c Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 14 Jul 2021 20:46:57 -0700 Subject: [PATCH 2/8] Format --- .../xcshareddata/xcschemes/Runner.xcscheme | 3 +- .../ios/RunnerTests/GoogleSignInTests.m | 311 +++++++++--------- .../ios/Classes/FLTGoogleSignInPlugin.m | 7 +- 3 files changed, 165 insertions(+), 156 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c6684a7fbf98..f85273f21768 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,8 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES" - codeCoverageEnabled = "YES"> + shouldUseLaunchSchemeArgsEnv = "YES"> *result) { - XCTAssertEqualObjects(result[@"idToken"], @"mockIdToken"); - XCTAssertEqualObjects(result[@"accessToken"], @"mockAccessToken"); - [expectation fulfill]; - }]; + XCTAssertEqualObjects(result[@"idToken"], @"mockIdToken"); + XCTAssertEqualObjects(result[@"accessToken"], @"mockAccessToken"); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -287,21 +290,23 @@ - (void)testGetTokensNoAuthKeychainError { OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); - NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain code:kGIDSignInErrorCodeHasNoAuthInKeychain userInfo:nil]; - [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain + code:kGIDSignInErrorCodeHasNoAuthInKeychain + userInfo:nil]; + [[mockAuthentication stub] + getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; OCMStub([mockUser authentication]).andReturn(mockAuthentication); - FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"getTokens" - arguments:nil]; + FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { - XCTAssertEqualObjects(result.code, @"sign_in_required"); - XCTAssertEqualObjects(result.message, kGIDSignInErrorDomain); - [expectation fulfill]; - }]; + XCTAssertEqualObjects(result.code, @"sign_in_required"); + XCTAssertEqualObjects(result.message, kGIDSignInErrorDomain); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -310,21 +315,23 @@ - (void)testGetTokensCancelledError { OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); - NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain code:kGIDSignInErrorCodeCanceled userInfo:nil]; - [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain + code:kGIDSignInErrorCodeCanceled + userInfo:nil]; + [[mockAuthentication stub] + getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; OCMStub([mockUser authentication]).andReturn(mockAuthentication); - FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"getTokens" - arguments:nil]; + FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { - XCTAssertEqualObjects(result.code, @"sign_in_canceled"); - XCTAssertEqualObjects(result.message, kGIDSignInErrorDomain); - [expectation fulfill]; - }]; + XCTAssertEqualObjects(result.code, @"sign_in_canceled"); + XCTAssertEqualObjects(result.message, kGIDSignInErrorDomain); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -334,20 +341,20 @@ - (void)testGetTokensURLError { id mockAuthentication = OCMClassMock([GIDAuthentication class]); NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:nil]; - [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + [[mockAuthentication stub] + getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; OCMStub([mockUser authentication]).andReturn(mockAuthentication); - FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"getTokens" - arguments:nil]; + FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { - XCTAssertEqualObjects(result.code, @"network_error"); - XCTAssertEqualObjects(result.message, NSURLErrorDomain); - [expectation fulfill]; - }]; + XCTAssertEqualObjects(result.code, @"network_error"); + XCTAssertEqualObjects(result.message, NSURLErrorDomain); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -357,20 +364,20 @@ - (void)testGetTokensUnknownError { id mockAuthentication = OCMClassMock([GIDAuthentication class]); NSError *error = [NSError errorWithDomain:@"BogusDomain" code:42 userInfo:nil]; - [[mockAuthentication stub] getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; + [[mockAuthentication stub] + getTokensWithHandler:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]]; OCMStub([mockUser authentication]).andReturn(mockAuthentication); - FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"getTokens" - arguments:nil]; + FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"getTokens" + arguments:nil]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { - XCTAssertEqualObjects(result.code, @"sign_in_failed"); - XCTAssertEqualObjects(result.message, @"BogusDomain"); - [expectation fulfill]; - }]; + XCTAssertEqualObjects(result.code, @"sign_in_failed"); + XCTAssertEqualObjects(result.message, @"BogusDomain"); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -380,15 +387,15 @@ - (void)testRequestScopesResultErrorIfNotSignedIn { OCMStub([self.mockSharedInstance currentUser]).andReturn(nil); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : @[ @"mockScope1" ]}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : @[ @"mockScope1" ]}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { - XCTAssertEqualObjects(result.code, @"sign_in_required"); - [expectation fulfill]; - }]; + XCTAssertEqualObjects(result.code, @"sign_in_required"); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -399,15 +406,15 @@ - (void)testRequestScopesIfNoMissingScope { NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(requestedScopes); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(NSNumber *result) { - XCTAssertTrue(result.boolValue); - [expectation fulfill]; - }]; + XCTAssertTrue(result.boolValue); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -421,12 +428,12 @@ - (void)testRequestScopesRequestsIfNotGranted { OCMStub([mockSharedInstance scopes]).andReturn(@[]); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; [self.plugin handleMethodCall:methodCall result:^(id r){ - }]; + }]; OCMVerify([mockSharedInstance setScopes:@[ @"mockScope1" ]]); OCMVerify([mockSharedInstance signIn]); @@ -446,15 +453,15 @@ - (void)testRequestScopesReturnsFalseIfNotGranted { }); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns false"]; [self.plugin handleMethodCall:methodCall result:^(NSNumber *result) { - XCTAssertFalse(result.boolValue); - [expectation fulfill]; - }]; + XCTAssertFalse(result.boolValue); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } @@ -474,15 +481,15 @@ - (void)testRequestScopesReturnsTrueIfGranted { }); FlutterMethodCall *methodCall = - [FlutterMethodCall methodCallWithMethodName:@"requestScopes" - arguments:@{@"scopes" : requestedScopes}]; + [FlutterMethodCall methodCallWithMethodName:@"requestScopes" + arguments:@{@"scopes" : requestedScopes}]; XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; [self.plugin handleMethodCall:methodCall result:^(NSNumber *result) { - XCTAssertTrue(result.boolValue); - [expectation fulfill]; - }]; + XCTAssertTrue(result.boolValue); + [expectation fulfill]; + }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 3abdc8c39034..2e1c968cbff6 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -76,7 +76,8 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSString *path = [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; if (path) { - NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; + NSMutableDictionary *plist = + [[NSMutableDictionary alloc] initWithContentsOfFile:path]; BOOL hasDynamicClientId = [[call.arguments valueForKey:@"clientId"] isKindOfClass:[NSString class]]; @@ -187,7 +188,9 @@ - (BOOL)setAccountRequest:(FlutterResult)request { return YES; } -- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { +- (BOOL)application:(UIApplication *)app + openURL:(NSURL *)url + options:(NSDictionary *)options { return [[GIDSignIn sharedInstance] handleURL:url]; } From cd4a6c4d8fc09573bbd551962005fd9acfcae170 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Thu, 15 Jul 2021 11:22:51 -0700 Subject: [PATCH 3/8] Injected GIDSignIn --- .../ios/RunnerTests/GoogleSignInTests.m | 86 +++++++++---------- .../ios/Classes/FLTGoogleSignInPlugin.m | 54 +++++++----- .../Classes/FLTGoogleSignInPlugin_Private.h | 13 +++ 3 files changed, 85 insertions(+), 68 deletions(-) create mode 100644 packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h diff --git a/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m b/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m index 4621045f145b..949ed5baeb0d 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m +++ b/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m @@ -16,7 +16,7 @@ @interface FLTGoogleSignInPluginTest : XCTestCase @property(strong, nonatomic) NSObject *mockBinaryMessenger; @property(strong, nonatomic) NSObject *mockPluginRegistrar; @property(strong, nonatomic) FLTGoogleSignInPlugin *plugin; -@property(strong, nonatomic) id mockSharedInstance; +@property(strong, nonatomic) id mockSignIn; @end @@ -27,20 +27,14 @@ - (void)setUp { self.mockBinaryMessenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); self.mockPluginRegistrar = OCMProtocolMock(@protocol(FlutterPluginRegistrar)); - id mockSharedInstance = OCMClassMock([GIDSignIn class]); - OCMStub([mockSharedInstance sharedInstance]).andReturn(mockSharedInstance); - self.mockSharedInstance = mockSharedInstance; + id mockSignIn = OCMClassMock([GIDSignIn class]); + self.mockSignIn = mockSignIn; OCMStub(self.mockPluginRegistrar.messenger).andReturn(self.mockBinaryMessenger); - self.plugin = [[FLTGoogleSignInPlugin alloc] init]; + self.plugin = [[FLTGoogleSignInPlugin alloc] initWithSignIn:mockSignIn]; [FLTGoogleSignInPlugin registerWithRegistrar:self.mockPluginRegistrar]; } -- (void)tearDown { - [self.mockSharedInstance stopMocking]; - [super tearDown]; -} - - (void)testUnimplementedMethod { FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"bogus" arguments:nil]; @@ -65,7 +59,7 @@ - (void)testSignOut { [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; - OCMVerify([self.mockSharedInstance signOut]); + OCMVerify([self.mockSignIn signOut]); } - (void)testDisconnect { @@ -75,7 +69,7 @@ - (void)testDisconnect { [self.plugin handleMethodCall:methodCall result:^(id result){ }]; - OCMVerify([self.mockSharedInstance disconnect]); + OCMVerify([self.mockSignIn disconnect]); } - (void)testClearAuthCache { @@ -120,14 +114,14 @@ - (void)testInitGoogleServiceInfoPlist { }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; - id mockSharedInstance = self.mockSharedInstance; - OCMVerify([mockSharedInstance setScopes:@[ @"mockScope1" ]]); - OCMVerify([mockSharedInstance setHostedDomain:@"example.com"]); + id mockSignIn = self.mockSignIn; + OCMVerify([mockSignIn setScopes:@[ @"mockScope1" ]]); + OCMVerify([mockSignIn setHostedDomain:@"example.com"]); // Set in example app GoogleService-Info.plist. - OCMVerify([mockSharedInstance + OCMVerify([mockSignIn setClientID:@"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com"]); - OCMVerify([mockSharedInstance setServerClientID:@"YOUR_SERVER_CLIENT_ID"]); + OCMVerify([mockSignIn setServerClientID:@"YOUR_SERVER_CLIENT_ID"]); } - (void)testInitNullDomain { @@ -141,7 +135,7 @@ - (void)testInitNullDomain { [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; - OCMVerify([self.mockSharedInstance setHostedDomain:nil]); + OCMVerify([self.mockSignIn setHostedDomain:nil]); } - (void)testInitDynamicClientId { @@ -155,13 +149,13 @@ - (void)testInitDynamicClientId { [expectation fulfill]; }]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; - OCMVerify([self.mockSharedInstance setClientID:@"mockClientId"]); + OCMVerify([self.mockSignIn setClientID:@"mockClientId"]); } #pragma mark - Is signed in - (void)testIsNotSignedIn { - OCMStub([self.mockSharedInstance hasPreviousSignIn]).andReturn(NO); + OCMStub([self.mockSignIn hasPreviousSignIn]).andReturn(NO); FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"isSignedIn" arguments:nil]; @@ -176,7 +170,7 @@ - (void)testIsNotSignedIn { } - (void)testIsSignedIn { - OCMStub([self.mockSharedInstance hasPreviousSignIn]).andReturn(YES); + OCMStub([self.mockSignIn hasPreviousSignIn]).andReturn(YES); FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"isSignedIn" arguments:nil]; @@ -193,7 +187,7 @@ - (void)testIsSignedIn { #pragma mark - Sign in silently - (void)testSignInSilently { - OCMExpect([self.mockSharedInstance restorePreviousSignIn]); + OCMExpect([self.mockSignIn restorePreviousSignIn]); FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"signInSilently" arguments:nil]; @@ -201,7 +195,7 @@ - (void)testSignInSilently { [self.plugin handleMethodCall:methodCall result:^(id result){ }]; - OCMVerifyAll(self.mockSharedInstance); + OCMVerifyAll(self.mockSignIn); } - (void)testSignInSilentlyFailsConcurrently { @@ -210,7 +204,7 @@ - (void)testSignInSilentlyFailsConcurrently { XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"]; - OCMExpect([self.mockSharedInstance restorePreviousSignIn]).andDo(^(NSInvocation *invocation) { + OCMExpect([self.mockSignIn restorePreviousSignIn]).andDo(^(NSInvocation *invocation) { // Simulate calling the same method while the previous one is in flight. [self.plugin handleMethodCall:methodCall result:^(FlutterError *result) { @@ -236,16 +230,16 @@ - (void)testSignIn { result:^(NSNumber *result){ }]; - id mockSharedInstance = self.mockSharedInstance; - OCMVerify([mockSharedInstance + id mockSignIn = self.mockSignIn; + OCMVerify([mockSignIn setPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]]); - OCMVerify([mockSharedInstance signIn]); + OCMVerify([mockSignIn signIn]); } - (void)testSignInExecption { FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"signIn" arguments:nil]; - OCMExpect([self.mockSharedInstance signIn]) + OCMExpect([self.mockSignIn signIn]) .andThrow([NSException exceptionWithName:@"MockName" reason:@"MockReason" userInfo:nil]); __block FlutterError *error; @@ -263,7 +257,7 @@ - (void)testSignInExecption { - (void)testGetTokens { id mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); OCMStub([mockAuthentication idToken]).andReturn(@"mockIdToken"); @@ -287,7 +281,7 @@ - (void)testGetTokens { - (void)testGetTokensNoAuthKeychainError { id mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain @@ -312,7 +306,7 @@ - (void)testGetTokensNoAuthKeychainError { - (void)testGetTokensCancelledError { id mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain @@ -337,7 +331,7 @@ - (void)testGetTokensCancelledError { - (void)testGetTokensURLError { id mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:nil]; @@ -360,7 +354,7 @@ - (void)testGetTokensURLError { - (void)testGetTokensUnknownError { id mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); id mockAuthentication = OCMClassMock([GIDAuthentication class]); NSError *error = [NSError errorWithDomain:@"BogusDomain" code:42 userInfo:nil]; @@ -384,7 +378,7 @@ - (void)testGetTokensUnknownError { #pragma mark - Request scopes - (void)testRequestScopesResultErrorIfNotSignedIn { - OCMStub([self.mockSharedInstance currentUser]).andReturn(nil); + OCMStub([self.mockSignIn currentUser]).andReturn(nil); FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"requestScopes" @@ -402,7 +396,7 @@ - (void)testRequestScopesResultErrorIfNotSignedIn { - (void)testRequestScopesIfNoMissingScope { // Mock Google Signin internal calls GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(requestedScopes); FlutterMethodCall *methodCall = @@ -421,11 +415,11 @@ - (void)testRequestScopesIfNoMissingScope { - (void)testRequestScopesRequestsIfNotGranted { // Mock Google Signin internal calls GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(@[]); - id mockSharedInstance = self.mockSharedInstance; - OCMStub([mockSharedInstance scopes]).andReturn(@[]); + id mockSignIn = self.mockSignIn; + OCMStub([mockSignIn scopes]).andReturn(@[]); FlutterMethodCall *methodCall = [FlutterMethodCall methodCallWithMethodName:@"requestScopes" @@ -435,19 +429,19 @@ - (void)testRequestScopesRequestsIfNotGranted { result:^(id r){ }]; - OCMVerify([mockSharedInstance setScopes:@[ @"mockScope1" ]]); - OCMVerify([mockSharedInstance signIn]); + OCMVerify([mockSignIn setScopes:@[ @"mockScope1" ]]); + OCMVerify([mockSignIn signIn]); } - (void)testRequestScopesReturnsFalseIfNotGranted { // Mock Google Signin internal calls GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; OCMStub(mockUser.grantedScopes).andReturn(@[]); - OCMStub([self.mockSharedInstance signIn]).andDo(^(NSInvocation *invocation) { - [((NSObject *)self.plugin) signIn:self.mockSharedInstance + OCMStub([self.mockSignIn signIn]).andDo(^(NSInvocation *invocation) { + [((NSObject *)self.plugin) signIn:self.mockSignIn didSignInForUser:mockUser withError:nil]; }); @@ -468,14 +462,14 @@ - (void)testRequestScopesReturnsFalseIfNotGranted { - (void)testRequestScopesReturnsTrueIfGranted { // Mock Google Signin internal calls GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]); - OCMStub([self.mockSharedInstance currentUser]).andReturn(mockUser); + OCMStub([self.mockSignIn currentUser]).andReturn(mockUser); NSArray *requestedScopes = @[ @"mockScope1" ]; NSMutableArray *availableScopes = [NSMutableArray new]; OCMStub(mockUser.grantedScopes).andReturn(availableScopes); - OCMStub([self.mockSharedInstance signIn]).andDo(^(NSInvocation *invocation) { + OCMStub([self.mockSignIn signIn]).andDo(^(NSInvocation *invocation) { [availableScopes addObject:@"mockScope1"]; - [((NSObject *)self.plugin) signIn:self.mockSharedInstance + [((NSObject *)self.plugin) signIn:self.mockSignIn didSignInForUser:mockUser withError:nil]; }); diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 2e1c968cbff6..ee0175a92eff 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -3,6 +3,8 @@ // found in the LICENSE file. #import "FLTGoogleSignInPlugin.h" +#import "FLTGoogleSignInPlugin_Private.h" + #import // The key within `GoogleService-Info.plist` used to hold the application's @@ -35,6 +37,10 @@ } @interface FLTGoogleSignInPlugin () +@property(strong, readonly) GIDSignIn *signIn; + +// Redeclared as not a designated initializer. +- (instancetype)init; @end @implementation FLTGoogleSignInPlugin { @@ -52,9 +58,14 @@ + (void)registerWithRegistrar:(NSObject *)registrar { } - (instancetype)init { + return [self initWithSignIn:GIDSignIn.sharedInstance]; +} + +- (instancetype)initWithSignIn:(GIDSignIn *)signIn { self = [super init]; if (self) { - [GIDSignIn sharedInstance].delegate = self; + _signIn = signIn; + _signIn.delegate = self; // On the iOS simulator, we get "Broken pipe" errors after sign-in for some // unknown reason. We can avoid crashing the app by ignoring them. @@ -82,17 +93,17 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result [[call.arguments valueForKey:@"clientId"] isKindOfClass:[NSString class]]; if (hasDynamicClientId) { - [GIDSignIn sharedInstance].clientID = [call.arguments valueForKey:@"clientId"]; + self.signIn.clientID = [call.arguments valueForKey:@"clientId"]; } else { - [GIDSignIn sharedInstance].clientID = plist[kClientIdKey]; + self.signIn.clientID = plist[kClientIdKey]; } - [GIDSignIn sharedInstance].serverClientID = plist[kServerClientIdKey]; - [GIDSignIn sharedInstance].scopes = call.arguments[@"scopes"]; + self.signIn.serverClientID = plist[kServerClientIdKey]; + self.signIn.scopes = call.arguments[@"scopes"]; if (call.arguments[@"hostedDomain"] == [NSNull null]) { - [GIDSignIn sharedInstance].hostedDomain = nil; + self.signIn.hostedDomain = nil; } else { - [GIDSignIn sharedInstance].hostedDomain = call.arguments[@"hostedDomain"]; + self.signIn.hostedDomain = call.arguments[@"hostedDomain"]; } result(nil); } else { @@ -103,23 +114,23 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result } } else if ([call.method isEqualToString:@"signInSilently"]) { if ([self setAccountRequest:result]) { - [[GIDSignIn sharedInstance] restorePreviousSignIn]; + [self.signIn restorePreviousSignIn]; } } else if ([call.method isEqualToString:@"isSignedIn"]) { - result(@([[GIDSignIn sharedInstance] hasPreviousSignIn])); + result(@([self.signIn hasPreviousSignIn])); } else if ([call.method isEqualToString:@"signIn"]) { - [GIDSignIn sharedInstance].presentingViewController = [self topViewController]; + self.signIn.presentingViewController = [self topViewController]; if ([self setAccountRequest:result]) { @try { - [[GIDSignIn sharedInstance] signIn]; + [self.signIn signIn]; } @catch (NSException *e) { result([FlutterError errorWithCode:@"google_sign_in" message:e.reason details:e.name]); [e raise]; } } } else if ([call.method isEqualToString:@"getTokens"]) { - GIDGoogleUser *currentUser = [GIDSignIn sharedInstance].currentUser; + GIDGoogleUser *currentUser = self.signIn.currentUser; GIDAuthentication *auth = currentUser.authentication; [auth getTokensWithHandler:^void(GIDAuthentication *authentication, NSError *error) { result(error != nil ? getFlutterError(error) : @{ @@ -128,18 +139,18 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result }); }]; } else if ([call.method isEqualToString:@"signOut"]) { - [[GIDSignIn sharedInstance] signOut]; + [self.signIn signOut]; result(nil); } else if ([call.method isEqualToString:@"disconnect"]) { if ([self setAccountRequest:result]) { - [[GIDSignIn sharedInstance] disconnect]; + [self.signIn disconnect]; } } else if ([call.method isEqualToString:@"clearAuthCache"]) { // There's nothing to be done here on iOS since the expired/invalid // tokens are refreshed automatically by getTokensWithHandler. result(nil); } else if ([call.method isEqualToString:@"requestScopes"]) { - GIDGoogleUser *user = [GIDSignIn sharedInstance].currentUser; + GIDGoogleUser *user = self.signIn.currentUser; if (user == nil) { result([FlutterError errorWithCode:@"sign_in_required" message:@"No account to grant scopes." @@ -147,7 +158,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result return; } - NSArray *currentScopes = [GIDSignIn sharedInstance].scopes; + NSArray *currentScopes = self.signIn.scopes; NSArray *scopes = call.arguments[@"scopes"]; NSArray *missingScopes = [scopes filteredArrayUsingPredicate:[NSPredicate @@ -162,12 +173,11 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result if ([self setAccountRequest:result]) { _additionalScopesRequest = missingScopes; - [GIDSignIn sharedInstance].scopes = - [currentScopes arrayByAddingObjectsFromArray:missingScopes]; - [GIDSignIn sharedInstance].presentingViewController = [self topViewController]; - [GIDSignIn sharedInstance].loginHint = user.profile.email; + self.signIn.scopes = [currentScopes arrayByAddingObjectsFromArray:missingScopes]; + self.signIn.presentingViewController = [self topViewController]; + self.signIn.loginHint = user.profile.email; @try { - [[GIDSignIn sharedInstance] signIn]; + [self.signIn signIn]; } @catch (NSException *e) { result([FlutterError errorWithCode:@"request_scopes" message:e.reason details:e.name]); } @@ -191,7 +201,7 @@ - (BOOL)setAccountRequest:(FlutterResult)request { - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { - return [[GIDSignIn sharedInstance] handleURL:url]; + return [self.signIn handleURL:url]; } #pragma mark - protocol diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h new file mode 100644 index 000000000000..e60a21e881da --- /dev/null +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h @@ -0,0 +1,13 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "FLTGoogleSignInPlugin.h" + +@class GIDSignIn; + +@interface FLTGoogleSignInPlugin () + +- (instancetype)initWithSignIn:(GIDSignIn *)signIn NS_DESIGNATED_INITIALIZER; + +@end From 9a672286793ad75e3efd6bfef13a9dcdf371f731 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Thu, 15 Jul 2021 15:27:43 -0700 Subject: [PATCH 4/8] valueForKey --- .../google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index ee0175a92eff..271466b6f790 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -90,10 +90,10 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; BOOL hasDynamicClientId = - [[call.arguments valueForKey:@"clientId"] isKindOfClass:[NSString class]]; + [call.arguments[@"clientId"] isKindOfClass:[NSString class]]; if (hasDynamicClientId) { - self.signIn.clientID = [call.arguments valueForKey:@"clientId"]; + self.signIn.clientID = call.arguments[@"clientId"]; } else { self.signIn.clientID = plist[kClientIdKey]; } From 6cc702faed1981aea46a63ee1fad6e6ef1e23b20 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Thu, 15 Jul 2021 15:33:03 -0700 Subject: [PATCH 5/8] Angle imports --- .../google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h index e60a21e881da..dc5227cd1209 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "FLTGoogleSignInPlugin.h" +#import @class GIDSignIn; From fab5aa01b0726346a89beafdd861b9f3c8f05898 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Thu, 15 Jul 2021 15:46:17 -0700 Subject: [PATCH 6/8] FLTGoogleSignInPlugin_Test --- .../google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m | 5 ++--- ...leSignInPlugin_Private.h => FLTGoogleSignInPlugin_Test.h} | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename packages/google_sign_in/google_sign_in/ios/Classes/{FLTGoogleSignInPlugin_Private.h => FLTGoogleSignInPlugin_Test.h} (100%) diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m index 271466b6f790..d13d64d2ba04 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.m @@ -3,7 +3,7 @@ // found in the LICENSE file. #import "FLTGoogleSignInPlugin.h" -#import "FLTGoogleSignInPlugin_Private.h" +#import "FLTGoogleSignInPlugin_Test.h" #import @@ -89,8 +89,7 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result if (path) { NSMutableDictionary *plist = [[NSMutableDictionary alloc] initWithContentsOfFile:path]; - BOOL hasDynamicClientId = - [call.arguments[@"clientId"] isKindOfClass:[NSString class]]; + BOOL hasDynamicClientId = [call.arguments[@"clientId"] isKindOfClass:[NSString class]]; if (hasDynamicClientId) { self.signIn.clientID = call.arguments[@"clientId"]; diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Test.h similarity index 100% rename from packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Private.h rename to packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Test.h From 6d48338d141fc1cc3ca16776b60e31a6c237b380 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Mon, 19 Jul 2021 12:38:00 -0700 Subject: [PATCH 7/8] google_sign_in.Test module --- packages/google_sign_in/google_sign_in/CHANGELOG.md | 4 ++-- .../example/ios/RunnerTests/GoogleSignInTests.m | 1 + .../ios/Classes/FLTGoogleSignInPlugin.modulemap | 10 ++++++++++ .../ios/Classes/FLTGoogleSignInPlugin_Test.h | 4 ++++ .../ios/Classes/google_sign_in-umbrella.h | 10 ++++++++++ .../google_sign_in/ios/google_sign_in.podspec | 3 ++- packages/google_sign_in/google_sign_in/pubspec.yaml | 2 +- 7 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.modulemap create mode 100644 packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md index 4aad80dbb352..186a1d39a223 100644 --- a/packages/google_sign_in/google_sign_in/CHANGELOG.md +++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md @@ -1,7 +1,7 @@ -## NEXT +## 5.0.5 * Add iOS unit and UI integration test targets. -* Add iOS unit tests. +* Add iOS unit test module map. * Exclude arm64 simulators in example app. ## 5.0.4 diff --git a/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m b/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m index 949ed5baeb0d..6f8b821a5299 100644 --- a/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m +++ b/packages/google_sign_in/google_sign_in/example/ios/RunnerTests/GoogleSignInTests.m @@ -6,6 +6,7 @@ @import XCTest; @import google_sign_in; +@import google_sign_in.Test; @import GoogleSignIn; // OCMock library doesn't generate a valid modulemap. diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.modulemap b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.modulemap new file mode 100644 index 000000000000..271f509e7fd7 --- /dev/null +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin.modulemap @@ -0,0 +1,10 @@ +framework module google_sign_in { + umbrella header "google_sign_in-umbrella.h" + + export * + module * { export * } + + explicit module Test { + header "FLTGoogleSignInPlugin_Test.h" + } +} diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Test.h b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Test.h index dc5227cd1209..8fa6cf348018 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Test.h +++ b/packages/google_sign_in/google_sign_in/ios/Classes/FLTGoogleSignInPlugin_Test.h @@ -2,12 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// This header is available in the Test module. Import via "@import google_sign_in.Test;" + #import @class GIDSignIn; +/// Methods exposed for unit testing. @interface FLTGoogleSignInPlugin () +/// Inject @c GIDSignIn for testing. - (instancetype)initWithSignIn:(GIDSignIn *)signIn NS_DESIGNATED_INITIALIZER; @end diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h b/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h new file mode 100644 index 000000000000..f9e4760db41f --- /dev/null +++ b/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h @@ -0,0 +1,10 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +#import + +FOUNDATION_EXPORT double google_sign_inVersionNumber; +FOUNDATION_EXPORT const unsigned char google_sign_inVersionString[]; diff --git a/packages/google_sign_in/google_sign_in/ios/google_sign_in.podspec b/packages/google_sign_in/google_sign_in/ios/google_sign_in.podspec index bf0b75f2957d..6b0741c65122 100644 --- a/packages/google_sign_in/google_sign_in/ios/google_sign_in.podspec +++ b/packages/google_sign_in/google_sign_in/ios/google_sign_in.podspec @@ -12,8 +12,9 @@ Enables Google Sign-In in Flutter apps. s.license = { :type => 'BSD', :file => '../LICENSE' } s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/google_sign_in' } - s.source_files = 'Classes/**/*' + s.source_files = 'Classes/**/*.{h,m}' s.public_header_files = 'Classes/**/*.h' + s.module_map = 'Classes/FLTGoogleSignInPlugin.modulemap' s.dependency 'Flutter' s.dependency 'GoogleSignIn', '~> 5.0' s.static_framework = true diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml index a57f2197576d..14f7d8901301 100644 --- a/packages/google_sign_in/google_sign_in/pubspec.yaml +++ b/packages/google_sign_in/google_sign_in/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for Google Sign-In, a secure authentication system for signing in with a Google account on Android and iOS. repository: https://github.com/flutter/plugins/tree/master/packages/google_sign_in/google_sign_in issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22 -version: 5.0.4 +version: 5.0.5 environment: sdk: ">=2.12.0 <3.0.0" From 72fba46bfbe8981f8a94a8da6009a073ff91f16b Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Mon, 19 Jul 2021 12:46:17 -0700 Subject: [PATCH 8/8] Format --- .../google_sign_in/ios/Classes/google_sign_in-umbrella.h | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h b/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h index f9e4760db41f..343c390f1782 100644 --- a/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h +++ b/packages/google_sign_in/google_sign_in/ios/Classes/google_sign_in-umbrella.h @@ -3,7 +3,6 @@ // found in the LICENSE file. #import - #import FOUNDATION_EXPORT double google_sign_inVersionNumber;