import { test, expect } from '@playwright/test' const API_BASE = 'http://localhost:9100' test.describe('API health and public endpoints', () => { test('health endpoint returns 200', async ({ request }) => { const res = await request.get(`${API_BASE}/api/health`) expect(res.status()).toBe(200) }) test('fights list returns valid JSON', async ({ request }) => { const res = await request.get(`${API_BASE}/api/fights`) expect(res.status()).toBe(200) const data = await res.json() expect(Array.isArray(data.fights)).toBe(true) }) test('leaderboard returns valid JSON', async ({ request }) => { const res = await request.get(`${API_BASE}/api/bots/leaderboard`) expect(res.status()).toBe(200) const data = await res.json() expect(data).toHaveProperty('leaderboard') }) test('public stats returns valid JSON', async ({ request }) => { const res = await request.get(`${API_BASE}/api/stats/public`) expect(res.status()).toBe(200) const data = await res.json() expect(data).toBeDefined() }) test('tournaments list returns valid JSON', async ({ request }) => { const res = await request.get(`${API_BASE}/api/tournaments`) expect(res.status()).toBe(200) const data = await res.json() expect(data).toHaveProperty('tournaments') }) test('check-name endpoint works', async ({ request }) => { const res = await request.get(`${API_BASE}/api/auth/check-name/TestBotName123`) expect(res.status()).toBe(200) const data = await res.json() expect(typeof data.available).toBe('boolean') }) }) test.describe('API auth protection', () => { test('admin stats requires auth', async ({ request }) => { const res = await request.get(`${API_BASE}/api/admin/stats`) expect(res.status()).toBe(403) }) test('payment confirm without auth returns 400/404', async ({ request }) => { const res = await request.post(`${API_BASE}/api/payments/confirm/nonexistent`, { data: {}, }) // Should be 400 or 404, not 500 expect([400, 404]).toContain(res.status()) }) test('fight respond without valid fight returns 404', async ({ request }) => { const res = await request.post(`${API_BASE}/api/fights/nonexistent/respond`, { data: { botId: 'fake', answer: 'test' }, }) expect([400, 404]).toContain(res.status()) }) test('queue join with nonexistent bot returns 404', async ({ request }) => { const res = await request.post(`${API_BASE}/api/queue/join/nonexistent-bot-id`) expect([400, 404]).toContain(res.status()) }) }) test.describe('API rate limiting', () => { test('payment create-invoice is rate limited', async ({ request }) => { const responses: number[] = [] // Send 15 requests quickly (limit is 10/min) for (let i = 0; i < 15; i++) { const res = await request.post(`${API_BASE}/api/payments/create-invoice`, { data: { botId: `test-${i}` }, }) responses.push(res.status()) } // At least some should be 429 (rate limited) expect(responses.some(s => s === 429)).toBe(true) }) }) test.describe('API security headers', () => { test('responses include security headers', async ({ request }) => { const res = await request.get(`${API_BASE}/api/health`) const headers = res.headers() expect(headers['x-content-type-options']).toBe('nosniff') expect(headers['x-frame-options']).toBe('DENY') }) })