// Profile page integration tests: verifies the profile API endpoint is accessible // from the profile page context (public, no auth). const { describe, it, before, after } = require('node:test'); const assert = require('node:assert/strict'); const { setup, teardown, cleanup } = require('../helpers'); describe('profile page (public)', () => { let baseUrl, userSeq = 0; before(async () => { baseUrl = await setup(); }); after(async () => { await teardown(); cleanup(); }); async function registerAndLogin(username, password) { await fetch(`${baseUrl}/api/auth/register`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); const res = await fetch(`${baseUrl}/api/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username, password }), }); assert.equal(res.status, 200); const setCookie = res.headers.get('set-cookie'); assert.ok(setCookie, 'Login should set a session cookie'); return setCookie.split(';')[0]; } async function createHero(cookie, heroName, heroClass) { const res = await fetch(`${baseUrl}/api/character`, { method: 'POST', headers: { 'Content-Type': 'application/json', Cookie: cookie }, body: JSON.stringify({ name: heroName, class: heroClass }), }); assert.equal(res.status, 201); return jsonSafe(res); } async function jsonSafe(res) { return res.json(); } function updateHeroField(characterId, column, value) { const db = require('../../src/db').getDb(); db.prepare(`UPDATE characters SET ${column} = ? WHERE id = ?`).run(value, characterId); } it('page loads and profile API returns correct data for a warrior', async () => { const cookie = await registerAndLogin(`profuser1`, 'password123'); await createHero(cookie, 'ProfileWarrior', 'warrior'); updateHeroField( require('../../src/db').getDb().prepare('SELECT id FROM characters WHERE name = ?').get('ProfileWarrior').id, 'level', 7 ); const res = await fetch(`${baseUrl}/api/heroes/ProfileWarrior`); assert.equal(res.status, 200); const json = await res.json(); assert.equal(json.ok, true); assert.equal(json.data.name, 'ProfileWarrior'); assert.equal(json.data.class, 'warrior'); assert.equal(json.data.level, 7); assert.ok('str' in json.data); assert.ok('agi' in json.data); assert.ok('int' in json.data); assert.ok('vit' in json.data); assert.ok('equipment' in json.data); assert.ok('weapon' in json.data.equipment); assert.ok('armor' in json.data.equipment); assert.ok('trinket' in json.data.equipment); }); it('page loads and profile API returns correct data for a mage', async () => { const cookie = await registerAndLogin(`profuser2`, 'password123'); await createHero(cookie, 'ProfileMage', 'mage'); const res = await fetch(`${baseUrl}/api/heroes/ProfileMage`); assert.equal(res.status, 200); const json = await res.json(); assert.equal(json.ok, true); assert.equal(json.data.name, 'ProfileMage'); assert.equal(json.data.class, 'mage'); }); it('page loads and profile API returns correct data for a ranger', async () => { const cookie = await registerAndLogin(`profuser3`, 'password123'); await createHero(cookie, 'ProfileRanger', 'ranger'); const res = await fetch(`${baseUrl}/api/heroes/ProfileRanger`); assert.equal(res.status, 200); const json = await res.json(); assert.equal(json.ok, true); assert.equal(json.data.name, 'ProfileRanger'); assert.equal(json.data.class, 'ranger'); }); it('returns 404 for non-existent hero', async () => { const res = await fetch(`${baseUrl}/api/heroes/DoesNotExist12345`); assert.equal(res.status, 404); const json = await res.json(); assert.equal(json.ok, false); assert.equal(json.error.code, 'NOT_FOUND'); }); it('hero names with special chars are URL-safe', async () => { const cookie = await registerAndLogin(`profuser4`, 'password123'); await createHero(cookie, "O'Brien", 'warrior'); const res = await fetch(`${baseUrl}/api/heroes/${encodeURIComponent("O'Brien")}`); assert.equal(res.status, 200); const json = await res.json(); assert.equal(json.ok, true); assert.equal(json.data.name, "O'Brien"); }); });