Tests / test (push) Canceled after 0s
Build Android (FCM) / build-android-fcm (push) Canceled after 0s
Build Android / build-android (push) Canceled after 0s
Build iOS / build-ios (push) Canceled after 0s
Build Linux / build-linux (push) Canceled after 0s
Build macOS / build-macos (push) Canceled after 0s
Build Windows / build-windows (push) Canceled after 0s
Native crypto / native-crypto (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s
87 lines
2.7 KiB
Dart
87 lines
2.7 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:ikar/core/share/share_inbox.dart';
|
|
|
|
void main() {
|
|
test(
|
|
'concurrent events present each share once and wait for file users',
|
|
() async {
|
|
final records = [
|
|
for (var i = 0; i < 3; i++) {'id': '$i', 'text': 'share $i'},
|
|
];
|
|
final shown = <String>[];
|
|
final acknowledged = <String>[];
|
|
final released = <String>[];
|
|
final upload = Completer<void>();
|
|
final inbox = ShareInbox(
|
|
consume: () async => records.isEmpty ? null : records.removeAt(0),
|
|
acknowledge: (id) async => acknowledged.add(id),
|
|
release: (id) async => released.add(id),
|
|
onShare: (payload) => shown.add(payload.text!),
|
|
);
|
|
await Future.wait([inbox.check(), inbox.check(), inbox.check()]);
|
|
expect(shown, ['share 0']);
|
|
final completing = inbox.complete(waitForRelease: () => upload.future);
|
|
await Future<void>.delayed(Duration.zero);
|
|
expect(acknowledged, ['0']);
|
|
expect(released, isEmpty);
|
|
expect(shown, ['share 0']);
|
|
upload.complete();
|
|
await completing;
|
|
expect(released, ['0']);
|
|
expect(shown, ['share 0', 'share 1']);
|
|
await inbox.complete();
|
|
await inbox.complete();
|
|
expect(shown, ['share 0', 'share 1', 'share 2']);
|
|
expect(released, ['0', '1', '2']);
|
|
},
|
|
);
|
|
|
|
test(
|
|
'ack failure keeps active record and retries without presenting twice',
|
|
() async {
|
|
var failures = 1;
|
|
var shown = 0;
|
|
var consumed = false;
|
|
final inbox = ShareInbox(
|
|
consume: () async {
|
|
if (consumed) return null;
|
|
consumed = true;
|
|
return {'id': 'a', 'text': 'text'};
|
|
},
|
|
acknowledge: (_) async {
|
|
if (failures-- > 0) throw StateError('disk');
|
|
},
|
|
release: (_) async {},
|
|
onShare: (_) => shown++,
|
|
);
|
|
await inbox.check();
|
|
await expectLater(inbox.complete(), throwsStateError);
|
|
await inbox.check();
|
|
expect(shown, 1);
|
|
},
|
|
);
|
|
|
|
test(
|
|
'invalid record is discarded and next valid record is presented',
|
|
() async {
|
|
final records = [
|
|
{'id': 'bad'},
|
|
{'id': 'good', 'text': 'ok'},
|
|
];
|
|
final acknowledged = <String>[];
|
|
final shown = <String>[];
|
|
final inbox = ShareInbox(
|
|
consume: () async => records.isEmpty ? null : records.removeAt(0),
|
|
acknowledge: (id) async => acknowledged.add(id),
|
|
release: (_) async {},
|
|
onShare: (payload) => shown.add(payload.text!),
|
|
);
|
|
await inbox.check();
|
|
expect(acknowledged, ['bad']);
|
|
expect(shown, ['ok']);
|
|
await inbox.complete();
|
|
},
|
|
);
|
|
}
|