MO-Fuel-Tax-Back/test/receipt_storage_test.dart

89 lines
2.8 KiB
Dart

import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:fuel_tax_tracker/services/database_service.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
/// Receipts are filed under `receipts/<vin>/<yyyy.mm>/` locally (mirroring
/// the `Receipts/<vin>/<yyyy.mm>` layout the cloud side uses — see
/// `cloud_sync_service_test.dart`), so browsing either one shows which
/// vehicle and month a photo belongs to.
void main() {
late Directory tempDir;
late DatabaseService database;
setUpAll(() {
sqfliteFfiInit();
databaseFactory = databaseFactoryFfi;
});
setUp(() async {
tempDir = await Directory.systemTemp.createTemp('receipt_storage_test_');
PathProviderPlatform.instance = _FakePathProviderPlatform(tempDir.path);
database = DatabaseService();
await database.init();
});
tearDown(() async {
await database.rawDb.close();
await tempDir.delete(recursive: true);
});
test('storeReceiptImage files the photo under receipts/<vin>/<yyyy.mm>/', () async {
final source = File(p.join(tempDir.path, 'source.jpg'))..writeAsBytesSync([1, 2, 3]);
final storedPath = await database.storeReceiptImage(
source,
'entry-1',
'1FMPU18L1TLB51349',
DateTime(2026, 8, 13),
);
expect(
p.dirname(storedPath),
p.join(database.receiptsDirectory.path, '1FMPU18L1TLB51349', '2026.08'),
);
expect(p.basename(storedPath), 'entry-1.jpg');
expect(await File(storedPath).exists(), isTrue);
});
test('storeReceiptImage sanitizes a VIN with characters unsafe in a path', () async {
final source = File(p.join(tempDir.path, 'source.jpg'))..writeAsBytesSync([1, 2, 3]);
final storedPath = await database.storeReceiptImage(
source,
'entry-2',
'../etc/passwd',
DateTime(2026, 1, 5),
);
expect(
p.dirname(storedPath),
p.join(
database.receiptsDirectory.path,
sanitizedPathSegment('../etc/passwd'),
'2026.01',
),
);
expect(p.isWithin(database.receiptsDirectory.path, storedPath), isTrue);
});
test('monthFolderName pads single-digit months', () {
expect(monthFolderName(DateTime(2026, 1, 5)), '2026.01');
expect(monthFolderName(DateTime(2026, 12, 5)), '2026.12');
});
}
class _FakePathProviderPlatform extends PathProviderPlatform with MockPlatformInterfaceMixin {
final String tempPath;
_FakePathProviderPlatform(this.tempPath);
@override
Future<String?> getApplicationDocumentsPath() async => tempPath;
@override
Future<String?> getTemporaryPath() async => tempPath;
}