import { TestCase } from "./framework/test_case.js"; import { setupDom, teardownDom } from "./framework/dom.js"; import { TrainModal, BuildingsModal, NationModal } from "../client/js/modals.js"; import { BUILDINGS, GOVERNMENTS, TECHNOLOGIES, PROTO_UNITS } from "../shared/data.js"; export class TrainModalTest extends TestCase { async test_lists_trainable_units_and_requests_one() { const env = await setupDom(); try { const modal = new TrainModal(); let requested = null; modal.onTrain = (cityId, protoIndex) => { requested = [cityId, protoIndex]; }; modal.show({ id: 5, name: "Paris" }, 1.0e9, [{ ...PROTO_UNITS[0], serverIndex: 0 }]); this.assertEqual(env.$("#train-title").text(), "Paris — Train"); this.assertSize(env.$("#train-list button"), 1); this.assertTrue(env.$("#train-list button").text().includes("Modern infantry")); env.$("#train-list button").click(); this.assertEqual(requested, [5, 0]); modal.close(); this.assertTrue(env.$("#modal-train").hasClass("hidden")); } finally { teardownDom(env); } } async test_training_progress_states() { const env = await setupDom(); try { const modal = new TrainModal(); modal.show({ id: 1, name: "Lyon" }, 1.0e9, [{ ...PROTO_UNITS[0], serverIndex: 0 }]); modal.beginTraining("Modern infantry", 10, 2); this.assertFalse(env.$("#train-status").hasClass("hidden")); this.assertTrue(env.$("#train-list button").prop("disabled")); modal.setTrainingProgress("Modern infantry", 4, 10); this.assertTrue(env.$("#train-label").text().includes("6 h left")); modal.endTraining(); this.assertEqual(env.$("#train-label").text(), "Training complete"); this.assertFalse(env.$("#train-list button").prop("disabled")); } finally { teardownDom(env); } } } export class BuildingsModalTest extends TestCase { async test_prices_rows_and_requests_build_and_demolish() { const env = await setupDom(); try { const modal = new BuildingsModal(); let built = null; let demolished = null; modal.onBuild = (cityId, index) => { built = [cityId, index]; }; modal.onDemolish = (cityId, index) => { demolished = [cityId, index]; }; modal.show({ id: 3, name: "Lyon" }, 1.0e9, 1.0e15, BUILDINGS, {}); this.assertEqual(env.$("#buildings-title").text(), "Lyon — Buildings"); this.assertSize(env.$("#buildings-list .row-card"), BUILDINGS.length); const first = env.$("#buildings-list .row-card").first(); this.assertTrue(first.find(".name").text().includes("Level 0")); this.assertFalse(first.find(".actions button").first().prop("disabled")); first.find(".actions button").first().click(); this.assertEqual(built, [3, 0]); modal.refresh(1.0e9, 1.0e15, { 0: 1 }); this.assertTrue(first.find(".name").text().includes("Level 1")); first.find(".actions button").eq(1).click(); this.assertEqual(demolished, [3, 0]); modal.close(); this.assertTrue(env.$("#modal-buildings").hasClass("hidden")); } finally { teardownDom(env); } } async test_unaffordable_upgrade_is_disabled() { const env = await setupDom(); try { const modal = new BuildingsModal(); modal.show({ id: 1, name: "X" }, 1.0e9, 0, BUILDINGS, {}); const upgrade = env.$("#buildings-list .row-card").first().find(".actions button").first(); this.assertTrue(upgrade.prop("disabled")); } finally { teardownDom(env); } } } export class NationModalTest extends TestCase { async test_government_and_technology_tabs() { const env = await setupDom(); try { const modal = new NationModal(); let government = null; let technology = null; modal.onGovernment = (index) => { government = index; }; modal.onTechnology = (index) => { technology = index; }; modal.show(GOVERNMENTS, 0, TECHNOLOGIES, new Set(), 1.0e9, 1.0e15, 1.0e6); this.assertSize(env.$("#government-list .row-card"), GOVERNMENTS.length); this.assertSize(env.$("#technology-list .row-card"), TECHNOLOGIES.length); const governmentRows = env.$("#government-list .row-card"); this.assertTrue(governmentRows.eq(0).find(".actions button").prop("disabled"), "current government is locked"); governmentRows.eq(1).find(".actions button").click(); this.assertEqual(government, 1); // A prerequisite-gated technology starts locked. const method = TECHNOLOGIES.findIndex((t) => t.id === "scientific_method"); const automation = TECHNOLOGIES.findIndex((t) => t.id === "industrial_automation"); const techRows = env.$("#technology-list .row-card"); this.assertEqual(techRows.eq(automation).find(".actions button").text(), "Locked"); // Researching its prerequisite unlocks it. modal.refresh(0, new Set([method]), 1.0e9, 1.0e15, 1.0e6); this.assertTrue(techRows.eq(method).find(".actions button").text().startsWith("Researched")); this.assertTrue(techRows.eq(automation).find(".actions button").text().startsWith("Research")); techRows.eq(automation).find(".actions button").click(); this.assertEqual(technology, automation); env.$("#modal-nation .tab[data-tab=technology]").click(); this.assertTrue(env.$("#tab-technology").hasClass("active")); env.$("#modal-nation .tab[data-tab=government]").click(); this.assertTrue(env.$("#tab-government").hasClass("active")); modal.close(); this.assertTrue(env.$("#modal-nation").hasClass("hidden")); } finally { teardownDom(env); } } async test_budget_tab_shows_income_and_upkeep_breakdown() { const env = await setupDom(); try { const modal = new NationModal(); const finances = { income: { rate: 0.001, base: 900, modifier: 0.15, total: 1035, sources: [ { label: "Bank", kind: "building", effect: 0.05, amount: 45 }, { label: "Republic", kind: "government", effect: 0.1, amount: 90 }, ], }, buildingUpkeep: { total: 400, sources: [{ label: "Bank", kind: "building", amount: 400 }] }, unitUpkeep: { total: 150, sources: [{ label: "Modern infantry", kind: "unit", amount: 150, count: 3 }], }, net: 485, }; modal.show(GOVERNMENTS, 0, TECHNOLOGIES, new Set(), 1.0e9, 1.0e15, 1.0e6, finances); env.$("#modal-nation .tab[data-tab=budget]").click(); this.assertTrue(env.$("#tab-budget").hasClass("active")); const rows = env.$("#budget-list .row-card"); this.assertSize(rows, 4); this.assertTrue(rows.eq(0).find(".value").text().includes("+€1 035/h")); this.assertTrue(rows.eq(0).find(".budget-detail").text().includes("Tax rate 0.10% of GDP")); this.assertTrue(rows.eq(0).find(".budget-detail").text().includes("Bank (building) +5.0%")); this.assertTrue(rows.eq(0).find(".budget-detail").text().includes("Republic (government) +10.0%")); this.assertTrue(rows.eq(1).find(".value").text().includes("−€400/h")); this.assertTrue(rows.eq(1).find(".budget-detail").text().includes("Bank — €400/h")); this.assertTrue(rows.eq(2).find(".value").text().includes("−€150/h")); this.assertTrue(rows.eq(2).find(".budget-detail").text().includes("Modern infantry ×3")); this.assertTrue(rows.eq(3).find(".value").text().includes("+€485/h")); this.assertTrue(rows.eq(3).find(".value").hasClass("positive")); this.assertTrue(env.$("#budget-sub").text().includes("Treasury")); modal.refresh(0, new Set(), 1.0e9, 1.0e15, 1.0e6, { income: { rate: 0.001, base: 100, modifier: 0, total: 100, sources: [] }, buildingUpkeep: { total: 400, sources: [] }, unitUpkeep: { total: 150, sources: [] }, net: -450, }); this.assertTrue(rows.eq(3).find(".value").text().includes("−€450/h")); this.assertTrue(rows.eq(3).find(".value").hasClass("negative")); this.assertTrue(rows.eq(0).find(".budget-detail").text().includes("No bonuses")); } finally { teardownDom(env); } } }