diff --git a/apps/web/next.config.js b/apps/web/next.config.js index d02ab61964..4bec508455 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -288,6 +288,11 @@ const nextConfig = { async rewrites() { const { orgSlug } = nextJsOrgRewriteConfig; const beforeFiles = [ + { + // This should be the first item in `beforeFiles` to take precedence over other rewrites + source: "/en/:path*", + destination: "/:path*", + }, { source: "/forms/:formQuery*", destination: "/apps/routing-forms/routing-link/:formQuery*", diff --git a/apps/web/playwright/i18n-routing.e2e.ts b/apps/web/playwright/i18n-routing.e2e.ts new file mode 100644 index 0000000000..8eeaba5e66 --- /dev/null +++ b/apps/web/playwright/i18n-routing.e2e.ts @@ -0,0 +1,27 @@ +import { expect } from "@playwright/test"; + +import { test } from "./lib/fixtures"; + +test.describe("/en/* pages must not 404", () => { + test("/en/login shouldn't 404", async ({ page }) => { + const response = await page.goto(`/en/login`); + expect(response?.status()).not.toBe(404); + }); + + test("/en/auth/login shouldn't 404", async ({ page }) => { + const response = await page.goto(`/en/auth/login`); + expect(response?.status()).not.toBe(404); + }); + + test("/en/[user] page shouldn't 404", async ({ page, users }) => { + const user = await users.create(); + const response = await page.goto(`/en/${user.username}`); + expect(response?.status()).not.toBe(404); + }); + + test("/en/[user]/[type] page shouldn't 404", async ({ page, users }) => { + const user = await users.create(); + const response = await page.goto(`/en/${user.username}/30-min`); + expect(response?.status()).not.toBe(404); + }); +}); diff --git a/apps/web/playwright/unpublished.e2e.ts b/apps/web/playwright/unpublished.e2e.ts index 85a96046fd..f52fc5fd49 100644 --- a/apps/web/playwright/unpublished.e2e.ts +++ b/apps/web/playwright/unpublished.e2e.ts @@ -14,16 +14,24 @@ test.afterEach(async ({ users }) => { await users.deleteAll(); }); +const assertChecks = async (page: any, entityName: string, entityType: string) => { + await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); + await expect(page.locator(`h2:has-text("${title(entityName)}")`)).toHaveCount(1); + await expect(page.locator(`div:text("${description(entityType)}")`)).toHaveCount(1); + await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); +}; + test.describe("Unpublished", () => { test("Regular team profile", async ({ page, users }) => { const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true }); const { team } = await owner.getFirstTeamMembership(); const { requestedSlug } = team.metadata as { requestedSlug: string }; - await page.goto(`/team/${requestedSlug}`); - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(team.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("team")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + const prefixes = ["", "/en"]; + + for (const prefix of prefixes) { + await page.goto(`${prefix}/team/${requestedSlug}`); + await assertChecks(page, team.name, "team"); + } }); test("Regular team event type", async ({ page, users }) => { @@ -35,22 +43,24 @@ test.describe("Unpublished", () => { const { team } = await owner.getFirstTeamMembership(); const { requestedSlug } = team.metadata as { requestedSlug: string }; const { slug: teamEventSlug } = await owner.getFirstTeamEvent(team.id); - await page.goto(`/team/${requestedSlug}/${teamEventSlug}`); - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(team.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("team")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + const prefixes = ["", "/en"]; + + for (const prefix of prefixes) { + await page.goto(`${prefix}/team/${requestedSlug}/${teamEventSlug}`); + await assertChecks(page, team.name, "team"); + } }); test("Organization profile", async ({ users, page }) => { const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true }); const { team: org } = await owner.getOrgMembership(); const { requestedSlug } = org.metadata as { requestedSlug: string }; - await page.goto(`/org/${requestedSlug}`); - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(org.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("organization")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + const prefixes = ["", "/en"]; + + for (const prefix of prefixes) { + await page.goto(`${prefix}/org/${requestedSlug}`); + await assertChecks(page, org.name, "organization"); + } }); test("Organization sub-team", async ({ users, page }) => { @@ -63,11 +73,12 @@ test.describe("Unpublished", () => { const { team: org } = await owner.getOrgMembership(); const { requestedSlug } = org.metadata as { requestedSlug: string }; const [{ slug: subteamSlug }] = org.children as { slug: string }[]; - await page.goto(`/org/${requestedSlug}/team/${subteamSlug}`); - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(org.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("organization")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + const prefixes = ["", "/en"]; + + for (const prefix of prefixes) { + await page.goto(`${prefix}/org/${requestedSlug}/team/${subteamSlug}`); + await assertChecks(page, org.name, "organization"); + } }); test("Organization sub-team event-type", async ({ users, page }) => { @@ -81,23 +92,24 @@ test.describe("Unpublished", () => { const { requestedSlug } = org.metadata as { requestedSlug: string }; const [{ slug: subteamSlug, id: subteamId }] = org.children as { slug: string; id: number }[]; const { slug: subteamEventSlug } = await owner.getFirstTeamEvent(subteamId); - await page.goto(`/org/${requestedSlug}/team/${subteamSlug}/${subteamEventSlug}`); + const prefixes = ["", "/en"]; - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(org.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("organization")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + for (const prefix of prefixes) { + await page.goto(`${prefix}/org/${requestedSlug}/team/${subteamSlug}/${subteamEventSlug}`); + await assertChecks(page, org.name, "organization"); + } }); test("Organization user", async ({ users, page }) => { const owner = await users.create(undefined, { hasTeam: true, isUnpublished: true, isOrg: true }); const { team: org } = await owner.getOrgMembership(); const { requestedSlug } = org.metadata as { requestedSlug: string }; - await page.goto(`/org/${requestedSlug}/${owner.username}`); - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(org.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("organization")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + const prefixes = ["", "/en"]; + + for (const prefix of prefixes) { + await page.goto(`${prefix}/org/${requestedSlug}/${owner.username}`); + await assertChecks(page, org.name, "organization"); + } }); test("Organization user event-type", async ({ users, page }) => { @@ -105,10 +117,11 @@ test.describe("Unpublished", () => { const { team: org } = await owner.getOrgMembership(); const { requestedSlug } = org.metadata as { requestedSlug: string }; const [{ slug: ownerEventType }] = owner.eventTypes; - await page.goto(`/org/${requestedSlug}/${owner.username}/${ownerEventType}`); - await expect(page.locator('[data-testid="empty-screen"]')).toHaveCount(1); - await expect(page.locator(`h2:has-text("${title(org.name)}")`)).toHaveCount(1); - await expect(page.locator(`div:text("${description("organization")}")`)).toHaveCount(1); - await expect(page.locator(`img`)).toHaveAttribute("src", /.*/); + const prefixes = ["", "/en"]; + + for (const prefix of prefixes) { + await page.goto(`${prefix}/org/${requestedSlug}/${owner.username}/${ownerEventType}`); + await assertChecks(page, org.name, "organization"); + } }); });