mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-16 06:18:42 +02:00
MISC: Make TIX access independent from WSE account (#2342)
This commit is contained in:
@@ -285,7 +285,9 @@ Place order for stocks.
|
||||
|
||||
</td><td>
|
||||
|
||||
Purchase 4S Market Data Access.
|
||||
Purchase 4S Market Data UI access (UI only).
|
||||
|
||||
You need to have a WSE account. Note that this feature only unlocks access to 4S Market Data in the Stock Market UI. If you want to access 4S Market Data via NS APIs, you have to unlock "4S Market Data TIX API access" via [purchase4SMarketDataTixApi](./bitburner.tix.purchase4smarketdatatixapi.md)<!-- -->, which is unrelated to this feature.
|
||||
|
||||
|
||||
</td></tr>
|
||||
@@ -296,7 +298,9 @@ Purchase 4S Market Data Access.
|
||||
|
||||
</td><td>
|
||||
|
||||
Purchase 4S Market Data TIX API Access.
|
||||
Purchase 4S Market Data TIX API access (NS APIs only).
|
||||
|
||||
You need to have TIX API access. Note that this feature only unlocks access to 4S Market Data via NS APIs.
|
||||
|
||||
|
||||
</td></tr>
|
||||
@@ -307,7 +311,9 @@ Purchase 4S Market Data TIX API Access.
|
||||
|
||||
</td><td>
|
||||
|
||||
Purchase TIX API Access
|
||||
Purchase TIX API access.
|
||||
|
||||
You need to have TIX API access to perform actions via NS APIs. Note that you can buy TIX API access without a WSE account.
|
||||
|
||||
|
||||
</td></tr>
|
||||
@@ -318,7 +324,9 @@ Purchase TIX API Access
|
||||
|
||||
</td><td>
|
||||
|
||||
Purchase WSE Account.
|
||||
Purchase a WSE account.
|
||||
|
||||
You need to have this account to perform actions via the Stock Market UI. Note that if you want to perform actions via NS APIs, you need to have TIX API access, not this account.
|
||||
|
||||
|
||||
</td></tr>
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
## TIX.purchase4SMarketData() method
|
||||
|
||||
Purchase 4S Market Data Access.
|
||||
Purchase 4S Market Data UI access (UI only).
|
||||
|
||||
You need to have a WSE account. Note that this feature only unlocks access to 4S Market Data in the Stock Market UI. If you want to access 4S Market Data via NS APIs, you have to unlock "4S Market Data TIX API access" via [purchase4SMarketDataTixApi](./bitburner.tix.purchase4smarketdatatixapi.md)<!-- -->, which is unrelated to this feature.
|
||||
|
||||
**Signature:**
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
## TIX.purchase4SMarketDataTixApi() method
|
||||
|
||||
Purchase 4S Market Data TIX API Access.
|
||||
Purchase 4S Market Data TIX API access (NS APIs only).
|
||||
|
||||
You need to have TIX API access. Note that this feature only unlocks access to 4S Market Data via NS APIs.
|
||||
|
||||
**Signature:**
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
## TIX.purchaseTixApi() method
|
||||
|
||||
Purchase TIX API Access
|
||||
Purchase TIX API access.
|
||||
|
||||
You need to have TIX API access to perform actions via NS APIs. Note that you can buy TIX API access without a WSE account.
|
||||
|
||||
**Signature:**
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
## TIX.purchaseWseAccount() method
|
||||
|
||||
Purchase WSE Account.
|
||||
Purchase a WSE account.
|
||||
|
||||
You need to have this account to perform actions via the Stock Market UI. Note that if you want to perform actions via NS APIs, you need to have TIX API access, not this account.
|
||||
|
||||
**Signature:**
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import { EntropyDev } from "./DevMenu/ui/EntropyDev";
|
||||
import { Exploit } from "./Exploits/Exploit";
|
||||
import { useRerender } from "./ui/React/hooks";
|
||||
import { AutoExpandContext, getAutoExpandData, setAutoExpandData } from "./ui/AutoExpand/AutoExpandContext";
|
||||
import { canAccessStockMarket } from "./StockMarket/StockMarket";
|
||||
|
||||
export function DevMenuRoot(): React.ReactElement {
|
||||
const autoExpandContextValue = useRef({
|
||||
@@ -65,7 +66,7 @@ export function DevMenuRoot(): React.ReactElement {
|
||||
|
||||
<CodingContractsDev />
|
||||
|
||||
{Player.hasWseAccount && <StockMarketDev />}
|
||||
{canAccessStockMarket() && <StockMarketDev />}
|
||||
|
||||
{Player.sleeves.length > 0 && <SleevesDev />}
|
||||
{Player.augmentations.some((aug) => aug.name === AugmentationName.StaneksGift1) && <StanekDev />}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
cancelOrder,
|
||||
initStockMarket,
|
||||
StockMarketPromise,
|
||||
isStockMarketInitialized,
|
||||
} from "../StockMarket/StockMarket";
|
||||
import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/StockMarketHelpers";
|
||||
import { StockSymbol } from "@enums";
|
||||
@@ -26,9 +27,6 @@ import { getEnumHelper } from "../utils/EnumHelper";
|
||||
export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
/** Checks if the player has TIX API access. Throws an error if the player does not */
|
||||
const checkTixApiAccess = function (ctx: NetscriptContext): void {
|
||||
if (!Player.hasWseAccount) {
|
||||
throw helpers.errorMessage(ctx, `You don't have WSE Access! Cannot use ${ctx.function}()`);
|
||||
}
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw helpers.errorMessage(ctx, `You don't have TIX API Access! Cannot use ${ctx.function}()`);
|
||||
}
|
||||
@@ -256,6 +254,11 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Player.hasWseAccount) {
|
||||
helpers.log(ctx, () => "You need to have a WSE account.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player.money < getStockMarket4SDataCost()) {
|
||||
helpers.log(ctx, () => "Not enough money to purchase 4S Market Data.");
|
||||
return false;
|
||||
@@ -301,7 +304,9 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
}
|
||||
|
||||
Player.hasWseAccount = true;
|
||||
initStockMarket();
|
||||
if (!isStockMarketInitialized()) {
|
||||
initStockMarket();
|
||||
}
|
||||
Player.loseMoney(getStockMarketWseCost(), "stock");
|
||||
helpers.log(ctx, () => "Purchased WSE Account Access");
|
||||
return true;
|
||||
@@ -318,6 +323,9 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
}
|
||||
|
||||
Player.hasTixApiAccess = true;
|
||||
if (!isStockMarketInitialized()) {
|
||||
initStockMarket();
|
||||
}
|
||||
Player.loseMoney(getStockMarketTixApiCost(), "stock");
|
||||
helpers.log(ctx, () => "Purchased TIX API");
|
||||
return true;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { resetPidCounter } from "./Netscript/Pid";
|
||||
import { GetServer, AddToAllServers, initForeignServers, prestigeAllServers } from "./Server/AllServers";
|
||||
import { prestigeHomeComputer } from "./Server/ServerHelpers";
|
||||
import { SpecialServers } from "./Server/data/SpecialServers";
|
||||
import { deleteStockMarket, initStockMarket } from "./StockMarket/StockMarket";
|
||||
import { canAccessStockMarket, deleteStockMarket, initStockMarket } from "./StockMarket/StockMarket";
|
||||
import { Terminal } from "./Terminal";
|
||||
|
||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
||||
@@ -161,7 +161,7 @@ export function prestigeAugmentation(): void {
|
||||
}
|
||||
|
||||
// Reset Stock market
|
||||
if (Player.hasWseAccount) {
|
||||
if (canAccessStockMarket()) {
|
||||
initStockMarket();
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ export function prestigeSourceFile(isFlume: boolean): void {
|
||||
if (Player.bitNodeN === 8) {
|
||||
Player.money = BitNode8StartingMoney;
|
||||
}
|
||||
if (Player.bitNodeN === 8 || Player.activeSourceFileLvl(8) > 0) {
|
||||
if (canAccessBitNodeFeature(8)) {
|
||||
Player.hasWseAccount = true;
|
||||
Player.hasTixApiAccess = true;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ export function prestigeSourceFile(isFlume: boolean): void {
|
||||
}
|
||||
|
||||
// Reset Stock market, gang, and corporation
|
||||
if (Player.hasWseAccount) {
|
||||
if (canAccessStockMarket()) {
|
||||
initStockMarket();
|
||||
} else {
|
||||
deleteStockMarket();
|
||||
|
||||
24
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
24
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@@ -1635,28 +1635,44 @@ export interface TIX {
|
||||
getForecast(sym: string): number;
|
||||
|
||||
/**
|
||||
* Purchase 4S Market Data Access.
|
||||
* Purchase 4S Market Data UI access (UI only).
|
||||
*
|
||||
* You need to have a WSE account. Note that this feature only unlocks access to 4S Market Data in the Stock Market
|
||||
* UI. If you want to access 4S Market Data via NS APIs, you have to unlock "4S Market Data TIX API access" via
|
||||
* {@link TIX.purchase4SMarketDataTixApi | purchase4SMarketDataTixApi}, which is unrelated to this feature.
|
||||
*
|
||||
* @remarks RAM cost: 2.5 GB
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
purchase4SMarketData(): boolean;
|
||||
|
||||
/**
|
||||
* Purchase 4S Market Data TIX API Access.
|
||||
* Purchase 4S Market Data TIX API access (NS APIs only).
|
||||
*
|
||||
* You need to have TIX API access. Note that this feature only unlocks access to 4S Market Data via NS APIs.
|
||||
*
|
||||
* @remarks RAM cost: 2.5 GB
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
purchase4SMarketDataTixApi(): boolean;
|
||||
|
||||
/**
|
||||
* Purchase WSE Account.
|
||||
* Purchase a WSE account.
|
||||
*
|
||||
* You need to have this account to perform actions via the Stock Market UI. Note that if you want to perform actions
|
||||
* via NS APIs, you need to have TIX API access, not this account.
|
||||
*
|
||||
* @remarks RAM cost: 2.5 GB
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
purchaseWseAccount(): boolean;
|
||||
|
||||
/**
|
||||
* Purchase TIX API Access
|
||||
* Purchase TIX API access.
|
||||
*
|
||||
* You need to have TIX API access to perform actions via NS APIs. Note that you can buy TIX API access without a WSE
|
||||
* account.
|
||||
*
|
||||
* @remarks RAM cost: 2.5 GB
|
||||
* @returns True if you successfully purchased it or if you already have access, false otherwise.
|
||||
*/
|
||||
|
||||
@@ -150,7 +150,7 @@ export function loadStockMarket(saveString: string): void {
|
||||
console.error(error);
|
||||
console.error("Invalid StockMarketSave:", saveString);
|
||||
deleteStockMarket();
|
||||
if (Player.hasWseAccount) {
|
||||
if (canAccessStockMarket()) {
|
||||
initStockMarket();
|
||||
}
|
||||
const errorMessage = `Cannot load data of StockMarket. StockMarket is reset.`;
|
||||
@@ -163,6 +163,18 @@ export function loadStockMarket(saveString: string): void {
|
||||
StockMarket = stockMarketData as IStockMarket;
|
||||
}
|
||||
|
||||
export function canAccessStockMarket(): boolean {
|
||||
return Player.hasWseAccount || Player.hasTixApiAccess;
|
||||
}
|
||||
|
||||
export function isStockMarketInitialized(): boolean {
|
||||
return StockMarket.lastUpdate > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* After calling this function, the stock market will be back to the uninitialized state (i.e.,
|
||||
* isStockMarketInitialized() returns false).
|
||||
*/
|
||||
export function deleteStockMarket(): void {
|
||||
StockMarket = getDefaultEmptyStockMarket();
|
||||
}
|
||||
@@ -187,7 +199,7 @@ export function initStockMarket(): void {
|
||||
StockMarket.Orders = orders;
|
||||
|
||||
StockMarket.storedCycles = 0;
|
||||
StockMarket.lastUpdate = 0;
|
||||
StockMarket.lastUpdate = Date.now();
|
||||
StockMarket.ticksUntilCycle = getRandomIntInclusive(1, StockMarketConstants.TicksPerCycle);
|
||||
initSymbolToStockMap();
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import { getStockMarket4SDataCost, getStockMarket4STixApiCost } from "../StockMa
|
||||
import { StockMarketConstants } from "../data/Constants";
|
||||
import { Player } from "@player";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { initStockMarket } from "../StockMarket";
|
||||
import { initStockMarket, isStockMarketInitialized } from "../StockMarket";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
@@ -47,7 +47,7 @@ function Purchase4SMarketDataTixApiAccessButton(props: IProps): React.ReactEleme
|
||||
if (Player.has4SDataTixApi) {
|
||||
return (
|
||||
<Typography>
|
||||
Market Data TIX API Access <CheckIcon />
|
||||
4S Market Data TIX API Access <CheckIcon />
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
@@ -91,19 +91,21 @@ function PurchaseWseAccountButton(props: IProps): React.ReactElement {
|
||||
return;
|
||||
}
|
||||
Player.hasWseAccount = true;
|
||||
initStockMarket();
|
||||
if (!isStockMarketInitialized()) {
|
||||
initStockMarket();
|
||||
}
|
||||
Player.loseMoney(StockMarketConstants.WseAccountCost, "stock");
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
const cost = StockMarketConstants.WseAccountCost;
|
||||
let tooltipTitle = "Let you trade stock";
|
||||
let tooltipTitle = "Let you trade stock via UI";
|
||||
if (!Player.canAfford(cost)) {
|
||||
tooltipTitle = "You do not have enough money";
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Typography>To begin trading, you must first purchase an account:</Typography>
|
||||
<Typography>If you want to trade via Stock Market dashboard (UI), you must purchase a WSE account.</Typography>
|
||||
<Tooltip title={<Typography>{tooltipTitle}</Typography>}>
|
||||
<span>
|
||||
<Button disabled={!Player.canAfford(cost)} onClick={purchaseWseAccount}>
|
||||
@@ -121,13 +123,13 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
|
||||
if (Player.hasTixApiAccess) {
|
||||
return;
|
||||
}
|
||||
if (!Player.hasWseAccount) {
|
||||
return;
|
||||
}
|
||||
if (!Player.canAfford(StockMarketConstants.TixApiCost)) {
|
||||
return;
|
||||
}
|
||||
Player.hasTixApiAccess = true;
|
||||
if (!isStockMarketInitialized()) {
|
||||
initStockMarket();
|
||||
}
|
||||
Player.loseMoney(StockMarketConstants.TixApiCost, "stock");
|
||||
props.rerender();
|
||||
}
|
||||
@@ -140,21 +142,26 @@ function PurchaseTixApiAccessButton(props: IProps): React.ReactElement {
|
||||
);
|
||||
}
|
||||
const cost = StockMarketConstants.TixApiCost;
|
||||
let tooltipTitle = "Let you trade stock through Netscript";
|
||||
if (!Player.hasWseAccount) {
|
||||
tooltipTitle = "Requires WSE Account";
|
||||
} else if (!Player.canAfford(cost)) {
|
||||
let tooltipTitle = "Let you trade stock via NS APIs";
|
||||
if (!Player.canAfford(cost)) {
|
||||
tooltipTitle = "You do not have enough money";
|
||||
}
|
||||
return (
|
||||
<Tooltip title={<Typography>{tooltipTitle}</Typography>}>
|
||||
<span>
|
||||
<Button disabled={!Player.hasWseAccount || !Player.canAfford(cost)} onClick={purchaseTixApiAccess}>
|
||||
Buy Trade Information eXchange (TIX) API Access -
|
||||
<Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<>
|
||||
<Typography>
|
||||
TIX, short for Trade Information eXchange, is the communications protocol used by the WSE. Purchasing access to
|
||||
the TIX API lets you write code to create your own algorithmic/automated trading strategies.
|
||||
</Typography>
|
||||
<Typography>If you want to trade via NS APIs, you must purchase TIX API access.</Typography>
|
||||
<Tooltip title={<Typography>{tooltipTitle}</Typography>}>
|
||||
<span>
|
||||
<Button disabled={!Player.canAfford(cost)} onClick={purchaseTixApiAccess}>
|
||||
Buy Trade Information eXchange (TIX) API Access -
|
||||
<Money money={cost} forPurchase={true} />
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -179,7 +186,7 @@ function Purchase4SMarketDataButton(props: IProps): React.ReactElement {
|
||||
if (Player.has4SData) {
|
||||
return (
|
||||
<Typography>
|
||||
4S Market Data Access <CheckIcon />
|
||||
4S Market Data UI Access <CheckIcon />
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
@@ -213,16 +220,16 @@ export function InfoAndPurchases(props: IProps): React.ReactElement {
|
||||
<>
|
||||
<Typography variant="h4">Welcome to the World Stock Exchange (WSE)!</Typography>
|
||||
|
||||
<Typography variant="h5" color="primary">
|
||||
WSE Account
|
||||
</Typography>
|
||||
<PurchaseWseAccountButton {...props} />
|
||||
|
||||
<Typography variant="h5" color="primary">
|
||||
Trade Information eXchange (TIX) API
|
||||
</Typography>
|
||||
<Typography>
|
||||
TIX, short for Trade Information eXchange, is the communications protocol used by the WSE. Purchasing access to
|
||||
the TIX API lets you write code to create your own algorithmic/automated trading strategies.
|
||||
</Typography>
|
||||
<PurchaseTixApiAccessButton {...props} />
|
||||
|
||||
<Typography variant="h5" color="primary">
|
||||
{FactionName.FourSigma} (4S) Market Data Feed
|
||||
</Typography>
|
||||
@@ -235,6 +242,7 @@ export function InfoAndPurchases(props: IProps): React.ReactElement {
|
||||
</Typography>
|
||||
<Purchase4SMarketDataTixApiAccessButton {...props} />
|
||||
<Purchase4SMarketDataButton {...props} />
|
||||
|
||||
<Typography>
|
||||
Commission Fees: Every transaction you make has a{" "}
|
||||
<Money money={StockMarketConstants.StockMarketCommission} forPurchase={true} /> commission fee.
|
||||
|
||||
@@ -25,7 +25,7 @@ import { saveObject, loadGame } from "./SaveObject";
|
||||
import { GetAllServers, initForeignServers } from "./Server/AllServers";
|
||||
import { Settings } from "./Settings/Settings";
|
||||
import { FormatsNeedToChange } from "./ui/formatNumber";
|
||||
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
|
||||
import { canAccessStockMarket, initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
|
||||
import { Terminal } from "./Terminal";
|
||||
|
||||
import { Money } from "./ui/React/Money";
|
||||
@@ -92,7 +92,7 @@ const Engine = {
|
||||
Player.processWork(numCycles);
|
||||
|
||||
// Update stock prices
|
||||
if (Player.hasWseAccount) {
|
||||
if (canAccessStockMarket()) {
|
||||
processStockPrices(numCycles);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ const Engine = {
|
||||
if (await loadGame(saveData)) {
|
||||
FormatsNeedToChange.emit();
|
||||
initBitNodeMultipliers();
|
||||
if (Player.hasWseAccount) {
|
||||
if (canAccessStockMarket()) {
|
||||
initSymbolToStockMap();
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ const Engine = {
|
||||
processPassiveFactionRepGain(numCyclesOffline);
|
||||
|
||||
// Stock Market offline progress
|
||||
if (Player.hasWseAccount) {
|
||||
if (canAccessStockMarket()) {
|
||||
processStockPrices(numCyclesOffline);
|
||||
}
|
||||
|
||||
|
||||
@@ -384,5 +384,12 @@ export const breakingChanges300: VersionBreakingChange = {
|
||||
`- "White Ferrari" was renamed to "${convertV2GangEquipmentNames("White Ferrari")}".\n`,
|
||||
showWarning: false,
|
||||
},
|
||||
{
|
||||
brokenAPIs: [{ name: "purchase4SMarketData" }],
|
||||
info:
|
||||
"You have to purchase a WSE account before purchasing 4S Market Data UI access via ns.stock.purchase4SMarketData().\n" +
|
||||
"Note that this change does not affect 4S Market Data TIX API access (ns.stock.purchase4SMarketDataTixApi()).",
|
||||
showWarning: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -29,8 +29,7 @@ import { installAugmentations } from "../../../src/Augmentation/AugmentationHelp
|
||||
import { AddToAllServers } from "../../../src/Server/AllServers";
|
||||
import { Server } from "../../../src/Server/Server";
|
||||
import { initSourceFiles } from "../../../src/SourceFile/SourceFiles";
|
||||
import type { NetscriptContext } from "../../../src/Netscript/APIWrapper";
|
||||
import type { WorkerScript } from "../../../src/Netscript/WorkerScript";
|
||||
import { getMockedNetscriptContext } from "../Utilities";
|
||||
|
||||
jest.mock("../../../src/Faction/Factions", () => ({
|
||||
Factions: {},
|
||||
@@ -43,18 +42,9 @@ jest.mock("../../../src/ui/GameRoot", () => ({
|
||||
},
|
||||
}));
|
||||
const mockLogger: (s: string) => void = jest.fn();
|
||||
const mockCtx: NetscriptContext = {
|
||||
function: "",
|
||||
functionPath: "",
|
||||
workerScript: {
|
||||
log: (_: string, text: () => string) => {
|
||||
mockLogger(text());
|
||||
},
|
||||
scriptRef: {
|
||||
dependencies: [],
|
||||
},
|
||||
} as unknown as WorkerScript,
|
||||
};
|
||||
const mockCtx = getMockedNetscriptContext((_: string, txt: () => string) => {
|
||||
mockLogger(txt());
|
||||
});
|
||||
|
||||
setPlayer(new PlayerObject());
|
||||
AddToAllServers(new Server({ hostname: "home" }));
|
||||
|
||||
133
test/jest/Netscript/StockMarket.test.ts
Normal file
133
test/jest/Netscript/StockMarket.test.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
import { Player } from "@player";
|
||||
import { getMockedNetscriptContext, getNS, initGameEnvironment, setupBasicTestingEnvironment } from "../Utilities";
|
||||
import { deleteStockMarket, getDefaultEmptyStockMarket, StockMarket } from "../../../src/StockMarket/StockMarket";
|
||||
import { Stock } from "../../../src/StockMarket/Stock";
|
||||
import { buyStock } from "../../../src/StockMarket/BuyingAndSelling";
|
||||
|
||||
function expectUninitializedStockMarket(): void {
|
||||
expect(StockMarket).toStrictEqual(getDefaultEmptyStockMarket());
|
||||
}
|
||||
|
||||
function expectInitializedStockMarket(): void {
|
||||
const symbols = Object.keys(StockMarket.Orders);
|
||||
expect(symbols.length).toBeGreaterThan(0);
|
||||
expect(symbols.includes("ECP")).toStrictEqual(true);
|
||||
expect(StockMarket["ECorp"] instanceof Stock).toStrictEqual(true);
|
||||
expect(StockMarket.lastUpdate).toBeGreaterThan(0);
|
||||
}
|
||||
|
||||
function buyShareOfECP(): void {
|
||||
const eCorpStock = StockMarket["ECorp"];
|
||||
expect(eCorpStock.playerShares).toStrictEqual(0);
|
||||
expect(buyStock(eCorpStock, 1, getMockedNetscriptContext(), {})).toStrictEqual(true);
|
||||
expect(eCorpStock.playerShares).toStrictEqual(1);
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
initGameEnvironment();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
setupBasicTestingEnvironment();
|
||||
Player.money = 1e100;
|
||||
|
||||
deleteStockMarket();
|
||||
expectUninitializedStockMarket();
|
||||
});
|
||||
|
||||
describe("WSE account and TIX API access", () => {
|
||||
test("purchaseWseAccount then purchaseTixApi", () => {
|
||||
const ns = getNS();
|
||||
|
||||
// Check if purchaseWseAccount works
|
||||
expect(Player.hasWseAccount).toStrictEqual(false);
|
||||
expect(ns.stock.purchaseWseAccount()).toStrictEqual(true);
|
||||
expect(Player.hasWseAccount).toStrictEqual(true);
|
||||
expectInitializedStockMarket();
|
||||
|
||||
buyShareOfECP();
|
||||
|
||||
// Check if purchaseTixApi works
|
||||
expect(Player.hasTixApiAccess).toStrictEqual(false);
|
||||
expect(ns.stock.purchaseTixApi()).toStrictEqual(true);
|
||||
expect(Player.hasTixApiAccess).toStrictEqual(true);
|
||||
|
||||
// Check if stock market data is reset
|
||||
expect(StockMarket["ECorp"].playerShares).toStrictEqual(1);
|
||||
});
|
||||
|
||||
test("purchaseTixApi then purchaseWseAccount", () => {
|
||||
const ns = getNS();
|
||||
|
||||
// Check if purchaseTixApi works
|
||||
expect(Player.hasTixApiAccess).toStrictEqual(false);
|
||||
expect(ns.stock.purchaseTixApi()).toStrictEqual(true);
|
||||
expect(Player.hasTixApiAccess).toStrictEqual(true);
|
||||
expectInitializedStockMarket();
|
||||
|
||||
buyShareOfECP();
|
||||
|
||||
// Check if purchaseWseAccount works
|
||||
expect(Player.hasWseAccount).toStrictEqual(false);
|
||||
expect(ns.stock.purchaseWseAccount()).toStrictEqual(true);
|
||||
expect(Player.hasWseAccount).toStrictEqual(true);
|
||||
|
||||
// Check if stock market data is reset
|
||||
expect(StockMarket["ECorp"].playerShares).toStrictEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("4S Market Data", () => {
|
||||
test("purchase4SMarketData", () => {
|
||||
const ns = getNS();
|
||||
expect(ns.stock.purchase4SMarketData()).toStrictEqual(false);
|
||||
ns.stock.purchaseWseAccount();
|
||||
expect(ns.stock.purchase4SMarketData()).toStrictEqual(true);
|
||||
expect(Player.has4SData).toStrictEqual(true);
|
||||
});
|
||||
test("purchase4SMarketDataTixApi", () => {
|
||||
const ns = getNS();
|
||||
expect(() => ns.stock.purchase4SMarketDataTixApi()).toThrow("You don't have TIX API Access");
|
||||
ns.stock.purchaseTixApi();
|
||||
expect(ns.stock.purchase4SMarketDataTixApi()).toStrictEqual(true);
|
||||
expect(Player.has4SDataTixApi).toStrictEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Prestige", () => {
|
||||
test("soft reset without initializing stock market", () => {
|
||||
const ns = getNS();
|
||||
ns.singularity.softReset();
|
||||
expectUninitializedStockMarket();
|
||||
});
|
||||
test("soft reset after initializing stock market", () => {
|
||||
const ns = getNS();
|
||||
ns.stock.purchaseTixApi();
|
||||
expectInitializedStockMarket();
|
||||
buyShareOfECP();
|
||||
expect(StockMarket["ECorp"].playerShares).toStrictEqual(1);
|
||||
|
||||
ns.singularity.softReset();
|
||||
expect(StockMarket["ECorp"].playerShares).toStrictEqual(0);
|
||||
});
|
||||
test("b1tflum3", () => {
|
||||
const ns = getNS();
|
||||
ns.stock.purchaseTixApi();
|
||||
expectInitializedStockMarket();
|
||||
buyShareOfECP();
|
||||
|
||||
ns.singularity.b1tflum3(1);
|
||||
expectUninitializedStockMarket();
|
||||
});
|
||||
test("b1tflum3 with SF8", () => {
|
||||
const ns = getNS();
|
||||
ns.stock.purchaseTixApi();
|
||||
expectInitializedStockMarket();
|
||||
buyShareOfECP();
|
||||
|
||||
Player.sourceFiles.set(8, 1);
|
||||
ns.singularity.b1tflum3(1);
|
||||
expectInitializedStockMarket();
|
||||
expect(StockMarket["ECorp"].playerShares).toStrictEqual(0);
|
||||
});
|
||||
});
|
||||
@@ -382,6 +382,7 @@ describe("Stock Market Tests", function () {
|
||||
const stocks: string[] = [];
|
||||
|
||||
beforeEach(function () {
|
||||
expect(deleteStockMarket).not.toThrow();
|
||||
expect(initStockMarket).not.toThrow();
|
||||
expect(initSymbolToStockMap).not.toThrow();
|
||||
});
|
||||
@@ -413,7 +414,7 @@ describe("Stock Market Tests", function () {
|
||||
expect(StockMarket).toHaveProperty("storedCycles");
|
||||
expect(StockMarket["storedCycles"]).toEqual(0);
|
||||
expect(StockMarket).toHaveProperty("lastUpdate");
|
||||
expect(StockMarket["lastUpdate"]).toEqual(0);
|
||||
expect(StockMarket["lastUpdate"]).toBeGreaterThan(0);
|
||||
expect(StockMarket).toHaveProperty("ticksUntilCycle");
|
||||
expect(typeof StockMarket["ticksUntilCycle"]).toBe("number");
|
||||
});
|
||||
@@ -1069,6 +1070,7 @@ describe("Stock Market Tests", function () {
|
||||
|
||||
describe("Order Placing & Processing", function () {
|
||||
beforeEach(function () {
|
||||
expect(deleteStockMarket).not.toThrow();
|
||||
expect(initStockMarket).not.toThrow();
|
||||
expect(initSymbolToStockMap).not.toThrow();
|
||||
|
||||
@@ -1155,6 +1157,7 @@ describe("Stock Market Tests", function () {
|
||||
let processOrdersRefs: IProcessOrderRefs;
|
||||
|
||||
beforeEach(function () {
|
||||
expect(deleteStockMarket).not.toThrow();
|
||||
expect(initStockMarket).not.toThrow();
|
||||
expect(initSymbolToStockMap).not.toThrow();
|
||||
|
||||
@@ -1289,6 +1292,7 @@ describe("Stock Market Tests", function () {
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
expect(deleteStockMarket).not.toThrow();
|
||||
expect(initStockMarket).not.toThrow();
|
||||
expect(initSymbolToStockMap).not.toThrow();
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { initSourceFiles } from "../../src/SourceFile/SourceFiles";
|
||||
import { FormatsNeedToChange } from "../../src/ui/formatNumber";
|
||||
import { Router } from "../../src/ui/GameRoot";
|
||||
import { config } from "../../src/NetscriptJSEvaluator";
|
||||
import type { NetscriptContext } from "../../src/Netscript/APIWrapper";
|
||||
|
||||
declare const importActual: (typeof config)["doImport"];
|
||||
|
||||
@@ -71,3 +72,18 @@ export function getNS(): NSFull {
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
|
||||
export function getMockedNetscriptContext(
|
||||
workerScriptLogFunction: (func: string, txt: () => string) => void = () => {},
|
||||
): NetscriptContext {
|
||||
return {
|
||||
function: "",
|
||||
functionPath: "",
|
||||
workerScript: {
|
||||
log: workerScriptLogFunction,
|
||||
scriptRef: {
|
||||
dependencies: [],
|
||||
},
|
||||
} as unknown as WorkerScript,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user