[google_sign_in] Use a transparent image as a placeholder for the `GoogleUserCircleAvatar` (#4391)
diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md
index 6f4cceb..b16b5f9 100644
--- a/packages/google_sign_in/google_sign_in/CHANGELOG.md
+++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.2.1
+
+ Change the placeholder of the GoogleUserCircleAvatar to a transparent image.
+
## 5.2.0
* Add `GoogleSignInAccount.serverAuthCode`. Mark `GoogleSignInAuthentication.serverAuthCode` as deprecated.
diff --git a/packages/google_sign_in/google_sign_in/lib/widgets.dart b/packages/google_sign_in/google_sign_in/lib/widgets.dart
index 18f9973..c031cb2 100644
--- a/packages/google_sign_in/google_sign_in/lib/widgets.dart
+++ b/packages/google_sign_in/google_sign_in/lib/widgets.dart
@@ -106,10 +106,22 @@
FadeInImage.memoryNetwork(
// This creates a transparent placeholder image, so that
// [placeholder] shows through.
- placeholder: Uint8List((size.round() * size.round())),
+ placeholder: _transparentImage,
image: sizedPhotoUrl,
)
]),
));
}
}
+
+/// This is an transparent 1x1 gif image.
+///
+/// Those bytes come from `resources/transparentImage.gif`.
+final Uint8List _transparentImage = Uint8List.fromList(
+ [
+ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x21, 0xf9, 0x04, 0x01, 0x00, //
+ 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, //
+ 0x00, 0x02, 0x01, 0x44, 0x00, 0x3B
+ ],
+);
diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml
index 91114c6..03e583a 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 @@
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.2.0
+version: 5.2.1
environment:
sdk: ">=2.14.0 <3.0.0"
diff --git a/packages/google_sign_in/google_sign_in/resources/README.md b/packages/google_sign_in/google_sign_in/resources/README.md
new file mode 100644
index 0000000..b3f0383
--- /dev/null
+++ b/packages/google_sign_in/google_sign_in/resources/README.md
@@ -0,0 +1,7 @@
+`transparentImage.gif` is a 1x1 transparent gif which comes from [this wikimedia page](https://commons.wikimedia.org/wiki/File:Transparent.gif):
+
+![](transparentImage.gif)
+
+This is the image used a placeholder for the `GoogleCircleAvatar` widget.
+
+The variable `_transparentImage` in `lib/widgets.dart` is the list of bytes of `transparentImage.gif`.
\ No newline at end of file
diff --git a/packages/google_sign_in/google_sign_in/resources/transparentImage.gif b/packages/google_sign_in/google_sign_in/resources/transparentImage.gif
new file mode 100644
index 0000000..f191b28
--- /dev/null
+++ b/packages/google_sign_in/google_sign_in/resources/transparentImage.gif
Binary files differ
diff --git a/packages/google_sign_in/google_sign_in/test/widgets_test.dart b/packages/google_sign_in/google_sign_in/test/widgets_test.dart
new file mode 100644
index 0000000..f7bd6f8
--- /dev/null
+++ b/packages/google_sign_in/google_sign_in/test/widgets_test.dart
@@ -0,0 +1,117 @@
+// 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 'dart:async';
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:google_sign_in/google_sign_in.dart';
+
+/// A instantiable class that extends [GoogleIdentity]
+class _TestGoogleIdentity extends GoogleIdentity {
+ _TestGoogleIdentity({
+ required this.id,
+ required this.email,
+ this.photoUrl,
+ });
+
+ final String id;
+ final String email;
+
+ final String? photoUrl;
+
+ @override
+ String? get displayName => null;
+
+ @override
+ String? get serverAuthCode => null;
+}
+
+/// A mocked [HttpClient] which always returns a [_MockHttpRequest].
+class _MockHttpClient extends Fake implements HttpClient {
+ @override
+ bool autoUncompress = true;
+
+ @override
+ Future<HttpClientRequest> getUrl(Uri url) {
+ return Future<HttpClientRequest>.value(_MockHttpRequest());
+ }
+}
+
+/// A mocked [HttpClientRequest] which always returns a [_MockHttpClientResponse].
+class _MockHttpRequest extends Fake implements HttpClientRequest {
+ @override
+ Future<HttpClientResponse> close() {
+ return Future<HttpClientResponse>.value(_MockHttpResponse());
+ }
+}
+
+/// Arbitrary valid image returned by the [_MockHttpResponse].
+///
+/// This is an transparent 1x1 gif image.
+/// It doesn't have to match the placeholder used in [GoogleUserCircleAvatar].
+///
+/// Those bytes come from `resources/transparentImage.gif`.
+final Uint8List _transparentImage = Uint8List.fromList(
+ [
+ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x21, 0xf9, 0x04, 0x01, 0x00, //
+ 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, //
+ 0x00, 0x02, 0x01, 0x44, 0x00, 0x3B
+ ],
+);
+
+/// A mocked [HttpClientResponse] which is empty and has a [statusCode] of 200
+/// and returns valid image.
+class _MockHttpResponse extends Fake implements HttpClientResponse {
+ final Stream<Uint8List> _delegate =
+ Stream<Uint8List>.value(_transparentImage);
+
+ @override
+ int get contentLength => -1;
+
+ @override
+ HttpClientResponseCompressionState get compressionState {
+ return HttpClientResponseCompressionState.decompressed;
+ }
+
+ @override
+ StreamSubscription<Uint8List> listen(void Function(Uint8List event)? onData,
+ {Function? onError, void Function()? onDone, bool? cancelOnError}) {
+ return _delegate.listen(onData,
+ onError: onError, onDone: onDone, cancelOnError: cancelOnError);
+ }
+
+ @override
+ int get statusCode => 200;
+}
+
+void main() {
+ testWidgets('It should build the GoogleUserCircleAvatar successfully',
+ (WidgetTester tester) async {
+ final GoogleIdentity identity = _TestGoogleIdentity(
+ email: 'email@email.com',
+ id: 'userId',
+ photoUrl: 'photoUrl',
+ );
+ tester.binding.window.physicalSizeTestValue = Size(100, 100);
+
+ await HttpOverrides.runZoned(
+ () async {
+ await tester.pumpWidget(MaterialApp(
+ home: SizedBox(
+ height: 100,
+ width: 100,
+ child: GoogleUserCircleAvatar(
+ identity: identity,
+ ),
+ ),
+ ));
+ },
+ createHttpClient: (SecurityContext? c) => _MockHttpClient(),
+ );
+ });
+}