fix: harden saved plan normalization
This commit is contained in:
@@ -12,11 +12,13 @@ import Layout from "../layouts/Layout.astro";
|
||||
const empty = document.querySelector<HTMLElement>("[data-plan-empty]");
|
||||
const count = document.querySelector<HTMLElement>("[data-plan-count]");
|
||||
const shareStatus = document.querySelector<HTMLElement>("[data-plan-share-status]");
|
||||
const planFieldLimits: Record<string, number> = { key: 512, waterbody: 160, coordinates: 80, baits: 1000, method: 120, retrieve: 160, risk: 160, freshness: 40, confidence: 8 };
|
||||
const planText = (key: string, value: unknown) => typeof value === "string" ? value.slice(0, planFieldLimits[key] ?? 240) : "";
|
||||
const normalisePlan = (value: unknown): Array<Record<string, string>> => {
|
||||
if (!Array.isArray(value)) return [];
|
||||
return value.filter(item => item && typeof item === "object" && typeof item.key === "string" && item.key.startsWith("/spots/")).slice(0, 5).map(item => {
|
||||
const source = item as Record<string, unknown>;
|
||||
return Object.fromEntries(["key", "waterbody", "coordinates", "baits", "method", "retrieve", "risk", "freshness", "confidence"].map(key => [key, typeof source[key] === "string" ? source[key] : ""]));
|
||||
return Object.fromEntries(["key", "waterbody", "coordinates", "baits", "method", "retrieve", "risk", "freshness", "confidence"].map(key => [key, planText(key, source[key])]));
|
||||
});
|
||||
};
|
||||
const readPlan = (): Array<Record<string, string>> => {
|
||||
@@ -37,7 +39,7 @@ import Layout from "../layouts/Layout.astro";
|
||||
const coordinate = document.createElement("strong"); coordinate.textContent = item.coordinates || "Координаты не указаны";
|
||||
const meta = document.createElement("p"); meta.textContent = item.baits ? `Наживка: ${item.baits.split("|").join(", ")}` : "Наживка не указана";
|
||||
const approach = document.createElement("p"); approach.textContent = [item.method, item.retrieve].filter(Boolean).join(" · ") || "Метод не указан";
|
||||
const facts = document.createElement("small"); facts.textContent = [item.risk ? `Риск: ${item.risk}` : "Риск не рассчитан", item.freshness ? "Свежесть сохранена" : "Свежесть не указана", item.confidence ? `Доверие: ${item.confidence}%` : "Доверие не рассчитано"].join(" · ");
|
||||
const facts = document.createElement("small"); facts.textContent = [item.risk ? `Риск: ${item.risk}` : "Риск не рассчитан", item.freshness ? "Свежесть сохранена" : "Свежесть не указана", item.confidence !== "" ? `Доверие: ${item.confidence}%` : "Доверие не рассчитано"].join(" · ");
|
||||
const link = document.createElement("a"); link.href = item.key || "/"; link.textContent = "Открыть точку";
|
||||
const remove = document.createElement("button"); remove.type = "button"; remove.dataset.action = "quiet"; remove.textContent = "Убрать"; remove.addEventListener("click", () => { localStorage.setItem(planStorageKey, JSON.stringify(readPlan().filter(entry => entry.key !== item.key))); render(); });
|
||||
const actions = document.createElement("div"); actions.className = "plan-card__actions"; actions.append(link, remove);
|
||||
|
||||
@@ -54,3 +54,25 @@ test("plan caps imported entries, stays printable and fits narrow viewports", as
|
||||
await expect(page.getByRole("button", { name: "Печать / PDF" })).toBeHidden();
|
||||
await expect(page.locator(".plan-card")).toHaveCount(5);
|
||||
});
|
||||
|
||||
test("plan preserves a real zero confidence and bounds imported text", async ({ page }) => {
|
||||
await page.goto("/plan");
|
||||
await page.evaluate(() => localStorage.setItem("rf4spotter:fishing-plan", JSON.stringify([{
|
||||
key: "/spots/" + "x".repeat(600),
|
||||
waterbody: "Вьюнок",
|
||||
coordinates: "6331:6332",
|
||||
baits: "Приманка",
|
||||
confidence: "0",
|
||||
risk: "Малая выборка",
|
||||
method: "Спиннинг",
|
||||
retrieve: "равномерная",
|
||||
oversized: "x".repeat(5000),
|
||||
}])));
|
||||
await page.reload();
|
||||
|
||||
await expect(page.getByText(/Доверие: 0%/)).toBeVisible();
|
||||
const stored = await page.evaluate(() => JSON.parse(localStorage.getItem("rf4spotter:fishing-plan") || "[]"));
|
||||
expect(stored[0].key.length).toBeLessThanOrEqual(512);
|
||||
expect(stored[0].confidence).toBe("0");
|
||||
expect(stored[0].oversized).toBeUndefined();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user