Update AppHeader to reflect authentication state. When not authenticated, show Logga in and Registrera links. When authenticated, show the user's email address and a Logga ut button. Uses v-if/v-else with template blocks for clean conditional rendering without wrapper elements. Changes: - authStore: add email computed that extracts sub claim from JWT payload - AppHeader: conditional nav with v-if/v-else (guest vs authenticated) - AppHeader: add email display and logout button with styles - App.spec.ts: add Pinia to test setup (required by AppHeader now) - AppHeader.spec.ts: rewrite with tests for both auth states - authStore.spec.ts: add tests for email extraction and clearing - header-auth.spec.ts: 5 Playwright E2E tests for header auth state
91 lines
2.7 KiB
TypeScript
91 lines
2.7 KiB
TypeScript
import { test, expect } from '@playwright/test'
|
|
|
|
test.describe('Header auth state', () => {
|
|
test('shows login and register links when not authenticated', async ({
|
|
page,
|
|
}) => {
|
|
await page.goto('/')
|
|
const header = page.locator('header')
|
|
await expect(header.getByRole('link', { name: 'Logga in' })).toBeVisible()
|
|
await expect(
|
|
header.getByRole('link', { name: 'Registrera' }),
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('does not show logout button when not authenticated', async ({
|
|
page,
|
|
}) => {
|
|
await page.goto('/')
|
|
const header = page.locator('header')
|
|
await expect(
|
|
header.getByRole('button', { name: 'Logga ut' }),
|
|
).not.toBeVisible()
|
|
})
|
|
|
|
test('shows email and logout when authenticated', async ({ page }) => {
|
|
const jwt = makeJwt({ sub: 'test@bilhalsning.se', role: 'user' })
|
|
await page.goto('/')
|
|
await page.evaluate(
|
|
(token) => localStorage.setItem('auth_token', token),
|
|
jwt,
|
|
)
|
|
await page.goto('/')
|
|
|
|
const header = page.locator('header')
|
|
await expect(header.getByText('test@bilhalsning.se')).toBeVisible()
|
|
await expect(
|
|
header.getByRole('button', { name: 'Logga ut' }),
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('hides login and register links when authenticated', async ({
|
|
page,
|
|
}) => {
|
|
const jwt = makeJwt({ sub: 'test@bilhalsning.se', role: 'user' })
|
|
await page.goto('/')
|
|
await page.evaluate(
|
|
(token) => localStorage.setItem('auth_token', token),
|
|
jwt,
|
|
)
|
|
await page.goto('/')
|
|
|
|
const header = page.locator('header')
|
|
await expect(
|
|
header.getByRole('link', { name: 'Logga in' }),
|
|
).not.toBeVisible()
|
|
await expect(
|
|
header.getByRole('link', { name: 'Registrera' }),
|
|
).not.toBeVisible()
|
|
})
|
|
|
|
test('logout restores login and register links', async ({ page }) => {
|
|
const jwt = makeJwt({ sub: 'test@bilhalsning.se', role: 'user' })
|
|
await page.goto('/')
|
|
await page.evaluate(
|
|
(token) => localStorage.setItem('auth_token', token),
|
|
jwt,
|
|
)
|
|
await page.goto('/')
|
|
|
|
const header = page.locator('header')
|
|
await header.getByRole('button', { name: 'Logga ut' }).click()
|
|
|
|
await expect(
|
|
header.getByRole('link', { name: 'Logga in' }),
|
|
).toBeVisible()
|
|
await expect(
|
|
header.getByRole('link', { name: 'Registrera' }),
|
|
).toBeVisible()
|
|
await expect(
|
|
header.getByRole('button', { name: 'Logga ut' }),
|
|
).not.toBeVisible()
|
|
await expect(header.getByText('test@bilhalsning.se')).not.toBeVisible()
|
|
})
|
|
})
|
|
|
|
function makeJwt(payload: Record<string, unknown>): string {
|
|
const header = btoa(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
|
|
const body = btoa(JSON.stringify(payload))
|
|
const signature = 'test-sig'
|
|
return `${header}.${body}.${signature}`
|
|
}
|