Files
oysqn.app/tests/e2e/auth.spec.ts
Patrick Toal 108c042921 fix(edge-fn): replace getClaims with adminClient.auth.getUser(token)
fix(edge-fn): use user.id instead of claims.sub; fixes 500s and false cert_required
fix(migrations): drop broad reservations SELECT policy; add reservation_slots view with security_invoker=false
fix(tests): correct weekSlot() keys from start/end to start_time/end_time
fix(tests): spread overlap test slots across separate ISO weeks
fix(tests): update e2e assertion to match actual authenticated home text
fix(app): hide IonMenu before user is authenticated
feat(dx): add test:all script running unit, integration, and e2e in sequence
docs(claude-md): document SELinux fix, Edge Function auth pattern, security_invoker behaviour
2026-04-20 14:32:37 -04:00

47 lines
1.9 KiB
TypeScript

import { test, expect } from '@playwright/test'
import { deleteAllMail, getMagicLink } from './helpers/mailpit'
const TEST_EMAIL = 'e2e-test@example.com'
test.beforeEach(async () => {
await deleteAllMail()
})
test.describe('Auth flow', () => {
test('splash → login → magic link → home', async ({ page }) => {
// Splash page shows logo and login button
await page.goto('/')
await expect(page.getByRole('img', { name: 'OYS Borrow a Boat' })).toBeVisible()
await expect(page.getByRole('link', { name: 'Log In' })).toBeVisible()
// Navigate to login page
await page.getByRole('link', { name: 'Log In' }).click()
await expect(page).toHaveURL('/login')
await expect(page.getByText('Sign In')).toBeVisible()
// Submit email for magic link
await page.getByPlaceholder('you@example.com').fill(TEST_EMAIL)
await page.getByRole('button', { name: 'Send Sign-In Link' }).click()
await expect(page.getByText('Check your email')).toBeVisible()
// Fetch magic link from Mailpit, then follow the Supabase verify redirect
// server-side (Node.js fetch) to get our app's callback URL.
// Playwright's headless shell can't reach 127.0.0.1:54321 directly.
const magicLink = await getMagicLink(TEST_EMAIL)
const redirectRes = await fetch(magicLink, { redirect: 'manual' })
const callbackUrl = redirectRes.headers.get('location')
if (!callbackUrl) throw new Error('Supabase did not redirect to app callback')
await page.goto(callbackUrl)
// Auth callback redirects to home (authenticated state)
await expect(page).toHaveURL('/')
await expect(page.getByText('Upcoming Reservations')).toBeVisible()
})
test('unauthenticated access to protected route redirects to splash', async ({ page }) => {
await page.goto('/dashboard')
await expect(page).toHaveURL('/')
await expect(page.getByRole('link', { name: 'Log In' })).toBeVisible()
})
})