Remote sync of webdav
This commit is contained in:
parent
f01186df79
commit
483fbeafb6
44 changed files with 4842 additions and 975 deletions
98
test/pending_receipt_upload_test.dart
Normal file
98
test/pending_receipt_upload_test.dart
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
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<void> 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);
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue