You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
meshcore-client/test/helpers/pending_reactions_test.dart

103 lines
2.9 KiB

import 'package:flutter_test/flutter_test.dart';
import 'package:meshcore_open/helpers/pending_reactions.dart';
import 'package:meshcore_open/helpers/reaction_helper.dart';
ReactionInfo _info(String hash) =>
ReactionInfo(targetHash: hash, emoji: '\u{1F44D}');
void main() {
group('PendingReactions', () {
final now = DateTime.utc(2026, 7, 24, 1, 43);
test('holds a reaction whose target has not arrived', () {
final pending = PendingReactions();
pending.add('channel:0', _info('dyps6yf0'), 'Node', now);
expect(pending.length, 1);
});
test('applies a held reaction once the target lands', () {
final pending = PendingReactions();
pending.add('channel:0', _info('dyps6yf0'), 'Node', now);
final applied = <String>[];
pending.retry('channel:0', (info) {
applied.add(info.targetHash);
return true;
}, now.add(const Duration(seconds: 5)));
expect(applied, ['dyps6yf0']);
expect(pending.length, 0);
});
test('keeps a reaction that still has no target', () {
final pending = PendingReactions();
pending.add('channel:0', _info('dyps6yf0'), 'Node', now);
pending.retry(
'channel:0',
(_) => false,
now.add(const Duration(seconds: 5)),
);
expect(pending.length, 1);
});
test('does not leak across scopes', () {
final pending = PendingReactions();
pending.add('channel:0', _info('dyps6yf0'), 'Node', now);
var called = false;
pending.retry('channel:1', (_) {
called = true;
return true;
}, now);
expect(called, isFalse);
expect(pending.length, 1);
});
test('drops a reaction that outlives the TTL', () {
final pending = PendingReactions();
pending.add('channel:0', _info('dyps6yf0'), 'Node', now);
pending.expire(now.add(PendingReactions.ttl));
expect(pending.length, 0);
});
test('keeps a reaction that is still inside the TTL', () {
final pending = PendingReactions();
pending.add('channel:0', _info('dyps6yf0'), 'Node', now);
pending.expire(
now.add(PendingReactions.ttl - const Duration(seconds: 1)),
);
expect(pending.length, 1);
});
test('caps the queue and evicts the oldest first', () {
final pending = PendingReactions();
for (var i = 0; i <= PendingReactions.maxEntries; i++) {
pending.add(
'channel:0',
_info(i.toString().padLeft(8, '0')),
'Node',
now.add(Duration(seconds: i)),
);
}
expect(pending.length, PendingReactions.maxEntries);
final seen = <String>[];
pending.retry('channel:0', (info) {
seen.add(info.targetHash);
return true;
}, now.add(const Duration(minutes: 1)));
expect(seen, isNot(contains('00000000')), reason: 'oldest was evicted');
expect(seen.length, PendingReactions.maxEntries);
});
});
}

Powered by TurnKey Linux.