import test from 'node:test' import assert from 'node:assert/strict' import {readFileSync} from 'node:fs' import * as Vue from 'vue' import {compile} from '@vue/compiler-dom' import {renderToString} from '@vue/server-renderer' import ts from 'typescript' import {folderAssets,reconcileSelection,activeJobs,previewHidden} from '../shared/studio2/viewer.mjs' import {useAsHero,useAsSource,restoreAll} from '../shared/studio2/input.mjs' import {toggleStyle,parseBatch,stylePrompt} from '../shared/studio2/styles.mjs' import {compilePrompt,validateRequest} from '../shared/studio2/contracts.mjs' import {cachedLoras} from '../shared/studio2/lora-cache.mjs' test('deleted library files never return from job outputs; selection falls back or clears',()=>{ const deleted={id:'gone',folderId:'f'},keep={id:'keep',folderId:'f',createdAt:2};const jobs=[{request:{folderId:'f'},outputs:[deleted]}] let assets=folderAssets({stills:[keep],clips:[]},jobs,'f');assert.deepEqual(assets.map(a=>a.id),['keep']);assert.equal(reconcileSelection(deleted,assets).id,'keep');assert.equal(reconcileSelection(deleted,[]),null) }) test('bench includes only active execution phases and clear finished retains internal cleanup records',()=>{ assert.deepEqual(activeJobs(['waiting','waking','submitting','rendering','saving','complete','cancelled','failed'].map(state=>({state}))).map(j=>j.state),['waking','submitting','rendering','saving']) const rows=[{id:'done',state:'complete',request:{folderId:'f'},cleanupPending:[{}]},{id:'active',state:'rendering',request:{folderId:'f'}}],saved=[] const src=readFileSync(new URL('../server/api/studio-2/clear-finished.post.ts',import.meta.url),'utf8').replace(/^import .*;\r?\n/gm,'').replace('export default ','const handler=') const js=ts.transpileModule(src,{compilerOptions:{target:ts.ScriptTarget.ES2022}}).outputText const fn=new Function('defineEventHandler','assertLibraryOwner','listStudioJobs','records','assertFolderAccess','saveRecord',js+';return handler')(f=>f,()=>({owner:'o'}),()=>[],()=>rows,()=>{},r=>saved.push(r)) assert.equal(fn({}).cleared,1);assert.equal(rows[0].dismissed,true);assert.equal(rows[0].cleanupPending.length,1);assert.equal(rows[1].dismissed,undefined) }) test('hidden xAIGen canvas and family render no image or video elements',async()=>{ const src=readFileSync(new URL('../components/studio2/Bench.vue',import.meta.url),'utf8') const stage=src.slice(src.indexOf('
line.includes('aria-label="Current family outputs"')) const render=new Function('Vue',compile('
'+stage+strip+'
',{mode:'function'}).code)(Vue) const state={selected:{id:'a',kind:'still'},hideOutput:true,xaigen:true,family:[{id:'a',kind:'still'}],form:{hideInput:true},previewHidden,stillUrl:id=>'/image/'+id,selectOutput(){}} const hidden=await renderToString(Vue.createSSRApp({render,data:()=>state}));assert.doesNotMatch(hidden,/