Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/widgets/user.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:flutter/material.dart';

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't delete this blank line; it separates third-party imports from our own imports. (Here and elsewhere in the PR.)

import '../api/model/model.dart';
import '../model/avatar_url.dart';
import '../model/binding.dart';
Expand Down Expand Up @@ -90,6 +89,9 @@ class AvatarImage extends StatelessWidget {
avatarUrl.get(physicalSize),
filterQuality: FilterQuality.medium,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) {
return _AvatarPlaceholder(size: size);
},
);
}
}
Expand Down
35 changes: 33 additions & 2 deletions test/widgets/user_test.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import 'package:checks/checks.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:zulip/widgets/icons.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:zulip/model/store.dart';
import 'package:zulip/widgets/content.dart';
import 'package:zulip/widgets/store.dart';
import 'package:zulip/widgets/user.dart';

import 'dart:io';
import '../example_data.dart' as eg;
import '../model/binding.dart';
import '../model/test_store.dart';
import '../stdlib_checks.dart';
import '../test_images.dart';
import 'test_app.dart';

class MockHttpClient extends Fake implements HttpClient {
@override
Future<HttpClientRequest> getUrl(Uri url) async {
throw const SocketException('test error');
}
}

void main() {
TestZulipBinding.ensureInitialized();
Expand Down Expand Up @@ -78,5 +86,28 @@ void main() {
check(await actualUrl(tester, avatarUrl)).isNull();
debugNetworkImageHttpClientProvider = null;
});

testWidgets('shows placeholder when image URL gives error', (WidgetTester tester) async {
await HttpOverrides.runZoned(() async {
addTearDown(testBinding.reset);
await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot());
final store = await testBinding.globalStore.perAccount(eg.selfAccount.id);
final user = eg.user(avatarUrl: 'https://zulip.com/avatar.png');
await store.addUser(user);

await tester.pumpWidget(
TestZulipApp(
accountId: eg.selfAccount.id,
child: AvatarImage(userId: user.userId, size: 32),
),
);
await tester.pump(); // Image provider is created
await tester.pump(); // Image fails to load
expect(find.byIcon(ZulipIcons.person), findsOneWidget);

expect(find.byType(DecoratedBox), findsOneWidget);

}, createHttpClient: (context) => MockHttpClient());
});
});
}