1
1
import 'dart:convert' ;
2
2
3
3
import 'package:checks/checks.dart' ;
4
+ import 'package:flutter/foundation.dart' ;
4
5
import 'package:flutter/material.dart' ;
5
6
import 'package:flutter/services.dart' ;
6
7
import 'package:flutter_test/flutter_test.dart' ;
@@ -12,6 +13,7 @@ import 'package:zulip/api/route/messages.dart';
12
13
import 'package:zulip/model/binding.dart' ;
13
14
import 'package:zulip/model/localizations.dart' ;
14
15
import 'package:zulip/model/narrow.dart' ;
16
+ import 'package:zulip/model/settings.dart' ;
15
17
import 'package:zulip/model/store.dart' ;
16
18
import 'package:zulip/widgets/actions.dart' ;
17
19
@@ -414,5 +416,95 @@ void main() {
414
416
await checkSnackBar (tester, expected: true );
415
417
});
416
418
});
419
+
420
+ group ('launchUrl' , () {
421
+ Future <void > call (WidgetTester tester, {required Uri url}) async {
422
+ await tester.pumpWidget (TestZulipApp (
423
+ child: Builder (builder: (context) => Center (
424
+ child: ElevatedButton (
425
+ onPressed: () async {
426
+ await PlatformActions .launchUrl (context, url);
427
+ },
428
+ child: const Text ('link' ))))));
429
+ await tester.pump ();
430
+ await tester.tap (find.text ('link' ));
431
+ await tester.pump (Duration .zero);
432
+ }
433
+
434
+ final httpUrl = Uri .parse ('http://chat.zulip.org' );
435
+ final nonHttpUrl
= Uri .
parse (
'mailto:[email protected] ' );
436
+
437
+ Future <void > runAndCheckSuccess (WidgetTester tester, {
438
+ required Uri url,
439
+ required UrlLaunchMode expectedModeAndroid,
440
+ required UrlLaunchMode expectedModeIos,
441
+ }) async {
442
+ await call (tester, url: url);
443
+
444
+ final expectedMode = switch (defaultTargetPlatform) {
445
+ TargetPlatform .android => expectedModeAndroid,
446
+ TargetPlatform .iOS => expectedModeIos,
447
+ _ => throw StateError ('attempted to test with $defaultTargetPlatform ' ),
448
+ };
449
+ check (testBinding.takeLaunchUrlCalls ()).single
450
+ .equals ((url: url, mode: expectedMode));
451
+ }
452
+
453
+ final androidIosVariant = TargetPlatformVariant ({TargetPlatform .iOS, TargetPlatform .android});
454
+
455
+ testWidgets ('globalSettings.browserPreference is null; use our per-platform defaults for HTTP links' , (tester) async {
456
+ await testBinding.globalStore.settings.setBrowserPreference (null );
457
+ await runAndCheckSuccess (tester,
458
+ url: httpUrl,
459
+ expectedModeAndroid: UrlLaunchMode .inAppBrowserView,
460
+ expectedModeIos: UrlLaunchMode .externalApplication);
461
+ }, variant: androidIosVariant);
462
+
463
+ testWidgets ('globalSettings.browserPreference is null; use our per-platform defaults for non-HTTP links' , (tester) async {
464
+ await testBinding.globalStore.settings.setBrowserPreference (null );
465
+ await runAndCheckSuccess (tester,
466
+ url: nonHttpUrl,
467
+ expectedModeAndroid: UrlLaunchMode .platformDefault,
468
+ expectedModeIos: UrlLaunchMode .externalApplication);
469
+ }, variant: androidIosVariant);
470
+
471
+ testWidgets ('globalSettings.browserPreference is inApp; follow the user preference for http links' , (tester) async {
472
+ await testBinding.globalStore.settings.setBrowserPreference (BrowserPreference .inApp);
473
+ await runAndCheckSuccess (tester,
474
+ url: httpUrl,
475
+ expectedModeAndroid: UrlLaunchMode .inAppBrowserView,
476
+ expectedModeIos: UrlLaunchMode .inAppBrowserView);
477
+ }, variant: androidIosVariant);
478
+
479
+ testWidgets ('globalSettings.browserPreference is inApp; use platform default for non-http links' , (tester) async {
480
+ await testBinding.globalStore.settings.setBrowserPreference (BrowserPreference .inApp);
481
+ await runAndCheckSuccess (tester,
482
+ url: nonHttpUrl,
483
+ expectedModeAndroid: UrlLaunchMode .platformDefault,
484
+ expectedModeIos: UrlLaunchMode .platformDefault);
485
+ }, variant: androidIosVariant);
486
+
487
+ testWidgets ('globalSettings.browserPreference is external; follow the user preference' , (tester) async {
488
+ await testBinding.globalStore.settings.setBrowserPreference (BrowserPreference .external );
489
+ await runAndCheckSuccess (tester,
490
+ url: httpUrl,
491
+ expectedModeAndroid: UrlLaunchMode .externalApplication,
492
+ expectedModeIos: UrlLaunchMode .externalApplication);
493
+ }, variant: androidIosVariant);
494
+
495
+ testWidgets ('ZulipBinding.launchUrl returns false' , (tester) async {
496
+ testBinding.launchUrlResult = false ;
497
+ await call (tester, url: httpUrl);
498
+ checkErrorDialog (tester, expectedTitle: 'Unable to open link' );
499
+ }, variant: androidIosVariant);
500
+
501
+ testWidgets ('ZulipBinding.launchUrl throws PlatformException' , (tester) async {
502
+ testBinding.launchUrlException = PlatformException (code: 'code' , message: 'error message' );
503
+ await call (tester, url: httpUrl);
504
+ checkErrorDialog (tester,
505
+ expectedTitle: 'Unable to open link' ,
506
+ expectedMessage: 'Link could not be opened: ${httpUrl .toString ()}\n\n error message' );
507
+ }, variant: androidIosVariant);
508
+ });
417
509
});
418
510
}
0 commit comments