main
dart 127 lines 3.91 KB
Raw
1 import 'package:flutter/material.dart';
2 import 'package:flutter_localizations/flutter_localizations.dart';
3 import 'package:flutter_riverpod/flutter_riverpod.dart';
4 import 'package:flutter_test/flutter_test.dart';
5 import 'package:localmind/core/providers/app_providers.dart';
6 import 'package:localmind/core/theme/app_theme.dart';
7 import 'package:localmind/features/chat/views/components/notification_permission_banner.dart';
8 import 'package:localmind/features/on_device/data/notification_permission_service.dart';
9 import 'package:localmind/features/on_device/providers/on_device_providers.dart';
10 import 'package:localmind/features/settings/data/models/app_settings.dart';
11 import 'package:localmind/l10n/app_localizations.dart';
12 import 'package:shadcn_ui/shadcn_ui.dart';
13 import 'package:shared_preferences/shared_preferences.dart';
14
15 class _FakeNotificationPermissionService
16 implements NotificationPermissionService {
17 _FakeNotificationPermissionService({this.granted = false});
18
19 final bool granted;
20 bool requestCalled = false;
21
22 @override
23 Future<void> init() async {}
24
25 @override
26 Future<bool> isPermissionGranted() async => granted;
27
28 @override
29 Future<bool> requestPermission() async {
30 requestCalled = true;
31 return true;
32 }
33 }
34
35 class _TestSettingsNotifier extends SettingsNotifier {
36 _TestSettingsNotifier(this._initial);
37 final AppSettings _initial;
38
39 @override
40 AppSettings build() => _initial;
41 }
42
43 Widget _wrapWithApp({required Widget child, List<dynamic>? overrides}) {
44 return ProviderScope(
45 overrides: [...?overrides?.cast()],
46 child: ShadTheme(
47 data: AppTheme.lightShadTheme,
48 child: MaterialApp(
49 locale: const Locale('en'),
50 localizationsDelegates: const [
51 AppLocalizations.delegate,
52 GlobalMaterialLocalizations.delegate,
53 GlobalWidgetsLocalizations.delegate,
54 GlobalCupertinoLocalizations.delegate,
55 ],
56 supportedLocales: AppLocalizations.supportedLocales,
57 home: Scaffold(body: child),
58 ),
59 ),
60 );
61 }
62
63 void main() {
64 TestWidgetsFlutterBinding.ensureInitialized();
65
66 setUp(() {
67 SharedPreferences.setMockInitialValues({});
68 });
69
70 group('NotificationPermissionBanner Widget Tests', () {
71 testWidgets(
72 'mounts cleanly and displays banner when permission not granted',
73 (tester) async {
74 final fakeService = _FakeNotificationPermissionService(granted: false);
75
76 await tester.pumpWidget(
77 _wrapWithApp(
78 overrides: [
79 notificationPermissionServiceProvider.overrideWithValue(
80 fakeService,
81 ),
82 settingsProvider.overrideWith(
83 () => _TestSettingsNotifier(
84 AppSettings(hasAskedForNotifications: false),
85 ),
86 ),
87 ],
88 child: const NotificationPermissionBanner(),
89 ),
90 );
91
92 // Verify no exception on first frame / mount
93 expect(tester.takeException(), isNull);
94
95 await tester.pumpAndSettle();
96
97 final l10n = lookupAppLocalizations(const Locale('en'));
98 expect(find.text(l10n.enable_notifications), findsOneWidget);
99 },
100 );
101
102 testWidgets('does not show banner when user already asked', (tester) async {
103 final fakeService = _FakeNotificationPermissionService(granted: false);
104
105 await tester.pumpWidget(
106 _wrapWithApp(
107 overrides: [
108 notificationPermissionServiceProvider.overrideWithValue(
109 fakeService,
110 ),
111 settingsProvider.overrideWith(
112 () => _TestSettingsNotifier(
113 AppSettings(hasAskedForNotifications: true),
114 ),
115 ),
116 ],
117 child: const NotificationPermissionBanner(),
118 ),
119 );
120
121 await tester.pumpAndSettle();
122
123 final l10n = lookupAppLocalizations(const Locale('en'));
124 expect(find.text(l10n.enable_notifications), findsNothing);
125 });
126 });
127 }