From 1df3df0f326e5d24360e90f3e4b83ccc7a6aa8a8 Mon Sep 17 00:00:00 2001 From: Tarek Hamaoui Date: Wed, 25 Dec 2024 00:03:53 +0100 Subject: [PATCH 01/14] feat: improve error handling and empty state handling for announcements - Updated apiService to remove blanket 404 redirection logic - Adjusted announcements page to handle empty states - Added Playwright tests for empty array scenario RISDEV-4872 --- ...to-amending-laws-page-and-test-content.spec.ts | 15 +++++++++++++++ frontend/src/services/apiService.ts | 10 ---------- .../src/views/amending-laws/AmendingLaws.view.vue | 4 ++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/frontend/e2e/redirect-to-amending-laws-page-and-test-content.spec.ts b/frontend/e2e/redirect-to-amending-laws-page-and-test-content.spec.ts index 869bb65f1..634efb6ad 100644 --- a/frontend/e2e/redirect-to-amending-laws-page-and-test-content.spec.ts +++ b/frontend/e2e/redirect-to-amending-laws-page-and-test-content.spec.ts @@ -45,4 +45,19 @@ test.describe("Redirect and start page content", () => { }), ).toBeVisible() }) + + test("should display a no data message when the API returns an empty array", async ({ + page, + }) => { + await page.route("**/api/v1/announcements", (route) => { + route.fulfill({ + status: 200, + body: JSON.stringify([]), + }) + }) + + await page.goto("/") + + await expect(page.getByText("Keine Verkündungen gefunden.")).toBeVisible() + }) }) diff --git a/frontend/src/services/apiService.ts b/frontend/src/services/apiService.ts index 55dc2708e..176aad7f7 100644 --- a/frontend/src/services/apiService.ts +++ b/frontend/src/services/apiService.ts @@ -1,5 +1,4 @@ import { getFallbackError } from "@/lib/errorResponseMapper" -import routerInstance from "@/router" import { createFetch, UseFetchReturn } from "@vueuse/core" /** @@ -59,15 +58,6 @@ export const useApiFetch = createFetch({ }, onFetchError(fetchContext) { - // We'll probably remove this again because we don't want a blanket - // redirect to 404 if anything goes wrong. - if (fetchContext.response?.status === 404 && routerInstance) { - routerInstance.push({ name: "NotFound" }).catch((err) => { - if (err.name !== "NavigationDuplicated") { - console.error("Failed to navigate to 404 page:", err) - } - }) - } // this error is sometimes throws when previous requests are automatically aborted as // some of the data changed and refetch is true. It seems to only be throws when the request // is aborted before it was actually send. diff --git a/frontend/src/views/amending-laws/AmendingLaws.view.vue b/frontend/src/views/amending-laws/AmendingLaws.view.vue index 629e70baa..43231c0ea 100644 --- a/frontend/src/views/amending-laws/AmendingLaws.view.vue +++ b/frontend/src/views/amending-laws/AmendingLaws.view.vue @@ -5,6 +5,7 @@ import { useGetAmendingLaws } from "@/services/announcementService" import { RouterLink } from "vue-router" import RisErrorCallout from "@/components/controls/RisErrorCallout.vue" import Button from "primevue/button" +import Message from "primevue/message" const { isFetching, error, data: amendingLaws } = useGetAmendingLaws() @@ -22,6 +23,9 @@ const { isFetching, error, data: amendingLaws } = useGetAmendingLaws() +
+ Keine Verkündungen gefunden. +
Date: Wed, 25 Dec 2024 00:09:36 +0100 Subject: [PATCH 02/14] removes 404 unit test for apiService RISDEV-4872 --- frontend/src/services/apiService.spec.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/frontend/src/services/apiService.spec.ts b/frontend/src/services/apiService.spec.ts index dccf03454..3a7209359 100644 --- a/frontend/src/services/apiService.spec.ts +++ b/frontend/src/services/apiService.spec.ts @@ -60,25 +60,6 @@ describe("useApiFetch", () => { ) }) - it("redirects to the 404 page if the API returns a 404", async () => { - vi.spyOn(window, "fetch").mockResolvedValue( - new Response("{}", { status: 404 }), - ) - - const mockPush = vi.fn().mockResolvedValue({}) - vi.doMock("@/router", () => ({ default: { push: mockPush } })) - - const { useApiFetch } = await import("@/services/apiService") - - useApiFetch("foo/bar") - - await vi.waitFor(() => - expect(mockPush).toHaveBeenCalledWith({ name: "NotFound" }), - ) - - vi.doUnmock("@/router") - }) - it("aborts the request if the URL is marked as invalid", async () => { const fetchSpy = vi .spyOn(window, "fetch") From e1c7e9821f0a4d924d1622844e135c72963defc1 Mon Sep 17 00:00:00 2001 From: Tarek Hamaoui Date: Wed, 25 Dec 2024 00:16:58 +0100 Subject: [PATCH 03/14] test: remove outdated 404 redirection test RISDEV-4872 --- frontend/e2e/render-not-found-page.spec.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/frontend/e2e/render-not-found-page.spec.ts b/frontend/e2e/render-not-found-page.spec.ts index 7cb87ad1a..a2e5ad4c3 100644 --- a/frontend/e2e/render-not-found-page.spec.ts +++ b/frontend/e2e/render-not-found-page.spec.ts @@ -10,19 +10,4 @@ test.describe("404 Page", () => { page.getByRole("heading", { name: /404 - Seite nicht gefunden/ }), ).toBeVisible() }) - - test(`should display 404 page when API response is 404`, async ({ page }) => { - await page.route("/api/v1/announcements", (route) => { - route.fulfill({ - status: 404, - body: "Not Found", - }) - }) - - await page.goto("/amending-laws") - - await expect( - page.getByRole("heading", { name: /404 - Seite nicht gefunden/ }), - ).toBeVisible() - }) }) From 95b4caa89262c1daf83e4c21c26efc58bc6918ad Mon Sep 17 00:00:00 2001 From: Tarek Hamaoui Date: Mon, 6 Jan 2025 14:33:27 +0100 Subject: [PATCH 04/14] feat: handle 404 errors in AmendingLaw view - Added a watcher to redirect to the 404 page if the `useGetNorm` API call returns a 404 status. - Updated error handling to display `RisErrorCallout` for non-404 errors. RISDEV-4872 --- .../views/amending-law/AmendingLaw.view.vue | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/amending-law/AmendingLaw.view.vue b/frontend/src/views/amending-law/AmendingLaw.view.vue index c81a62305..546b9809b 100644 --- a/frontend/src/views/amending-law/AmendingLaw.view.vue +++ b/frontend/src/views/amending-law/AmendingLaw.view.vue @@ -9,9 +9,11 @@ import RisNavbarSide, { import { useEliPathParameter } from "@/composables/useEliPathParameter" import { getFrbrDisplayText } from "@/lib/frbr" import { useGetNorm } from "@/services/normService" -import { ref } from "vue" -import { RouterView } from "vue-router" +import { ref, watch } from "vue" import RisErrorCallout from "@/components/controls/RisErrorCallout.vue" +import { RouterView, useRouter } from "vue-router" + +const router = useRouter() const menuItems: LevelOneMenuItem[] = [ { @@ -40,6 +42,14 @@ const menuItems: LevelOneMenuItem[] = [ const eli = useEliPathParameter() const { data: amendingLaw, isFetching, error } = useGetNorm(eli) +watch( + () => error.value, + (err) => { + if (err && err.status === 404) { + router.push({ name: "NotFound" }) + } + }, +) const breadcrumbs = ref([ { @@ -61,8 +71,8 @@ const breadcrumbs = ref([
-
- +
+
Date: Mon, 6 Jan 2025 14:34:49 +0100 Subject: [PATCH 05/14] feat: handle 404 errors in AmendingLaw overview - Added a watcher to redirect to the 404 page if the `useGetNormHtml` API call returns a 404 status. - Updated error handling logic to conditionally display `RisErrorCallout` for non-404 errors or `loadXmlError`. RISDEV-4872 --- .../overview/AmendingLawOverview.view.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/frontend/src/views/amending-law/overview/AmendingLawOverview.view.vue b/frontend/src/views/amending-law/overview/AmendingLawOverview.view.vue index 2987a491b..5c59b6cb9 100644 --- a/frontend/src/views/amending-law/overview/AmendingLawOverview.view.vue +++ b/frontend/src/views/amending-law/overview/AmendingLawOverview.view.vue @@ -6,9 +6,11 @@ import { useModHighlightClasses } from "@/composables/useModHighlightClasses" import { useNormXml } from "@/composables/useNormXml" import { useGetNormHtml } from "@/services/normService" import { xmlStringToDocument } from "@/services/xmlService" -import { computed, toValue } from "vue" +import { computed, toValue, watch } from "vue" +import { useRouter } from "vue-router" import RisErrorCallout from "@/components/controls/RisErrorCallout.vue" +const router = useRouter() const eli = useEliPathParameter() const { isFetching, error, data: amendingLawHtml } = useGetNormHtml(eli) @@ -25,12 +27,21 @@ const normDocument = computed(() => { }) const classesForPreview = useModHighlightClasses(normDocument, () => false) + +watch( + () => error?.value, + (err) => { + if (err?.status === 404) { + router.push({ name: "NotFound" }) + } + }, +)