[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(),
+    );
+  });
+}