Files
AzerothAI/tests/realm-insights.test.cjs
T
2026-09-22 21:18:32 -04:00

13 lines
3.6 KiB
JavaScript

const {test}=require('node:test');const assert=require('node:assert/strict');
const {observeInsights,activityReason,reportWindow,summarize}=require('../.test-build/realm-insights.js');
const now=200000;
function bot(id='A'){return {id,name:id,status:'online',level:1,relationships:[],autonomy:{managed:true},world:{at:now,x:0,y:0,mapId:0,healthPct:100,stationarySince:now-700},lastDecision:{action:'quest'}};}
function state(){return {bots:[bot(),bot('B')],community:{guilds:[],feed:[]}};}
test('insight baseline does not invent historical events; detects changed facts once',()=>{const s=state();let a=observeInsights(s,undefined,now);assert.equal(a.events.length,0);s.bots[0].level=3;s.bots[1].status='dead';s.bots[1].death={verified:true,level:1,zone:'Forest'};s.bots.push(bot('C'));const b=observeInsights(s,a.cursor,now+60);assert.deepEqual(b.events.map(e=>[e.kind,e.amount]),[['levels',2],['deaths',1],['arrivals',1]]);assert.equal(observeInsights(s,b.cursor,now+120).events.length,0);});
test('report counts confirmed bot replies, unique positive pairs and same-goal guild progress',()=>{const s=state();s.community.guilds=[{id:'g',name:'Guild',goal:'Explore',progress:1,target:10}];const a=observeInsights(s,undefined,now);s.community.guilds[0].progress=4;s.bots[0].relationships=[{targetId:'B',affinity:5}];s.bots[1].relationships=[{targetId:'A',affinity:5}];s.community.feed=['social-1:reply','social-1:opener','whisper-1','social-2:reply'].map((id,i)=>({id,kind:'conversation',at:new Date((now+60)*1000).toISOString(),status:i===3?'pending':'confirmed',names:['A','B']}));const b=observeInsights(s,a.cursor,now+60);assert.equal(b.events.filter(e=>e.kind==='conversations').length,1);assert.equal(b.events.filter(e=>e.kind==='bonds').length,1);assert.equal(b.events.find(e=>e.kind==='guild').amount,3);assert.equal(observeInsights(s,b.cursor,now+120).events.length,0);});
test('report closes at six UTC, records partial baseline and observed totals',()=>{assert.equal(reportWindow(21600),21600);assert.equal(reportWindow(21599),21600-86400);const r=summarize([{kind:'levels',amount:3}],21600,108000,22000,5);assert.equal(r.partial,true);assert.equal(r.observedSince,22000);assert.equal(r.totals.levels,3);assert.equal(r.samples,5);});
test('activity distinguishes stale data and guarded actions from inferred stalls',()=>{const b=bot();assert.equal(activityReason(b,now).label,'Possible stall');b.world.inCombat=true;assert.equal(activityReason(b,now).label,'In combat');b.world.at=now-121;assert.equal(activityReason(b,now).label,'Telemetry delayed');b.world.at=now;b.world.inCombat=false;b.world.casting=true;assert.equal(activityReason(b,now).label,'Casting');b.world.casting=false;b.lastDecision.action='rest';assert.equal(activityReason(b,now).label,'Intends to rest');});
test('pending social events count once after native confirmation',()=>{const s=state();s.community.feed=[{id:'social-1:reply',kind:'conversation',status:'pending',at:new Date(now*1000).toISOString(),names:['A','B']}];const a=observeInsights(s,undefined,now);s.community.feed[0].status='confirmed';const b=observeInsights(s,a.cursor,now+60);assert.equal(b.events.length,1);assert.equal(observeInsights(s,b.cursor,now+120).events.length,0);});
test('enabling failure tracking does not backfill old failed party actions',()=>{const s=state();const a=observeInsights(s,undefined,now);s.community.feed=[{id:'party-old',kind:'party',status:'failed',at:new Date((now-600)*1000).toISOString(),names:['A','B']},{id:'party-new',kind:'party',status:'failed',at:new Date((now+20)*1000).toISOString(),names:['A','B']}];const b=observeInsights(s,a.cursor,now+60);assert.deepEqual(b.events.map(e=>e.id),['social:party-new']);});