@@ -294,6 +294,102 @@ void main() {
294
294
tester.widget (find.textContaining (RegExp (r'^(Tue, Jan 30|Wed, Jan 31), 2024, \d+:\d\d [AP]M$' )));
295
295
});
296
296
297
+ group ('MessageImages' , () {
298
+ final message = eg.streamMessage ();
299
+
300
+ Future <void > prepareContent (WidgetTester tester, String html) async {
301
+ addTearDown (testBinding.reset);
302
+
303
+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
304
+ final httpClient = FakeImageHttpClient ();
305
+
306
+ debugNetworkImageHttpClientProvider = () => httpClient;
307
+ httpClient.request.response
308
+ ..statusCode = HttpStatus .ok
309
+ ..content = kSolidBlueAvatar;
310
+
311
+ await tester.pumpWidget (
312
+ MaterialApp (
313
+ home: Directionality (
314
+ textDirection: TextDirection .ltr,
315
+ child: GlobalStoreWidget (
316
+ child: PerAccountStoreWidget (
317
+ accountId: eg.selfAccount.id,
318
+ child: MessageContent (
319
+ message: message,
320
+ content: parseContent (html)))))));
321
+ await tester.pump (); // global store
322
+ await tester.pump (); // per-account store
323
+ debugNetworkImageHttpClientProvider = null ;
324
+ }
325
+
326
+ testWidgets ('single image' , (tester) async {
327
+ // "https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3"
328
+ await prepareContent (tester,
329
+ '<div class="message_inline_image">'
330
+ '<a href="https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3">'
331
+ '<img src="https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3"></a></div>' );
332
+ tester.widget (find.byType (RealmContentNetworkImage ));
333
+ final images = tester.widgetList <RealmContentNetworkImage >(find.byType (RealmContentNetworkImage ));
334
+ check (images.map ((i) => i.src.toString ()).toList ())
335
+ .deepEquals ([
336
+ 'https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3'
337
+ ]);
338
+ });
339
+
340
+ testWidgets ('parse multiple images' , (tester) async {
341
+ // "https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3\nhttps://chat.zulip.org/user_avatars/2/realm/icon.png?version=4"
342
+ await prepareContent (tester,
343
+ '<p>'
344
+ '<a href="https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3">https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3</a><br>\n '
345
+ '<a href="https://chat.zulip.org/user_avatars/2/realm/icon.png?version=4">https://chat.zulip.org/user_avatars/2/realm/icon.png?version=4</a></p>\n '
346
+ '<div class="message_inline_image">'
347
+ '<a href="https://chat.zulip.org/user_avatars/2/realm/icon.png?version=3">'
348
+ '<img src="https://uploads.zulipusercontent.net/f535ba07f95b99a83aa48e44fd62bbb6c6cf6615/68747470733a2f2f636861742e7a756c69702e6f72672f757365725f617661746172732f322f7265616c6d2f69636f6e2e706e673f76657273696f6e3d33"></a></div>'
349
+ '<div class="message_inline_image">'
350
+ '<a href="https://chat.zulip.org/user_avatars/2/realm/icon.png?version=4">'
351
+ '<img src="https://uploads.zulipusercontent.net/8f63bc2632a0e41be3f457d86c077e61b4a03e7e/68747470733a2f2f636861742e7a756c69702e6f72672f757365725f617661746172732f322f7265616c6d2f69636f6e2e706e673f76657273696f6e3d34"></a></div>' );
352
+ final images = tester.widgetList <RealmContentNetworkImage >(find.byType (RealmContentNetworkImage ));
353
+ check (images.map ((i) => i.src.toString ()).toList ())
354
+ .deepEquals ([
355
+ 'https://uploads.zulipusercontent.net/f535ba07f95b99a83aa48e44fd62bbb6c6cf6615/68747470733a2f2f636861742e7a756c69702e6f72672f757365725f617661746172732f322f7265616c6d2f69636f6e2e706e673f76657273696f6e3d33' ,
356
+ 'https://uploads.zulipusercontent.net/8f63bc2632a0e41be3f457d86c077e61b4a03e7e/68747470733a2f2f636861742e7a756c69702e6f72672f757365725f617661746172732f322f7265616c6d2f69636f6e2e706e673f76657273696f6e3d34' ,
357
+ ]);
358
+ });
359
+
360
+ testWidgets ('multiple clusters of images' , (tester) async {
361
+ // "https://en.wikipedia.org/static/images/icons/wikipedia.png\nhttps://en.wikipedia.org/static/images/icons/wikipedia.png?v=1\n\nTest\n\nhttps://en.wikipedia.org/static/images/icons/wikipedia.png?v=2\nhttps://en.wikipedia.org/static/images/icons/wikipedia.png?v=3"
362
+ await prepareContent (tester,
363
+ '<p>'
364
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png">https://en.wikipedia.org/static/images/icons/wikipedia.png</a><br>\n '
365
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png?v=1">https://en.wikipedia.org/static/images/icons/wikipedia.png?v=1</a></p>\n '
366
+ '<div class="message_inline_image">'
367
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png">'
368
+ '<img src="https://uploads.zulipusercontent.net/34b2695ca83af76204b0b25a8f2019ee35ec38fa/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e67"></a></div>'
369
+ '<div class="message_inline_image">'
370
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png?v=1">'
371
+ '<img src="https://uploads.zulipusercontent.net/d200fb112aaccbff9df767373a201fa59601f362/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e673f763d31"></a></div>'
372
+ '<p>Test</p>\n '
373
+ '<p>'
374
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png?v=2">https://en.wikipedia.org/static/images/icons/wikipedia.png?v=2</a><br>\n '
375
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png?v=3">https://en.wikipedia.org/static/images/icons/wikipedia.png?v=3</a></p>\n '
376
+ '<div class="message_inline_image">'
377
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png?v=2">'
378
+ '<img src="https://uploads.zulipusercontent.net/c4db87e81348dac94eacaa966b46d968b34029cc/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e673f763d32"></a></div>'
379
+ '<div class="message_inline_image">'
380
+ '<a href="https://en.wikipedia.org/static/images/icons/wikipedia.png?v=3">'
381
+ '<img src="https://uploads.zulipusercontent.net/51b70540cf6a5b3c8a0b919c893b8abddd447e88/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e673f763d33"></a></div>' );
382
+ final images = tester.widgetList <RealmContentNetworkImage >(find.byType (RealmContentNetworkImage ));
383
+ check (images.map ((i) => i.src.toString ()).toList ())
384
+ .deepEquals ([
385
+ 'https://uploads.zulipusercontent.net/34b2695ca83af76204b0b25a8f2019ee35ec38fa/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e67' ,
386
+ 'https://uploads.zulipusercontent.net/d200fb112aaccbff9df767373a201fa59601f362/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e673f763d31' ,
387
+ 'https://uploads.zulipusercontent.net/c4db87e81348dac94eacaa966b46d968b34029cc/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e673f763d32' ,
388
+ 'https://uploads.zulipusercontent.net/51b70540cf6a5b3c8a0b919c893b8abddd447e88/68747470733a2f2f656e2e77696b6970656469612e6f72672f7374617469632f696d616765732f69636f6e732f77696b6970656469612e706e673f763d33' ,
389
+ ]);
390
+ });
391
+ });
392
+
297
393
group ('RealmContentNetworkImage' , () {
298
394
final authHeaders = authHeader (email: eg.selfAccount.email, apiKey: eg.selfAccount.apiKey);
299
395
0 commit comments