import { TestCase } from "./framework/test_case.js"; import { smallState, settleInlandCity, smallConfig } from "./framework/helpers.js"; import { GameServer } from "../server/game_server.js"; import { isLoopback, isLocalRequest } from "../server/server.js"; const BIG_BUDGET = 1.0e15; function makeServer(testing) { const network = { getPeerIds: () => [], send: () => {} }; const server = new GameServer(network); server.configureGame({ seed: 12345, player_civ: 0, civilisations: ["france", "britain"], testing, mapConfig: smallConfig(), // These fixtures compare the treasury before and after an order, so they // pin the hard economy, where an order has a money cost to charge. economyModel: "hard", }); return server; } export class TestingModeTest extends TestCase { test_loopback_addresses_are_recognised() { this.assertTrue(isLoopback("127.0.0.1"), "v4 loopback"); this.assertTrue(isLoopback("127.0.1.5"), "any 127/8 address"); this.assertTrue(isLoopback("::1"), "v6 loopback"); this.assertTrue(isLoopback("::ffff:127.0.0.1"), "mapped v4 loopback"); this.assertFalse(isLoopback("10.0.0.1"), "a private address is remote"); this.assertFalse(isLoopback("::ffff:8.8.8.8"), "a mapped public address is remote"); this.assertFalse(isLoopback(""), "an empty address is remote"); this.assertFalse(isLoopback(undefined), "a missing address is remote"); } test_a_local_page_is_distinguished_from_a_proxied_remote_client() { this.assertTrue(isLocalRequest("127.0.0.1", "http://127.0.0.1:27015"), "a local page"); this.assertTrue( isLocalRequest("::ffff:127.0.0.1", "http://localhost:27015"), "a mapped local page" ); this.assertFalse( isLocalRequest("127.0.0.1", "https://tismo.example.com"), "a proxied remote page is remote even though its socket is loopback" ); this.assertFalse( isLocalRequest("10.0.0.1", "http://127.0.0.1:27015"), "a remote socket is remote" ); this.assertFalse(isLocalRequest("127.0.0.1", ""), "a missing origin is remote"); } test_free_training_spawns_instantly_and_costs_nothing() { const state = smallState(); state.budgets.set(0, BIG_BUDGET); const city = state.cities.find((c) => c.civ === 0); const artillery = state.protoUnits.findIndex((u) => u.id === "artillery"); const before = state.units.filter((u) => u.civ === 0).length; this.assertTrue(state.requestTrain(city.id, artillery, true), "the free order is accepted"); this.assertEqual( state.units.filter((u) => u.civ === 0).length, before + 1, "the unit appears at once" ); this.assertEqual(state.getBudget(0), BIG_BUDGET, "nothing is charged"); this.assertFalse(state.training.has(city.id), "nothing is queued"); } test_free_build_raises_the_level_instantly_and_costs_nothing() { const state = smallState(); state.budgets.set(0, BIG_BUDGET); const city = state.cities.find((c) => c.civ === 0); const barracks = state.protoBuildings.findIndex((b) => b.id === "barracks"); this.assertTrue(state.requestBuild(city.id, barracks, true), "the free build is accepted"); this.assertEqual(state.getCityBuildingLevel(city, barracks), 1, "the level rose at once"); this.assertEqual(state.getBudget(0), BIG_BUDGET, "nothing is charged"); this.assertFalse(state.training.has(city.id), "nothing is queued"); } test_free_build_still_respects_placement_rules() { const state = smallState(); const inland = settleInlandCity(state, 0); this.assertNotNull(inland, "the fixture has an inland city"); const shipyard = state.protoBuildings.findIndex((b) => b.id === "shipyard"); this.assertFalse(state.requestBuild(inland.id, shipyard, true), "an inland shipyard is refused"); } test_a_normal_order_still_charges_and_queues() { const state = smallState(); state.budgets.set(0, BIG_BUDGET); const city = state.cities.find((c) => c.civ === 0); const barracks = state.protoBuildings.findIndex((b) => b.id === "barracks"); this.assertTrue(state.requestBuild(city.id, barracks), "the paid order is accepted"); this.assertEqual(state.getCityBuildingLevel(city, barracks), 0, "it does not rise at once"); this.assertLess(state.getBudget(0), BIG_BUDGET, "it was charged"); this.assertTrue(state.training.has(city.id), "it went into the queue"); } test_server_honours_free_orders_in_a_testing_game() { const server = makeServer(true); server.peerCiv.set(1, 0); const city = server.state.cities.find((c) => c.civ === 0); const barracks = server.state.protoBuildings.findIndex((b) => b.id === "barracks"); const levelBefore = server.state.getCityBuildingLevel(city, barracks); const budgetBefore = server.state.getBudget(0); this.assertTrue( server.handleOrder(1, { type: "build", city: city.id, building: barracks, free: true }), "the order is accepted" ); this.assertEqual( server.state.getCityBuildingLevel(city, barracks), levelBefore + 1, "the building went up" ); this.assertEqual(server.state.getBudget(0), budgetBefore, "it was free"); this.assertTrue(server.state.testing, "the snapshot flag is set"); } test_server_ignores_the_free_flag_in_a_normal_game() { const server = makeServer(false); server.peerCiv.set(1, 0); const city = server.state.cities.find((c) => c.civ === 0); const barracks = server.state.protoBuildings.findIndex((b) => b.id === "barracks"); const levelBefore = server.state.getCityBuildingLevel(city, barracks); const budgetBefore = server.state.getBudget(0); this.assertTrue( server.handleOrder(1, { type: "build", city: city.id, building: barracks, free: true }), "the order is still processed" ); this.assertEqual( server.state.getCityBuildingLevel(city, barracks), levelBefore, "it only went into the queue" ); this.assertLess(server.state.getBudget(0), budgetBefore, "the normal cost was charged"); this.assertFalse(server.state.testing, "the testing flag stays off"); } test_a_local_peer_gets_free_orders_in_a_normal_game() { const server = makeServer(false); server.setPeerLocal(1, true); server.peerCiv.set(1, 0); const city = server.state.cities.find((c) => c.civ === 0); const barracks = server.state.protoBuildings.findIndex((b) => b.id === "barracks"); const levelBefore = server.state.getCityBuildingLevel(city, barracks); const budgetBefore = server.state.getBudget(0); this.assertTrue( server.handleOrder(1, { type: "build", city: city.id, building: barracks, free: true }), "the order is accepted" ); this.assertEqual( server.state.getCityBuildingLevel(city, barracks), levelBefore + 1, "the building went up" ); this.assertEqual(server.state.getBudget(0), budgetBefore, "it was free"); this.assertFalse(server.state.testing, "the game itself stays a normal game"); } }