Files
ark-stronghold-protocol/test/static-local-art.test.js
T
sganggs 01a44cd288 卫戍协议:盟约 web remake — initial import
Online co-op browser remake of Arknights' Stronghold Protocol: Alliance
(client-simulated combat, official waves/bonds/items/strategies, 3D board,
facing wheel, operator loadout, official emotes, deployment scripts).
2026-09-29 16:21:31 +08:00

72 lines
2.8 KiB
JavaScript

// The optional local-client art manifest (data/local-assets.json, DESIGN §13): an install without it must get an
// empty manifest (200) instead of a 404, and an install with it must get the real file.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import http from 'node:http';
import { fileURLToPath } from 'node:url';
import { createStaticHandler } from '../server/index.js';
const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
function serve(dataDir) {
const handler = createStaticHandler({ publicDir: path.join(ROOT, 'public'), dataDir, sharedDir: path.join(ROOT, 'shared') });
const srv = http.createServer((req, res) => {
const [p, q] = req.url.split('?');
handler(req, res, p, q || '');
});
return new Promise((resolve) => srv.listen(0, '127.0.0.1', () => resolve(srv)));
}
function get(srv, url, method = 'GET') {
return new Promise((resolve, reject) => {
const req = http.request({ host: '127.0.0.1', port: srv.address().port, path: url, method }, (res) => {
let body = '';
res.setEncoding('utf8');
res.on('data', (d) => { body += d; });
res.on('end', () => resolve({ status: res.statusCode, type: res.headers['content-type'], body }));
});
req.on('error', reject);
req.end();
});
}
test('missing data/local-assets.json → 200 empty manifest (no 404 on installs without local art)', async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sp-noart-'));
fs.writeFileSync(path.join(dir, 'config.json'), '{}');
const srv = await serve(dir);
try {
const r = await get(srv, '/data/local-assets.json');
assert.equal(r.status, 200);
assert.match(r.type, /application\/json/);
const doc = JSON.parse(r.body);
assert.deepEqual(doc.groups, {});
const h = await get(srv, '/data/local-assets.json', 'HEAD');
assert.equal(h.status, 200);
assert.equal(h.body, '');
// other missing data files still 404
assert.equal((await get(srv, '/data/nope.json')).status, 404);
assert.equal((await get(srv, '/data/sub/local-assets.json')).status, 404);
} finally {
srv.close();
fs.rmSync(dir, { recursive: true, force: true });
}
});
test('present data/local-assets.json is served as-is', async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sp-art-'));
const doc = { version: 1, source: 'local-client', count: 1, groups: { module: { 'mar-x': { path: '/assets/local/module/mar-x.png' } } } };
fs.writeFileSync(path.join(dir, 'local-assets.json'), JSON.stringify(doc));
const srv = await serve(dir);
try {
const r = await get(srv, '/data/local-assets.json');
assert.equal(r.status, 200);
assert.deepEqual(JSON.parse(r.body), doc);
} finally {
srv.close();
fs.rmSync(dir, { recursive: true, force: true });
}
});