deadhead-space-freight-tycoon/packages/content/test/onboarding.test.ts

90 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
content,
onboardingGoalSchema,
welcomeSchema,
onboardingGoals,
scriptedTutorialContractSchema,
scriptedTutorialContracts,
} from "../src/index";
describe("loaner ship", () => {
it("is not in the Market's purchasable list", () => {
const ids = content.purchasableShipModels.map((s) => s.id);
expect(ids).not.toContain("company-courier");
expect(ids).toEqual(["courier", "lighter", "clipper", "freighter", "bulk-hauler"]);
});
it("is faster with less overhead than the Courier", () => {
const loaner = content.shipModel("company-courier")!;
const courier = content.shipModel("courier")!;
expect(loaner.cruiseSpeedKmPerGameHour).toBeGreaterThan(courier.cruiseSpeedKmPerGameHour);
expect(loaner.overheadGameHours).toBeLessThan(courier.overheadGameHours);
});
});
describe("scripted tutorial contracts", () => {
it("validate and reference real cargo and a tutorial run before the deal", () => {
for (const scripted of scriptedTutorialContracts) {
expect(() => scriptedTutorialContractSchema.parse(scripted)).not.toThrow();
expect(content.cargoType(scripted.cargoTypeId)).toBeDefined();
expect(scripted.run).toBeLessThanOrEqual(content.config.tutorialRunsBeforeDeal);
}
});
it("include Unmarked crates on run 3 at double pay", () => {
expect(scriptedTutorialContracts).toContainEqual(
expect.objectContaining({
name: "Unmarked crates",
run: 3,
payMultiplier: 2,
cargoTypeId: "standard",
}),
);
});
});
describe("onboarding goals", () => {
it("validate, have unique ids and are in the specified order", () => {
for (const goal of onboardingGoals) {
expect(() => onboardingGoalSchema.parse(goal)).not.toThrow();
expect(content.onboardingGoal(goal.id)).toBe(goal);
}
expect(new Set(onboardingGoals.map((g) => g.id)).size).toBe(onboardingGoals.length);
expect(onboardingGoals.map((g) => g.condition.kind)).toEqual([
"own-ship-deliveries",
"skill-points-spent",
"market-ships-bought",
"priority-deliveries",
"locations-discovered",
"loan-paid-off",
]);
});
});
describe("welcome cards (Step 22.1, decision 0.5.131)", () => {
it("validates, with three cards and the tutorial employer's name in the last", () => {
expect(() => welcomeSchema.parse(content.welcome)).not.toThrow();
expect(content.welcome.cards.map((c) => c.title)).toEqual([
"Welcome to Deadhead",
"Your ships keep flying",
"First, earn your wings",
]);
expect(content.welcome.cards[2]!.body).toContain("{company}");
expect(content.tutorialCompanyName).toBe("Halvorsen Lunar Freight");
expect(content.welcome).toMatchObject({
next: "Next",
skip: "Skip",
start: "Let's fly",
close: "Close",
});
});
it("rejects empty text", () => {
expect(welcomeSchema.safeParse({ ...content.welcome, cards: [] }).success).toBe(false);
expect(
welcomeSchema.safeParse({ ...content.welcome, cards: [{ title: "", body: "x" }] }).success,
).toBe(false);
});
});