launcher_controller_test.dart 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import 'package:cardash_launcher/data/models/app_entry.dart';
  2. import 'package:cardash_launcher/data/models/slot_type.dart';
  3. import 'package:cardash_launcher/data/models/system_status.dart';
  4. import 'package:cardash_launcher/data/repositories/settings_repository.dart';
  5. import 'package:cardash_launcher/data/services/native_bridge.dart';
  6. import 'package:cardash_launcher/features/home/launcher_controller.dart';
  7. import 'package:flutter_test/flutter_test.dart';
  8. import 'package:shared_preferences/shared_preferences.dart';
  9. class FakeLauncherPlatform implements LauncherPlatform {
  10. FakeLauncherPlatform(this.apps);
  11. final List<AppEntry> apps;
  12. @override
  13. Future<List<AppEntry>> listApps() async => apps;
  14. @override
  15. Future<void> launchApp({
  16. required String packageName,
  17. required String activityName,
  18. }) async {}
  19. @override
  20. Future<bool> isDefaultHome() async => true;
  21. @override
  22. Future<bool> requestDefaultHome() async => true;
  23. @override
  24. Future<SystemStatus> getStatus() async => const SystemStatus();
  25. @override
  26. Future<VolumeInfo> getVolume() async => const VolumeInfo();
  27. @override
  28. Future<void> setVolume(int index) async {}
  29. }
  30. List<AppEntry> _apps(int count) {
  31. return List.generate(
  32. count,
  33. (index) => AppEntry(
  34. packageName: 'com.example.app$index',
  35. activityName: 'com.example.app$index.Main',
  36. label: 'App $index',
  37. ),
  38. );
  39. }
  40. Future<LauncherController> _controller({
  41. int appCount = 20,
  42. FakeLauncherPlatform? platform,
  43. }) async {
  44. SharedPreferences.setMockInitialValues({});
  45. final prefs = await SharedPreferences.getInstance();
  46. final controller = LauncherController(
  47. platform ?? FakeLauncherPlatform(_apps(appCount)),
  48. SettingsRepository(prefs),
  49. );
  50. controller.initialize();
  51. return controller;
  52. }
  53. void main() {
  54. TestWidgetsFlutterBinding.ensureInitialized();
  55. test('home buttons default to enabled and count the fixed buttons', () async {
  56. final controller = await _controller();
  57. addTearDown(controller.dispose);
  58. expect(controller.isSlotEnabled(SlotType.navigation), isTrue);
  59. expect(controller.isSlotEnabled(SlotType.music), isTrue);
  60. expect(controller.isSlotEnabled(SlotType.radio), isTrue);
  61. expect(controller.homeButtonCount, 5);
  62. expect(controller.pinnedApps, isEmpty);
  63. });
  64. test('disabling a slot hides it and keeps the assignment', () async {
  65. final controller = await _controller();
  66. addTearDown(controller.dispose);
  67. final app = _apps(1).first;
  68. await controller.assign(SlotType.navigation, app);
  69. expect(await controller.setSlotEnabled(SlotType.navigation, false), isNull);
  70. expect(controller.isSlotEnabled(SlotType.navigation), isFalse);
  71. expect(controller.homeButtonCount, 4);
  72. expect(controller.assignmentFor(SlotType.navigation)?.label, 'App 0');
  73. expect(await controller.setSlotEnabled(SlotType.navigation, true), isNull);
  74. expect(controller.homeButtonCount, 5);
  75. });
  76. test('pinned apps can be added once and removed again', () async {
  77. final controller = await _controller();
  78. addTearDown(controller.dispose);
  79. final apps = _apps(3);
  80. expect(await controller.addPinnedApp(apps[0]), isNull);
  81. expect(controller.pinnedApps.length, 1);
  82. expect(controller.homeButtonCount, 6);
  83. expect(await controller.addPinnedApp(apps[0]), contains('already'));
  84. await controller.removePinnedApp(apps[0].toAssignment());
  85. expect(controller.pinnedApps, isEmpty);
  86. expect(controller.homeButtonCount, 5);
  87. });
  88. test('the home screen stops at 16 buttons', () async {
  89. final controller = await _controller();
  90. addTearDown(controller.dispose);
  91. final apps = _apps(20);
  92. for (var index = 0; index < 11; index++) {
  93. expect(await controller.addPinnedApp(apps[index]), isNull);
  94. }
  95. expect(controller.homeButtonCount, 16);
  96. expect(await controller.addPinnedApp(apps[11]), contains('full'));
  97. expect(controller.pinnedApps.length, 11);
  98. await controller.removePinnedApp(apps[0].toAssignment());
  99. expect(controller.homeButtonCount, 15);
  100. expect(await controller.addPinnedApp(apps[11]), isNull);
  101. expect(controller.homeButtonCount, 16);
  102. });
  103. test('pinned apps and slot visibility survive a new controller', () async {
  104. SharedPreferences.setMockInitialValues({});
  105. final prefs = await SharedPreferences.getInstance();
  106. final platform = FakeLauncherPlatform(_apps(3));
  107. final settings = SettingsRepository(prefs);
  108. final first = LauncherController(platform, settings);
  109. first.initialize();
  110. addTearDown(first.dispose);
  111. await first.setSlotEnabled(SlotType.radio, false);
  112. expect(await first.addPinnedApp(_apps(1).first), isNull);
  113. final second = LauncherController(platform, SettingsRepository(prefs));
  114. second.initialize();
  115. addTearDown(second.dispose);
  116. expect(second.isSlotEnabled(SlotType.radio), isFalse);
  117. expect(second.pinnedApps.length, 1);
  118. expect(second.pinnedApps.first.label, 'App 0');
  119. expect(second.homeButtonCount, 5);
  120. });
  121. }