84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
import { afterEach, describe, expect, it } from "vitest";
|
|
import type { BoatProfile } from "@watermaps/shared";
|
|
import {
|
|
BOAT_PROFILE_COOKIE_NAME,
|
|
DEFAULT_BOAT_PROFILE,
|
|
readBoatProfileCookie,
|
|
serializeBoatProfileCookie,
|
|
toVesselProfile,
|
|
validateBoatProfile,
|
|
writeBoatProfileCookie
|
|
} from "../src/lib/boat-profile";
|
|
|
|
afterEach(() => {
|
|
document.cookie = `${BOAT_PROFILE_COOKIE_NAME}=; Path=/; Max-Age=0`;
|
|
});
|
|
|
|
describe("boat profile cookie", () => {
|
|
it("round-trips a validated Unicode profile", () => {
|
|
const profile: BoatProfile = {
|
|
...DEFAULT_BOAT_PROFILE,
|
|
name: "Möwe ⛵; 50%=gut",
|
|
category: "sailboat",
|
|
lengthM: 9.4,
|
|
airDraftM: 13.2
|
|
};
|
|
|
|
expect(writeBoatProfileCookie(profile)).toBe(true);
|
|
expect(readBoatProfileCookie()).toEqual(profile);
|
|
});
|
|
|
|
it("uses a versioned host cookie with safe attributes", () => {
|
|
const serialized = serializeBoatProfileCookie(DEFAULT_BOAT_PROFILE, {
|
|
secure: true,
|
|
updatedAt: "2026-07-26T12:00:00.000Z"
|
|
});
|
|
|
|
expect(serialized).toContain(`${BOAT_PROFILE_COOKIE_NAME}=`);
|
|
expect(serialized).toContain("Path=/");
|
|
expect(serialized).toContain("Max-Age=31536000");
|
|
expect(serialized).toContain("SameSite=Lax");
|
|
expect(serialized).toContain("Secure");
|
|
expect(serialized).not.toContain("Domain=");
|
|
});
|
|
|
|
it("rejects damaged, unknown-version and out-of-range data", () => {
|
|
expect(readBoatProfileCookie(`${BOAT_PROFILE_COOKIE_NAME}=%E0%A4%A`)).toBeNull();
|
|
expect(
|
|
readBoatProfileCookie(
|
|
`${BOAT_PROFILE_COOKIE_NAME}=${encodeURIComponent(JSON.stringify({
|
|
v: 2,
|
|
updatedAt: new Date().toISOString(),
|
|
profile: DEFAULT_BOAT_PROFILE
|
|
}))}`
|
|
)
|
|
).toBeNull();
|
|
expect(
|
|
validateBoatProfile({ ...DEFAULT_BOAT_PROFILE, draughtM: Number.NaN }).valid
|
|
).toBe(false);
|
|
expect(
|
|
validateBoatProfile({ ...DEFAULT_BOAT_PROFILE, airDraftM: 81 }).valid
|
|
).toBe(false);
|
|
});
|
|
|
|
it("maps only routing-relevant fields to the API profile", () => {
|
|
const vessel = toVesselProfile({
|
|
...DEFAULT_BOAT_PROFILE,
|
|
name: "Seestern",
|
|
category: "motorboat",
|
|
lengthM: 12
|
|
});
|
|
|
|
expect(vessel).toEqual({
|
|
draughtM: 1.4,
|
|
safetyReserveM: 0.5,
|
|
airDraftM: 2.5,
|
|
beamM: 3.2,
|
|
cruiseSpeedKn: 6
|
|
});
|
|
expect(vessel).not.toHaveProperty("name");
|
|
expect(vessel).not.toHaveProperty("category");
|
|
expect(vessel).not.toHaveProperty("lengthM");
|
|
});
|
|
});
|