Files
OpenFrontIO/tests/client/TerritoryPatternsModal.test.ts
T
Ryan 3c0b5149b5 [Feature] Test a skin (#2857)
## Description:

It lets users test skins :)
<img width="847" height="734" alt="image"
src="https://github.com/user-attachments/assets/55ed112c-a401-417d-bc39-06deb7f4817e"
/>

They are added to Iceland Map no bots, no nations, max troops, max
speed, auto attack wilderness, win victory at 99%, and then the testing
complete modal appears with the skin they tested is present (rating
system not developed as OOS)

<img width="1165" height="703" alt="image"
src="https://github.com/user-attachments/assets/037add18-95b4-46cc-9627-3eabfb51c631"
/>

<img width="618" height="647" alt="image"
src="https://github.com/user-attachments/assets/8d1d6afe-8107-4472-a143-181eabaa67c6"
/>

Game does not save, the username of the player is the name of the skin,
the ID of the game is the name of the skin too.


## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

w.o.n

---------

Co-authored-by: Evan <evanpelle@gmail.com>
Co-authored-by: iamlewis <lewismmmm@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: VariableVince <24507472+VariableVince@users.noreply.github.com>
2026-05-26 23:31:07 +01:00

124 lines
3.6 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
// Keep translations deterministic in tests
vi.mock("../../src/client/Utils", () => ({
translateText: (k: string) => k,
getSvgAspectRatio: async () => 1,
}));
// Mock cosmetics fetch so we can deterministically render owned patterns.
const fetchCosmeticsMock = vi.fn();
const getPlayerCosmeticsMock = vi.fn();
const resolveCosmetics = vi.fn();
const resolvedToPlayerPatternMock = vi.fn();
vi.mock("../../src/client/Cosmetics", () => ({
fetchCosmetics: (...args: any[]) => fetchCosmeticsMock(...args),
getPlayerCosmetics: (...args: any[]) => getPlayerCosmeticsMock(...args),
resolveCosmetics: (...args: any[]) => resolveCosmetics(...args),
resolvedToPlayerPattern: (...args: any[]) =>
resolvedToPlayerPatternMock(...args),
purchaseCosmetic: vi.fn(),
}));
// Stub CosmeticButton to avoid canvas rendering in JSDOM.
vi.mock("../../src/client/components/CosmeticButton", () => {
if (!customElements.get("cosmetic-button")) {
customElements.define(
"cosmetic-button",
class extends HTMLElement {
connectedCallback() {
this.innerHTML = '<button data-testid="cosmetic-btn">mock</button>';
}
},
);
}
return {};
});
import { TerritoryPatternsModal } from "../../src/client/TerritoryPatternsModal";
const makeUserMe = () =>
({
user: { discord: { id: "d" } },
player: { publicId: "client123", flares: [] },
}) as any;
const makeOwnedPattern = () =>
({
type: "pattern",
cosmetic: { name: "owned_pattern", pattern: "AQID" },
colorPalette: null,
relationship: "owned",
key: "pattern:owned_pattern",
}) as any;
describe("TerritoryPatternsModal", () => {
let modal: TerritoryPatternsModal;
beforeEach(async () => {
if (typeof (globalThis as any).localStorage?.getItem !== "function") {
let store: Record<string, string> = {};
Object.defineProperty(globalThis, "localStorage", {
value: {
getItem: (k: string) => (k in store ? store[k] : null),
setItem: (k: string, v: string) => {
store[k] = String(v);
},
removeItem: (k: string) => {
delete store[k];
},
clear: () => {
store = {};
},
},
configurable: true,
});
}
if (!customElements.get("territory-patterns-modal")) {
customElements.define("territory-patterns-modal", TerritoryPatternsModal);
}
fetchCosmeticsMock.mockResolvedValue({
patterns: {},
colorPalettes: {},
});
getPlayerCosmeticsMock.mockResolvedValue({ pattern: null, color: null });
resolveCosmetics.mockReturnValue([makeOwnedPattern()]);
modal = document.createElement(
"territory-patterns-modal",
) as TerritoryPatternsModal;
modal.inline = true;
document.body.appendChild(modal);
await modal.updateComplete;
await modal.onUserMe(makeUserMe());
await modal.updateComplete;
});
afterEach(() => {
document.body.removeChild(modal);
vi.clearAllMocks();
});
it("renders owned patterns via cosmetic-button", async () => {
await modal.open();
await modal.updateComplete;
const buttons = modal.querySelectorAll("cosmetic-button");
expect(buttons.length).toBeGreaterThan(0);
});
it("shows the Store navigation button", async () => {
await modal.open();
await modal.updateComplete;
// The store button is rendered as an <o-button> custom element with translationKey="main.store"
const storeBtn = modal.querySelector(
'o-button[translationKey="main.store"]',
);
expect(storeBtn).toBeTruthy();
});
});