66 lines
2.5 KiB
TypeScript
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);
|
|
});
|
|
});
|