Phase3
This commit is contained in:
111
apps/api/test/phase3.test.js
Normal file
111
apps/api/test/phase3.test.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import {
|
||||
parsePropertiesFile,
|
||||
serializePropertiesFile,
|
||||
} from '../dist/servers/properties/server-properties.util.js';
|
||||
import { assertSafeServerPath } from '../dist/servers/shared/server-path.util.js';
|
||||
|
||||
describe('phase 3 server utilities', () => {
|
||||
it('parses server.properties with types', () => {
|
||||
const raw = [
|
||||
'# comment',
|
||||
'max-players=20',
|
||||
'online-mode=false',
|
||||
'motd=Hello World',
|
||||
'',
|
||||
].join('\n');
|
||||
|
||||
const parsed = parsePropertiesFile(raw);
|
||||
assert.equal(parsed['max-players'], 20);
|
||||
assert.equal(parsed['online-mode'], false);
|
||||
assert.equal(parsed['motd'], 'Hello World');
|
||||
});
|
||||
|
||||
it('serializes server.properties while preserving comments', () => {
|
||||
const raw = '# header\nmax-players=10\nonline-mode=true\n';
|
||||
const updated = parsePropertiesFile(raw);
|
||||
updated['max-players'] = 25;
|
||||
updated['online-mode'] = false;
|
||||
|
||||
const serialized = serializePropertiesFile(updated, raw);
|
||||
assert.match(serialized, /^# header/);
|
||||
assert.match(serialized, /max-players=25/);
|
||||
assert.match(serialized, /online-mode=false/);
|
||||
});
|
||||
|
||||
it('rejects path traversal', () => {
|
||||
assert.throws(
|
||||
() => assertSafeServerPath('../etc/passwd'),
|
||||
(error) => error.message.includes('traversal'),
|
||||
);
|
||||
assert.throws(() => assertSafeServerPath('foo//bar'));
|
||||
});
|
||||
|
||||
it('normalizes safe paths', () => {
|
||||
assert.equal(assertSafeServerPath(''), '.');
|
||||
assert.equal(assertSafeServerPath('logs/latest.log'), 'logs/latest.log');
|
||||
assert.equal(assertSafeServerPath('\\world\\level.dat'), 'world/level.dat');
|
||||
});
|
||||
});
|
||||
|
||||
describe('phase 3 api contract', () => {
|
||||
it('documents console, files, properties and players routes', () => {
|
||||
const files = [
|
||||
'servers/console/console.controller.ts',
|
||||
'servers/files/files.controller.ts',
|
||||
'servers/properties/properties.controller.ts',
|
||||
'servers/players/players.controller.ts',
|
||||
'servers/console/console.gateway.ts',
|
||||
];
|
||||
|
||||
for (const file of files) {
|
||||
const source = readFileSync(join(process.cwd(), 'src', file), 'utf8');
|
||||
assert.ok(source.length > 0, `${file} should exist`);
|
||||
}
|
||||
|
||||
const consoleSource = readFileSync(
|
||||
join(process.cwd(), 'src', 'servers/console/console.controller.ts'),
|
||||
'utf8',
|
||||
);
|
||||
assert.ok(consoleSource.includes("@Get('token')"));
|
||||
|
||||
const gatewaySource = readFileSync(
|
||||
join(process.cwd(), 'src', 'servers/console/console.gateway.ts'),
|
||||
'utf8',
|
||||
);
|
||||
assert.ok(gatewaySource.includes('console/ws'));
|
||||
|
||||
const filesSource = readFileSync(
|
||||
join(process.cwd(), 'src', 'servers/files/files.controller.ts'),
|
||||
'utf8',
|
||||
);
|
||||
assert.ok(filesSource.includes("@Get('content')"));
|
||||
|
||||
const propertiesSource = readFileSync(
|
||||
join(process.cwd(), 'src', 'servers/properties/properties.controller.ts'),
|
||||
'utf8',
|
||||
);
|
||||
assert.ok(propertiesSource.includes("@Patch()"));
|
||||
|
||||
const playersSource = readFileSync(
|
||||
join(process.cwd(), 'src', 'servers/players/players.controller.ts'),
|
||||
'utf8',
|
||||
);
|
||||
assert.ok(playersSource.includes('whitelist'));
|
||||
|
||||
const combined = [
|
||||
consoleSource,
|
||||
gatewaySource,
|
||||
filesSource,
|
||||
propertiesSource,
|
||||
playersSource,
|
||||
].join('\n');
|
||||
for (const snippet of ['files', 'properties', 'players']) {
|
||||
assert.ok(combined.includes(snippet), `missing route hint ${snippet}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user