@@ -96,6 +96,14 @@ void main() {
96
96
return BlockContentList (nodes: parseContent (html).nodes);
97
97
}
98
98
99
+ Widget messageContent (String html) {
100
+ return MessageContent (message: eg.streamMessage (content: html),
101
+ content: parseContent (html));
102
+ }
103
+
104
+ // TODO(#488) For content that we need to show outside a per-message context
105
+ // or a context without a full PerAccountStore, make sure to include tests
106
+ // that don't provide such context.
99
107
Future <void > prepareContentBare (WidgetTester tester, Widget child, {
100
108
List <NavigatorObserver > navObservers = const [],
101
109
bool wrapWithPerAccountStoreWidget = false ,
@@ -173,27 +181,16 @@ void main() {
173
181
174
182
group ('interactions: spoiler with tappable content (an image) in the header' , () {
175
183
Future <List <Route <dynamic >>> prepareContent (WidgetTester tester, String html) async {
176
- addTearDown (testBinding.reset);
177
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
178
- prepareBoringImageHttpClient ();
179
-
180
184
final pushedRoutes = < Route <dynamic >> [];
181
185
final testNavObserver = TestNavigatorObserver ()
182
186
..onPushed = (route, prevRoute) => pushedRoutes.add (route);
183
-
184
- await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
185
- localizationsDelegates: ZulipLocalizations .localizationsDelegates,
186
- supportedLocales: ZulipLocalizations .supportedLocales,
187
- navigatorObservers: [testNavObserver],
188
- home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
189
- child: MessageContent (
190
- message: eg.streamMessage (content: html),
191
- content: parseContent (html))))));
192
- await tester.pump (); // global store
193
- await tester.pump (); // per-account store
194
- debugNetworkImageHttpClientProvider = null ;
195
-
196
- // `tester.pumpWidget` introduces an initial route;
187
+ await prepareContentBare (tester,
188
+ // Message is needed for the image's lightbox.
189
+ messageContent (html),
190
+ navObservers: [testNavObserver],
191
+ // We try to resolve the image's URL on the self-account's realm.
192
+ wrapWithPerAccountStoreWidget: true );
193
+ // `tester.pumpWidget` in prepareContentBare introduces an initial route;
197
194
// remove it so consumers only have newly pushed routes.
198
195
assert (pushedRoutes.length == 1 );
199
196
pushedRoutes.removeLast ();
@@ -261,18 +258,12 @@ void main() {
261
258
262
259
group ('MessageImage, MessageImageList' , () {
263
260
Future <void > prepareContent (WidgetTester tester, String html) async {
264
- addTearDown (testBinding.reset);
265
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
266
- prepareBoringImageHttpClient ();
267
-
268
- await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
269
- home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
270
- child: MessageContent (
271
- message: eg.streamMessage (content: html),
272
- content: parseContent (html))))));
273
- await tester.pump (); // global store
274
- await tester.pump (); // per-account store
275
- debugNetworkImageHttpClientProvider = null ;
261
+ await prepareContentBare (tester,
262
+ // Message is needed for an image's lightbox.
263
+ messageContent (html),
264
+ // We try to resolve image URLs on the self-account's realm.
265
+ // For URLs on the self-account's realm, we include the auth credential.
266
+ wrapWithPerAccountStoreWidget: true );
276
267
}
277
268
278
269
testWidgets ('single image' , (tester) async {
@@ -353,22 +344,21 @@ void main() {
353
344
354
345
group ("MessageInlineVideo" , () {
355
346
Future <List <Route <dynamic >>> prepareContent (WidgetTester tester, String html) async {
356
- addTearDown (testBinding.reset);
357
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
358
-
359
347
final pushedRoutes = < Route <dynamic >> [];
360
348
final testNavObserver = TestNavigatorObserver ()
361
349
..onPushed = (route, prevRoute) => pushedRoutes.add (route);
362
-
363
- await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
364
- navigatorObservers: [testNavObserver],
365
- home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
366
- child: MessageContent (
367
- message: eg.streamMessage (content: html),
368
- content: parseContent (html))))));
369
- await tester.pump (); // global store
370
- await tester.pump (); // per-account store
371
-
350
+ await prepareContentBare (tester,
351
+ // Message is needed for a video's lightbox.
352
+ messageContent (html),
353
+ navObservers: [testNavObserver],
354
+ // We try to resolve video URLs on the self-account's realm.
355
+ // With #656, we'll show a preview image. We'll try to resolve this
356
+ // image's URL on the self-account's realm. If it's on the
357
+ // self-account's realm, we'll request it with the auth credential.
358
+ // TODO(#656) in above comment, change "we will" to "we do"
359
+ wrapWithPerAccountStoreWidget: true );
360
+ // `tester.pumpWidget` in prepareContentBare introduces an initial route;
361
+ // remove it so consumers only have newly pushed routes.
372
362
assert (pushedRoutes.length == 1 );
373
363
pushedRoutes.removeLast ();
374
364
return pushedRoutes;
@@ -386,18 +376,11 @@ void main() {
386
376
387
377
group ("MessageEmbedVideo" , () {
388
378
Future <void > prepareContent (WidgetTester tester, String html) async {
389
- addTearDown (testBinding.reset);
390
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
391
- prepareBoringImageHttpClient ();
392
-
393
- await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
394
- home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
395
- child: MessageContent (
396
- message: eg.streamMessage (content: html),
397
- content: parseContent (html))))));
398
- await tester.pump (); // global store
399
- await tester.pump (); // per-account store
400
- debugNetworkImageHttpClientProvider = null ;
379
+ await prepareContentBare (tester,
380
+ // Message is needed for a video's lightbox.
381
+ messageContent (html),
382
+ // We try to resolve a video preview URL on the self-account's realm.
383
+ wrapWithPerAccountStoreWidget: true );
401
384
}
402
385
403
386
Future <void > checkEmbedVideo (WidgetTester tester, ContentExample example) async {
@@ -537,17 +520,9 @@ void main() {
537
520
// We use this to simulate taps on specific glyphs.
538
521
539
522
Future <void > prepareContent (WidgetTester tester, String html) async {
540
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
541
- addTearDown (testBinding.reset);
542
-
543
- await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
544
- localizationsDelegates: ZulipLocalizations .localizationsDelegates,
545
- supportedLocales: ZulipLocalizations .supportedLocales,
546
- home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
547
- child: BlockContentList (
548
- nodes: parseContent (html).nodes)))));
549
- await tester.pump ();
550
- await tester.pump ();
523
+ await prepareContentBare (tester, plainContent (html),
524
+ // We try to resolve relative links on the self-account's realm.
525
+ wrapWithPerAccountStoreWidget: true );
551
526
}
552
527
553
528
testWidgets ('can tap a link to open URL' , (tester) async {
@@ -636,32 +611,29 @@ void main() {
636
611
});
637
612
638
613
group ('LinkNode on internal links' , () {
639
- Future <List <Route <dynamic >>> prepareContent (WidgetTester tester, {
640
- required String html,
641
- }) async {
642
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot (
643
- streams: [eg.stream (streamId: 1 , name: 'check' )],
644
- ));
645
- addTearDown (testBinding.reset);
614
+ Future <List <Route <dynamic >>> prepareContent (WidgetTester tester, String html) async {
646
615
final pushedRoutes = < Route <dynamic >> [];
647
616
final testNavObserver = TestNavigatorObserver ()
648
617
..onPushed = (route, prevRoute) => pushedRoutes.add (route);
649
- await tester. pumpWidget ( GlobalStoreWidget (child : MaterialApp (
650
- navigatorObservers : [testNavObserver] ,
651
- home : PerAccountStoreWidget (accountId : eg.selfAccount.id ,
652
- child : BlockContentList (nodes : parseContent (html).nodes)))));
653
- await tester. pump (); // global store
654
- await tester. pump (); // per-account store
655
- // `tester.pumpWidget` introduces an initial route, remove so
656
- // consumers only have newly pushed routes.
618
+
619
+ await prepareContentBare (tester, plainContent (html) ,
620
+ navObservers : [testNavObserver] ,
621
+ // We try to resolve relative links on the self-account's realm.
622
+ wrapWithPerAccountStoreWidget : true );
623
+
624
+ // `tester.pumpWidget` in prepareContentBare introduces an initial route;
625
+ // remove it so consumers only have newly pushed routes.
657
626
assert (pushedRoutes.length == 1 );
658
627
pushedRoutes.removeLast ();
628
+
629
+ final store = await testBinding.globalStore.perAccount (eg.selfAccount.id);
630
+ store.addStream (eg.stream (name: 'stream' ));
659
631
return pushedRoutes;
660
632
}
661
633
662
634
testWidgets ('valid internal links are navigated to within app' , (tester) async {
663
635
final pushedRoutes = await prepareContent (tester,
664
- html : '<p><a href="/#narrow/stream/1-check">stream</a></p>' );
636
+ '<p><a href="/#narrow/stream/1-check">stream</a></p>' );
665
637
666
638
await tapText (tester, find.text ('stream' ));
667
639
check (testBinding.takeLaunchUrlCalls ()).isEmpty ();
@@ -672,7 +644,7 @@ void main() {
672
644
testWidgets ('invalid internal links are opened in browser' , (tester) async {
673
645
// Link is invalid due to `topic` operator missing an operand.
674
646
final pushedRoutes = await prepareContent (tester,
675
- html : '<p><a href="/#narrow/stream/1-check/topic">invalid</a></p>' );
647
+ '<p><a href="/#narrow/stream/1-check/topic">invalid</a></p>' );
676
648
677
649
await tapText (tester, find.text ('invalid' ));
678
650
final expectedUrl = eg.realmUrl.resolve ('/#narrow/stream/1-check/topic' );
@@ -717,11 +689,9 @@ void main() {
717
689
});
718
690
719
691
testWidgets ('clock icon and text are the same color' , (tester) async {
720
- await tester.pumpWidget (MaterialApp (home: DefaultTextStyle (
721
- style: const TextStyle (color: Colors .green),
722
- child: BlockContentList (nodes:
723
- parseContent ('<p>$timeSpanHtml </p>' ).nodes),
724
- )));
692
+ await prepareContentBare (tester,
693
+ DefaultTextStyle (style: const TextStyle (color: Colors .green),
694
+ child: plainContent ('<p>$timeSpanHtml </p>' )));
725
695
726
696
final icon = tester.widget <Icon >(
727
697
find.descendant (of: find.byType (GlobalTime ),
@@ -779,15 +749,10 @@ void main() {
779
749
780
750
group ('MessageImageEmoji' , () {
781
751
Future <void > prepareContent (WidgetTester tester, String html) async {
782
- addTearDown (testBinding.reset);
783
- await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot ());
784
- prepareBoringImageHttpClient ();
785
-
786
- await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
787
- home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
788
- child: BlockContentList (nodes: parseContent (html).nodes)))));
789
- await tester.pump (); // global store
790
- await tester.pump (); // per-account store
752
+ await prepareContentBare (tester, plainContent (html),
753
+ // We try to resolve image-emoji URLs on the self-account's realm.
754
+ // For URLs on the self-account's realm, we include the auth credential.
755
+ wrapWithPerAccountStoreWidget: true );
791
756
}
792
757
793
758
testWidgets ('smoke: custom emoji' , (tester) async {
0 commit comments