diff --git a/app/library/language-switcher/LanguageSwitcher.tsx b/app/library/language-switcher/LanguageSwitcher.tsx index 85294f7dd..3602fba9b 100644 --- a/app/library/language-switcher/LanguageSwitcher.tsx +++ b/app/library/language-switcher/LanguageSwitcher.tsx @@ -6,7 +6,6 @@ import { Link } from "../link" const LanguageSwitcher = () => { const { i18n } = useTranslation() const location = useLocation() - const to = location.pathname return (
+ {url.pathname} + {url.search} +
+ + go + + > + ) + }, + }, + { + path: "/second", + Component: () => { + const url = useLocation() + return ( + <> ++ {url.pathname} + {url.search} +
+ go + > + ) + }, + }, +] +describe("Link", () => { + it("if the url is /first and you redirect to /second nothing is added to the url", async ({ renderStub }) => { + const { getByText } = await renderStub({ + entries: getEntries(), + props: { + initialEntries: ["/first"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + expect(url).toBeDefined() + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second") + }) + }) + + it("if the url is /first?a=1 and you redirect to /second without keepSearchParams nothing is added to the url", async ({ + renderStub, + }) => { + const { getByText } = await renderStub({ + entries: getEntries(), + props: { + initialEntries: ["/first?a=1"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second") + }) + }) + + it("if the url is /first?a=1 and you redirect to /second with keepSearchParams search params are kept", async ({ + renderStub, + }) => { + const { getByText } = await renderStub({ + entries: getEntries({ keepSearchParams: true, to: "/second" }), + props: { + initialEntries: ["/first?a=1"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second?a=1") + }) + }) + + it("if the url is /first?a=1&lng=en and you redirect to /second with keepSearchParams search params and language are kept", async ({ + renderStub, + }) => { + const { getByText } = await renderStub({ + entries: getEntries({ keepSearchParams: true, to: "/second" }), + props: { + initialEntries: ["/first?a=1&lng=en"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second?a=1&lng=en") + }) + }) + + it("if the url is /first?a=1&lng=en and you redirect to /second without keepSearchParams language is kept", async ({ + renderStub, + }) => { + const { getByText } = await renderStub({ + entries: getEntries({ to: "/second" }), + props: { + initialEntries: ["/first?lng=en"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second?lng=en") + }) + }) + + it("if the url is /first?a=1&lng=en and you redirect to /second with a language override it is changed and search params are removed", async ({ + renderStub, + }) => { + const { getByText } = await renderStub({ + entries: getEntries({ to: "/second", language: "bs" }), + props: { + initialEntries: ["/first?lng=en"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second?lng=bs") + }) + }) + + it("if the url is /first?a=1&lng=en and you redirect to /second with a language override it is changed and search params are kept with keepSearchParams", async ({ + renderStub, + }) => { + const { getByText } = await renderStub({ + entries: getEntries({ to: "/second", language: "bs", keepSearchParams: true }), + props: { + initialEntries: ["/first?a=a&lng=en"], + }, + }) + const link = getByText("go") + await userEvent.click(link) + const url = getByText("/second") + await waitFor(() => { + expect(url.element()).toBeDefined() + expect(url.element()).toHaveTextContent("/second?a=a&lng=bs") + }) + }) +}) diff --git a/app/library/link/link.tsx b/app/library/link/link.tsx index 3d7db669d..c3dd8a035 100644 --- a/app/library/link/link.tsx +++ b/app/library/link/link.tsx @@ -1,7 +1,20 @@ import { Link as ReactRouterLink, type LinkProps as ReactRouterLinkProps } from "react-router" +import type { Language } from "~/localization/resource" +import { useEnhancedTo } from "./useEnhancedTo" -interface LinkProps extends ReactRouterLinkProps {} +export interface LinkProps extends ReactRouterLinkProps { + keepSearchParams?: boolean + language?: Language +} -export const Link = ({ prefetch = "intent", viewTransition = true, ...props }: LinkProps) => { - return