11import 'package:checks/checks.dart' ;
2- import 'package:flutter/cupertino.dart' ;
32import 'package:flutter/material.dart' ;
4- import 'package:flutter/rendering .dart' ;
3+ import 'package:flutter_checks/flutter_checks .dart' ;
54import 'package:flutter_test/flutter_test.dart' ;
65import 'package:zulip/model/store.dart' ;
76import 'package:zulip/widgets/image.dart' ;
8- import 'package:zulip/widgets/store .dart' ;
7+ import 'package:zulip/widgets/icons .dart' ;
98import 'package:zulip/widgets/user.dart' ;
109
1110import '../example_data.dart' as eg;
1211import '../model/binding.dart' ;
1312import '../model/test_store.dart' ;
1413import '../stdlib_checks.dart' ;
1514import '../test_images.dart' ;
15+ import 'test_app.dart' ;
1616
1717void main () {
1818 TestZulipBinding .ensureInitialized ();
1919
2020 group ('AvatarImage' , () {
2121 late PerAccountStore store;
2222
23+ final findPlaceholder = find.descendant (
24+ of: find.byType (AvatarImage ),
25+ matching: find.byIcon (ZulipIcons .person),
26+ );
27+
2328 Future <Uri ?> actualUrl (WidgetTester tester, String avatarUrl, [double ? size]) async {
2429 addTearDown (testBinding.reset);
2530 await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
@@ -28,9 +33,9 @@ void main() {
2833 await store.addUser (user);
2934
3035 prepareBoringImageHttpClient ();
31- await tester.pumpWidget (GlobalStoreWidget (
32- child : PerAccountStoreWidget (accountId: eg.selfAccount.id,
33- child: AvatarImage (userId: user.userId, size: size ?? 30 ) )));
36+ await tester.pumpWidget (
37+ TestZulipApp (accountId: eg.selfAccount.id,
38+ child: AvatarImage (userId: user.userId, size: size ?? 30 )));
3439 await tester.pump ();
3540 await tester.pump ();
3641 tester.widget (find.byType (AvatarImage ));
@@ -78,5 +83,48 @@ void main() {
7883 check (await actualUrl (tester, avatarUrl)).isNull ();
7984 debugNetworkImageHttpClientProvider = null ;
8085 });
86+
87+ testWidgets ('shows placeholder when image URL gives error' , (WidgetTester tester) async {
88+ addTearDown (testBinding.reset);
89+ prepareBoringImageHttpClient (success: false );
90+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
91+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
92+ final badUser = eg.user (avatarUrl: 'https://zulip.com/avatarinvalid.png' );
93+ await store.addUser (badUser);
94+ await tester.pumpWidget (
95+ TestZulipApp (accountId: eg.selfAccount.id,
96+ child: AvatarImage (userId: badUser.userId, size: 30 )));
97+ await tester.pumpAndSettle ();
98+ check (findPlaceholder).findsOne ();
99+ debugNetworkImageHttpClientProvider = null ;
100+ });
101+
102+ testWidgets ('shows placeholder when user avatarUrl is null' , (WidgetTester tester) async {
103+ addTearDown (testBinding.reset);
104+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
105+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
106+
107+ final userWithNoUrl = eg.user (avatarUrl: null );
108+ await store.addUser (userWithNoUrl);
109+
110+ await tester.pumpWidget (
111+ TestZulipApp (accountId: eg.selfAccount.id,
112+ child: AvatarImage (userId: userWithNoUrl.userId, size: 30 )));
113+ await tester.pumpAndSettle ();
114+ check (findPlaceholder).findsOne ();
115+ });
116+
117+ testWidgets ('shows placeholder when user is not found' , (WidgetTester tester) async {
118+ addTearDown (testBinding.reset);
119+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
120+
121+ const nonExistentUserId = 9999999 ;
122+
123+ await tester.pumpWidget (
124+ TestZulipApp (accountId: eg.selfAccount.id,
125+ child: AvatarImage (userId: nonExistentUserId, size: 30 )));
126+ await tester.pumpAndSettle ();
127+ check (findPlaceholder).findsOne ();
128+ });
81129 });
82130}
0 commit comments