Files
dsh-web/web/src/runtimeSession.test.ts
T
m1saka 9a71772771 Harden image admission, resource recovery and session renewal
Add exact-image compatibility policy, experimental admission, paginated build history and shared reauthentication checks. Preserve uncertain Docker creation records, bound frontend resource waits and renew runtime sessions proactively.

Lazy-load and split Monaco, add regression and opt-in live Docker fault tests, and record full race and real-browser acceptance results.
2026-10-14 13:41:54 +08:00

76 lines
3.9 KiB
TypeScript

import { readFileSync } from 'node:fs';
import { runInNewContext } from 'node:vm';
import { expect, it, vi } from 'vitest';
const source = readFileSync(new URL('../../internal/api/runtime_session.go', import.meta.url), 'utf8').split('const runtimeSessionJS = `')[1].split('`')[0];
it.each([401, 403, 409, 500])('runtime only reloads a confirmed revoked session (%s)', async status => {
const reload = vi.fn();
let renew: (() => void) | undefined;
const fetch = vi.fn(async (path: string) => new Response('{}', {status: path === '/api/refresh' ? status : 401}));
runInNewContext(source, {
location:{pathname:'/',reload}, navigator:{}, fetch,
document:{cookie:'dsh_csrf=csrf',addEventListener() {}},
window:{addEventListener(_name: string, handler: () => void) {renew = handler;}},
setInterval() {}, setTimeout(resolve: () => void) {resolve();},
});
await renew?.();
expect(reload).toHaveBeenCalledTimes(status === 401 || status === 403 ? 1 : 0);
expect(fetch.mock.calls.filter(c => c[0] === '/api/refresh')).toHaveLength(1);
expect(fetch.mock.calls.filter(c => c[0] === '/api/me')).toHaveLength(status === 500 ? 0 : 4);
});
it.each([false, true])('renews before access expiry, with Web Locks=%s', async withLocks => {
let now = 0, expires = 300_000;
let tick!: () => Promise<void>;
const locks = {request: vi.fn(async (_name: string, run: () => Promise<void>) => run())};
const fetch = vi.fn(async (path: string) => {
if (path === '/api/refresh') expires = now + 300_000;
return new Response('{}', {status: now < expires ? 200 : 401});
});
runInNewContext(source, {
location: {pathname: '/', reload: vi.fn()}, navigator: withLocks ? {locks} : {}, fetch,
document: {cookie: 'dsh_csrf=csrf', addEventListener() {}},
window: {addEventListener() {}},
setInterval(fn: typeof tick, interval: number) {tick = fn; expect(interval).toBe(240_000);},
setTimeout,
});
for (now = 240_000; now <= 960_000; now += 240_000) {
expect(now).toBeLessThan(expires);
await tick();
expect(expires).toBe(now + 300_000);
}
expect(fetch.mock.calls.map(c => c[0])).toEqual(Array(4).fill('/api/refresh'));
expect(locks.request).toHaveBeenCalledTimes(withLocks ? 4 : 0);
});
it('coalesces renewal events and keeps a session recovered by a sibling page', async () => {
let tick!: () => Promise<void>, finish!: (response: Response) => void;
const reload = vi.fn();
const fetch = vi.fn((path: string) => path === '/api/refresh'
? new Promise<Response>(resolve => {finish = resolve;})
: Promise.resolve(new Response('{}', {status: 200})));
runInNewContext(source, {
location: {pathname: '/', reload}, navigator: {}, fetch,
document: {cookie: 'dsh_csrf=csrf', addEventListener() {}},
window: {addEventListener() {}}, setInterval(fn: typeof tick) {tick = fn;}, setTimeout,
});
const first = tick(), second = tick();
expect(fetch).toHaveBeenCalledOnce();
finish(new Response('{}', {status: 409}));
await Promise.all([first, second]);
expect(fetch.mock.calls.map(c => c[0])).toEqual(['/api/refresh', '/api/me']);
expect(reload).not.toHaveBeenCalled();
});
it('reads the latest CSRF cookie after waiting for the refresh lock', async () => {
let tick!: () => Promise<void>, enter!: () => void;
const document = {cookie: 'dsh_csrf=old', addEventListener() {}};
const fetch = vi.fn(async () => new Response('{}'));
const locks = {request: (_name: string, run: () => Promise<void>) => new Promise<void>((resolve, reject) => {enter = () => {run().then(resolve, reject);};})};
runInNewContext(source, {
location: {pathname: '/', reload: vi.fn()}, navigator: {locks}, document, fetch,
window: {addEventListener() {}}, setInterval(fn: typeof tick) {tick = fn;}, setTimeout,
});
const pending = tick();
expect(fetch).not.toHaveBeenCalled();
document.cookie = 'dsh_csrf=new';
enter(); await pending;
expect(fetch).toHaveBeenCalledWith('/api/refresh', expect.objectContaining({headers: {'X-CSRF-Token': 'new'}}));
});