scenarioSendOffline function
- FakeServer server,
- WorldSeed w,
- ScenarioClient client
04 16.2: a message written offline is sent after the reconnect and its catch-up; the
first response is lost after the commit, the retry with the same client_msg_id is a
replay (200, Idempotent-Replay: true), and exactly one message exists.
Implementation
Future<void> scenarioSendOffline(
FakeServer server,
WorldSeed w,
ScenarioClient client,
) async {
await client.start();
await client.goOffline();
for (var i = 1; i <= 3; i++) {
w.post(w.sam, w.releaseNotes, 'While Alex is away $i');
}
final id = await client.send(w.releaseNotes, 'Written offline');
_check(
server.requestsOf('createMessage').isEmpty,
'nothing is sent while offline',
);
_check((await client.outbox()).length == 1, 'the entry waits in the outbox');
server.faults
..dropResponseAfterCommit('createMessage')
..holdDispatches();
await client.goOnline();
await waitFor(
'the retry',
() => server.requestsOf('createMessage').length >= 2,
);
final attempts = server.requestsOf('createMessage');
final statuses = [for (final r in attempts) r.status];
_check(attempts.first.status == 0, 'the first response was lost: $statuses');
_check(
attempts[1].status == 200,
'the retry was a replay with 200: $statuses',
);
_check(
attempts.every((r) => (r.body! as JsonMap)['client_msg_id'] == id),
'every attempt carried the same client_msg_id',
);
server.faults.releaseDispatches();
await waitFor(
'the echo of $id',
() async => (await _withId(client, w.releaseNotes, id)).isNotEmpty,
);
await waitFor(
'the empty outbox',
() async => (await client.outbox()).isEmpty,
);
_check(
(await _withId(client, w.releaseNotes, id)).length == 1,
'exactly one local message',
);
_check(
server.world
.messagesOf(w.releaseNotes)
.where((m) => m['client_msg_id'] == id)
.length ==
1,
'exactly one message on the server',
);
final texts = [for (final m in await client.messages(w.releaseNotes)) m.text];
_check(
texts.contains('While Alex is away 3'),
'the catch-up delivered the missed messages',
);
_contract(server);
}