focus-flow/packages/scheduler_notifications/test/notification_adapter_contract.dart

71 lines
2 KiB
Dart

import 'package:scheduler_notifications/notifications.dart';
import 'package:test/test.dart';
/// Test harness for [NotificationAdapter] contract checks.
final class NotificationAdapterContractHarness {
/// Creates a harness around one adapter instance.
const NotificationAdapterContractHarness({
required this.adapter,
required this.scheduledRequests,
required this.cancelledIds,
this.dispose,
});
/// Adapter under test.
final NotificationAdapter adapter;
/// Snapshot of requests delivered through [adapter].
final List<NotificationRequest> Function() scheduledRequests;
/// Snapshot of ids cancelled through [adapter].
final List<String> Function() cancelledIds;
/// Optional cleanup callback.
final Future<void> Function()? dispose;
}
/// Runs shared notification adapter behavior checks.
void runNotificationAdapterContractTests(
String name,
NotificationAdapterContractHarness Function() createHarness,
) {
group('$name notification adapter contract', () {
test('schedules normalized notification requests', () async {
final harness = createHarness();
final dispose = harness.dispose;
if (dispose != null) {
addTearDown(dispose);
}
await harness.adapter.schedule(_request(' reminder-1 '));
expect(harness.scheduledRequests().map((request) => request.id), [
'reminder-1',
]);
expect(harness.scheduledRequests().single.scheduledDateTimeUtc.isUtc,
isTrue);
});
test('cancels normalized ids', () async {
final harness = createHarness();
final dispose = harness.dispose;
if (dispose != null) {
addTearDown(dispose);
}
await harness.adapter.cancel(' reminder-1 ');
expect(harness.cancelledIds(), ['reminder-1']);
});
});
}
NotificationRequest _request(String id) {
return NotificationRequest(
id: id,
title: 'Start task',
body: 'Time to begin.',
scheduledDateTimeUtc: DateTime.utc(2026, 1, 1, 9),
payloadJson: '{"taskId":"task-1"}',
);
}