mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-04-27 14:20:47 +00:00
3ac06bffaa
Closes deferred phases 04 + 05 of loldle-new-modes plan. - loldle-ability: 5 guesses, DDragon ability icon as photo. State pins slot (P/Q/W/E/R) so the same icon shows every turn. Abilities pulled from DDragon per-champion — same source loldle.net uses at runtime. - loldle-splash: 4 guesses, random skin splash as photo. Skin pool scraped from loldle.net bundle (var Ad=[…] — 172 champs × 1939 skins, non-chroma, matches their splash mode exactly). URLs from Riot DDragon CDN (no version segment, stable across patches). - fetch-ddragon-data.js: extended to write all four JSONs in one run. Shares a single DDragon per-champion fetch cycle (concurrency 10). - Credits loldle.net + Riot Games in all loldle-family READMEs. 19 new tests (503 total). Lint clean. register:dry reports 12 loldle_* commands with no conflicts.
77 lines
2.4 KiB
JavaScript
77 lines
2.4 KiB
JavaScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { createStore } from "../../../src/db/create-store.js";
|
|
import {
|
|
handleGiveup,
|
|
handleSplash,
|
|
handleStats,
|
|
} from "../../../src/modules/loldle-splash/handlers.js";
|
|
import splashesData from "../../../src/modules/loldle-splash/splashes.json" with { type: "json" };
|
|
import { loadStats } from "../../../src/modules/loldle-splash/state.js";
|
|
import { makeFakeKv } from "../../fakes/fake-kv-namespace.js";
|
|
|
|
function pinRandom(value) {
|
|
vi.spyOn(Math, "random").mockReturnValue(value);
|
|
}
|
|
|
|
function makeCtx({ text = "", fromId = 1, chatType = "private", chatId = 1 } = {}) {
|
|
const replies = [];
|
|
const photos = [];
|
|
return {
|
|
replies,
|
|
photos,
|
|
ctx: {
|
|
from: { id: fromId },
|
|
chat: { id: chatId, type: chatType },
|
|
message: { text },
|
|
reply: async (body, opts) => {
|
|
replies.push({ body, opts });
|
|
},
|
|
replyWithPhoto: async (url, opts) => {
|
|
photos.push({ url, opts });
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("loldle-splash handlers — happy path", () => {
|
|
let db;
|
|
beforeEach(() => {
|
|
db = createStore("loldle-splash", { KV: makeFakeKv() });
|
|
pinRandom(0); // picks first champion + first skin
|
|
});
|
|
|
|
it("no-arg sends a splash photo with 0/4 caption", async () => {
|
|
const { ctx, photos } = makeCtx();
|
|
await handleSplash(ctx, db);
|
|
expect(photos).toHaveLength(1);
|
|
expect(photos[0].url).toMatch(
|
|
/^https:\/\/ddragon\.leagueoflegends\.com\/cdn\/img\/champion\/splash\//,
|
|
);
|
|
expect(photos[0].opts.caption).toMatch(/0\/4 guesses so far/);
|
|
});
|
|
|
|
it("correct guess wins and names the skin", async () => {
|
|
const target = splashesData[0];
|
|
const { ctx, replies } = makeCtx({ text: `/loldle_splash ${target.championName}` });
|
|
await handleSplash(ctx, db);
|
|
expect(replies[0].body).toContain("🎉 Got it!");
|
|
expect(replies[0].body).toContain("skin");
|
|
const s = await loadStats(db, 1);
|
|
expect(s).toMatchObject({ played: 1, wins: 1 });
|
|
});
|
|
|
|
it("giveup records loss and names skin", async () => {
|
|
await handleSplash(makeCtx().ctx, db);
|
|
const { ctx, replies } = makeCtx();
|
|
await handleGiveup(ctx, db);
|
|
expect(replies[0].body).toContain("🏳️");
|
|
expect(replies[0].body).toContain("skin");
|
|
});
|
|
|
|
it("stats renders zero-state", async () => {
|
|
const { ctx, replies } = makeCtx();
|
|
await handleStats(ctx, db);
|
|
expect(replies[0].body).toContain("Played: 0");
|
|
});
|
|
});
|