Skip to content

Commit 41211cf

Browse files
authored
[gis_web] Make maybeEnum more robust in google_identity_services_web shared file. (#8999)
When the needle value is unexpected, instead of throwing error, it'll return null now. Fixes flutter/flutter#166548 ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
1 parent 6ce3776 commit 41211cf

File tree

8 files changed

+56
-20
lines changed

8 files changed

+56
-20
lines changed

packages/google_identity_services_web/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.3.3+1
2+
3+
* Handles potential exceptions gracefully while fetching `Moment*Reason` for invalid value.
4+
15
## 0.3.3
26

37
* Moves all the JavaScript types to extend `JSObject`.

packages/google_identity_services_web/README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,3 @@ Refer to the official documentation site for the latest browser compatibility
9393
information of the underlying JS SDK:
9494

9595
* **Sign In With Google > [Supported browsers and platforms](https://developers.google.com/identity/gsi/web/guides/supported-browsers)**
96-
97-
## Testing
98-
99-
This web-only package uses `dart:test` to test its features. They can be run
100-
with `dart test -p chrome`.
101-
102-
_(Look at `test/README.md` and `tool/run_tests.dart` for more info.)_

packages/google_identity_services_web/example/integration_test/js_interop_id_test.dart

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ void main() async {
8383
});
8484

8585
group('prompt', () {
86-
testWidgets('supports a moment notification callback', (_) async {
86+
testWidgets(
87+
'supports a moment notification callback with correct type and reason',
88+
(_) async {
8789
id.initialize(IdConfiguration(client_id: 'testing_1-2-3'));
90+
utils.setMockMomentNotification('skipped', 'user_cancel');
8891

8992
final StreamController<PromptMomentNotification> controller =
9093
StreamController<PromptMomentNotification>();
@@ -93,11 +96,27 @@ void main() async {
9396

9497
final PromptMomentNotification moment = await controller.stream.first;
9598

96-
// These defaults are set in mock-gis.js
9799
expect(moment.getMomentType(), MomentType.skipped);
98100
expect(moment.getSkippedReason(), MomentSkippedReason.user_cancel);
99101
});
100102

103+
testWidgets(
104+
'supports a moment notification callback while handling invalid reason '
105+
'value gracefully', (_) async {
106+
id.initialize(IdConfiguration(client_id: 'testing_1-2-3'));
107+
utils.setMockMomentNotification('skipped', 'random_invalid_reason');
108+
109+
final StreamController<PromptMomentNotification> controller =
110+
StreamController<PromptMomentNotification>();
111+
112+
id.prompt(controller.add);
113+
114+
final PromptMomentNotification moment = await controller.stream.first;
115+
116+
expect(moment.getMomentType(), MomentType.skipped);
117+
expect(moment.getSkippedReason(), isNull);
118+
});
119+
101120
testWidgets('calls config callback with credential response', (_) async {
102121
const String expected = 'should_be_a_proper_jwt_token';
103122
utils.setMockCredentialResponse(expected);

packages/google_identity_services_web/example/integration_test/utils.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,31 @@ void setMockTokenResponse(TokenClient client, [String? authToken]) {
9090
client.setMockTokenResponse(authToken?.toJS);
9191
}
9292

93-
/// Allows calling a `setMockCredentialResponse` method (set by mock-gis.js)
93+
/// Allows calling `setMockCredentialResponse` and `setMockMomentNotification`
94+
/// methods (set by mock-gis.js).
9495
extension on GoogleAccountsId {
9596
external void setMockCredentialResponse(
9697
JSString credential,
9798
JSString select_by, //ignore: non_constant_identifier_names
9899
);
100+
101+
external void setMockMomentNotification(
102+
JSString momentType,
103+
JSString reason,
104+
);
99105
}
100106

101107
/// Sets a mock credential response in `google.accounts.id`.
102108
void setMockCredentialResponse([String value = 'default_value']) {
103109
_getGoogleAccountsId().setMockCredentialResponse(value.toJS, 'auto'.toJS);
104110
}
105111

112+
/// Sets a mock moment notification in `google.accounts.id`.
113+
void setMockMomentNotification(String momentType, String reason) {
114+
_getGoogleAccountsId()
115+
.setMockMomentNotification(momentType.toJS, reason.toJS);
116+
}
117+
106118
GoogleAccountsId _getGoogleAccountsId() {
107119
return _getDeepProperty<GoogleAccountsId>(
108120
web.window as JSObject, 'google.accounts.id');

packages/google_identity_services_web/example/web/mock-gis.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ class PromptMomentNotification {
2222
isNotDisplayed() { return this.isDisplayMoment() && this.reason; }
2323
}
2424

25-
const CREDENTIAL_RETURNED = new PromptMomentNotification("dismissed", "credential_returned");
26-
const USER_CANCEL = new PromptMomentNotification("skipped", "user_cancel");
27-
2825
function callAsync(func, timeout = 100) {
2926
window.setTimeout(func, timeout)
3027
}
@@ -47,11 +44,11 @@ class Id {
4744
if (callback) {
4845
callback(this.mockCredentialResponse);
4946
}
50-
if (momentListener) {
51-
momentListener(CREDENTIAL_RETURNED);
47+
}
48+
if (momentListener) {
49+
if (this.mockMomentNotification) {
50+
momentListener(this.mockMomentNotification);
5251
}
53-
} else if (momentListener) {
54-
momentListener(USER_CANCEL);
5552
}
5653
});
5754
}
@@ -61,11 +58,15 @@ class Id {
6158
select_by: select_by,
6259
};
6360
}
61+
setMockMomentNotification(momentType, reason) {
62+
this.mockMomentNotification = new PromptMomentNotification(momentType, reason);
63+
}
6464
disableAutoSelect() {}
6565
storeCredential() {}
6666
cancel() {}
6767
revoke(hint, callback) {
6868
this.mockCredentialResponse = null;
69+
this.mockMomentNotification = null;
6970
if (!callback) {
7071
return;
7172
}

packages/google_identity_services_web/lib/src/js_interop/shared.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
// found in the LICENSE file.
44

55
/// Attempts to retrieve an enum value from [haystack] if [needle] is not null.
6+
///
7+
/// Returns `null` if no enum value in [haystack] matches [needle].
68
T? maybeEnum<T extends Enum>(String? needle, List<T> haystack) {
79
if (needle == null) {
810
return null;
911
}
10-
return haystack.byName(needle);
12+
for (final T value in haystack) {
13+
if (value.name == needle) {
14+
return value;
15+
}
16+
}
17+
return null;
1118
}
1219

1320
/// The type of several functions from the library, that don't receive

packages/google_identity_services_web/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: google_identity_services_web
22
description: A Dart JS-interop layer for Google Identity Services. Google's new sign-in SDK for Web that supports multiple types of credentials.
33
repository: https://github.com/flutter/packages/tree/main/packages/google_identity_services_web
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_identiy_services_web%22
5-
version: 0.3.3
5+
version: 0.3.3+1
66

77
environment:
88
sdk: ^3.4.0

packages/google_identity_services_web/test/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Tests
22

3-
Use `dart run tool/run_tests.dart` to run tests in this package.
3+
Use `dart test -p chrome <test_name>.dart` to run tests in this package.
44

55
## Failed to run Chrome: No such file or directory
66

0 commit comments

Comments
 (0)