A whole bunch of changes

This commit is contained in:
Courtney Arnold 2026-08-15 17:52:25 -05:00
parent 901ec678a3
commit 956231048e
122 changed files with 5442 additions and 914 deletions

View file

@ -0,0 +1,115 @@
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<void> 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);
});
}