import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:provider/provider.dart'; import 'package:fuel_tax_tracker/models/fuel_entry.dart'; import 'package:fuel_tax_tracker/models/vehicle.dart'; import 'package:fuel_tax_tracker/screens/edit_fuel_entry_screen.dart'; import 'package:fuel_tax_tracker/screens/receipt_detail_screen.dart'; import 'package:fuel_tax_tracker/screens/receipt_image_screen.dart'; import 'package:fuel_tax_tracker/services/app_state.dart'; /// Covers [ReceiptDetailScreen] itself — the single place to view a /// receipt's photo and logged data together, with edit/delete for the /// entry. Deliberately never taps through to an actual delete: that would /// call [AppState.deleteFuelEntry], which needs an initialized database not /// set up here (see settings_purge_test.dart for the same convention). void main() { final vehicle = Vehicle(id: 'v1', vin: '1FMPU18L1TLB51349', nickname: 'Red Truck', updatedAt: DateTime.utc(2026, 1, 1)); final entry = FuelEntry( id: 'e1', vehicleId: 'v1', date: DateTime(2026, 5, 14, 9, 30), gallons: 10.523, pricePerGallon: 3.499, totalCost: 36.81, updatedAt: DateTime.utc(2026, 5, 14), receiptDriveFileId: 'remote-1', ); Future pumpDetail(WidgetTester tester, AppState appState) async { await tester.pumpWidget( ChangeNotifierProvider.value( value: appState, child: MaterialApp(home: ReceiptDetailScreen(entryId: 'e1')), ), ); } testWidgets('shows the vehicle, date, gallons, price, and total', (tester) async { final appState = AppState() ..isLoading = false ..vehicles = [vehicle] ..fuelEntries = [entry]; await pumpDetail(tester, appState); expect(find.text('Red Truck'), findsOneWidget); expect(find.text('VIN: 1FMPU18L1TLB51349'), findsOneWidget); expect(find.text('10.523 gal'), findsOneWidget); expect(find.text('\$3.50'), findsOneWidget, reason: 'price per gallon'); expect(find.text('\$36.81'), findsOneWidget, reason: 'total cost'); }); testWidgets('shows a fallback instead of crashing when the entry no longer exists', (tester) async { final appState = AppState() ..isLoading = false ..vehicles = [vehicle] ..fuelEntries = []; await pumpDetail(tester, appState); expect(find.text('Receipt not found'), findsOneWidget); }); testWidgets('the edit icon opens EditFuelEntryScreen pre-filled', (tester) async { final appState = AppState() ..isLoading = false ..vehicles = [vehicle] ..fuelEntries = [entry]; await pumpDetail(tester, appState); await tester.tap(find.byTooltip('Edit fuel entry')); await tester.pumpAndSettle(); expect(find.byType(EditFuelEntryScreen), findsOneWidget); expect(find.widgetWithText(TextFormField, '10.523'), findsOneWidget); }); testWidgets('the delete icon shows a warning dialog; Cancel dismisses it without deleting', (tester) async { final appState = AppState() ..isLoading = false ..vehicles = [vehicle] ..fuelEntries = [entry]; await pumpDetail(tester, appState); await tester.tap(find.byTooltip('Delete fuel entry')); await tester.pumpAndSettle(); expect(find.text('Delete fuel entry?'), findsOneWidget); await tester.tap(find.text('Cancel')); await tester.pumpAndSettle(); expect(find.text('Delete fuel entry?'), findsNothing); expect(appState.fuelEntries, hasLength(1), reason: 'not deleted'); }); testWidgets('tapping the photo opens the full-screen viewer', (tester) async { final appState = AppState() ..isLoading = false ..vehicles = [vehicle] ..fuelEntries = [entry]; await pumpDetail(tester, appState); await tester.tap(find.byType(GestureDetector).first); await tester.pumpAndSettle(); expect(find.byType(ReceiptImageScreen), findsOneWidget); }); }