Files
tono/frontend/tests/defaultWorkflow.test.mjs

118 lines
3.4 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { embedWorkflow } from '../src/pngMetadata.js';
import { loadDefaultWorkflowAsset } from '../src/defaultWorkflow.js';
const PNG_BASE64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+aF9sAAAAASUVORK5CYII=';
function makePngBlob() {
return new Blob([Buffer.from(PNG_BASE64, 'base64')], { type: 'image/png' });
}
test('loadDefaultWorkflowAsset prefers checked-in JSON when present', async () => {
const workflow = { version: 1, nodes: [{ id: '1' }], edges: [] };
const requests = [];
const fetchImpl = async (url) => {
requests.push(url);
if (url === '/default-workflow.json') {
return {
ok: true,
status: 200,
async json() {
return workflow;
},
};
}
throw new Error('PNG fallback should not be requested when JSON exists');
};
const loaded = await loadDefaultWorkflowAsset({ fetchImpl });
assert.deepEqual(loaded, {
source: '/default-workflow.json',
format: 'json',
workflow,
});
assert.deepEqual(requests, ['/default-workflow.json']);
});
test('loadDefaultWorkflowAsset falls back to PNG workflow metadata when JSON is missing', async () => {
const workflow = { version: 1, nodes: [{ id: '2' }], edges: [] };
const pngWithWorkflow = await embedWorkflow(makePngBlob(), workflow);
const requests = [];
const fetchImpl = async (url) => {
requests.push(url);
if (url === '/default-workflow.json') {
return { ok: false, status: 404 };
}
if (url === '/default-workflow.png') {
return {
ok: true,
status: 200,
async blob() {
return pngWithWorkflow;
},
};
}
throw new Error(`Unexpected URL ${url}`);
};
const loaded = await loadDefaultWorkflowAsset({ fetchImpl });
assert.deepEqual(loaded, {
source: '/default-workflow.png',
format: 'png',
workflow,
});
assert.deepEqual(requests, ['/default-workflow.json', '/default-workflow.png']);
});
test('loadDefaultWorkflowAsset returns null when no default workflow asset is present', async () => {
const fetchImpl = async () => ({ ok: false, status: 404 });
const loaded = await loadDefaultWorkflowAsset({ fetchImpl });
assert.equal(loaded, null);
});
test('loadDefaultWorkflowAsset stays quiet when default assets are simply absent in the host runtime', async () => {
const fetchImpl = async () => {
throw new TypeError('Failed to fetch');
};
const loaded = await loadDefaultWorkflowAsset({ fetchImpl });
assert.equal(loaded, null);
});
test('loadDefaultWorkflowAsset stays quiet when the host serves app HTML for missing default assets', async () => {
const fetchImpl = async (url) => ({
ok: true,
status: 200,
headers: {
get(name) {
return name.toLowerCase() === 'content-type' ? 'text/html; charset=utf-8' : null;
},
},
async json() {
throw new SyntaxError(`Unexpected token '<' while parsing ${url}`);
},
async blob() {
return new Blob(['<html></html>'], { type: 'text/html' });
},
});
const loaded = await loadDefaultWorkflowAsset({ fetchImpl });
assert.equal(loaded, null);
});
test('loadDefaultWorkflowAsset stays quiet when the host reports missing assets with status 0', async () => {
const fetchImpl = async () => ({ ok: false, status: 0 });
const loaded = await loadDefaultWorkflowAsset({ fetchImpl });
assert.equal(loaded, null);
});