57 lines
4.5 KiB
JavaScript
57 lines
4.5 KiB
JavaScript
const {test}=require('node:test');
|
|
const assert=require('node:assert/strict');
|
|
const {partyDecision,bondEvidence,community,compileCommunityAction,observePresence,applyCooperation}=require('../.test-build/community.js');
|
|
const now=()=>Date.now()/1000;
|
|
function bot(id){return {id,name:id,status:'online',level:5,autonomy:{managed:true,characterGuid:id==='A'?1:2,accountId:id==='A'?11:12},personality:{sociability:60,activities:['quest']},relationships:[],memories:[],world:{at:now(),team:1,nearby:id==='A'?['B']:['A'],inCombat:false,groupNames:[],groupId:'',guildId:3,guildName:'Guild',guildRank:0,mapId:0,x:1,y:1}};}
|
|
test('party acceptance respects faction, level, hostility, combat, and observation freshness',()=>{
|
|
const a=bot('A'),b=bot('B');assert.equal(partyDecision(a,b).accepted,true);
|
|
b.world.team=0;assert.equal(partyDecision(a,b).accepted,false);b.world.team=1;
|
|
b.level=55;assert.equal(partyDecision(a,b).accepted,false);b.level=5;
|
|
b.relationships=[{targetId:'A',affinity:-10}];assert.equal(partyDecision(a,b).accepted,false);b.relationships=[];
|
|
b.world.at=now()-150;assert.equal(partyDecision(a,b).accepted,false);b.world.at=now();
|
|
b.world.inCombat=true;assert.equal(partyDecision(a,b).accepted,false);
|
|
});
|
|
test('relationship evidence is reciprocal, replay safe, bounded, and excludes deaths',()=>{
|
|
const a=bot('A'),b=bot('B'),s={bots:[a,b]};
|
|
bondEvidence(s,'x',a,b,'Helped',3);bondEvidence(s,'x',a,b,'Helped',3);
|
|
assert.equal(a.relationships[0].affinity,3);assert.equal(b.relationships[0].affinity,3);
|
|
applyCooperation(s,{observedAt:now(),evidenceId:'q',characterGuid:1,peerGuid:2,cooperation:'quest',questId:5});
|
|
assert.equal(a.relationships[0].affinity,6);assert.equal(a.memories.length,1);
|
|
applyCooperation(s,{observedAt:now(),evidenceId:'q',characterGuid:1,peerGuid:2,cooperation:'quest',questId:5});assert.equal(a.memories.length,1);
|
|
b.status='dead';applyCooperation(s,{observedAt:now(),evidenceId:'q2',characterGuid:1,peerGuid:2,cooperation:'quest'});assert.equal(a.memories.length,1);
|
|
});
|
|
test('native commands protect human parties, cap party size, verify identities and enforce guild authority',()=>{
|
|
const a=bot('A'),b=bot('B');
|
|
const p=compileCommunityAction('party',a,b);assert.match(p,/AzerothAIQueueParty/);assert.match(p,/guid=2,account=12/);assert.match(p,/__command_id/);
|
|
const g=compileCommunityAction('recruit',a,b);assert.match(g,/GetGuildRank\(\)~=0/);assert.match(g,/Already belongs to a guild/);
|
|
assert.match(compileCommunityAction('leave',a),/Party changed/);
|
|
});
|
|
test('fresh movement snapshots update guild registry and stale snapshots cannot create stuck alerts',()=>{
|
|
const a=bot('A'),s={bots:[a]};a.world.at=now()-30;
|
|
observePresence(s,a,{observedAt:now(),team:1,x:10,y:20,mapId:0,guildId:3,guildName:'Guild',groupId:'',nearbyBots:'B'});
|
|
assert.equal(community(s).guilds[0].name,'Guild');const at=a.world.at;
|
|
observePresence(s,a,{observedAt:now()-500,team:1,x:2,y:2});assert.equal(a.world.at,at);
|
|
});
|
|
|
|
test('offline party members are protected when their identity cannot be checked live',()=>{
|
|
assert.match(compileCommunityAction('party',bot('A'),bot('B')),/AzerothAIQueueParty/);
|
|
assert.match(compileCommunityAction('leave',bot('A')),/Party has offline members/);
|
|
});
|
|
test('recent danger encourages shy companions without overriding hostility or human control',()=>{
|
|
const {partyDecision}=require('../.test-build/community.js');const a=bot('A'),b=bot('B');a.personality.sociability=0;b.personality.sociability=0;
|
|
assert.equal(partyDecision(a,b).accepted,false);a.world.dangerAt=now();assert.equal(partyDecision(a,b).accepted,true);
|
|
b.relationships=[{targetId:'A',affinity:-1}];assert.equal(partyDecision(a,b).accepted,false);b.relationships=[];
|
|
b.world.humanControlled=true;assert.equal(partyDecision(a,b).accepted,false);b.world.humanControlled=false;
|
|
a.world.dangerAt=now()-601;assert.equal(partyDecision(a,b).accepted,false);
|
|
});
|
|
test('companion ranking prefers complementary native roles and shared active quests',()=>{
|
|
const {companionScore}=require('../.test-build/community.js');const a=bot('A'),b=bot('B'),c=bot('C');a.world.combatRole='tank';b.world.combatRole='healer';c.world.combatRole='damage';assert.ok(companionScore(a,b)>companionScore(a,c));
|
|
b.world.combatRole='damage';a.world.quests=[1,2];c.world.quests=[1,2];assert.ok(companionScore(a,c)>companionScore(a,b));
|
|
});
|
|
|
|
test('adventuring companions stay within five levels',()=>{
|
|
const a=bot('A'),b=bot('B');b.level=a.level+6;
|
|
assert.equal(partyDecision(a,b).accepted,false);
|
|
b.level=a.level+5;assert.equal(partyDecision(a,b).accepted,true);
|
|
});
|