Allow Richese reveal during selected responses
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-29 07:58:48 +11:00
1 parent a1b2aacbac
commit 82d857b667
9 files changed
+518 -4

No files matched your search

+58
View File
@@ -1,6 +1,8 @@
// @dune-suite integration
import test from 'node:test';
import assert from 'node:assert/strict';
import { Agent as HttpAgent, request as httpRequest } from 'node:http';
import { Agent as HttpsAgent, request as httpsRequest } from 'node:https';
import type { GameView } from '../game/engine';
import type { TalkPage } from '../lib/table-talk';
const base = process.env.DUNE_TEST_URL ?? 'http://localhost:3000';
@@ -230,3 +232,59 @@ void test('discussion HTTP retries save once and seat recovery inherits conversa
{ messages: [], before: null, muted: false },
);
});
/** Reuse one connection when the server permits it; a server that explicitly
* closes a connection may instead provide a fresh one. Never retry a POST. */
void test('rejected discussion posts leave the next recovered-seat request usable', async () => {
const f = await fixture();
const endpoint = f.path + '/messages';
const message = { id: crypto.randomUUID(), recipientId: f.b.data.me, text: 'Keep-alive recovery witness.' };
assert.equal((await request(endpoint, message, f.a.cookie)).status, 200);
const recoverySecret = 'b8'.repeat(32);
assert.equal((await request(f.path + '/control', {
type: 'setRecoveryKey', version: f.version, recoverySecret,
}, f.a.cookie)).status, 200);
const recovered = await request(f.path + '/control', {
type: 'recoverSeat', playerId: f.a.data.me, recoverySecret,
operationId: crypto.randomUUID(),
newSessionToken: crypto.randomUUID().replaceAll('-', '') + crypto.randomUUID().replaceAll('-', ''),
});
assert.equal(recovered.status, 200);
assert.ok(recovered.cookie);
const address = new URL(base);
const agent = address.protocol === 'https:'
? new HttpsAgent({ keepAlive: true, maxSockets: 1 })
: new HttpAgent({ keepAlive: true, maxSockets: 1 });
async function onConnection(path: string, cookie: string, body?: unknown, origin?: string) {
const url = new URL(path, base);
const payload = body === undefined ? undefined : JSON.stringify(body);
const send = url.protocol === 'https:' ? httpsRequest : httpRequest;
return await new Promise<{status: number; body: string}>((resolve, reject) => {
const req = send(url, {
agent, method: payload === undefined ? 'GET' : 'POST', signal: AbortSignal.timeout(15_000),
headers: { cookie, ...(origin ? { origin } : {}),
...(payload === undefined ? {} : { 'content-type': 'application/json', 'content-length': Buffer.byteLength(payload) }) },
}, response => {
const chunks: Buffer[] = [];
response.on('data', chunk => chunks.push(Buffer.from(chunk)));
response.on('error', reject);
response.on('end', () => resolve({status: response.statusCode ?? 0, body: Buffer.concat(chunks).toString('utf8')}));
});
req.on('error', reject);
req.end(payload);
});
}
try {
const restoredPath = endpoint + `?recipient=${f.b.data.me}`;
assert.equal((await onConnection(endpoint, f.a.cookie!, message)).status, 409);
const restored = await onConnection(restoredPath, recovered.cookie);
assert.equal(restored.status, 200);
assert.deepEqual((JSON.parse(restored.body) as TalkPage).messages.map(row => row.id), [message.id]);
assert.equal((await onConnection(endpoint, recovered.cookie, message, 'https://foreign.invalid')).status, 403);
assert.equal((await onConnection(restoredPath, recovered.cookie)).status, 200);
assert.equal((await onConnection(restoredPath, f.a.cookie!)).status, 409);
} finally {
agent.destroy();
}
});