import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:fuel_tax_tracker/screens/data_settings_screen.dart'; import 'package:fuel_tax_tracker/services/app_state.dart'; /// Covers the "Danger Zone" purge UI's warning-dialog gating, now folded /// into the Settings > Data > Advanced section — the actual delete behavior /// (soft-delete tombstones, dirty flags, receipt file cleanup) is covered /// against a real database in purge_data_test.dart. This deliberately never /// taps a dialog's destructive "Delete" button: doing so would call through /// to [AppState.purgeAllData]/[AppState.purgeFuelEntriesInRange], which need /// an initialized database — not set up here, matching every other Settings /// widget test (see theme_toggle_test.dart) that stops short of a full /// [AppState.init]. void main() { setUp(() { SharedPreferences.setMockInitialValues({}); }); Future pumpSettings(WidgetTester tester, AppState appState) async { await tester.pumpWidget( ChangeNotifierProvider.value( value: appState, child: const MaterialApp(home: DataSettingsScreen()), ), ); } // The purge controls sit inside the collapsed "Advanced" ExpansionTile, // below the fold — every test needs to expand it and scroll it into view // before tapping anything inside it. Future scrollToDangerZone(WidgetTester tester) async { await tester.scrollUntilVisible(find.text('Advanced'), 200, scrollable: find.byType(Scrollable)); await tester.tap(find.text('Advanced')); await tester.pumpAndSettle(); await tester.scrollUntilVisible(find.text('Danger Zone'), 200, scrollable: find.byType(Scrollable)); await tester.pumpAndSettle(); } testWidgets('Purge All Data shows a warning dialog; Cancel dismisses it without purging', (tester) async { final appState = AppState()..isLoading = false; await pumpSettings(tester, appState); await scrollToDangerZone(tester); await tester.tap(find.widgetWithText(OutlinedButton, 'Purge All Data')); await tester.pumpAndSettle(); expect(find.text('Purge all data?'), findsOneWidget); expect(find.textContaining("can't be undone"), findsOneWidget); await tester.tap(find.text('Cancel')); await tester.pumpAndSettle(); expect(find.text('Purge all data?'), findsNothing); expect(appState.vehicles, isEmpty); }); testWidgets('mentions the connected cloud provider in the warning when one is connected', (tester) async { final appState = AppState()..isLoading = false; await pumpSettings(tester, appState); await scrollToDangerZone(tester); await tester.tap(find.widgetWithText(OutlinedButton, 'Purge All Data')); await tester.pumpAndSettle(); expect(find.textContaining('connected to'), findsNothing, reason: 'no cloud provider connected in this test'); await tester.tap(find.text('Cancel')); await tester.pumpAndSettle(); }); testWidgets('Purge Range is disabled until both a start and end date are picked', (tester) async { final appState = AppState()..isLoading = false; await pumpSettings(tester, appState); await scrollToDangerZone(tester); final purgeRangeButton = tester.widget(find.widgetWithText(OutlinedButton, 'Purge Range')); expect(purgeRangeButton.onPressed, isNull); }); testWidgets('picking a start and end date enables Purge Range, which shows a warning dialog', (tester) async { final appState = AppState()..isLoading = false; await pumpSettings(tester, appState); await scrollToDangerZone(tester); await tester.tap(find.text('Start date')); await tester.pumpAndSettle(); await tester.tap(find.text('OK')); await tester.pumpAndSettle(); await tester.tap(find.text('End date')); await tester.pumpAndSettle(); await tester.tap(find.text('OK')); await tester.pumpAndSettle(); final purgeRangeButton = tester.widget(find.widgetWithText(OutlinedButton, 'Purge Range')); expect(purgeRangeButton.onPressed, isNotNull); await tester.tap(find.widgetWithText(OutlinedButton, 'Purge Range')); await tester.pumpAndSettle(); expect(find.text('Purge data in range?'), findsOneWidget); await tester.tap(find.text('Cancel')); await tester.pumpAndSettle(); }); }