108 lines
3.1 KiB
JavaScript
108 lines
3.1 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createRealtimeServer } from './realtime-server.mjs';
|
|
import WebSocket from 'ws';
|
|
|
|
const productDetail = {
|
|
product_id: 'prod_abc123',
|
|
versions: [
|
|
{
|
|
version_id: 'ver_old',
|
|
created_at: '2026-09-13T08:00:00Z',
|
|
wordcloud_archives: [
|
|
{ source_job_id: 'job_old', created_at: '2026-09-13T08:00:00Z' },
|
|
],
|
|
},
|
|
{
|
|
version_id: 'ver_new',
|
|
created_at: '2026-09-13T09:00:00Z',
|
|
wordcloud_archives: [
|
|
{ source_job_id: 'job_new', created_at: '2026-09-13T09:00:00Z' },
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
test('resolves a product id to the latest source job id', async () => {
|
|
const requests = [];
|
|
const fetchImpl = async (input, init) => {
|
|
requests.push({ input: String(input), init });
|
|
if (input === 'http://wordcloud.test/api/login') {
|
|
return new Response(JSON.stringify({ token: 'product-token' }), { status: 200 });
|
|
}
|
|
if (input === 'http://wordcloud.test/api/products/prod_abc123') {
|
|
return new Response(JSON.stringify(productDetail), { status: 200 });
|
|
}
|
|
return new Response('not found', { status: 404 });
|
|
};
|
|
|
|
const server = createRealtimeServer(0, {
|
|
upstreamUrl: 'http://wordcloud.test',
|
|
adminPassword: 'test-password',
|
|
tokenSecret: 'test-secret',
|
|
fetchImpl,
|
|
});
|
|
await new Promise((resolve) => server.listen(resolve));
|
|
const { port } = server.address();
|
|
|
|
try {
|
|
const response = await fetch(`http://127.0.0.1:${port}/api/products/prod_abc123/source-job`);
|
|
assert.equal(response.status, 200);
|
|
assert.deepEqual(await response.json(), {
|
|
product_id: 'prod_abc123',
|
|
source_job_id: 'job_new',
|
|
});
|
|
assert.deepEqual(requests.map((request) => request.input), [
|
|
'http://wordcloud.test/api/login',
|
|
'http://wordcloud.test/api/products/prod_abc123',
|
|
]);
|
|
|
|
const loginBody = JSON.parse(requests[0].init.body);
|
|
assert.equal(loginBody.password, 'test-password');
|
|
assert.equal(requests[1].init.headers.Authorization, 'Bearer product-token');
|
|
} finally {
|
|
server.close();
|
|
}
|
|
});
|
|
|
|
test('broadcasts focus events to other connected clients', async () => {
|
|
const server = createRealtimeServer(0);
|
|
await new Promise((resolve) => server.listen(resolve));
|
|
const { port } = server.address();
|
|
|
|
try {
|
|
const screen = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
const controller = new WebSocket(`ws://127.0.0.1:${port}`);
|
|
|
|
await Promise.all([
|
|
new Promise((resolve) => screen.once('open', resolve)),
|
|
new Promise((resolve) => controller.once('open', resolve)),
|
|
]);
|
|
|
|
const received = new Promise((resolve) => {
|
|
screen.once('message', (data) => resolve(JSON.parse(data)));
|
|
});
|
|
|
|
controller.send(JSON.stringify({
|
|
type: 'FOCUS_NAME',
|
|
cloudId: 'demo',
|
|
name: 'Sophia',
|
|
messageId: 'focus-1',
|
|
sentAt: 1,
|
|
}));
|
|
|
|
assert.deepEqual(await received, {
|
|
type: 'FOCUS_NAME',
|
|
cloudId: 'demo',
|
|
name: 'Sophia',
|
|
messageId: 'focus-1',
|
|
sentAt: 1,
|
|
});
|
|
|
|
screen.close();
|
|
controller.close();
|
|
} finally {
|
|
await new Promise((resolve) => server.close(resolve));
|
|
}
|
|
});
|