Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions front-end/tests/hashtag.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { test, expect } from "@playwright/test";

test("should not make infinite hashtag endpoint requests", async ({ page }) => {
// ===== ARRANGE
const requests = [];
page.on("request", (request) => {
if (
request.url().includes(":3000/hashtag/do") &&
request.resourceType() === "fetch"
) {
requests.push(request);
}
});
// ====== ACT
// When I navigate to the hashtag
await page.goto("/#/hashtag/do");
// And I wait a reasonable time for any additional requests
await page.waitForTimeout(200);

// ====== ASSERT
// Then the number of requests should be 1
console.log("Number of requests:", requests.length);
expect(requests.length).toEqual(1);
});
28 changes: 28 additions & 0 deletions front-end/tests/profile-logout-login.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { test, expect } from "@playwright/test";
import { loginAsSample, logout } from "./test-utils.mjs";

test("can visit another user's profile after logout and re-login", async ({
page,
}) => {
// Given I am logged in
await loginAsSample(page);

// And I visit another user's profile
await page.goto("/#/profile/AS");

// And I log out
await logout(page);

// When I log in again
await loginAsSample(page);

// And I visit the same profile again
await page.goto("/#/profile/AS");

// Then I should see the profile view (NOT a server error)
await expect(page.locator("#profile-container")).toBeVisible();

await expect(page.locator("body")).not.toContainText(
"Server does not support this operation",
);
});
21 changes: 14 additions & 7 deletions front-end/views/hashtag.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,45 @@ import {createHeading} from "../components/heading.mjs";
function hashtagView(hashtag) {
destroy();

apiService.getBloomsByHashtag(hashtag);
// Normalize the hashtag to always include a leading '#' and
// prevent infinite API calls by only fetching if the hashtag has changed

const normalizedHashtag = hashtag.startsWith("#") ? hashtag : `#${hashtag}`;
if (state.currentHashtag !== normalizedHashtag) {
state.currentHashtag = normalizedHashtag;
apiService.getBloomsByHashtag(normalizedHashtag);
}
renderOne(
state.isLoggedIn,
getLogoutContainer(),
"logout-template",
createLogout
createLogout,
);

document
.querySelector("[data-action='logout']")
?.addEventListener("click", handleLogout);
renderOne(
state.isLoggedIn,
getLoginContainer(),
"login-template",
createLogin
createLogin,
);
document
.querySelector("[data-action='login']")
?.addEventListener("click", handleLogin);
.querySelector("[data-form='login']")
?.addEventListener("submit", handleLogin);

renderOne(
state.currentHashtag,
getHeadingContainer(),
"heading-template",
createHeading
createHeading,
);
renderEach(
state.hashtagBlooms || [],
getTimelineContainer(),
"bloom-template",
createBloom
createBloom,
);
}

Expand Down
4 changes: 2 additions & 2 deletions front-end/views/profile.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ function profileView(username) {
createLogin
);
document
.querySelector("[data-action='login']")
?.addEventListener("click", handleLogin);
.querySelector("[data-form='login']")
?.addEventListener("submit", handleLogin);

const profileData = state.profiles.find((p) => p.username === username);
if (profileData) {
Expand Down