Files
Client/test/widget/async_action_controller_test.dart
T

83 lines
2.5 KiB
Dart

import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:marianum_mobile/widget/async_action_button.dart';
void main() {
group('AsyncActionController.run', () {
test('toggles busy true while running and false after success', () async {
final controller = AsyncActionController();
addTearDown(controller.dispose);
var seenBusyInsideCallback = false;
final ok = await controller.run(() async {
seenBusyInsideCallback = controller.busy;
});
expect(seenBusyInsideCallback, isTrue,
reason: 'busy must be true while the callback is running');
expect(ok, isTrue);
expect(controller.busy, isFalse);
expect(controller.error, isNull);
});
test('captures mapped error message on failure and returns false', () async {
final controller = AsyncActionController();
addTearDown(controller.dispose);
final ok = await controller.run(
() async => throw Exception('boom'),
errorBuilder: (e) => 'custom: $e',
);
expect(ok, isFalse);
expect(controller.busy, isFalse);
expect(controller.error, contains('custom:'));
expect(controller.error, contains('boom'));
});
test('rejects re-entry while busy', () async {
final controller = AsyncActionController();
addTearDown(controller.dispose);
final firstStarted = Completer<void>();
final firstCanFinish = Completer<void>();
final firstFuture = controller.run(() async {
firstStarted.complete();
await firstCanFinish.future;
});
await firstStarted.future;
expect(controller.busy, isTrue);
final reentrant = await controller.run(() async {});
expect(reentrant, isFalse,
reason: 'second run while busy must be rejected without invoking callback');
firstCanFinish.complete();
expect(await firstFuture, isTrue);
expect(controller.busy, isFalse);
});
test('clearError resets error and notifies listeners', () async {
final controller = AsyncActionController();
addTearDown(controller.dispose);
var notifyCount = 0;
controller.addListener(() => notifyCount++);
await controller.run(() async => throw Exception('x'));
expect(controller.error, isNotNull);
final beforeClear = notifyCount;
controller.clearError();
expect(controller.error, isNull);
expect(notifyCount, beforeClear + 1);
// No-op when already cleared.
controller.clearError();
expect(notifyCount, beforeClear + 1);
});
});
}