Files
Portfolio/tests/unit/route-memory.test.ts

66 lines
2.5 KiB
TypeScript

import { mount } from "@vue/test-utils";
import { afterEach, describe, expect, it } from "vitest";
import { defineComponent, h, nextTick, ref } from "vue";
import type { SectionId } from "@/content/types";
import { useRouteMemory, type RouteMemory } from "@/composables/useRouteMemory";
const ids = ["start", "profile", "experience", "contact"] as unknown as readonly SectionId[];
const harness = (initial: SectionId) => {
const active = ref<SectionId>(initial);
let memory: RouteMemory | undefined;
const wrapper = mount(defineComponent({
setup() {
memory = useRouteMemory(ids, () => active.value);
return () => h("div");
},
}));
return { active, memory: memory!, wrapper };
};
afterEach(() => {
window.localStorage.clear();
window.location.hash = "";
});
describe("route memory", () => {
it("records passed exits and offers the last stop as a resume point", async () => {
const first = harness("start" as SectionId);
first.active.value = "profile" as SectionId;
await nextTick();
first.active.value = "experience" as SectionId;
await nextTick();
expect([...first.memory.visited.value]).toEqual(["start", "profile", "experience"]);
first.wrapper.unmount();
const second = harness("start" as SectionId);
await nextTick();
expect(second.memory.resumeFrom.value).toBe("experience");
expect(second.memory.visited.value.has("profile" as SectionId)).toBe(true);
// Idling at the on-ramp keeps the resume point for the next visit.
second.wrapper.unmount();
expect(harness("start" as SectionId).memory.resumeFrom.value).toBe("experience");
});
it("drops the offer once the visitor drives on and ignores corrupt storage", async () => {
window.localStorage.setItem("nightdrive:route", JSON.stringify({ visited: ["profile", "nowhere"], last: "profile" }));
const run = harness("start" as SectionId);
expect(run.memory.resumeFrom.value).toBe("profile");
expect([...run.memory.visited.value]).toEqual(["profile", "start"]);
run.active.value = "experience" as SectionId;
await nextTick();
expect(run.memory.resumeFrom.value).toBeNull();
window.localStorage.setItem("nightdrive:route", "{not json");
expect(harness("start" as SectionId).memory.resumeFrom.value).toBeNull();
});
it("logs the trip once the destination is reached", async () => {
const run = harness("start" as SectionId);
expect(run.memory.tripMinutes.value).toBeNull();
run.active.value = "contact" as SectionId;
await nextTick();
expect(run.memory.tripMinutes.value).toBe(1);
});
});