import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:fuel_tax_tracker/services/db_schema.dart'; import 'package:path/path.dart' as p; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; /// Regression coverage for a real bug: the "needs upload" query used to /// match on `receipt_image_path IS NOT NULL` alone, which would have kept /// re-uploading the same photo as a duplicate Drive file on every sync /// once a "keep photos on this phone" option let an already-uploaded row /// keep its local path. See [pendingReceiptUploadWhereClause]. void main() { late Directory tempDir; late Database db; setUpAll(() { sqfliteFfiInit(); databaseFactory = databaseFactoryFfi; }); setUp(() async { tempDir = await Directory.systemTemp.createTemp('pending_receipt_test_'); db = await databaseFactory.openDatabase(p.join(tempDir.path, 'test.db')); await db.execute(createFuelEntriesTableSql); }); tearDown(() async { await db.close(); await tempDir.delete(recursive: true); }); Future insertEntry( String id, { String? receiptImagePath, String? receiptDriveFileId, int dirty = 1, int? deletedAt, }) { return db.insert('fuel_entries', { 'id': id, 'vehicle_id': 'v1', 'date': 0, 'gallons': 10.0, 'price_per_gallon': 3.5, 'total_cost': 35.0, 'receipt_image_path': receiptImagePath, 'receipt_drive_file_id': receiptDriveFileId, 'updated_at': 0, 'deleted_at': deletedAt, 'dirty': dirty, }); } test('matches a row with a local photo not yet uploaded', () async { await insertEntry('needs-upload', receiptImagePath: '/local/a.jpg'); final rows = await db.query('fuel_entries', where: pendingReceiptUploadWhereClause); expect(rows.map((r) => r['id']), ['needs-upload']); }); test('excludes a row already uploaded, even if the local copy was kept', () async { await insertEntry( 'kept-after-upload', receiptImagePath: '/local/a.jpg', receiptDriveFileId: 'drive-file-1', ); final rows = await db.query('fuel_entries', where: pendingReceiptUploadWhereClause); expect(rows, isEmpty); }); test('excludes a row with no local photo at all', () async { await insertEntry('no-receipt'); final rows = await db.query('fuel_entries', where: pendingReceiptUploadWhereClause); expect(rows, isEmpty); }); test('excludes a soft-deleted row even if it has a pending local photo', () async { await insertEntry('deleted', receiptImagePath: '/local/a.jpg', deletedAt: 123); final rows = await db.query('fuel_entries', where: pendingReceiptUploadWhereClause); expect(rows, isEmpty); }); test('excludes a clean (already-synced) row', () async { await insertEntry('clean', receiptImagePath: '/local/a.jpg', dirty: 0); final rows = await db.query('fuel_entries', where: pendingReceiptUploadWhereClause); expect(rows, isEmpty); }); }