fix(i18n): sort discovery titles using selected UI locale

This commit is contained in:
cesnimda
2026-11-10 23:16:58 +01:00
parent 6c75e97bdb
commit ce7e48665c
7 changed files with 95 additions and 3 deletions
+30
View File
@@ -97,6 +97,36 @@ test("sorts returned vacancies by title", async () => {
expect(screen.getAllByRole("heading", { level: 3 }).map((element) => element.textContent)).toEqual(["Analyst", "Zoologist"]);
});
test("title sorting follows UI language changes without refetching or changing discovery filters", async () => {
searchResponse([
{ id: "1", title: "Åker agronom", url: "https://example.test/1", source: "nav", countryCode: "NO" },
{ id: "2", title: "Zoologist", url: "https://example.test/2", source: "nav", countryCode: "NO" },
]);
renderPage();
fireEvent.change(screen.getByLabelText("Role or company"), { target: { value: "science" } });
fireEvent.change(screen.getByLabelText("Municipality"), { target: { value: "Oslo" } });
fireEvent.click(screen.getByRole("button", { name: "Search NAV" }));
await screen.findByText("2 vacancies found");
fireEvent.mouseDown(screen.getByRole("combobox", { name: "Sort results" }));
fireEvent.click(await screen.findByRole("option", { name: "Title A–Z" }));
const titles = () => screen.getAllByRole("heading", { level: 3 }).map((element) => element.textContent);
expect(titles()).toEqual(["Åker agronom", "Zoologist"]);
const reads = mockedApi.get.mock.calls.length;
act(() => { window.dispatchEvent(new StorageEvent("storage", { key: "uiLanguage", newValue: "nb" })); });
expect(titles()).toEqual(["Zoologist", "Åker agronom"]);
expect(screen.getByLabelText("Rolle eller bedrift")).toHaveValue("science");
expect(screen.getByLabelText("Kommune")).toHaveValue("Oslo");
expect(screen.getByRole("combobox", { name: translations.nb.jobDiscoverySort })).toHaveTextContent(translations.nb.jobDiscoverySortTitle);
act(() => { window.dispatchEvent(new StorageEvent("storage", { key: "uiLanguage", newValue: "en" })); });
expect(titles()).toEqual(["Åker agronom", "Zoologist"]);
expect(mockedApi.get).toHaveBeenCalledTimes(reads);
expect(mockedApi.post).not.toHaveBeenCalled();
expect(mockedApi.patch).not.toHaveBeenCalled();
expect(mockedApi.delete).not.toHaveBeenCalled();
});
test("renders the discovery workflow in Norwegian Bokmål", async () => {
window.localStorage.setItem("uiLanguage", "nb");
renderPage();
@@ -171,16 +171,17 @@ export default function JobDiscoveryPage() {
finally { pending.current = false; setMutating(false); }
};
const locale = language === "nb" ? "nb-NO" : "en";
const sortedJobs = useMemo(() => [...jobs].sort((left, right) => {
if (sortOrder === "title") return left.title.localeCompare(right.title);
if (sortOrder === "title") return left.title.localeCompare(right.title, locale);
if (sortOrder === "deadline") {
const leftDeadline = left.deadline ? new Date(left.deadline).getTime() : Number.MAX_SAFE_INTEGER;
const rightDeadline = right.deadline ? new Date(right.deadline).getTime() : Number.MAX_SAFE_INTEGER;
return leftDeadline - rightDeadline;
}
return new Date(right.modifiedAt || 0).getTime() - new Date(left.modifiedAt || 0).getTime();
}), [jobs, sortOrder]);
const formatDate = (value?: string) => value ? new Date(value).toLocaleDateString(language === "nb" ? "nb-NO" : "en") : null;
}), [jobs, sortOrder, locale]);
const formatDate = (value?: string) => value ? new Date(value).toLocaleDateString(locale) : null;
return (
<Stack spacing={3} sx={{ minWidth: 0 }}>