brackt/app/components/league/settings/__tests__/SettingsNavigation.test.tsx
Claude 1ff4082129
Give user settings sections their own URLs
Each section of the user settings page (Profile, Account, Notifications,
API Access, Data & Privacy) is now a real, linkable path
(/settings/profile, /settings/account, etc.) instead of local toggle
state, so sections can be bookmarked, shared, opened in a new tab, and
reached via the browser back/forward buttons.

- Route now matches an optional segment (settings/:section?), keeping the
  single route so the shared loader/action and form submissions are
  unchanged. An unknown section redirects back to /settings.
- The shared settings nav components render proper <Link>s when given a
  buildHref/backHref, and keep their button/onClick behaviour for the
  league settings page (which has unsaved-changes guards).
- The settings page derives the active section and mobile grid/section
  view from the URL param instead of useState.
- Notifications "Account settings" link and the Discord OAuth callback
  now point at /settings/account.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jt8Hhsio4bHGMaDZy7ftBs
2026-06-30 06:48:09 +00:00

67 lines
2.2 KiB
TypeScript

import { describe, it, expect, vi } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import { MemoryRouter } from "react-router";
import { Bell, User } from "lucide-react";
import {
SettingsDesktopNav,
SettingsMobileGridNav,
SettingsMobileSectionPill,
type SettingsGridSection,
} from "../SettingsNavigation";
const sections: readonly SettingsGridSection[] = [
{ id: "profile", label: "Profile", icon: User, subtitle: "Name, avatar" },
{ id: "notifications", label: "Notifications", icon: Bell, subtitle: "Email & Discord" },
];
describe("SettingsNavigation link mode", () => {
it("renders desktop nav entries as anchors built from buildHref", () => {
render(
<MemoryRouter>
<SettingsDesktopNav
sections={sections}
activeSection="profile"
buildHref={(id) => `/settings/${id}`}
/>
</MemoryRouter>
);
expect(screen.getByRole("link", { name: "Profile" })).toHaveAttribute("href", "/settings/profile");
expect(screen.getByRole("link", { name: "Notifications" })).toHaveAttribute(
"href",
"/settings/notifications"
);
expect(screen.getByRole("link", { name: "Profile" })).toHaveAttribute("aria-current", "page");
});
it("renders the mobile grid as anchors and the back pill as an anchor", () => {
render(
<MemoryRouter>
<SettingsMobileGridNav sections={sections} buildHref={(id) => `/settings/${id}`} />
<SettingsMobileSectionPill backHref="/settings" />
</MemoryRouter>
);
expect(screen.getByRole("link", { name: /Profile/i })).toHaveAttribute("href", "/settings/profile");
expect(screen.getByRole("link", { name: /back to all settings/i })).toHaveAttribute(
"href",
"/settings"
);
});
});
describe("SettingsNavigation button mode (league settings)", () => {
it("still fires onSectionChange when no buildHref is provided", () => {
const onSectionChange = vi.fn();
render(
<SettingsDesktopNav
sections={sections}
activeSection="profile"
onSectionChange={onSectionChange}
/>
);
fireEvent.click(screen.getByRole("button", { name: "Notifications" }));
expect(onSectionChange).toHaveBeenCalledWith("notifications");
});
});