step 10.8: wip (not ticked)
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
// Integration tests for POST /api/character/allocate endpoint.
|
||||
const { describe, it, before, after } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { setup, teardown, cleanup } = require('../helpers');
|
||||
|
||||
describe('POST /api/character/allocate (integration)', () => {
|
||||
let baseUrl;
|
||||
let loginCookie;
|
||||
|
||||
before(async () => {
|
||||
baseUrl = await setup();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
const { resetNow } = require('../../src/utils/time');
|
||||
resetNow();
|
||||
await teardown();
|
||||
cleanup();
|
||||
});
|
||||
|
||||
function allocate(body) {
|
||||
return fetch(`${baseUrl}/api/character/allocate`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Cookie: loginCookie },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
}
|
||||
|
||||
function registerAndLogin(username) {
|
||||
return fetch(`${baseUrl}/api/auth/register`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password: 'password123' }),
|
||||
}).then(() => fetch(`${baseUrl}/api/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password: 'password123' }),
|
||||
}));
|
||||
}
|
||||
|
||||
function createHero(cookie, name) {
|
||||
return fetch(`${baseUrl}/api/character`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', Cookie: cookie },
|
||||
body: JSON.stringify({ name, class: 'warrior' }),
|
||||
});
|
||||
}
|
||||
|
||||
it('spend 2 of 3 points on STR → str +2, unspent_points 1, derived attack increased', async () => {
|
||||
const res = await registerAndLogin('alloc1');
|
||||
loginCookie = res.headers.get('set-cookie');
|
||||
await createHero(loginCookie, 'Allocher1');
|
||||
|
||||
// Use the service directly to set up test state (bypasses HTTP/session layer)
|
||||
const db = require('../../src/db').getDb();
|
||||
const svc = require('../../src/services/characterService');
|
||||
const userId = Number(db.prepare('SELECT id FROM users WHERE username = ?').get('alloc1').id);
|
||||
const char = db.prepare('SELECT id FROM characters WHERE user_id = ?').get(userId);
|
||||
db.prepare('UPDATE characters SET unspent_points = 3 WHERE id = ?').run(char.id);
|
||||
|
||||
const allocateRes = await allocate({ str: 2 });
|
||||
assert.equal(allocateRes.status, 200);
|
||||
|
||||
const body = await allocateRes.json();
|
||||
assert.equal(body.ok, true);
|
||||
assert.equal(body.data.character.str, 10); // warrior base 8 + 2
|
||||
assert.equal(body.data.character.unspent_points, 1);
|
||||
// Warrior attack = 5 + str*2 + level = 5 + 10*2 + 1 = 26
|
||||
assert.equal(body.data.derived.attack, 26);
|
||||
});
|
||||
|
||||
it('spending 4 of 3 → 422 NOT_ENOUGH_POINTS, nothing changed', async () => {
|
||||
const res = await registerAndLogin('alloc2');
|
||||
loginCookie = res.headers.get('set-cookie');
|
||||
await createHero(loginCookie, 'Allocher2');
|
||||
|
||||
const db = require('../../src/db').getDb();
|
||||
const userId = Number(db.prepare('SELECT id FROM users WHERE username = ?').get('alloc2').id);
|
||||
const char = db.prepare('SELECT id FROM characters WHERE user_id = ?').get(userId);
|
||||
db.prepare('UPDATE characters SET unspent_points = 3 WHERE id = ?').run(char.id);
|
||||
|
||||
const allocateRes = await allocate({ str: 4 });
|
||||
assert.equal(allocateRes.status, 422);
|
||||
|
||||
const body = await allocateRes.json();
|
||||
assert.equal(body.ok, false);
|
||||
assert.equal(body.error.code, 'NOT_ENOUGH_POINTS');
|
||||
|
||||
// Verify nothing changed in DB
|
||||
const refreshed = db.prepare('SELECT str, unspent_points FROM characters WHERE id = ?').get(char.id);
|
||||
assert.equal(refreshed.str, 8); // warrior base unchanged
|
||||
assert.equal(refreshed.unspent_points, 3); // points unchanged
|
||||
});
|
||||
|
||||
it('negative values → 400', async () => {
|
||||
const res = await registerAndLogin('alloc3');
|
||||
loginCookie = res.headers.get('set-cookie');
|
||||
await createHero(loginCookie, 'Allocher3');
|
||||
|
||||
const allocateRes = await allocate({ str: -1 });
|
||||
assert.equal(allocateRes.status, 400);
|
||||
const body = await allocateRes.json();
|
||||
assert.equal(body.ok, false);
|
||||
});
|
||||
|
||||
it('float values → 400', async () => {
|
||||
const res = await registerAndLogin('alloc4');
|
||||
loginCookie = res.headers.get('set-cookie');
|
||||
await createHero(loginCookie, 'Allocher4');
|
||||
|
||||
const allocateRes = await allocate({ str: 1.5 });
|
||||
assert.equal(allocateRes.status, 400);
|
||||
const body = await allocateRes.json();
|
||||
assert.equal(body.ok, false);
|
||||
});
|
||||
|
||||
it('unknown keys → 400', async () => {
|
||||
const res = await registerAndLogin('alloc5');
|
||||
loginCookie = res.headers.get('set-cookie');
|
||||
await createHero(loginCookie, 'Allocher5');
|
||||
|
||||
const allocateRes = await allocate({ str: 1, luck: 1 });
|
||||
assert.equal(allocateRes.status, 400);
|
||||
const body = await allocateRes.json();
|
||||
assert.equal(body.ok, false);
|
||||
});
|
||||
|
||||
it('another user cannot affect user A\'s character', async () => {
|
||||
const db = require('../../src/db').getDb();
|
||||
|
||||
// Get user A's character (from first test)
|
||||
const charA = db.prepare('SELECT id, str FROM characters WHERE name = ?').get('Allocher1');
|
||||
const oldStr = charA.str;
|
||||
|
||||
// User B creates hero and tries to allocate
|
||||
const res = await registerAndLogin('alloc_b');
|
||||
loginCookie = res.headers.get('set-cookie');
|
||||
await createHero(loginCookie, 'AllocherB');
|
||||
|
||||
// User B allocates on their own character (which has 0 unspent points)
|
||||
const allocateRes = await allocate({ str: 1 });
|
||||
assert.equal(allocateRes.status, 422); // NOT_ENOUGH_POINTS for user B
|
||||
|
||||
// User A's character is untouched
|
||||
const refreshed = db.prepare('SELECT str FROM characters WHERE id = ?').get(charA.id);
|
||||
assert.equal(refreshed.str, oldStr);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user