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///` locally (mirroring /// the `Receipts//` 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///', () 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 getApplicationDocumentsPath() async => tempPath; @override Future getTemporaryPath() async => tempPath; }