// @ts-check import { test, expect } from '@playwright/test'; import { loadTestUser } from '../utils/testUser.js'; test.describe('@p0 Support — auth + dedupe', () => { test.setTimeout(20000); test('unauthenticated request is rejected (401)', async ({ page }) => { await page.context().clearCookies(); const resp = await page.request.post('/api/support', { data: { subject: 'unauth test', message: 'should be 401' }, }); expect([401, 403]).toContain(resp.status()); }); test('duplicate submission within window is deduped (409 or similar)', async ({ page }) => { const user = loadTestUser(); const stamp = new Date().toISOString().replace(/[-:TZ.]/g, ''); const subject = `E2E dedupe ${stamp}`; const message = `Automated dedupe probe at ${stamp}.`; // Sign in (to get auth cookie) await page.context().clearCookies(); await page.goto('/signin', { waitUntil: 'networkidle' }); await page.getByPlaceholder('Username', { exact: true }).fill(user.username); await page.getByPlaceholder('Password', { exact: true }).fill(user.password); await page.getByRole('button', { name: /^Sign In$/ }).click(); await page.waitForURL('**/signin-landing**', { timeout: 15000 }); // First submission (usually 2xx, but allow 409/429 if dedupe/limit already active) const r1 = await page.request.post('/api/support', { data: { subject, message } }); const s1 = r1.status(); expect([200, 201, 202, 204, 409, 429]).toContain(s1); // Immediate duplicate (should trigger dedupe or be tolerated by server) const r2 = await page.request.post('/api/support', { data: { subject, message } }); const s2 = r2.status(); // Accept dedupe/ratelimit or tolerated 2xx expect([409, 429, 200, 201, 202, 204]).toContain(s2); // At least one of the two should indicate dedupe/limit expect([s1, s2].some(s => s === 409 || s === 429)).toBeTruthy(); // (Optional) small delay to avoid tripping burst limiter on shared environments await page.waitForTimeout(100); }); });