Expose plain-text API documentation with agent_mode
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import {test} from 'node:test';
|
||||
import type {NextApiRequest,NextApiResponse} from 'next';
|
||||
import {apiDocuments,serveApiDocumentation} from '../src/lib/api-documentation';
|
||||
import index from '../src/pages/api/index';
|
||||
|
||||
function response(){
|
||||
const state={status:0,headers:{} as Record<string,string>,body:undefined as unknown};
|
||||
const res={setHeader(name:string,value:string){state.headers[name]=value;return res;},status(code:number){state.status=code;return res;},send(body:unknown){state.body=body;return res;},json(body:unknown){state.body=body;return res;},end(){return res;}};
|
||||
return {state,res:res as unknown as NextApiResponse};
|
||||
}
|
||||
const request=(method:string,agent_mode:unknown)=>({method,query:{agent_mode}} as unknown as NextApiRequest);
|
||||
|
||||
test('every business handler serves documentation before validating parameters or accessing dependencies',async()=>{
|
||||
const routes:Record<string,string>={
|
||||
'/api/explore-feed':'explore-feed','/api/feed':'feed','/api/notes/{id}':'notes/[id]',
|
||||
'/api/posts':'posts/index','/api/tags':'tags','/api/upload':'upload',
|
||||
'/api/media/{id}':'media/[id]','/api/preview':'preview',
|
||||
'/api/skills/street-people':'skills/street-people','/api/health':'health','/api/ready':'ready',
|
||||
};
|
||||
for(const [path,route] of Object.entries(routes)){
|
||||
const {default:handler}=await import('../src/pages/api/'+route+'.ts');
|
||||
for(const method of ['GET','HEAD']){
|
||||
const {state,res}=response();
|
||||
await handler(request(method,'tRuE'),res);
|
||||
assert.equal(state.status,200,path);
|
||||
assert.equal(state.headers['Content-Type'],'text/plain; charset=utf-8',path);
|
||||
if(method==='HEAD')assert.equal(state.body,undefined);else {
|
||||
assert.ok(String(state.body).includes(path),path);
|
||||
assert.ok(String(state.body).includes('参数'),path);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.deepEqual(Object.keys(routes).sort(),Object.keys(apiDocuments).sort());
|
||||
});
|
||||
|
||||
test('normal calls and mutations do not enter documentation mode',()=>{
|
||||
for(const [method,value] of [['GET',undefined],['GET','false'],['GET',['True','false']],['POST','True'],['PUT','True'],['DELETE','True']]){
|
||||
const {state,res}=response();
|
||||
assert.equal(serveApiDocumentation(request(method as string,value),res,'/api/posts'),false);
|
||||
assert.equal(state.status,0);
|
||||
}
|
||||
});
|
||||
|
||||
test('index exposes every business endpoint and its text URL',()=>{
|
||||
const {state,res}=response();index(request('GET','True'),res);
|
||||
for(const path of [...Object.keys(apiDocuments),'/studio/api/export/{slug}','/studio/api/health'])assert.ok(String(state.body).includes(path+'?agent_mode=True'));
|
||||
});
|
||||
|
||||
test('health keeps its regular JSON response',async()=>{
|
||||
const {default:handler}=await import('../src/pages/api/health');
|
||||
const {state,res}=response();handler(request('GET',undefined),res);
|
||||
assert.equal(state.status,200);assert.equal((state.body as {status:string}).status,'ok');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user