Uh oh!
There was an error while loading. Please reload this page.
[google_sign_in] Increase iOS coverage tests - #12484
Conversation
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request adds a comprehensive suite of Swift unit tests for the iOS Google Sign-In plugin, covering URL handling, error mapping, disconnect scenarios, user data parsing, and top view controller resolution. The review feedback suggests passing nil instead of a scene instance in the sceneOpenURLContexts test to prevent potential test failures in headless CI environments where connected scenes may be empty.
| @Test func sceneOpenURLContexts() throws { | ||
| let (plugin, fakeSignIn) = createTestPlugin() | ||
| let url = URL(string: "com.googleusercontent.apps.test:/oauthredirect")! | ||
| let scene = try #require(UIApplication.shared.connectedScenes.first) | ||
| let fakeContext = FakeOpenURLContext(url: url) | ||
| plugin.perform( | ||
| NSSelectorFromString("scene:openURLContexts:"), | ||
| with: scene, | ||
| with: NSSet(object: fakeContext)) | ||
| #expect(fakeSignIn.handledURLs == [url]) | ||
| } |
There was a problem hiding this comment.
In headless unit test environments (such as CI runners), UIApplication.shared.connectedScenes can be empty, which causes try #require(UIApplication.shared.connectedScenes.first) to throw and fail the test. Since the scene parameter is completely unused in the plugin's implementation of scene:openURLContexts:, we can pass nil instead and make the test more robust and independent of the application's scene state.
@Testfunc sceneOpenURLContexts(){let(plugin, fakeSignIn)=createTestPlugin()leturl=URL(string:"com.googleusercontent.apps.test:/oauthredirect")!
letfakeContext=FakeOpenURLContext(url: url)
plugin.perform(NSSelectorFromString("scene:openURLContexts:"),
with:nil,
with:NSSet(object: fakeContext))
#expect(fakeSignIn.handledURLs ==[url])}There was a problem hiding this comment.
please address gemini comments. It will make review easier.
Add URL handling, error mapping, disconnect, and topViewController cases so FLTGoogleSignInPlugin.m is covered before the Obj-C to Swift migration.
e37d0b6 to
2dccfa6CompareallowSignInPermissions looked up the system permission alert's confirmation button by the literal title "Continue", so testSignInPopUp failed on any simulator whose language is not English; the button is titled in the simulator's language (for example "Continuar" in Spanish). Tap the last of the alert's buttons instead, which is the confirmation button in every localization.
167fe18 to
59fbe19Compare
hellohuanlin
left a comment
There was a problem hiding this comment.
Overall looks good. Just some nits.
| let fakeContext = FakeOpenURLContext(url: url) | ||
| plugin.perform( | ||
| NSSelectorFromString("scene:openURLContexts:"), |
There was a problem hiding this comment.
This loses compilation safety. let's avoid using objc hacks
There was a problem hiding this comment.
Done! Dropped scene:openURLContexts: because UIOpenURLContext has no public initializer, so the only way to call it was performSelector. Left a TODO to add a typed test after the Obj-C → Swift migration (flutter/flutter#119103).
| @Test func sceneOpenURLContexts() throws { | ||
| let (plugin, fakeSignIn) = createTestPlugin() | ||
| let url = URL(string: "com.googleusercontent.apps.test:/oauthredirect")! | ||
| let scene = try #require(UIApplication.shared.connectedScenes.first) | ||
| let fakeContext = FakeOpenURLContext(url: url) | ||
| plugin.perform( | ||
| NSSelectorFromString("scene:openURLContexts:"), | ||
| with: scene, | ||
| with: NSSet(object: fakeContext)) | ||
| #expect(fakeSignIn.handledURLs == [url]) | ||
| } |
There was a problem hiding this comment.
please address gemini comments. It will make review easier.
…swift, with a note to re-add after Obj-C plugin migration to Swift.
| // the Obj-C plugin is migrated to Swift. The test was dropped because | ||
| // UIOpenURLContext has no public initializer, so invoking the Obj-C | ||
| // method required performSelector. See | ||
| // https://github.com/flutter/flutter/issues/119103 |
There was a problem hiding this comment.
This issue doesn't describe the problem that you are describing above though
There was a problem hiding this comment.
You’re right, #119103 is the Swift migration tracker, not this test gap. I linked it because that is the issue we are using for this migration effort, and the typed scene:openURLContexts: test is meant to come back as part of that work. Should I drop the #119103 link from the TODO?
| // TODO(victogomez-cs): Re-add a typed scene:openURLContexts: test after | ||
| // the Obj-C plugin is migrated to Swift. The test was dropped because | ||
| // UIOpenURLContext has no public initializer, so invoking the Obj-C |
There was a problem hiding this comment.
How is the previous objc hack related to UIOpenURLContext's public initializer? Can you add more info?
There was a problem hiding this comment.
A typed call needs NSSet<UIOpenURLContext *>. UIKit marks UIOpenURLContextinit/new unavailable, so tests cannot build a real context. The old test used performSelector with an NSObject stand-in, which isn’t type-checked. I expanded the TODO to spell that out, still pointing at #119103 as the migration tracker
There was a problem hiding this comment.
This is a limitation on UIKit testing in Swift. One common workaround is to move all your logic into a method that takes a custom type, and then the original method's implementation would be just 1-liner wrapper of this new method. Then you can just test this new method. The drawback is that the 1-liner wrapper would untested, but this is acceptable since it's trivial.
There was a problem hiding this comment.
Thanks, that makes sense. I’ll keep this PR tests-only (no production Obj-C changes) and add that seam in the Swift migration: a typed method that takes [URL], with scene:openURLContexts: as a one-line wrapper, then unit-test the new method. I’ll update the TODO to mention that pattern, unless you need the seam in this PR
There was a problem hiding this comment.
@victogomez-cs it’s better to add it in this PR rather than deferring it. TODOs can easily get lost, and this ensures we keep test coverage solid right away.
There was a problem hiding this comment.
Done. Extracted handleURLs: (takes [URL]) and left scene:openURLContexts: as a thin wrapper that maps UIOpenURLContext.URL. Tests call handleURLs: directly
…d unit test for scene:openURLContexts:. The previous test was removed due to limitations in constructing UIOpenURLContext in Swift.
…iOS scene URL handling and refactoring URL handling logic in the plugin. Added unit tests for URL handling in GoogleSignInTests.swift.
… by adding NS_SWIFT_NAME annotation to handleURLs method.
Uh oh!
There was an error while loading. Please reload this page.
…er#191734) flutter/packages@df2ba94...740f093 2026-08-25 srawlins@google.com [cupertino_ui] Remove unused parameters from constructors of generic classes. (flutter/packages#12457) 2026-08-25 srawlins@google.com [material_ui] Remove unused parameters from constructors of generic classes. (flutter/packages#12458) 2026-08-25 6655696+guidezpl@users.noreply.github.com Ignore shared code for iOS platform implementation of Google Maps plugin (flutter/packages#12529) 2026-08-25 136096126+glitchfl@users.noreply.github.com [cross_file] fixed `readAsString` decoding in-memory bytes as UTF-16 (flutter/packages#12479) 2026-08-25 lozhkovoi@gmail.com [cupertino_ui] Remove two items assert to allow CupertinoTabBar to have one tab (flutter/packages#12546) 2026-08-25 huahua8893@sina.cn [cupertino_ui] Fix covered sheet revealing root route through top gap (flutter/packages#12530) 2026-08-25 fluttergithubbot@gmail.com Sync release-go_router-18.0.0 to main (flutter/packages#12575) 2026-08-25 fluttergithubbot@gmail.com Sync release-material_ui-1.1.0 to main (flutter/packages#12577) 2026-08-25 fluttergithubbot@gmail.com Sync release-cupertino_ui-1.0.1 to main (flutter/packages#12576) 2026-08-24 41930132+hellohuanlin@users.noreply.github.com [quick_actions_ios]unskip XCUITests (flutter/packages#12436) 2026-08-24 karthimanikuttan001@gmail.com Fix RangeSlider thumb overlay remains visible after touch interaction ends (flutter/packages#12560) 2026-08-24 victor.orozco@cloudsufi.com [google_sign_in] Increase iOS coverage tests (flutter/packages#12484) 2026-08-24 269567208+reidbaker-agent@users.noreply.github.com [camera_android_camerax] Migrate from dart_skills_lint to skills_lint (flutter/packages#12543) 2026-08-24 74037732+developerashkan@users.noreply.github.com [go_router] Clarify onEnter/redirect ordering, add regression test (flutter/packages#12337) 2026-08-24 brunocorona.alcantar@gmail.com [material_ui] Port flutter/flutter flutter#185149 "Slider label clips the screen" (flutter/packages#12572) 2026-08-24 engine-flutter-autoroll@skia.org Roll Flutter from 65c9a8d to 9a82789 (17 revisions) (flutter/packages#12578) 2026-08-24 stuartmorgan@google.com [tool] Fix dart_test.yaml parsing (flutter/packages#12574) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Adds native unit tests for previously untested paths in
FLTGoogleSignInPlugin.mbefore the Objective-C → Swift migration. Production code is unchanged.This is a tests-only change, so it does not bump the package version or CHANGELOG.
Native unit tests go from 21 tests / 6 suites to 31 tests / 11 suites.
New test cases
urlHandling(iOS / Mac Catalyst only) — these APIs do not exist on macOS (handleOpenURLs:is the macOS path):applicationOpenURL—application:openURL:options:forwards the URL to GID and returnstrueapplicationOpenURLReturnsHandleResult— same path returnsfalsewhen GID doessceneOpenURLContexts—scene:openURLContexts:forwards the URL from aUIOpenURLContextstand-inerrorMapping:mapsRemainingGIDSignInErrorCodes(parameterized):GIDSignInError.keychain→FSIGoogleSignInErrorCode.keychainErrorGIDSignInError.EMM→FSIGoogleSignInErrorCode.eemErrorGIDSignInError.unknown→FSIGoogleSignInErrorCode.unknown12345) →FSIGoogleSignInErrorCode.unknownsanitizesComplexUserInfoInFlutterError—FSISanitizedUserInfokeeps strings/numbers/URLs/arrays/dicts/nested errors and stringifies unsupported types (e.g.Date)disconnect:disconnectReturnsFlutterErrorOnFailure— a GID disconnect failure is returned as a Flutter error with domain/code and userInfouserData:signInWithoutProfileImageOmitsPhotoUrl— a user with no profile photo getsphotoUrl == niland still mapsdisplayNametopViewController(iOS / Mac Catalyst only) — macOS presents withNSWindow, not aUIViewControllerhierarchy:usesNavigationControllerVisibleController— presents from the nav stack’s top VCusesTabBarControllerSelectedController— presents from the selected tab VCusesPresentedViewController— presents from a presented VCAlso records URLs passed to
TestSignIn.handle(_:)so the URL-handling cases can assert the fake was called.First part of Swift migration to backfill code coverage for flutter/flutter#119103
Pre-Review Checklist
[shared_preferences]///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩↩2