import {test} from 'node:test';import assert from 'node:assert/strict';import {readFileSync} from 'node:fs';import vm from 'node:vm'; const source=readFileSync(new URL('../deploy-admin-functions.mjs',import.meta.url),'utf8').match(/const appGatewayCode = String.raw`([\s\S]*?)\n`;/)[1]; test('real AI adapter appends all server-resolved words and rejects stale source before provider call',async()=>{ const sent=[],wordList=Array.from({length:17},(_,i)=>'word'+i); const ctx=vm.createContext({Parse:{Config:{get:async()=>({get:()=> 'test-provider-token'})}},fetch:async(url,init)=>{sent.push(JSON.parse(init.body));return{ok:true,text:async()=>JSON.stringify({choices:[{message:{content:'article'}}]})}}}); vm.runInContext(source,ctx);ctx.appReadingSource=async()=>({sourceVersion:'4',wordList}); await ctx.readingAi({sourceStudyId:'fixture',sourceVersion:'4',prompt:'Write a story'},{}); assert.equal(sent.length,1);for(const word of wordList)assert(sent[0].messages[0].content.includes(word)); await assert.rejects(ctx.readingAi({sourceStudyId:'fixture',sourceVersion:'3',prompt:'Write a story'},{}),/已更新/);assert.equal(sent.length,1); });