Files
stack/packages/webui/tests/s6b-states-browser.test.mjs

53 lines
4.1 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { setup, P, T } from './helpers/w15-conversations.mjs';
async function scenario(t, failure = false) {
const { b, render, wait } = await setup(t);
await b.evaluate(`(() => { const old=fetch; window.fetch=(url,opts)=>{const p=String(url); const json=(v,status=200)=>Promise.resolve(new Response(JSON.stringify(v),{status,headers:{'content-type':'application/json'}})); if(p==='/api/config')return json({send:true,requests:true}); if(p.startsWith('/api/project-file'))return json({error:'project-records-missing'},502); if(p.startsWith('/api/requests/'))return json({error:${JSON.stringify(failure?'storage-refused':'request-not-found')}},${failure?503:404}); return old(url,opts); }; })()`);
await render(`/projects/${P}`);
await wait(`document.querySelector('[data-project-content] .project-metrics')`);
return { b, render, wait };
}
test('overview and conversation show empty states for correlation ids without requests and missing records', async t => {
const {b,render,wait}=await scenario(t);
const text=await b.evaluate(`document.querySelector('[data-project-content]').textContent`);
assert.match(text,/This project has no records yet/);
assert.doesNotMatch(text,/Not available yet|Status unavailable|Request tasks unavailable|PRD unavailable|Request files unavailable/);
await render(`/projects/threads/${T}`);
await wait(`document.querySelector('.chat-log')`);
await wait(`document.querySelector('.request-mount')`);
assert.equal(await b.evaluate(`document.querySelector('[data-conversation-request-status]')?.textContent`), '');
assert.doesNotMatch(await b.evaluate(`document.querySelector('.chat-conversation').textContent`),/request could not be read|Status unavailable/i);
});
test('overview keeps real request read failures visible', async t => {
const {b}=await scenario(t,true);
assert.match(await b.evaluate(`document.querySelector('[data-project-content]').textContent`),/Status unavailable/);
});
test('project document read failure is not shown as an empty repository', async t => {
const {b, render, wait}=await setup(t);
await b.evaluate(`(() => {const old=fetch; window.fetch=(url,opts)=>String(url).startsWith('/api/project-file') ? Promise.resolve(new Response(JSON.stringify({error:'storage-refused'}),{status:502,headers:{'content-type':'application/json'}})) : old(url,opts); })()`);
await render(`/projects/${P}`);
await wait(`document.querySelector('[data-project-content] .project-metrics')`);
const text=await b.evaluate(`document.querySelector('[data-project-content]').textContent`);
assert.match(text,/North star unavailable/);
assert.doesNotMatch(text,/This project has no records yet/);
});
test('an absent north star is an empty state rather than a read failure', async t => {
const {b, render, wait}=await setup(t);
await b.evaluate(`(() => {const old=fetch; window.fetch=(url,opts)=>{const p=String(url), json=(v,status=200)=>Promise.resolve(new Response(JSON.stringify(v),{status,headers:{'content-type':'application/json'}})); if(p.startsWith('/api/project-files?'))return json({files:[]}); if(p.startsWith('/api/project-file?'))return json({error:'project-read-missing'},404); return old(url,opts); }; })()`);
await render(`/projects/${P}`);
await wait(`document.querySelector('[data-project-content] .project-metrics')`);
assert.match(await b.evaluate(`document.querySelector('[data-project-content]').textContent`),/No north star yet/);
});
test('an unlinked project reports zero files instead of an unavailable file count', async t => {
const {b, render, wait}=await setup(t);
await b.evaluate(`(() => {const old=fetch; window.fetch=(url,opts)=>String(url)==='/api/config' ? Promise.resolve(new Response(JSON.stringify({send:true,requests:true}),{headers:{'content-type':'application/json'}})) : old(url,opts); })()`);
await render('/projects/10000000-0000-4000-8000-000000000002');
await wait(`document.querySelector('[data-project-content] .project-metrics')`);
const files=await b.evaluate(`document.querySelector('.project-metrics a:last-of-type').textContent`);
assert.match(files,/Files\s*0/);
assert.doesNotMatch(files,/Not available yet/);
});