utils/crdt_sync_flutter/test/google_any_sign_in_test.dart
Krzysztof kuhy Rudnicki 2298fd4ba2 Own the Google sign-in glue, on desktop as well as Android
Five apps had copied google_sign_in_backend.dart; home_inventory's copy was
byte-identical to todo's. lyricanki was about to become the sixth, which is
the mistake this package exists to prevent. So the plugin call moves here.

Desktop is the new half. google_sign_in ships android, ios and web
implementations only -- there is no google_sign_in_linux -- so lyricanki's
real GTK build could never have used the plugin, and "one tap" would have
meant "one tap on the phone, type a password on the PC". The OAuth loopback
flow covers it: bind a socket, open the system browser, catch the redirect,
exchange the code with PKCE. Both halves return a Google ID token of the same
shape, so signInWithGoogle cannot tell them apart.

googleSignInSupported takes the client id rather than reading a const. In
todo the emptiness check was a second conjunct at the call site, and moving
the fetcher here without it would have let a forgetful app ship a button that
always reports "cancelled" -- todo's own file documents that failure. Taking
the value as an argument makes the check impossible to drop.

The decision (which flow, or none) is pure and covered; the two one-line
delegations that reach a platform channel and a real browser are the only
suppressions. 83 tests, 100% coverage.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CFSGeWxHPY5rHUGrPqhcmG
2026-08-22 18:45:48 +02:00

73 lines
2.5 KiB
Dart

import 'package:crdt_sync_flutter/crdt_sync_flutter.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
// Under `flutter test` the io platform gate answers for the host, which is
// Linux -- so the plugin half is false and the loopback half is live. That
// is the desktop configuration, and it is the one this suite can exercise
// honestly; the Android half is asserted on the device instead.
group('desktopSignInSupported', () {
test('is true on this host once a desktop client id exists', () {
expect(desktopSignInSupported('desktop-cid'), isTrue);
});
test('is false without a desktop client id', () {
// The guard against a button that can only ever fail.
expect(desktopSignInSupported(''), isFalse);
});
});
group('googleAnySignInSupported', () {
test('is true when only the desktop half is configured', () {
expect(
googleAnySignInSupported(
serverClientId: '',
desktopClientId: 'desktop-cid',
),
isTrue,
);
});
test('is false when neither half is configured', () {
expect(googleAnySignInSupported(serverClientId: ''), isFalse);
});
test('is false on this host when only the plugin half is configured', () {
// The plugin does not run on Linux, so a Web client id alone buys
// nothing here -- and the button must not appear.
expect(googleAnySignInSupported(serverClientId: 'web-cid'), isFalse);
});
});
group('googleFlowFor', () {
test('picks the desktop flow on this host', () {
expect(
googleFlowFor(serverClientId: '', desktopClientId: 'd'),
GoogleFlow.desktop,
);
});
test('picks nothing when neither half is configured', () {
expect(googleFlowFor(serverClientId: ''), GoogleFlow.none);
});
test('picks nothing when only the plugin half is configured here', () {
// The plugin does not run on Linux, so a Web client id alone must not
// route anywhere -- that would be a button that cannot succeed.
expect(googleFlowFor(serverClientId: 'web-cid'), GoogleFlow.none);
});
});
group('googleAnyIdToken', () {
test('returns null when no flow is available', () async {
expect(await googleAnyIdToken(serverClientId: ''), isNull);
});
test('returns null when the plugin half alone is configured', () async {
// Would reach the plugin's platform channel if the gate were wrong,
// which throws rather than returning null.
expect(await googleAnyIdToken(serverClientId: 'web-cid'), isNull);
});
});
}