import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:relationship_saver/features/sync/sync_auto_trigger_controller.dart'; import 'package:relationship_saver/features/sync/sync_coordinator.dart'; void main() { test('triggers sync once and respects cooldown interval', () async { int callCount = 0; DateTime now = DateTime(2026, 2, 15, 12); final SyncAutoTriggerController controller = SyncAutoTriggerController( syncNow: () async { callCount += 1; return _result(success: true); }, now: () => now, minimumInterval: const Duration(seconds: 60), ); final bool first = await controller.trigger(); final bool second = await controller.trigger(); now = now.add(const Duration(seconds: 61)); final bool third = await controller.trigger(); expect(first, isTrue); expect(second, isFalse); expect(third, isTrue); expect(callCount, 2); expect(controller.lastTriggeredAt, now); }); test('applies backoff after failed sync attempts', () async { DateTime now = DateTime(2026, 2, 15, 14); bool shouldFail = true; final SyncAutoTriggerController controller = SyncAutoTriggerController( syncNow: () async => _result(success: !shouldFail), now: () => now, minimumInterval: const Duration(seconds: 60), ); final bool first = await controller.trigger(); now = now.add(const Duration(seconds: 61)); final bool second = await controller.trigger(); now = now.add(const Duration(seconds: 60)); shouldFail = false; final bool third = await controller.trigger(); expect(first, isTrue); expect(second, isFalse); expect(third, isTrue); expect(controller.consecutiveFailures, 0); }); test('does not run a second sync while a run is still in progress', () async { int callCount = 0; final Completer completer = Completer(); final SyncAutoTriggerController controller = SyncAutoTriggerController( syncNow: () async { callCount += 1; await completer.future; return _result(success: true); }, now: DateTime.now, minimumInterval: Duration.zero, ); final Future first = controller.trigger(); final bool second = await controller.trigger(); completer.complete(); final bool firstCompleted = await first; expect(firstCompleted, isTrue); expect(second, isFalse); expect(callCount, 1); }); } SyncRunResult _result({required bool success}) { return SyncRunResult( success: success, operation: 'sync', message: success ? 'ok' : 'fail', pendingAfter: 0, ); }