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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/google_sign_in/google_sign_in_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.12.2

* Adds server auth code retrieval to google_sign_in_web.
* Adds `web_only` library to access web-only methods more easily.

## 0.12.1

* Enables FedCM on browsers that support this authentication mechanism.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,24 @@ void main() {
expect(arguments.elementAt(1), someAccessToken);
});
});

group('requestServerAuthCode', () {
const String someAuthCode = '50m3_4u7h_c0d3';

setUp(() {
plugin.initWithParams(options);
});

testWidgets('passes-through call to gis client', (_) async {
mockito
.when(mockGis.requestServerAuthCode())
.thenAnswer((_) => Future<String>.value(someAuthCode));

final String? serverAuthCode = await plugin.requestServerAuthCode();

expect(serverAuthCode, someAuthCode);
});
});
});

group('userDataEvents', () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Mocks generated by Mockito 5.4.0 from annotations
// Mocks generated by Mockito 5.4.1 from annotations
// in google_sign_in_web_integration_tests/integration_test/google_sign_in_web_test.dart.
// Do not manually edit this file.

// @dart=2.19

// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i4;

Expand Down Expand Up @@ -47,6 +49,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValueForMissingStub:
_i4.Future<_i2.GoogleSignInUserData?>.value(),
) as _i4.Future<_i2.GoogleSignInUserData?>);

@override
_i4.Future<void> renderButton(
Object? parent,
Expand All @@ -63,6 +66,17 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<String?> requestServerAuthCode() => (super.noSuchMethod(
Invocation.method(
#requestServerAuthCode,
[],
),
returnValue: _i4.Future<String?>.value(),
returnValueForMissingStub: _i4.Future<String?>.value(),
) as _i4.Future<String?>);

@override
_i4.Future<_i2.GoogleSignInUserData?> signIn() => (super.noSuchMethod(
Invocation.method(
Expand All @@ -73,6 +87,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValueForMissingStub:
_i4.Future<_i2.GoogleSignInUserData?>.value(),
) as _i4.Future<_i2.GoogleSignInUserData?>);

@override
_i2.GoogleSignInTokenData getTokens() => (super.noSuchMethod(
Invocation.method(
Expand All @@ -94,6 +109,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
),
),
) as _i2.GoogleSignInTokenData);

@override
_i4.Future<void> signOut() => (super.noSuchMethod(
Invocation.method(
Expand All @@ -103,6 +119,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<void> disconnect() => (super.noSuchMethod(
Invocation.method(
Expand All @@ -112,6 +129,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<bool> isSignedIn() => (super.noSuchMethod(
Invocation.method(
Expand All @@ -121,6 +139,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValue: _i4.Future<bool>.value(false),
returnValueForMissingStub: _i4.Future<bool>.value(false),
) as _i4.Future<bool>);

@override
_i4.Future<void> clearAuthCache() => (super.noSuchMethod(
Invocation.method(
Expand All @@ -130,6 +149,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<bool> requestScopes(List<String>? scopes) => (super.noSuchMethod(
Invocation.method(
Expand All @@ -139,6 +159,7 @@ class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
returnValue: _i4.Future<bool>.value(false),
returnValueForMissingStub: _i4.Future<bool>.value(false),
) as _i4.Future<bool>);

@override
_i4.Future<bool> canAccessScopes(
List<String>? scopes,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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 'package:flutter_test/flutter_test.dart';
import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart';
import 'package:google_sign_in_web/google_sign_in_web.dart'
show GoogleSignInPlugin;
import 'package:google_sign_in_web/src/gis_client.dart';
import 'package:google_sign_in_web/web_only.dart' as web;
import 'package:integration_test/integration_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart' as mockito;

import 'web_only_test.mocks.dart';

// Mock GisSdkClient so we can simulate any response from the JS side.
@GenerateMocks(<Type>[], customMocks: <MockSpec<dynamic>>[
MockSpec<GisSdkClient>(onMissingStub: OnMissingStub.returnDefault),
])
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('non-web plugin instance', () {
setUp(() {
GoogleSignInPlatform.instance = NonWebImplementation();
});

testWidgets('renderButton throws', (WidgetTester _) async {
expect(() {
web.renderButton();
}, throwsAssertionError);
});

testWidgets('requestServerAuthCode throws', (WidgetTester _) async {
expect(() async {
await web.requestServerAuthCode();
}, throwsAssertionError);
});
});

group('web plugin instance', () {
const String someAuthCode = '50m3_4u7h_c0d3';
late MockGisSdkClient mockGis;

setUp(() {
mockGis = MockGisSdkClient();
GoogleSignInPlatform.instance = GoogleSignInPlugin(
debugOverrideLoader: true,
debugOverrideGisSdkClient: mockGis,
)..initWithParams(
const SignInInitParameters(
clientId: 'does-not-matter',
),
);
});

testWidgets('call reaches GIS API', (WidgetTester _) async {
mockito
.when(mockGis.requestServerAuthCode())
.thenAnswer((_) => Future<String>.value(someAuthCode));

final String? serverAuthCode = await web.requestServerAuthCode();

expect(serverAuthCode, someAuthCode);
});
});
}

/// Fake non-web implementation used to verify that the web_only methods
/// throw when the wrong type of instance is configured.
class NonWebImplementation extends GoogleSignInPlatform {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Mocks generated by Mockito 5.4.1 from annotations
// in google_sign_in_web_integration_tests/integration_test/web_only_test.dart.
// Do not manually edit this file.

// @dart=2.19

// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i4;

import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart'
as _i2;
import 'package:google_sign_in_web/src/button_configuration.dart' as _i5;
import 'package:google_sign_in_web/src/gis_client.dart' as _i3;
import 'package:mockito/mockito.dart' as _i1;

// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class

class _FakeGoogleSignInTokenData_0 extends _i1.SmartFake
implements _i2.GoogleSignInTokenData {
_FakeGoogleSignInTokenData_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}

/// A class which mocks [GisSdkClient].
///
/// See the documentation for Mockito's code generation for more information.
class MockGisSdkClient extends _i1.Mock implements _i3.GisSdkClient {
@override
_i4.Future<_i2.GoogleSignInUserData?> signInSilently() => (super.noSuchMethod(
Invocation.method(
#signInSilently,
[],
),
returnValue: _i4.Future<_i2.GoogleSignInUserData?>.value(),
returnValueForMissingStub:
_i4.Future<_i2.GoogleSignInUserData?>.value(),
) as _i4.Future<_i2.GoogleSignInUserData?>);

@override
_i4.Future<void> renderButton(
Object? parent,
_i5.GSIButtonConfiguration? options,
) =>
(super.noSuchMethod(
Invocation.method(
#renderButton,
[
parent,
options,
],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<String?> requestServerAuthCode() => (super.noSuchMethod(
Invocation.method(
#requestServerAuthCode,
[],
),
returnValue: _i4.Future<String?>.value(),
returnValueForMissingStub: _i4.Future<String?>.value(),
) as _i4.Future<String?>);

@override
_i4.Future<_i2.GoogleSignInUserData?> signIn() => (super.noSuchMethod(
Invocation.method(
#signIn,
[],
),
returnValue: _i4.Future<_i2.GoogleSignInUserData?>.value(),
returnValueForMissingStub:
_i4.Future<_i2.GoogleSignInUserData?>.value(),
) as _i4.Future<_i2.GoogleSignInUserData?>);

@override
_i2.GoogleSignInTokenData getTokens() => (super.noSuchMethod(
Invocation.method(
#getTokens,
[],
),
returnValue: _FakeGoogleSignInTokenData_0(
this,
Invocation.method(
#getTokens,
[],
),
),
returnValueForMissingStub: _FakeGoogleSignInTokenData_0(
this,
Invocation.method(
#getTokens,
[],
),
),
) as _i2.GoogleSignInTokenData);

@override
_i4.Future<void> signOut() => (super.noSuchMethod(
Invocation.method(
#signOut,
[],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<void> disconnect() => (super.noSuchMethod(
Invocation.method(
#disconnect,
[],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<bool> isSignedIn() => (super.noSuchMethod(
Invocation.method(
#isSignedIn,
[],
),
returnValue: _i4.Future<bool>.value(false),
returnValueForMissingStub: _i4.Future<bool>.value(false),
) as _i4.Future<bool>);

@override
_i4.Future<void> clearAuthCache() => (super.noSuchMethod(
Invocation.method(
#clearAuthCache,
[],
),
returnValue: _i4.Future<void>.value(),
returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>);

@override
_i4.Future<bool> requestScopes(List<String>? scopes) => (super.noSuchMethod(
Invocation.method(
#requestScopes,
[scopes],
),
returnValue: _i4.Future<bool>.value(false),
returnValueForMissingStub: _i4.Future<bool>.value(false),
) as _i4.Future<bool>);

@override
_i4.Future<bool> canAccessScopes(
List<String>? scopes,
String? accessToken,
) =>
(super.noSuchMethod(
Invocation.method(
#canAccessScopes,
[
scopes,
accessToken,
],
),
returnValue: _i4.Future<bool>.value(false),
returnValueForMissingStub: _i4.Future<bool>.value(false),
) as _i4.Future<bool>);
}
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,11 @@ class GoogleSignInPlugin extends GoogleSignInPlatform {
@override
Stream<GoogleSignInUserData?>? get userDataEvents =>
_userDataController.stream;

/// Requests server auth code from GIS Client per:
/// https://developers.google.com/identity/oauth2/web/guides/use-code-model#initialize_a_code_client
Future<String?> requestServerAuthCode() async {
await initialized;
return _gisClient.requestServerAuthCode();
}
}
Loading