mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
649 lines
26 KiB
TypeScript
649 lines
26 KiB
TypeScript
import { installAugmentations } from "../../../src/Augmentation/AugmentationHelpers";
|
|
import { blackOpsArray } from "../../../src/Bladeburner/data/BlackOperations";
|
|
import { AugmentationName, CompanyName, CompletedProgramName, FactionName, JobField, JobName } from "@enums";
|
|
import { Player } from "@player";
|
|
import { prestigeSourceFile } from "../../../src/Prestige";
|
|
import { disconnectServers, GetServerOrThrow } from "../../../src/Server/AllServers";
|
|
import { SpecialServers } from "../../../src/Server/data/SpecialServers";
|
|
import { Factions } from "../../../src/Faction/Factions";
|
|
import { PlayerOwnedAugmentation } from "../../../src/Augmentation/PlayerOwnedAugmentation";
|
|
import { getNS, initGameEnvironment, setupBasicTestingEnvironment } from "../Utilities";
|
|
import { Terminal } from "../../../src/Terminal";
|
|
import type { NSFull } from "../../../src/NetscriptFunctions";
|
|
import { Companies } from "../../../src/Company/Companies";
|
|
import { CompanyPositions } from "../../../src/Company/CompanyPositions";
|
|
import { getTorRouter } from "../../../src/Server/ServerHelpers";
|
|
import * as exceptionAlertModule from "../../../src/utils/helpers/exceptionAlert";
|
|
|
|
const nextBN = 4;
|
|
|
|
function setNumBlackOpsComplete(value: number): void {
|
|
if (!Player.bladeburner) {
|
|
throw new Error("Invalid Bladeburner data");
|
|
}
|
|
Player.bladeburner.numBlackOpsComplete = value;
|
|
}
|
|
|
|
function gainTonsOfExp() {
|
|
Player.exp.hacking = 1e100;
|
|
Player.exp.strength = 1e100;
|
|
Player.exp.defense = 1e100;
|
|
Player.exp.dexterity = 1e100;
|
|
Player.exp.agility = 1e100;
|
|
Player.exp.charisma = 1e100;
|
|
Player.updateSkillLevels();
|
|
}
|
|
|
|
function resetExp() {
|
|
Player.exp.hacking = 0;
|
|
Player.exp.strength = 0;
|
|
Player.exp.defense = 0;
|
|
Player.exp.dexterity = 0;
|
|
Player.exp.agility = 0;
|
|
Player.exp.charisma = 0;
|
|
Player.updateSkillLevels();
|
|
}
|
|
|
|
beforeAll(() => {
|
|
initGameEnvironment();
|
|
});
|
|
|
|
function testIntelligenceOverride(
|
|
ns: NSFull,
|
|
prestigeAPI: "b1tflum3" | "destroyW0r1dD43m0n",
|
|
expectSuccessPrestige: () => void,
|
|
setUpBeforePrestige = () => {},
|
|
): void {
|
|
Player.sourceFiles.set(5, 1);
|
|
// The intelligence skill level starts at 0.
|
|
expect(Player.skills.intelligence).toStrictEqual(0);
|
|
prestigeSourceFile(true);
|
|
// Start without exp.
|
|
expect(Player.exp.intelligence).toStrictEqual(0);
|
|
// When having SF5 and the skill level is 0, it's set to 1.
|
|
expect(Player.skills.intelligence).toStrictEqual(1);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(0);
|
|
// Gain 1e6 exp (skill = 242).
|
|
Player.gainIntelligenceExp(1e6);
|
|
expect(Player.exp.intelligence).toStrictEqual(1e6);
|
|
expect(Player.skills.intelligence).toStrictEqual(242);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6);
|
|
|
|
// Prestige and check if intelligenceOverride works (exp is set to 11255, skill = 100, and
|
|
// persistentIntelligenceData.exp is still 1e6).
|
|
const intelligenceExpGainOnPrestige = prestigeAPI === "destroyW0r1dD43m0n" ? 300 : 0;
|
|
setUpBeforePrestige();
|
|
ns.singularity[prestigeAPI](nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: 100,
|
|
});
|
|
expectSuccessPrestige();
|
|
expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(100);
|
|
expect(Player.exp.intelligence).toStrictEqual(11255.317546552918 + intelligenceExpGainOnPrestige);
|
|
expect(Player.skills.intelligence).toStrictEqual(100);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige);
|
|
|
|
// Gain 500e3 exp.
|
|
const intExpGain = 500e3;
|
|
Player.gainIntelligenceExp(intExpGain);
|
|
// Check if int gain is accumulated correctly in both Player.exp.intelligence and
|
|
// Player.persistentIntelligenceData.exp.
|
|
expect(Player.exp.intelligence).toStrictEqual(11255.317546552918 + intelligenceExpGainOnPrestige + intExpGain);
|
|
expect(Player.skills.intelligence).toStrictEqual(220);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige + intExpGain);
|
|
|
|
// Prestige and check if int gain is still retained correctly.
|
|
setUpBeforePrestige();
|
|
ns.singularity[prestigeAPI](nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: undefined,
|
|
});
|
|
expectSuccessPrestige();
|
|
expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(undefined);
|
|
expect(Player.exp.intelligence).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2 + intExpGain);
|
|
expect(Player.skills.intelligence).toStrictEqual(255);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2 + intExpGain);
|
|
|
|
// Prestige with intelligenceOverride set higher than the persistent int skill and check if the int skill is
|
|
// incorrectly set to that value.
|
|
setUpBeforePrestige();
|
|
ns.singularity[prestigeAPI](nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: 1000,
|
|
});
|
|
expectSuccessPrestige();
|
|
expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(1000);
|
|
expect(Player.exp.intelligence).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 3 + intExpGain);
|
|
expect(Player.skills.intelligence).toStrictEqual(255);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 3 + intExpGain);
|
|
|
|
// Start testing another scenario.
|
|
// Set the initial state (int exp = 1e6, skill = 242) and bitflume.
|
|
Player.exp.intelligence = 1e6;
|
|
Player.skills.intelligence = 242;
|
|
Player.persistentIntelligenceData.exp = 1e6;
|
|
ns.singularity.b1tflum3(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: undefined,
|
|
});
|
|
|
|
// Double-check the initial state.
|
|
expect(Player.exp.intelligence).toStrictEqual(1e6);
|
|
expect(Player.skills.intelligence).toStrictEqual(242);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6);
|
|
expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(undefined);
|
|
|
|
// Limit int skill to 100.
|
|
setUpBeforePrestige();
|
|
ns.singularity[prestigeAPI](nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: 100,
|
|
});
|
|
expectSuccessPrestige();
|
|
|
|
// Check if int is overridden correctly.
|
|
expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(100);
|
|
expect(Player.exp.intelligence).toStrictEqual(11255.317546552918 + intelligenceExpGainOnPrestige);
|
|
expect(Player.skills.intelligence).toStrictEqual(100);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige);
|
|
|
|
// Limit int skill to 1000.
|
|
setUpBeforePrestige();
|
|
ns.singularity[prestigeAPI](nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: 1000,
|
|
});
|
|
expectSuccessPrestige();
|
|
|
|
// The limit is higher than the persistent int skill, so it's not applied. Exp and skill are reset back to the initial
|
|
// state, plus the int exp gained from prestige.
|
|
expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(1000);
|
|
expect(Player.exp.intelligence).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2);
|
|
expect(Player.skills.intelligence).toStrictEqual(242);
|
|
expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2);
|
|
}
|
|
|
|
function setUpBeforeDestroyingWD(): void {
|
|
Player.queueAugmentation(AugmentationName.TheRedPill);
|
|
installAugmentations();
|
|
Player.gainHackingExp(1e100);
|
|
const wdServer = GetServerOrThrow(SpecialServers.WorldDaemon);
|
|
wdServer.hasAdminRights = true;
|
|
Player.startBladeburner();
|
|
setNumBlackOpsComplete(blackOpsArray.length);
|
|
}
|
|
|
|
describe("b1tflum3", () => {
|
|
beforeEach(() => {
|
|
setupBasicTestingEnvironment();
|
|
Player.queueAugmentation(AugmentationName.Targeting1);
|
|
installAugmentations();
|
|
Player.gainHackingExp(1e100);
|
|
});
|
|
// Make sure that the player is in the next BN without SF rewards.
|
|
const expectSucceedInB1tflum3 = () => {
|
|
expect(Player.bitNodeN).toStrictEqual(nextBN);
|
|
expect(Player.augmentations.length).toStrictEqual(0);
|
|
expect(Player.exp.hacking).toStrictEqual(0);
|
|
expect(Player.sourceFileLvl(1)).toStrictEqual(0);
|
|
};
|
|
|
|
describe("Success", () => {
|
|
test("Without BN options", () => {
|
|
const ns = getNS();
|
|
ns.singularity.b1tflum3(nextBN);
|
|
expectSucceedInB1tflum3();
|
|
});
|
|
test("With BN options", () => {
|
|
const ns = getNS();
|
|
ns.singularity.b1tflum3(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
sourceFileOverrides: new Map(),
|
|
intelligenceOverride: 1,
|
|
});
|
|
expectSucceedInB1tflum3();
|
|
});
|
|
test("intelligenceOverride", () => {
|
|
testIntelligenceOverride(getNS(), "b1tflum3", expectSucceedInB1tflum3);
|
|
});
|
|
});
|
|
|
|
// Make sure that the player is still in the same BN without SF rewards.
|
|
const expectFailToB1tflum3 = () => {
|
|
expect(Player.bitNodeN).toStrictEqual(1);
|
|
expect(Player.augmentations.length).toStrictEqual(1);
|
|
expect(Player.augmentations[0].name).toStrictEqual(AugmentationName.Targeting1);
|
|
expect(Player.exp.hacking).toStrictEqual(1e100);
|
|
expect(Player.sourceFileLvl(1)).toStrictEqual(0);
|
|
};
|
|
describe("Failure", () => {
|
|
test("Invalid intelligenceOverride", () => {
|
|
const ns = getNS();
|
|
expect(() => {
|
|
ns.singularity.b1tflum3(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: -1,
|
|
});
|
|
}).toThrow();
|
|
expectFailToB1tflum3();
|
|
});
|
|
test("Invalid sourceFileOverrides", () => {
|
|
const ns = getNS();
|
|
expect(() => {
|
|
ns.singularity.b1tflum3(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
sourceFileOverrides: [] as unknown as Map<number, number>,
|
|
});
|
|
}).toThrow();
|
|
expectFailToB1tflum3();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("destroyW0r1dD43m0n", () => {
|
|
beforeEach(() => {
|
|
setupBasicTestingEnvironment();
|
|
setUpBeforeDestroyingWD();
|
|
});
|
|
|
|
describe("Success", () => {
|
|
// Make sure that the player is in the next BN and received SF rewards.
|
|
const expectSucceedInDestroyingWD = () => {
|
|
expect(Player.bitNodeN).toStrictEqual(nextBN);
|
|
expect(Player.augmentations.length).toStrictEqual(0);
|
|
expect(Player.sourceFileLvl(1)).toStrictEqual(1);
|
|
};
|
|
test("Hacking route", () => {
|
|
setNumBlackOpsComplete(0);
|
|
const ns = getNS();
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN);
|
|
expectSucceedInDestroyingWD();
|
|
});
|
|
test("Hacking route with BN options", () => {
|
|
setNumBlackOpsComplete(0);
|
|
const ns = getNS();
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
sourceFileOverrides: new Map(),
|
|
intelligenceOverride: 1,
|
|
});
|
|
expectSucceedInDestroyingWD();
|
|
});
|
|
test("Bladeburner route", () => {
|
|
Player.skills.hacking = 0;
|
|
const ns = getNS();
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN);
|
|
expectSucceedInDestroyingWD();
|
|
});
|
|
test("Bladeburner route with BN options", () => {
|
|
Player.skills.hacking = 0;
|
|
const ns = getNS();
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
sourceFileOverrides: new Map(),
|
|
intelligenceOverride: 1,
|
|
});
|
|
expectSucceedInDestroyingWD();
|
|
});
|
|
test("intelligenceOverride", () => {
|
|
testIntelligenceOverride(getNS(), "destroyW0r1dD43m0n", expectSucceedInDestroyingWD, setUpBeforeDestroyingWD);
|
|
});
|
|
});
|
|
|
|
describe("Failure", () => {
|
|
// Make sure that the player is still in the same BN without SF rewards.
|
|
const expectFailToDestroyWD = () => {
|
|
expect(Player.bitNodeN).toStrictEqual(1);
|
|
expect(Player.augmentations.length).toStrictEqual(1);
|
|
expect(Player.sourceFileLvl(1)).toStrictEqual(0);
|
|
};
|
|
test("Do not have enough hacking level and numBlackOpsComplete", () => {
|
|
Player.skills.hacking = 0;
|
|
setNumBlackOpsComplete(0);
|
|
const ns = getNS();
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN);
|
|
expectFailToDestroyWD();
|
|
});
|
|
test("Do not have admin rights on WD and do not have enough numBlackOpsComplete", () => {
|
|
const wdServer = GetServerOrThrow(SpecialServers.WorldDaemon);
|
|
wdServer.hasAdminRights = false;
|
|
setNumBlackOpsComplete(0);
|
|
const ns = getNS();
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN);
|
|
expectFailToDestroyWD();
|
|
});
|
|
test("Invalid intelligenceOverride", () => {
|
|
const ns = getNS();
|
|
expect(() => {
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
intelligenceOverride: -1,
|
|
});
|
|
}).toThrow();
|
|
expectFailToDestroyWD();
|
|
});
|
|
test("Invalid sourceFileOverrides", () => {
|
|
const ns = getNS();
|
|
expect(() => {
|
|
ns.singularity.destroyW0r1dD43m0n(nextBN, undefined, {
|
|
...ns.getResetInfo().bitNodeOptions,
|
|
sourceFileOverrides: [] as unknown as Map<number, number>,
|
|
});
|
|
}).toThrow();
|
|
expectFailToDestroyWD();
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("purchaseAugmentation", () => {
|
|
beforeEach(() => {
|
|
setupBasicTestingEnvironment();
|
|
prestigeSourceFile(true);
|
|
Player.money = 1e100;
|
|
Player.factions.push(FactionName.CyberSec);
|
|
Factions[FactionName.CyberSec].playerReputation = 1e10;
|
|
Player.factions.push(FactionName.Illuminati);
|
|
});
|
|
|
|
describe("Success", () => {
|
|
const expectQueuedAugmentation = (augmentationName: AugmentationName, level: number) => {
|
|
expect(
|
|
Player.queuedAugmentations.find((augmentation) => augmentation.name === augmentationName)?.level,
|
|
).toStrictEqual(level);
|
|
};
|
|
test("NFG", () => {
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.NeuroFluxGovernor),
|
|
).toStrictEqual(true);
|
|
expectQueuedAugmentation(AugmentationName.NeuroFluxGovernor, 1);
|
|
});
|
|
// Check if the level of NFG is increased properly.
|
|
test("Upgrade NFG", () => {
|
|
Player.augmentations.push(new PlayerOwnedAugmentation(AugmentationName.NeuroFluxGovernor));
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.NeuroFluxGovernor),
|
|
).toStrictEqual(true);
|
|
expectQueuedAugmentation(AugmentationName.NeuroFluxGovernor, 2);
|
|
});
|
|
test("Normal augmentation", () => {
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.CranialSignalProcessorsG1),
|
|
).toStrictEqual(true);
|
|
expectQueuedAugmentation(AugmentationName.CranialSignalProcessorsG1, 1);
|
|
});
|
|
test("Normal augmentation with prerequisite", () => {
|
|
Player.augmentations.push(new PlayerOwnedAugmentation(AugmentationName.CranialSignalProcessorsG1));
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.CranialSignalProcessorsG2),
|
|
).toStrictEqual(true);
|
|
expectQueuedAugmentation(AugmentationName.CranialSignalProcessorsG2, 1);
|
|
});
|
|
test("Buy 0-money-cost augmentation with negative money", () => {
|
|
Player.money = -1000;
|
|
Player.factions.push(FactionName.Daedalus);
|
|
Factions[FactionName.Daedalus].playerReputation = 1e10;
|
|
const ns = getNS();
|
|
expect(ns.singularity.purchaseAugmentation(FactionName.Daedalus, AugmentationName.TheRedPill)).toStrictEqual(
|
|
true,
|
|
);
|
|
expectQueuedAugmentation(AugmentationName.TheRedPill, 1);
|
|
});
|
|
});
|
|
|
|
describe("Failure", () => {
|
|
const expectNoQueuedAugmentation = (augmentationName: AugmentationName) => {
|
|
expect(Player.queuedAugmentations.find((augmentation) => augmentation.name === augmentationName)).toStrictEqual(
|
|
undefined,
|
|
);
|
|
};
|
|
test("Not a member of specified faction", () => {
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.Daedalus, AugmentationName.NeuroFluxGovernor),
|
|
).toStrictEqual(false);
|
|
expectNoQueuedAugmentation(AugmentationName.NeuroFluxGovernor);
|
|
});
|
|
test("Faction does not have specified augmentation", () => {
|
|
const ns = getNS();
|
|
expect(ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.QLink)).toStrictEqual(false);
|
|
expectNoQueuedAugmentation(AugmentationName.QLink);
|
|
});
|
|
test("Purchase installed augmentation", () => {
|
|
Player.augmentations.push(new PlayerOwnedAugmentation(AugmentationName.CranialSignalProcessorsG1));
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.CranialSignalProcessorsG1),
|
|
).toStrictEqual(false);
|
|
expectNoQueuedAugmentation(AugmentationName.CranialSignalProcessorsG1);
|
|
});
|
|
test("Purchase queued augmentation", () => {
|
|
Player.queuedAugmentations.push(new PlayerOwnedAugmentation(AugmentationName.CranialSignalProcessorsG1));
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.CranialSignalProcessorsG1),
|
|
).toStrictEqual(false);
|
|
});
|
|
test("Not have prerequisite augmentation", () => {
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.CranialSignalProcessorsG2),
|
|
).toStrictEqual(false);
|
|
expectNoQueuedAugmentation(AugmentationName.CranialSignalProcessorsG2);
|
|
});
|
|
test("Not enough money", () => {
|
|
Player.money = 1000;
|
|
const ns = getNS();
|
|
expect(
|
|
ns.singularity.purchaseAugmentation(FactionName.CyberSec, AugmentationName.CranialSignalProcessorsG1),
|
|
).toStrictEqual(false);
|
|
expectNoQueuedAugmentation(AugmentationName.CranialSignalProcessorsG1);
|
|
});
|
|
test("Not enough reputation", () => {
|
|
const ns = getNS();
|
|
expect(ns.singularity.purchaseAugmentation(FactionName.Illuminati, AugmentationName.QLink)).toStrictEqual(false);
|
|
expectNoQueuedAugmentation(AugmentationName.QLink);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("connect", () => {
|
|
beforeEach(() => {
|
|
setupBasicTestingEnvironment();
|
|
Player.sourceFiles.set(9, 3);
|
|
prestigeSourceFile(true);
|
|
Player.money = 1e100;
|
|
});
|
|
|
|
describe("Success", () => {
|
|
const expectConnectSuccessfully = (ns: NSFull, targetHostname: string) => {
|
|
const currentServerBeforeConnecting = Player.getCurrentServer();
|
|
expect(ns.singularity.connect(targetHostname)).toStrictEqual(true);
|
|
expect(currentServerBeforeConnecting.isConnectedTo).toStrictEqual(false);
|
|
|
|
const currentServerAfterConnecting = Player.getCurrentServer();
|
|
expect(currentServerAfterConnecting.hostname).toStrictEqual(targetHostname);
|
|
expect(currentServerAfterConnecting.isConnectedTo).toStrictEqual(true);
|
|
};
|
|
test("Built-in adjacent server", () => {
|
|
expectConnectSuccessfully(getNS(), "n00dles");
|
|
});
|
|
test("Home", () => {
|
|
Terminal.connectToServer(SpecialServers.DaedalusServer);
|
|
expectConnectSuccessfully(getNS(), "home");
|
|
});
|
|
test("Private server", () => {
|
|
const ns = getNS();
|
|
ns.cloud.purchaseServer("cloud-server-0", 8);
|
|
Terminal.connectToServer(SpecialServers.DaedalusServer);
|
|
expectConnectSuccessfully(ns, "cloud-server-0");
|
|
});
|
|
test("Hacknet server", () => {
|
|
const ns = getNS();
|
|
ns.hacknet.purchaseNode();
|
|
Terminal.connectToServer(SpecialServers.DaedalusServer);
|
|
expectConnectSuccessfully(ns, "hacknet-server-0");
|
|
});
|
|
test("Backdoored server", () => {
|
|
const ns = getNS();
|
|
Terminal.connectToServer(SpecialServers.DaedalusServer);
|
|
GetServerOrThrow("n00dles").backdoorInstalled = true;
|
|
expectConnectSuccessfully(ns, "n00dles");
|
|
});
|
|
});
|
|
|
|
describe("Failure", () => {
|
|
test("Non-existent server", () => {
|
|
const ns = getNS();
|
|
expect(() => ns.singularity.connect("abc")).toThrow();
|
|
expect(Player.getCurrentServer().hostname).not.toStrictEqual("abc");
|
|
});
|
|
test("Non-adjacent server", () => {
|
|
const ns = getNS();
|
|
expect(ns.singularity.connect(SpecialServers.DaedalusServer)).toStrictEqual(false);
|
|
expect(Player.getCurrentServer().hostname).not.toStrictEqual(SpecialServers.DaedalusServer);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("applyToCompany", () => {
|
|
beforeEach(() => {
|
|
setupBasicTestingEnvironment();
|
|
prestigeSourceFile(true);
|
|
gainTonsOfExp();
|
|
});
|
|
|
|
describe("Success", () => {
|
|
test("Apply to entry position", () => {
|
|
const ns = getNS();
|
|
Companies[CompanyName.MegaCorp].playerReputation = 0;
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software0);
|
|
});
|
|
test("Apply and be promoted to next position", () => {
|
|
const ns = getNS();
|
|
const nextPosition = CompanyPositions["Junior Software Engineer"];
|
|
Companies[CompanyName.MegaCorp].playerReputation = nextPosition.requiredReputation;
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software1);
|
|
});
|
|
test("Apply and be promoted to highest position", () => {
|
|
const ns = getNS();
|
|
Companies[CompanyName.MegaCorp].playerReputation = 1e10;
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software7);
|
|
});
|
|
test("Apply then apply again to be promoted to highest position", () => {
|
|
const ns = getNS();
|
|
Companies[CompanyName.MegaCorp].playerReputation = 0;
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software0);
|
|
Companies[CompanyName.MegaCorp].playerReputation = 1e10;
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software7);
|
|
});
|
|
});
|
|
|
|
describe("Failure", () => {
|
|
test("Not qualified", () => {
|
|
resetExp();
|
|
const ns = getNS();
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(null);
|
|
});
|
|
test("Invalid field", () => {
|
|
const ns = getNS();
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.agent)).toStrictEqual(null);
|
|
});
|
|
test("Already at highest position", () => {
|
|
const ns = getNS();
|
|
Companies[CompanyName.MegaCorp].playerReputation = 1e10;
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software7);
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(null);
|
|
});
|
|
test("Already at highest available position", () => {
|
|
const ns = getNS();
|
|
Companies[CompanyName.WatchdogSecurity].playerReputation = 1e10;
|
|
// Watchdog Security only offers up to software5 (Head of Engineering).
|
|
expect(ns.singularity.applyToCompany(CompanyName.WatchdogSecurity, JobField.software)).toStrictEqual(
|
|
JobName.software5,
|
|
);
|
|
expect(ns.singularity.applyToCompany(CompanyName.WatchdogSecurity, JobField.software)).toStrictEqual(null);
|
|
});
|
|
test("Not qualified for promotion", () => {
|
|
const ns = getNS();
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(JobName.software0);
|
|
expect(ns.singularity.applyToCompany(CompanyName.MegaCorp, JobField.software)).toStrictEqual(null);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("purchaseProgram", () => {
|
|
beforeEach(() => {
|
|
setupBasicTestingEnvironment();
|
|
prestigeSourceFile(true);
|
|
Player.money = 1e15;
|
|
getTorRouter();
|
|
});
|
|
|
|
describe("Success", () => {
|
|
beforeEach(() => {
|
|
const ns = getNS();
|
|
expect(ns.singularity.purchaseTor()).toStrictEqual(true);
|
|
});
|
|
test("return true if already bought", () => {
|
|
const ns = getNS();
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
Player.getHomeComputer().pushProgram(CompletedProgramName.bruteSsh);
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(true);
|
|
expect(ns.singularity.purchaseProgram(CompletedProgramName.bruteSsh)).toStrictEqual(true);
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(true);
|
|
});
|
|
test("bruteSsh", () => {
|
|
const ns = getNS();
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
expect(ns.singularity.purchaseProgram(CompletedProgramName.bruteSsh)).toStrictEqual(true);
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(true);
|
|
});
|
|
test("darkscape", () => {
|
|
const spiedExceptionAlert = jest.spyOn(exceptionAlertModule, "exceptionAlert");
|
|
const ns = getNS();
|
|
expect(Player.hasProgram(CompletedProgramName.darkscape)).toStrictEqual(false);
|
|
expect(ns.singularity.purchaseProgram(CompletedProgramName.darkscape)).toStrictEqual(true);
|
|
expect(Player.hasProgram(CompletedProgramName.darkscape)).toStrictEqual(true);
|
|
expect(spiedExceptionAlert).not.toHaveBeenCalled();
|
|
});
|
|
test("darkscape with lowercase program name", () => {
|
|
const spiedExceptionAlert = jest.spyOn(exceptionAlertModule, "exceptionAlert");
|
|
const ns = getNS();
|
|
expect(Player.hasProgram(CompletedProgramName.darkscape)).toStrictEqual(false);
|
|
// @ts-expect-error - Intentionally use lowercase program name
|
|
expect(ns.singularity.purchaseProgram(CompletedProgramName.darkscape.toLowerCase())).toStrictEqual(true);
|
|
expect(Player.hasProgram(CompletedProgramName.darkscape)).toStrictEqual(true);
|
|
expect(spiedExceptionAlert).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("Failure", () => {
|
|
test("No TOR", () => {
|
|
// Remove TOR router
|
|
disconnectServers(Player.getHomeComputer(), GetServerOrThrow(SpecialServers.DarkWeb));
|
|
|
|
const ns = getNS();
|
|
expect(Player.hasTorRouter()).toStrictEqual(false);
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
expect(ns.singularity.purchaseProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
});
|
|
test("Invalid program name", () => {
|
|
const ns = getNS();
|
|
// @ts-expect-error - Intentionally use invalid program name
|
|
expect(ns.singularity.purchaseProgram("InvalidProgram.exe")).toStrictEqual(false);
|
|
});
|
|
test("Not enough money", () => {
|
|
const ns = getNS();
|
|
Player.money = 0;
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
expect(ns.singularity.purchaseProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
expect(Player.hasProgram(CompletedProgramName.bruteSsh)).toStrictEqual(false);
|
|
});
|
|
});
|
|
});
|