A whole bunch of changes
This commit is contained in:
parent
901ec678a3
commit
956231048e
122 changed files with 5442 additions and 914 deletions
115
test/receipt_detail_screen_test.dart
Normal file
115
test/receipt_detail_screen_test.dart
Normal 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);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue