import assert from 'node:assert/strict'; import test from 'node:test'; import { bureaucratPaymentModeSupported } from '../game/bureaucrat-payment'; import { discoveryModeSupported, selectedDiscoveryLeaderSkillsProfile } from '../game/discovery-module-profile'; import { selectedDiscoveryWithoutCardsProfile, type FactionModuleProfile } from '../game/faction-module-profile'; import { advancedMoritaniLeaderSkillsProfile, basicMoritaniLeaderSkillsProfile, nativeDiscoveryLeaderSkillsProfile, nativeEcazLeaderSkillsProfile, ordinaryLeaderSkillModeSupported, strongholdLeaderSkillsProfile } from '../game/leader-skill-profile'; const base: FactionModuleProfile = { advanced: false, expansions: ['ix', 'choam', 'ecaz'], players: [{faction:'atreides'}, {faction:'guild'}, {faction:'emperor'}], discoveryEnabled: true, leaderSkills: {}, }; void test('selected Discovery and Skills use the shared registered roster without requiring native seats', () => { const rows: FactionModuleProfile[] = [ base, {...base, advanced:true}, {...base, expansions:['ecaz'], players:[{faction:'atreides'}, {faction:'guild'}]}, {...base, expansions:['ix', 'ecaz'], players:[{faction:'ixians'}, {faction:'guild'}]}, {...base, players:[{faction:'ixians'}, {faction:'ecaz'}, {faction:'moritani'}]}, {...base, players:[{faction:'ixians'}, {faction:'ecaz'}, {faction:'guild'}], discoveries:{}, discoveryStash:{}, greatMaker:{}, ecazOccupyPreview:true}, {...base, advanced:true, players:[{faction:'moritani'}, {faction:'atreides'}, {faction:'guild'}], moritaniAssassinatePreview:true}, {...base, advanced:true, homeworlds:{}, techTokens:{}, strongholdCards:{}}, {...base, advanced:true, players:[{faction:'harkonnen'}, {faction:'ixians'}]}, ]; for (const row of rows) { const label = JSON.stringify(row); assert.equal(selectedDiscoveryWithoutCardsProfile(row), true, label); assert.equal(selectedDiscoveryLeaderSkillsProfile(row), true, label); assert.equal(discoveryModeSupported(row), true, label); assert.equal(nativeDiscoveryLeaderSkillsProfile(row), true, label); assert.equal(ordinaryLeaderSkillModeSupported(row), true, label); assert.equal(bureaucratPaymentModeSupported(row), true, label); } // The pre-deal lobby has not allocated the physical Skills deck yet. const lobby: FactionModuleProfile = {...base, leaderSkills:undefined}; assert.equal(selectedDiscoveryLeaderSkillsProfile(lobby), true); assert.equal(strongholdLeaderSkillsProfile({...base, advanced:true, strongholdCards:{}}), true); }); void test('selected Discovery Skills preserve native Ecaz and Moritani participation', () => { const pair = {...base, players:[{faction:'ecaz'}, {faction:'moritani'}, {faction:'guild'}]}; assert.equal(nativeEcazLeaderSkillsProfile(pair), true); assert.equal(basicMoritaniLeaderSkillsProfile(pair), true); assert.equal(advancedMoritaniLeaderSkillsProfile(pair), false); const advanced = {...pair, advanced:true, moritaniAssassinatePreview:true}; assert.equal(nativeEcazLeaderSkillsProfile(advanced), true); assert.equal(advancedMoritaniLeaderSkillsProfile(advanced), true); }); void test('selected Discovery Skills reject illegal seats, decks, overlays and phase-module prerequisites', () => { const rejected: FactionModuleProfile[] = [ {...base, discoveryEnabled:false}, {...base, expansions:[]}, {...base, expansions:['ix', 'ix']}, {...base, expansions:['ix', 'unknown']}, {...base, players:[{faction:'atreides'}]}, {...base, players:[{faction:'atreides'}, {faction:'atreides'}]}, {...base, players:[{faction:'atreides'}, {faction:'unknown'}]}, {...base, expansions:['ix'], players:[{faction:'choam'}, {faction:'atreides'}]}, {...base, players:[{faction:'atreides'}, {faction:'guild'}], techTokens:{}}, {...base, strongholdCards:{}}, {...base, nexusCards:{}}, {...base, ecazTreachery:true}, {...base, semutaPreview:true}, {...base, kullPreview:true}, {...base, nexusKullPreview:true}, {...base, guildBetrayalPreview:true}, {...base, nexusIxianBetrayalPreview:true}, {...base, moritaniAssassinatePreview:true}, ]; for (const row of rejected) { const label = JSON.stringify(row); assert.equal(selectedDiscoveryWithoutCardsProfile(row), false, label); assert.equal(selectedDiscoveryLeaderSkillsProfile(row), false, label); } }); void test('Advanced trained Harkonnen with actual E3 native remains excluded', () => { for (const faction of ['ecaz', 'moritani']) { const players = [{faction:'harkonnen'}, {faction}]; assert.equal(selectedDiscoveryLeaderSkillsProfile({...base, players}), true, faction); assert.equal(selectedDiscoveryLeaderSkillsProfile({...base, players, advanced:true}), false, faction); assert.equal(discoveryModeSupported({...base, players, advanced:true}), false, faction); } });