Files
blackcanyontickets/tests/auth/auth-api.spec.ts
dzinesco dbf4b11e81 fix: Implement comprehensive edit event button functionality and resolve authentication issues
Major fixes and improvements:
- Fixed edit event button functionality with proper event handlers and DOM ready state checking
- Added status column to tickets table via Supabase migration to resolve 500 API errors
- Updated stats API to correctly calculate revenue from decimal price values
- Resolved authentication redirect loops by fixing cookie configuration for Docker environment
- Fixed Permissions-Policy header syntax errors
- Added comprehensive debugging and error handling for event management
- Implemented modal-based event editing with form validation and API integration
- Enhanced event data loading with proper error handling and user feedback

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14 18:49:49 -06:00

237 lines
7.3 KiB
TypeScript

import { test, expect } from '@playwright/test'
test.describe('Auth API Integration', () => {
test('should handle successful login API call', async ({ page }) => {
await page.route('**/api/auth/login', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
user: {
id: '1',
email: 'test@example.com',
roleType: 'user'
},
session: {
accessToken: 'mock-token',
refreshToken: 'mock-refresh-token',
expiresAt: Math.floor(Date.now() / 1000) + 3600
}
})
})
})
await page.goto('/login')
await page.fill('input[name="email"]', 'test@example.com')
await page.fill('input[name="password"]', 'password123')
await page.click('button[type="submit"]')
await expect(page).toHaveURL(/.*dashboard/)
})
test('should handle failed login API call', async ({ page }) => {
await page.route('**/api/auth/login', async route => {
await route.fulfill({
status: 401,
contentType: 'application/json',
body: JSON.stringify({
error: {
code: 'invalid_credentials',
message: 'Invalid email or password'
}
})
})
})
await page.goto('/login')
await page.fill('input[name="email"]', 'test@example.com')
await page.fill('input[name="password"]', 'wrongpassword')
await page.click('button[type="submit"]')
await expect(page.locator('.text-red-600')).toContainText('Invalid email or password')
})
test('should handle session refresh', async ({ page }) => {
let refreshCalled = false
await page.route('**/api/auth/refresh', async route => {
refreshCalled = true
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
session: {
accessToken: 'new-mock-token',
refreshToken: 'new-mock-refresh-token',
expiresAt: Math.floor(Date.now() / 1000) + 3600
}
})
})
})
await page.goto('/login')
await page.fill('input[name="email"]', 'test@example.com')
await page.fill('input[name="password"]', 'password123')
await page.click('button[type="submit"]')
await page.evaluate(() => {
const session = {
accessToken: 'expiring-token',
refreshToken: 'mock-refresh-token',
expiresAt: Math.floor(Date.now() / 1000) + 60,
user: { id: '1', email: 'test@example.com' }
}
localStorage.setItem('bct_auth_session', JSON.stringify(session))
})
await page.reload()
await page.waitForTimeout(1000)
expect(refreshCalled).toBe(true)
})
test('should handle logout API call', async ({ page }) => {
await page.route('**/api/auth/logout', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ success: true })
})
})
await page.goto('/login')
await page.fill('input[name="email"]', 'test@example.com')
await page.fill('input[name="password"]', 'password123')
await page.click('button[type="submit"]')
await page.click('[data-testid="user-menu-button"]')
await page.click('button:has-text("Sign Out")')
await expect(page).toHaveURL(/.*login/)
})
test('should handle password reset API call', async ({ page }) => {
await page.route('**/api/auth/reset-password', async route => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ message: 'Reset email sent' })
})
})
await page.goto('/reset-password')
await page.fill('input[name="email"]', 'test@example.com')
await page.click('button[type="submit"]')
await expect(page.locator('.text-green-600')).toContainText('Reset email sent')
})
test('should handle signup API call', async ({ page }) => {
await page.route('**/api/auth/signup', async route => {
await route.fulfill({
status: 201,
contentType: 'application/json',
body: JSON.stringify({
user: {
id: '2',
email: 'newuser@example.com',
roleType: 'user'
},
message: 'Account created successfully'
})
})
})
await page.goto('/signup')
await page.fill('input[name="email"]', 'newuser@example.com')
await page.fill('input[name="password"]', 'password123')
await page.fill('input[name="confirmPassword"]', 'password123')
await page.click('button[type="submit"]')
await expect(page.locator('.text-green-600')).toContainText('Account created successfully')
})
})
test.describe('Protected API Routes', () => {
test('should include auth headers in API requests', async ({ page }) => {
let authHeaderReceived = false
await page.route('**/api/dashboard/stats', async route => {
const headers = route.request().headers()
if (headers.authorization?.startsWith('Bearer ')) {
authHeaderReceived = true
}
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ stats: { events: 5, revenue: 1000 } })
})
})
await page.goto('/login')
await page.fill('input[name="email"]', 'test@example.com')
await page.fill('input[name="password"]', 'password123')
await page.click('button[type="submit"]')
await page.goto('/dashboard')
await page.waitForTimeout(1000)
expect(authHeaderReceived).toBe(true)
})
test('should handle 401 responses by refreshing token', async ({ page }) => {
let refreshCalled = false
let retrySuccessful = false
await page.route('**/api/dashboard/stats', async route => {
const headers = route.request().headers()
if (headers.authorization === 'Bearer expiring-token') {
await route.fulfill({
status: 401,
contentType: 'application/json',
body: JSON.stringify({ error: 'Token expired' })
})
} else if (headers.authorization === 'Bearer new-mock-token') {
retrySuccessful = true
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ stats: { events: 5, revenue: 1000 } })
})
}
})
await page.route('**/api/auth/refresh', async route => {
refreshCalled = true
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
session: {
accessToken: 'new-mock-token',
refreshToken: 'new-mock-refresh-token',
expiresAt: Math.floor(Date.now() / 1000) + 3600
}
})
})
})
await page.evaluate(() => {
const session = {
accessToken: 'expiring-token',
refreshToken: 'mock-refresh-token',
expiresAt: Math.floor(Date.now() / 1000) + 3600,
user: { id: '1', email: 'test@example.com' }
}
localStorage.setItem('bct_auth_session', JSON.stringify(session))
})
await page.goto('/dashboard')
await page.waitForTimeout(2000)
expect(refreshCalled).toBe(true)
expect(retrySuccessful).toBe(true)
})
})