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,51 @@ 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+
93+ final badUser = eg.user (avatarUrl: 'https://zulip.com/avatarinvalid.png' );
94+ await store.addUser (badUser);
95+
96+ await tester.pumpWidget (
97+ TestZulipApp (accountId: eg.selfAccount.id,
98+ child: AvatarImage (userId: badUser.userId, size: 30 )));
99+ await tester.pumpAndSettle ();
100+ check (findPlaceholder).findsOne ();
101+
102+ debugNetworkImageHttpClientProvider = null ;
103+ });
104+
105+ testWidgets ('shows placeholder when user avatarUrl is null' , (WidgetTester tester) async {
106+ addTearDown (testBinding.reset);
107+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
108+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
109+
110+ final userWithNoUrl = eg.user (avatarUrl: null );
111+ await store.addUser (userWithNoUrl);
112+
113+ await tester.pumpWidget (
114+ TestZulipApp (accountId: eg.selfAccount.id,
115+ child: AvatarImage (userId: userWithNoUrl.userId, size: 30 )));
116+ await tester.pumpAndSettle ();
117+ check (findPlaceholder).findsOne ();
118+ });
119+
120+ testWidgets ('shows placeholder when user is not found' , (WidgetTester tester) async {
121+ addTearDown (testBinding.reset);
122+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
123+
124+ const nonExistentUserId = 9999999 ;
125+
126+ await tester.pumpWidget (
127+ TestZulipApp (accountId: eg.selfAccount.id,
128+ child: AvatarImage (userId: nonExistentUserId, size: 30 )));
129+ await tester.pumpAndSettle ();
130+ check (findPlaceholder).findsOne ();
131+ });
81132 });
82133}
0 commit comments