91 lines
3.5 KiB
JavaScript
91 lines
3.5 KiB
JavaScript
const { test, before, after } = require('node:test');
|
|
const assert = require('node:assert');
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
|
|
let requestRouter = async () => ({ statusCode: 200, headers: {}, body: { text: async () => '{}' } });
|
|
const undici = require('undici');
|
|
const _origUndiciRequest = undici.request;
|
|
undici.request = (...a) => requestRouter(...a);
|
|
delete require.cache[require.resolve('../lib/hosters')];
|
|
const hostersMod = require('../lib/hosters');
|
|
const { uploadFile } = hostersMod;
|
|
|
|
let tmpFile;
|
|
let origFetch;
|
|
before(() => {
|
|
tmpFile = path.join(os.tmpdir(), `byse-itest-${process.pid}.mkv`);
|
|
fs.writeFileSync(tmpFile, Buffer.alloc(2048, 7));
|
|
origFetch = global.fetch;
|
|
});
|
|
after(() => {
|
|
global.fetch = origFetch;
|
|
undici.request = _origUndiciRequest;
|
|
delete require.cache[require.resolve('../lib/hosters')];
|
|
try { fs.unlinkSync(tmpFile); } catch {}
|
|
});
|
|
|
|
function stubByseUploadServer() {
|
|
global.fetch = async (url) => {
|
|
if (/upload\/server/.test(String(url))) {
|
|
return { status: 200, text: async () => JSON.stringify({ status: 200, result: 'https://node1.byse.sx/upload/01' }) };
|
|
}
|
|
return { status: 200, text: async () => '{"status":200}' };
|
|
};
|
|
}
|
|
|
|
test('byse explicit "Not video file format" throws fast WITHOUT recovery polling', async () => {
|
|
stubByseUploadServer();
|
|
let listCalls = 0;
|
|
requestRouter = async (url, opts) => {
|
|
const u = String(url);
|
|
if (/\/api\/file\/list/.test(u)) {
|
|
listCalls++;
|
|
return { statusCode: 200, headers: {}, body: { text: async () => '{"status":200,"result":{"files":[]}}' } };
|
|
}
|
|
if (opts && opts.body && typeof opts.body[Symbol.asyncIterator] === 'function') {
|
|
for await (const chunk of opts.body) { if (chunk && chunk.length === -1) break; }
|
|
}
|
|
return {
|
|
statusCode: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
body: { text: async () => JSON.stringify({ status: 200, msg: 'OK', files: [{ filecode: '', filename: 'x.mkv', status: 'Not video file format' }] }) }
|
|
};
|
|
};
|
|
|
|
await assert.rejects(
|
|
() => uploadFile('byse.sx', tmpFile, 'VALIDKEY', null, null, null),
|
|
(err) => err.fileRejected === true && /Not video file format/i.test(err.message)
|
|
);
|
|
|
|
assert.strictEqual(listCalls, 1, 'file/list should be hit ONCE (baseline only) — no 15-attempt recovery poll on explicit rejection');
|
|
});
|
|
|
|
test('byse empty filecode WITHOUT explicit rejection still polls recovery', async () => {
|
|
stubByseUploadServer();
|
|
let listCalls = 0;
|
|
requestRouter = async (url, opts) => {
|
|
const u = String(url);
|
|
if (/\/api\/file\/list/.test(u)) {
|
|
listCalls++;
|
|
const body = listCalls === 1
|
|
? '{"status":200,"result":{"files":[]}}'
|
|
: JSON.stringify({ status: 200, result: { files: [{ file_code: 'RECOVERED99', title: path.basename(tmpFile) }] } });
|
|
return { statusCode: 200, headers: {}, body: { text: async () => body } };
|
|
}
|
|
if (opts && opts.body && typeof opts.body[Symbol.asyncIterator] === 'function') {
|
|
for await (const chunk of opts.body) { if (chunk && chunk.length === -1) break; }
|
|
}
|
|
return {
|
|
statusCode: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
body: { text: async () => JSON.stringify({ status: 200, msg: 'OK' }) }
|
|
};
|
|
};
|
|
|
|
const res = await uploadFile('byse.sx', tmpFile, 'VALIDKEY', null, null, null);
|
|
assert.strictEqual(res.file_code, 'RECOVERED99');
|
|
assert.ok(listCalls >= 2, 'recovery polling must run when there is no explicit rejection');
|
|
});
|