88 lines
3.9 KiB
JavaScript
88 lines
3.9 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const http = require('node:http');
|
|
const test = require('node:test');
|
|
const {
|
|
createEzRemoteServerClient,
|
|
buildDownloadRequest,
|
|
normalizeDownloadStates,
|
|
} = require('../../src/services/ezremote-server-client');
|
|
|
|
test('ezRemote request builder maps the documented client types and enforces safe PS5 roots', () => {
|
|
const payload = buildDownloadRequest({
|
|
source: { protocol: 'smb', host: 'server.example.test', port: 445, path: '/Media/roms/PS5', username: 'chimera' },
|
|
sourcePath: 'CUSA00001/game.pkg',
|
|
destinationPath: '/data/ezremote/CUSA00001.pkg',
|
|
size: 123,
|
|
id: 42,
|
|
password: 'transient-only',
|
|
});
|
|
assert.deepEqual(payload, {
|
|
type: 2,
|
|
url: 'smb://server.example.test:445',
|
|
username: 'chimera',
|
|
password: 'transient-only',
|
|
src_path: '/Media/roms/PS5/CUSA00001/game.pkg',
|
|
dest_path: '/data/ezremote/CUSA00001.pkg',
|
|
size: 123,
|
|
id: 42,
|
|
});
|
|
assert.throws(() => buildDownloadRequest({ source: { protocol: 'smb', host: 'tower', port: 445 }, sourcePath: '../secret', destinationPath: '/data/ezremote/x', id: 1 }), /geen \.\./i);
|
|
assert.throws(() => buildDownloadRequest({ source: { protocol: 'smb', host: 'tower', port: 445 }, sourcePath: 'game.pkg', destinationPath: '/system/unsafe.pkg', id: 1 }), /veilige ezRemote-roots/i);
|
|
});
|
|
|
|
test('ezRemote client probes version, normalizes progress and submits the exact upstream JSON contract', async t => {
|
|
const requests = [];
|
|
const states = [{ path: '/data/ezremote/already.pkg', bytes_transfered: 50, file_size: 100, state: 2, timestamp: 7 }];
|
|
const server = http.createServer((req, res) => {
|
|
if (req.url === '/version') return res.end('0.3.3');
|
|
if (req.url === '/get_download_state') {
|
|
res.setHeader('Content-Type', 'application/json');
|
|
return res.end(JSON.stringify(states));
|
|
}
|
|
if (req.url === '/download_url' && req.method === 'POST') {
|
|
const chunks = [];
|
|
req.on('data', chunk => chunks.push(chunk));
|
|
return req.on('end', () => {
|
|
requests.push(JSON.parse(Buffer.concat(chunks).toString('utf8')));
|
|
res.statusCode = 200;
|
|
res.end('');
|
|
});
|
|
}
|
|
res.statusCode = 404;
|
|
res.end();
|
|
});
|
|
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
|
t.after(() => new Promise(resolve => server.close(resolve)));
|
|
const values = new Map([['ftp.host', '127.0.0.1'], ['ezremote.serverPort', server.address().port]]);
|
|
const client = createEzRemoteServerClient({ settings: { get: (key, fallback) => values.has(key) ? values.get(key) : fallback } });
|
|
|
|
const probe = await client.probe();
|
|
assert.equal(probe.reachable, true);
|
|
assert.equal(probe.version, '0.3.3');
|
|
assert.equal(probe.downloads[0].state, 'resumed');
|
|
assert.equal(probe.downloads[0].percent, 50);
|
|
assert.equal(probe.capabilities.cancel, false);
|
|
|
|
const source = { protocol: 'ftp', host: 'nas.local', port: 21, path: '/roms', username: 'jens' };
|
|
const existing = await client.ensureDownload({ source, sourcePath: 'already.pkg', destinationPath: '/data/ezremote/already.pkg', id: 11 });
|
|
assert.equal(existing.submitted, false);
|
|
assert.equal(requests.length, 0);
|
|
|
|
const submitted = await client.submit({ source, sourcePath: 'new.pkg', destinationPath: '/data/ezremote/new.pkg', id: 12, password: 'runtime-secret' });
|
|
assert.equal(submitted.accepted, true);
|
|
assert.equal(requests.length, 1);
|
|
assert.deepEqual(requests[0], {
|
|
type: 0, url: 'ftp://nas.local:21', username: 'jens', password: 'runtime-secret',
|
|
src_path: '/roms/new.pkg', dest_path: '/data/ezremote/new.pkg', size: 0, id: 12,
|
|
});
|
|
});
|
|
|
|
test('ezRemote download status normalizer bounds unknown console data', () => {
|
|
const rows = normalizeDownloadStates([{ path: 'bad\0\npath', bytes_transfered: -1, file_size: 0, state: 99, timestamp: -2 }]);
|
|
assert.equal(rows[0].path, 'bad path');
|
|
assert.equal(rows[0].transferred, 0);
|
|
assert.equal(rows[0].state, 'unknown');
|
|
});
|