feat(backup): tap automatic-backups to make a copy now

This commit is contained in:
vjrj 2026-07-10 11:05:36 +02:00
parent 7cba4f7fcf
commit e90a3831f2
4 changed files with 112 additions and 9 deletions

View file

@ -139,6 +139,21 @@ void main() {
]);
});
test('backupNow writes even when a copy is not yet due', () async {
final store = AutoBackupStore(InMemorySecretStore());
await store.markBackupAt(DateTime.utc(2026, 7, 10)); // today: not due
final service = newService(
newExporter(),
store: store,
now: DateTime.utc(2026, 7, 10),
);
// runIfDue is a no-op today, but an explicit tap still makes a copy.
expect(await service.runIfDue(), isFalse);
expect(await service.backupNow(), isTrue);
expect(autoCopies(), ['tanemaki-auto-2026-07-10.tanemaki']);
});
test('a failed backup returns false and never throws', () async {
final service = newService(
_ThrowingExporter(db),

View file

@ -9,6 +9,8 @@ import 'package:tane/data/export_import/inventory_json_codec.dart';
import 'package:tane/db/database.dart';
import 'package:tane/i18n/strings.g.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/services/recovery_sheet_service.dart';
@ -232,4 +234,46 @@ void main() {
// of the sheet. Just assert it saved and confirmed.
expect(find.text('Copy saved'), findsOneWidget);
});
testWidgets('tapping the automatic-backups line makes a copy now', (
tester,
) async {
final spy = _SpyAutoBackup(db);
await tester.pumpWidget(
wrap(
Scaffold(
body: BackupSection(service: service, sheet: sheet, autoBackup: spy),
),
),
);
await tester.pump(); // resolve the "last copy" future
await tester.tap(find.text('Automatic backups'));
await tester.pumpAndSettle();
expect(spy.calls, 1);
expect(find.text('Copy saved'), findsOneWidget);
});
}
/// Counts explicit "back up now" taps without touching the disk.
class _SpyAutoBackup extends AutoBackupService {
_SpyAutoBackup(AppDatabase db)
: super(
exporter: ExportImportService(
repository: newTestRepository(db),
files: FakeFileService(),
keys: SecureKeyStore(store: InMemorySecretStore()),
),
store: AutoBackupStore(InMemorySecretStore()),
directory: () async => throw UnimplementedError(),
);
int calls = 0;
@override
Future<bool> backupNow() async {
calls++;
return true;
}
}