fix(settings): forward moved anchors on hash changes too, prove targets exist

A same-page link to a moved anchor changes only the hash, so the
arrival check never forwarded it; the shell now also listens for
hashchange. The legacy-routes guard walks the component tree of every
forward target's page and fails when the anchor it forwards to is not
rendered there.
This commit is contained in:
Marc-André Bombeck committed 2026-10-21 21:52:22 +02:00
1 parent b25ee09f7d
commit 709d28523c
3 files changed
+152 -3

No files matched your search

@@ -0,0 +1,37 @@
import { describe, expect, it, vi } from "vitest";
vi.mock("next/navigation", () => ({
usePathname: () => "/settings/privacy",
useRouter: () => ({ replace: vi.fn() }),
}));
import { watchAnchorForwards } from "../settings-anchor-forward";
function fakeWindow(hash: string) {
const target = new EventTarget();
return Object.assign(target, { location: { hash } });
}
describe("watchAnchorForwards", () => {
it("forwards a moved anchor on arrival", () => {
const replace = vi.fn();
watchAnchorForwards("/settings/privacy", replace, fakeWindow("#sessions"));
expect(replace).toHaveBeenCalledWith("/settings/security#sessions");
});
it("forwards when a same-page link changes only the hash", () => {
const replace = vi.fn();
const win = fakeWindow("#retention");
const stop = watchAnchorForwards("/settings/privacy", replace, win);
expect(replace).not.toHaveBeenCalled();
win.location.hash = "#trusted-devices";
win.dispatchEvent(new Event("hashchange"));
expect(replace).toHaveBeenCalledWith("/settings/security#trusted-devices");
stop();
win.location.hash = "#sessions";
win.dispatchEvent(new Event("hashchange"));
expect(replace).toHaveBeenCalledTimes(1);
});
});