import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:tane/db/database.dart'; import 'package:tane/security/secure_key_store.dart'; import 'package:tane/services/auto_backup_service.dart'; import 'package:tane/services/auto_backup_store.dart'; import 'package:tane/services/export_import_service.dart'; import 'package:tane/services/file_service.dart'; import 'package:tane/ui/auto_backup_gate.dart'; import '../support/test_support.dart'; class _NoFiles implements FileService { @override Future saveFile({ required String suggestedName, required Uint8List bytes, }) async => null; @override Future pickFileBytes({List? allowedExtensions}) async => null; } /// Counts how many times the lifecycle asked for a backup. class _SpyAutoBackup extends AutoBackupService { _SpyAutoBackup(AppDatabase db) : super( exporter: ExportImportService( repository: newTestRepository(db), files: _NoFiles(), keys: SecureKeyStore(store: InMemorySecretStore()), ), store: AutoBackupStore(InMemorySecretStore()), directory: () async => throw UnimplementedError(), ); int calls = 0; @override Future runIfDue({Duration interval = const Duration(days: 7)}) async { calls++; return false; } } void main() { late AppDatabase db; setUp(() => db = newTestDatabase()); tearDown(() => db.close()); testWidgets('runs a backup on startup', (tester) async { final spy = _SpyAutoBackup(db); await tester.pumpWidget( AutoBackupGate(service: spy, child: const SizedBox()), ); await tester.pump(); // let the post-frame callback fire expect(spy.calls, 1); }); testWidgets('runs a backup again when the app is hidden', (tester) async { final spy = _SpyAutoBackup(db); await tester.pumpWidget( AutoBackupGate(service: spy, child: const SizedBox()), ); await tester.pump(); // startup backup tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.inactive); tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.hidden); expect(spy.calls, 2); }); testWidgets('does nothing when no service is provided', (tester) async { await tester.pumpWidget( const AutoBackupGate(child: Text('ok', textDirection: TextDirection.ltr)), ); await tester.pump(); expect(find.text('ok'), findsOneWidget); }); }