launch.max becomes launch.models plus launch.limits (total, providers, exact provider/model). The launcher re-reads limits on every attempt. Settings and `mosaic limits` write through one locked, journaled organization writer. `mosaic limits migrate` is print-only. Candidate 00b84e311475f97ced0d9a9599fba23a28442971ed15d8d489d9422d84a8812e, Rocko packet4b6e50636, Filbert round 2 approve (comment 28542). Landing gate at0c56cc2d4: 23 suites green. Decision 123 go from Mos. Co-Authored-By: Claude Opus 5.5 <[email protected]>
19 lines
2.4 KiB
JavaScript
19 lines
2.4 KiB
JavaScript
// REQ-WEB-1 / REQ-LIMIT-1: Settings uses the Console's human send boundary.
|
|
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {request} from 'node:http';
|
|
import {startServer} from '../src/serve.mjs';
|
|
const preview={host:'console.example',header:'x-user',user:'jason'};
|
|
const headers={host:'console.example','x-user':'jason',origin:'https://console.example','sec-fetch-site':'same-origin','content-type':'application/json'};
|
|
const payload={revision:'a'.repeat(64),limits:{total:0}};
|
|
async function setup(t,enabled=true){const calls=[];const server=await startServer({port:0,preview,send:enabled?async()=>({}):null,settingsWrite:async args=>{calls.push(args);return {...args,business:'acme'};}});t.after(()=>new Promise(r=>server.close(r)));return {calls,port:server.address().port};}
|
|
function post(s,hs=headers,data=payload){return new Promise((resolve,reject)=>{const req=request({hostname:'127.0.0.1',port:s.port,path:'/api/settings',method:'POST',headers:hs},r=>{let text='';r.on('data',c=>text+=c);r.on('end',()=>resolve({status:r.statusCode,text}));});req.on('error',reject);req.end(typeof data==='string'?data:JSON.stringify(data));});}
|
|
test('REQ-WEB-1 signed-in same-origin Settings write reaches exactly one human operation',async t=>{const s=await setup(t);const r=await post(s);assert.equal(r.status,200,r.text);assert.deepEqual(s.calls,[payload]);});
|
|
test('REQ-WEB-1 Settings writes require enabled send, named Host, identity, exact Origin and same-origin Fetch Metadata',async t=>{
|
|
const off=await setup(t,false);assert.equal((await post(off)).status,403);assert.equal(off.calls.length,0);
|
|
const s=await setup(t);for(const [key,value,status] of [['host','wrong.example',403],['x-user','other',401],['origin','https://else.example',403],['sec-fetch-site','cross-site',403],['origin',undefined,403],['sec-fetch-site',undefined,403],['x-user',['jason','jason'],401]]){const hs={...headers};if(value===undefined)delete hs[key];else hs[key]=value;assert.equal((await post(s,hs)).status,status,key);}assert.equal(s.calls.length,0);
|
|
});
|
|
test('REQ-WEB-1 Settings validates JSON, size, revision and strict writable keys before broker call',async t=>{
|
|
const s=await setup(t);for(const value of [{...payload,actor:'jason'},{limits:{}},[],null,'bad','x'.repeat(17000)])assert.equal((await post(s,headers,value)).status,400,String(value));assert.equal((await post(s,{...headers,'content-type':'text/plain'})).status,400);assert.equal(s.calls.length,0);
|
|
});
|