import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'package:fuel_tax_tracker/screens/data_settings_screen.dart'; import 'package:fuel_tax_tracker/screens/faq_screen.dart'; import 'package:fuel_tax_tracker/screens/settings_screen.dart'; import 'package:fuel_tax_tracker/screens/ui_settings_screen.dart'; import 'package:fuel_tax_tracker/screens/user_agreement_screen.dart'; import 'package:fuel_tax_tracker/services/app_state.dart'; /// Covers the Settings landing page's menu wiring: it groups settings into /// two submenus — [UiSettingsScreen] (appearance) and [DataSettingsScreen] /// (cloud storage, photo syncing/quality, advanced/purge) — plus keeps a /// read-only summary on the landing page itself. The submenu screens' /// actual contents are covered by theme_toggle_test.dart and /// settings_purge_test.dart respectively. void main() { Future pumpSettings(WidgetTester tester) async { final appState = AppState()..isLoading = false; await tester.pumpWidget( ChangeNotifierProvider.value( value: appState, child: const MaterialApp(home: SettingsScreen()), ), ); } testWidgets('shows UI, Data, FAQ, and User Agreement menu entries, plus the summary', (tester) async { await pumpSettings(tester); expect(find.text('UI'), findsOneWidget); expect(find.text('Data'), findsOneWidget); expect(find.text('FAQ'), findsOneWidget); expect(find.text('User Agreement'), findsOneWidget); await tester.scrollUntilVisible(find.text('Summary'), 300, scrollable: find.byType(Scrollable)); expect(find.text('Summary'), findsOneWidget); // None of Data's contents leaked onto the landing page. expect(find.text('Cloud Storage'), findsNothing); expect(find.text('Advanced'), findsNothing); }); testWidgets('tapping UI opens UiSettingsScreen', (tester) async { await pumpSettings(tester); await tester.tap(find.text('UI')); await tester.pumpAndSettle(); expect(find.byType(UiSettingsScreen), findsOneWidget); expect(find.text('Appearance'), findsOneWidget); }); testWidgets('tapping Data opens DataSettingsScreen', (tester) async { await pumpSettings(tester); await tester.tap(find.text('Data')); await tester.pumpAndSettle(); expect(find.byType(DataSettingsScreen), findsOneWidget); expect(find.text('Cloud Storage'), findsOneWidget); await tester.scrollUntilVisible(find.text('Advanced'), 200, scrollable: find.byType(Scrollable)); expect(find.text('Advanced'), findsOneWidget); }); testWidgets('tapping FAQ opens FaqScreen with its questions collapsed by default', (tester) async { await pumpSettings(tester); await tester.tap(find.text('FAQ')); await tester.pumpAndSettle(); expect(find.byType(FaqScreen), findsOneWidget); expect(find.text('What is the Missouri Motor Fuel Tax Refund?'), findsOneWidget); // Answers are inside collapsed ExpansionTiles, not visible until tapped. expect(find.textContaining('12.5¢ per gallon'), findsNothing); await tester.tap(find.text('What is the Missouri Motor Fuel Tax Refund?')); await tester.pumpAndSettle(); expect(find.textContaining('12.5¢ per gallon'), findsOneWidget); }); testWidgets('tapping User Agreement opens it in review mode (no Decline/I Agree)', (tester) async { await pumpSettings(tester); await tester.tap(find.text('User Agreement')); await tester.pumpAndSettle(); expect(find.byType(UserAgreementScreen), findsOneWidget); expect(find.widgetWithText(FilledButton, 'I Agree'), findsNothing); expect(find.widgetWithText(OutlinedButton, 'Decline'), findsNothing); }); testWidgets('Ads card offers both buying and restoring when ads are not disabled', (tester) async { await pumpSettings(tester); // Not tapped — buyAdFreeYear/restoreAdFreeYear reach a real platform // channel via PurchaseService, which isn't set up in this test; only // confirming both entry points render. expect(find.widgetWithText(FilledButton, 'Remove Ads for a Year'), findsOneWidget); expect(find.widgetWithText(TextButton, 'Restore Purchase'), findsOneWidget); }); }