import test from 'node:test' import assert from 'node:assert/strict' import {validateHeaderValue} from 'node:http' import {gpuStatus} from '../shared/studio2/status.mjs' import {inlineFilename} from '../shared/content-disposition.mjs' import {readFileSync} from 'node:fs' test('waiting records never replace the idle GPU status after completion',()=>{ const waiting={state:'waiting',request:{promptSections:{action:'Old waiting prompt'}}},running={state:'rendering',request:{promptSections:{action:'Current video'}}},health={comfy:{ok:true}}; assert.equal(gpuStatus([waiting,running],health).detail,'Current video'); assert.deepEqual(gpuStatus([waiting,{...running,state:'complete'}],health),{label:'Ready',tone:'ready',detail:'No job running'}); assert.equal(gpuStatus([waiting],health,[{status:'running',name:'Upscale current clip'}]).label,'Upscaling'); assert.equal(gpuStatus([waiting],{comfy:{asleep:true}}).label,'Sleeping'); assert.equal(gpuStatus([waiting],{comfy:{asleep:true},yue2:{busy:true}}).label,'Generating'); assert.equal(gpuStatus([waiting],{comfy:{asleep:true}},[],[{status:'running',name:'song',live:{message:'Planning'}}]).label,'Generating'); }); test('Unicode video titles produce valid response headers and retain UTF-8 filename',()=>{ for(const title of ['A scene… “hello” — 🎥.mp4','日本語.mp4','bad\r\nheader".mp4']){ const header=inlineFilename(title);assert.doesNotThrow(()=>validateHeaderValue('Content-Disposition',header));assert.match(header,/filename\*=UTF-8''/);assert.doesNotMatch(header,/[\r\n]/); } assert.match(inlineFilename('Scene….mp4'),/%E2%80%A6/); }); test('Studio 2 upscale button delegates progress to the queue without stretching actions',()=>{ const bench=readFileSync(new URL('../components/studio2/Bench.vue',import.meta.url),'utf8'),control=readFileSync(new URL('../components/VideoUpscaleControl.vue',import.meta.url),'utf8'); assert.match(bench,/:clip-id="selected.id" queue-only/);assert.match(bench,/items-start gap-3/);assert.match(bench,/Job queue/);assert.match(control,/state\?\.job && !queueOnly/); });