@@ -8,13 +8,19 @@ import 'package:flutter_test/flutter_test.dart';
8
8
import 'package:url_launcher/url_launcher.dart' ;
9
9
import 'package:zulip/api/core.dart' ;
10
10
import 'package:zulip/model/content.dart' ;
11
+ import 'package:zulip/model/narrow.dart' ;
11
12
import 'package:zulip/widgets/content.dart' ;
13
+ import 'package:zulip/widgets/message_list.dart' ;
14
+ import 'package:zulip/widgets/page.dart' ;
12
15
import 'package:zulip/widgets/store.dart' ;
13
16
14
17
import '../example_data.dart' as eg;
15
18
import '../model/binding.dart' ;
16
19
import '../test_images.dart' ;
20
+ import '../test_navigation.dart' ;
17
21
import 'dialog_checks.dart' ;
22
+ import 'message_list_checks.dart' ;
23
+ import 'page_checks.dart' ;
18
24
19
25
void main () {
20
26
TestZulipBinding .ensureInitialized ();
@@ -158,6 +164,51 @@ void main() {
158
164
});
159
165
});
160
166
167
+ group ('LinkNode on internal links' , () {
168
+ Future <List <Route <dynamic >>> prepareContent (WidgetTester tester, {
169
+ required String html,
170
+ }) async {
171
+ await testBinding.globalStore.add (eg.selfAccount, eg.initialSnapshot (
172
+ streams: [eg.stream (streamId: 1 , name: 'check' )],
173
+ ));
174
+ addTearDown (testBinding.reset);
175
+ final pushedRoutes = < Route <dynamic >> [];
176
+ final testNavObserver = TestNavigatorObserver ()
177
+ ..onPushed = (route, prevRoute) => pushedRoutes.add (route);
178
+ await tester.pumpWidget (GlobalStoreWidget (child: MaterialApp (
179
+ navigatorObservers: [testNavObserver],
180
+ home: PerAccountStoreWidget (accountId: eg.selfAccount.id,
181
+ child: BlockContentList (nodes: parseContent (html).nodes)))));
182
+ await tester.pump ();
183
+ await tester.pump ();
184
+ assert (pushedRoutes.length == 1 );
185
+ pushedRoutes.removeLast ();
186
+ return pushedRoutes;
187
+ }
188
+
189
+ testWidgets ('valid internal links are resolved' , (tester) async {
190
+ final pushedRoutes = await prepareContent (tester,
191
+ html: '<p><a href="/#narrow/stream/1-check">stream</a></p>' );
192
+
193
+ await tester.tap (find.text ('stream' ));
194
+ check (testBinding.takeLaunchUrlCalls ()).isEmpty ();
195
+ check (pushedRoutes).single.isA <WidgetRoute >()
196
+ .page.isA <MessageListPage >()
197
+ .narrow.equals (const StreamNarrow (1 ));
198
+ });
199
+
200
+ testWidgets ('invalid internal links are not followed' , (tester) async {
201
+ final pushedRoutes = await prepareContent (tester,
202
+ html: '<p><a href="/#narrow/stream/1-check/topic">invalid</a></p>' );
203
+
204
+ await tester.tap (find.text ('invalid' ));
205
+ final expectedUrl = Uri .parse ('${eg .realmUrl }#narrow/stream/1-check/topic' );
206
+ check (testBinding.takeLaunchUrlCalls ())
207
+ .single.equals ((url: expectedUrl, mode: LaunchMode .externalApplication));
208
+ check (pushedRoutes).isEmpty ();
209
+ });
210
+ });
211
+
161
212
group ('UnicodeEmoji' , () {
162
213
Future <void > prepareContent (WidgetTester tester, String html) async {
163
214
await tester.pumpWidget (MaterialApp (home: BlockContentList (nodes: parseContent (html).nodes)));
0 commit comments