diff --git a/lib/app/cubit/app_cubit.dart b/lib/app/cubit/app_cubit.dart index 5b0183f9..7138112f 100644 --- a/lib/app/cubit/app_cubit.dart +++ b/lib/app/cubit/app_cubit.dart @@ -1,25 +1,34 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; import '../../logs/logs.dart'; import '../../storage/storage_repository.dart'; -import '../../url_launcher/url_launcher.dart'; part 'app_state.dart'; +/// A function that launches a [url] in the default browser. +typedef LaunchUrl = Future Function( + Uri url, { + url_launcher.LaunchMode mode, + url_launcher.WebViewConfiguration webViewConfiguration, + String? webOnlyWindowName, +}); + /// Handles general app-related functionality, like launching urls and checking /// for app updates. class AppCubit extends Cubit { final StorageRepository _storageRepository; - final UrlLauncher _urlLauncher; + final LaunchUrl _launchUrl; static late AppCubit instance; AppCubit( - this._storageRepository, - this._urlLauncher, - ) : super(AppState.initial()) { + this._storageRepository, [ + LaunchUrl? launchUrl, + ]) : _launchUrl = launchUrl ?? url_launcher.launchUrl, + super(AppState.initial()) { instance = this; init(); } @@ -47,10 +56,8 @@ class AppCubit extends Cubit { return false; } - if (!await _urlLauncher.canLaunch(uri)) return false; - try { - return await _urlLauncher.launch(uri); + return await _launchUrl(uri); } on PlatformException catch (e) { log.e('Could not launch url: $url', e); return false; diff --git a/lib/main.dart b/lib/main.dart index 23fcf55b..29bc6a30 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,6 @@ import 'settings/cubit/settings_cubit.dart'; import 'storage/storage_repository.dart'; import 'system_tray/system_tray_manager.dart'; import 'theme/theme.dart'; -import 'url_launcher/url_launcher.dart'; import 'window/app_window.dart'; Future main(List args) async { @@ -76,10 +75,7 @@ Future main(List args) async { MultiBlocProvider( providers: [ BlocProvider( - create: (context) => AppCubit( - storage, - UrlLauncher(), - ), + create: (context) => AppCubit(storage), lazy: false, ), BlocProvider.value(value: settingsCubit), diff --git a/lib/url_launcher/src/src.dart b/lib/url_launcher/src/src.dart deleted file mode 100644 index 39c994f5..00000000 --- a/lib/url_launcher/src/src.dart +++ /dev/null @@ -1 +0,0 @@ -export 'url_launcher.dart'; diff --git a/lib/url_launcher/src/url_launcher.dart b/lib/url_launcher/src/url_launcher.dart deleted file mode 100644 index 6656ce6f..00000000 --- a/lib/url_launcher/src/url_launcher.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:url_launcher/url_launcher.dart'; - -/// Launches URLs on the host platform. -class UrlLauncher { - Future canLaunch(Uri uri) async => await canLaunchUrl(uri); - - Future launch(Uri uri) async => await launchUrl(uri); -} diff --git a/lib/url_launcher/url_launcher.dart b/lib/url_launcher/url_launcher.dart deleted file mode 100644 index c62c850d..00000000 --- a/lib/url_launcher/url_launcher.dart +++ /dev/null @@ -1 +0,0 @@ -export 'src/src.dart'; diff --git a/test/app/cubit/app_cubit_test.dart b/test/app/cubit/app_cubit_test.dart index 58bde698..7670830a 100644 --- a/test/app/cubit/app_cubit_test.dart +++ b/test/app/cubit/app_cubit_test.dart @@ -1,31 +1,40 @@ +import 'package:flutter/services.dart'; import 'package:mocktail/mocktail.dart'; import 'package:nyrna/app/app.dart'; +import 'package:nyrna/logs/logs.dart'; import 'package:nyrna/storage/storage_repository.dart'; -import 'package:nyrna/url_launcher/url_launcher.dart'; import 'package:test/test.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; class MockStorageRepository extends Mock implements StorageRepository {} -class MockUrlLauncher extends Mock implements UrlLauncher {} +class MockLaunchUrl extends Mock { + Future call( + Uri url, { + url_launcher.LaunchMode mode, + url_launcher.WebViewConfiguration webViewConfiguration, + String? webOnlyWindowName, + }); +} late AppCubit cubit; AppState get state => cubit.state; void main() { late StorageRepository storageRepository; - late UrlLauncher urlLauncher; + late LaunchUrl urlLauncher; - setUpAll(() { + setUpAll(() async { registerFallbackValue(Uri()); + await LoggingManager.initialize(verbose: false); }); setUp(() { storageRepository = MockStorageRepository(); when(() => storageRepository.getValue(any())).thenAnswer((_) async => null); - urlLauncher = MockUrlLauncher(); - when(() => urlLauncher.canLaunch(any())).thenAnswer((_) async => true); - when(() => urlLauncher.launch(any())).thenAnswer((_) async => true); + urlLauncher = MockLaunchUrl(); + when(() => urlLauncher.call(any())).thenAnswer((_) async => true); cubit = AppCubit( storageRepository, @@ -45,18 +54,17 @@ void main() { test('launches a correct url', () async { final result = await cubit.launchURL(correctTestUrl); expect(result, true); - verify(() => urlLauncher.canLaunch(any())).called(1); - verify(() => urlLauncher.launch(any())).called(1); + verify(() => urlLauncher.call(any())).called(1); }); test('bad url returns false', () async { const badTestUrl = 'htp:/gogg.m'; - when(() => urlLauncher.canLaunch(Uri.parse(badTestUrl))) - .thenAnswer((_) async => false); + final uri = Uri.parse(badTestUrl); + when(() => urlLauncher.call(uri)) + .thenThrow(PlatformException(code: 'bad url')); final result = await cubit.launchURL(badTestUrl); expect(result, false); - verify(() => urlLauncher.canLaunch(any())).called(1); - verifyNever(() => urlLauncher.launch(any())); + verify(() => urlLauncher.call(any())).called(1); }); }); });