From 10fb2abe95f83f02b56e3c5bcd4b2be42e7fca49 Mon Sep 17 00:00:00 2001 From: Fatma Date: Sun, 28 Dec 2025 08:33:33 +0000 Subject: [PATCH 1/2] fix: prevent infinite loop in hashtag view --- front-end/views/hashtag.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/front-end/views/hashtag.mjs b/front-end/views/hashtag.mjs index 7b7e996..647d1d8 100644 --- a/front-end/views/hashtag.mjs +++ b/front-end/views/hashtag.mjs @@ -17,7 +17,10 @@ import {createHeading} from "../components/heading.mjs"; function hashtagView(hashtag) { destroy(); - apiService.getBloomsByHashtag(hashtag); + const formattedHashtag = hashtag.startsWith('#') ? hashtag : `#${hashtag}`; + if (state.currentHashtag !== formattedHashtag) { + apiService.getBloomsByHashtag(hashtag); + } renderOne( state.isLoggedIn, From 70c00f995668c37388fec9200cdd95013f35cfcf Mon Sep 17 00:00:00 2001 From: Fatma Date: Sun, 28 Dec 2025 09:31:04 +0000 Subject: [PATCH 2/2] test: add test for hashtag infinite loop --- front-end/tests/hashtag.spec.mjs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 front-end/tests/hashtag.spec.mjs diff --git a/front-end/tests/hashtag.spec.mjs b/front-end/tests/hashtag.spec.mjs new file mode 100644 index 0000000..635c64c --- /dev/null +++ b/front-end/tests/hashtag.spec.mjs @@ -0,0 +1,30 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Hashtag View Tests", () => { + + test("should only make one fetch request (no infinite loop)", async ({ page }) => { + + // How many requests go to the server + let fetchCount = 0; + + // Network requests + page.on("request", (request) => { + if ( + request.url().includes("hashtag") && + request.resourceType() === "fetch" + ) { + fetchCount++; + } + }); + + // Go to the hashtag page + await page.goto("/#/hashtag/do"); + + // Wait for a short time (0.5 seconds) + await page.waitForTimeout(500); + + // We expect only 1 or 2 requests. + expect(fetchCount).toBeLessThan(3); + }); + +}); \ No newline at end of file