Files
core2026/app/game-frontend/test/deploymentVersionNotice.test.ts
T

114 lines
4.0 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
createDeploymentVersionChecker,
deploymentVersionAssetSource,
parseDeploymentCommitSha,
} from '../src/config/deploymentVersion.ts';
const currentCommitSha = '0123456789abcdef0123456789abcdef01234567';
const nextCommitSha = '89abcdef0123456789abcdef0123456789abcdef';
const laterCommitSha = 'fedcba9876543210fedcba9876543210fedcba98';
const jsonResponse = (commitSha: string): Response =>
new Response(JSON.stringify({ commitSha }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
void test('accepts only full hexadecimal deployment commit values', () => {
assert.equal(parseDeploymentCommitSha({ commitSha: nextCommitSha.toUpperCase() }), nextCommitSha);
assert.equal(parseDeploymentCommitSha({ commitSha: 'main' }), null);
assert.equal(parseDeploymentCommitSha({ version: nextCommitSha }), null);
assert.equal(parseDeploymentCommitSha(null), null);
});
void test('exposes only the read-only build commit in the deployment version asset', () => {
assert.deepEqual(JSON.parse(deploymentVersionAssetSource(currentCommitSha)), { commitSha: currentCommitSha });
});
void test('notifies once per available version while revalidating one stable URL', async () => {
const requests: Array<{ url: string; init?: RequestInit }> = [];
const stored = new Map<string, string>();
const notifications: string[] = [];
let availableCommitSha = currentCommitSha;
const checker = createDeploymentVersionChecker({
currentCommitSha,
versionUrl: '/che/deployment-version.json',
storage: {
getItem: (key) => stored.get(key) ?? null,
setItem: (key, value) => void stored.set(key, value),
},
fetchVersion: async (url, init) => {
requests.push({ url: String(url), init });
return jsonResponse(availableCommitSha);
},
onVersionChanged: (commitSha) => notifications.push(commitSha),
});
await checker.check();
availableCommitSha = nextCommitSha;
await checker.check();
await checker.check();
availableCommitSha = laterCommitSha;
await checker.check();
assert.deepEqual(notifications, [nextCommitSha, laterCommitSha]);
assert.equal(
requests.every(({ url }) => url === '/che/deployment-version.json'),
true
);
assert.equal(
requests.every(({ init }) => init?.cache === 'no-cache'),
true
);
assert.equal(
requests.every(({ init }) => init?.headers === undefined),
true
);
});
void test('shares the once-only notice within the current tab session', async () => {
const stored = new Map<string, string>();
const storage = {
getItem: (key: string) => stored.get(key) ?? null,
setItem: (key: string, value: string) => void stored.set(key, value),
};
let notifications = 0;
const options = {
currentCommitSha,
versionUrl: '/hwe/deployment-version.json',
storage,
fetchVersion: async () => jsonResponse(nextCommitSha),
onVersionChanged: () => notifications++,
};
await createDeploymentVersionChecker(options).check();
await createDeploymentVersionChecker(options).check();
assert.equal(notifications, 1);
});
void test('ignores unavailable or malformed version documents without disrupting the page', async () => {
let notifications = 0;
const unavailable = createDeploymentVersionChecker({
currentCommitSha,
versionUrl: '/che/deployment-version.json',
fetchVersion: async () => {
throw new Error('offline');
},
onVersionChanged: () => notifications++,
});
const malformed = createDeploymentVersionChecker({
currentCommitSha,
versionUrl: '/che/deployment-version.json',
fetchVersion: async () => new Response('{', { status: 200 }),
onVersionChanged: () => notifications++,
});
await unavailable.check();
await malformed.check();
assert.equal(notifications, 0);
});