98 lines
3.9 KiB
JavaScript
98 lines
3.9 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert');
|
|
const { renderFolderTree, renderExecutionList, renderExecutionDetail, renderN8nPage } = require('../src/n8nView');
|
|
|
|
test('renderFolderTree renders nothing for an empty tree', () => {
|
|
assert.strictEqual(renderFolderTree([]), '');
|
|
});
|
|
|
|
test('renderFolderTree renders a workflow item with its id in a data attribute', () => {
|
|
const html = renderFolderTree([{ type: 'workflow', id: 'w1', name: 'ワークフローA', active: true }]);
|
|
assert.ok(html.includes('data-workflow-id="w1"'));
|
|
assert.ok(html.includes('ワークフローA'));
|
|
});
|
|
|
|
test('renderFolderTree marks inactive workflows differently from active ones', () => {
|
|
const activeHtml = renderFolderTree([{ type: 'workflow', id: 'w1', name: 'A', active: true }]);
|
|
const inactiveHtml = renderFolderTree([{ type: 'workflow', id: 'w2', name: 'B', active: false }]);
|
|
assert.ok(activeHtml.includes('bg-success'));
|
|
assert.ok(inactiveHtml.includes('bg-secondary'));
|
|
});
|
|
|
|
test('renderFolderTree escapes HTML in workflow and folder names', () => {
|
|
const html = renderFolderTree([{ type: 'workflow', id: 'w1', name: '<script>bad</script>', active: true }]);
|
|
assert.ok(!html.includes('<script>bad</script>'));
|
|
assert.ok(html.includes('<script>'));
|
|
});
|
|
|
|
test('renderFolderTree nests folder children inside the folder element', () => {
|
|
const html = renderFolderTree([
|
|
{
|
|
type: 'folder',
|
|
id: 'f1',
|
|
name: 'フォルダA',
|
|
children: [{ type: 'workflow', id: 'w1', name: 'ワークフローA', active: true }],
|
|
},
|
|
]);
|
|
assert.ok(html.includes('フォルダA'));
|
|
assert.ok(html.includes('data-workflow-id="w1"'));
|
|
});
|
|
|
|
test('renderExecutionList renders a row per execution with a status badge', () => {
|
|
const html = renderExecutionList([
|
|
{ id: 'e1', status: 'success', startedAt: '2026-09-19T00:00:00.000Z' },
|
|
{ id: 'e2', status: 'error', startedAt: '2026-09-18T00:00:00.000Z' },
|
|
]);
|
|
assert.ok(html.includes('data-execution-id="e1"'));
|
|
assert.ok(html.includes('data-execution-id="e2"'));
|
|
assert.ok(html.includes('bg-success'));
|
|
assert.ok(html.includes('bg-danger'));
|
|
});
|
|
|
|
test('renderExecutionList shows the started time converted to JST, not raw UTC', () => {
|
|
const html = renderExecutionList([{ id: 'e1', status: 'success', startedAt: '2026-09-19T00:00:00.000Z' }]);
|
|
assert.ok(html.includes('2026-09-19 09:00:00'));
|
|
assert.ok(!html.includes('2026-09-19T00:00:00.000Z'));
|
|
});
|
|
|
|
test('renderExecutionList shows a Japanese label for each status', () => {
|
|
const statuses = ['success', 'error', 'running', 'waiting', 'canceled'];
|
|
for (const status of statuses) {
|
|
const html = renderExecutionList([{ id: 'e1', status, startedAt: '2026-09-19T00:00:00.000Z' }]);
|
|
assert.ok(!html.includes(`>${status}<`), `expected status "${status}" to be translated`);
|
|
}
|
|
});
|
|
|
|
test('renderExecutionList shows a message when there are no executions', () => {
|
|
const html = renderExecutionList([]);
|
|
assert.ok(html.includes('実行履歴なし'));
|
|
});
|
|
|
|
test('renderExecutionDetail lists each node result with its status', () => {
|
|
const execution = {
|
|
id: 'e1',
|
|
status: 'error',
|
|
data: {
|
|
resultData: {
|
|
runData: {
|
|
'SSH: 対象wav一覧取得': [{ error: undefined }],
|
|
'IF: 未登録ファイルあり': [{ error: { message: 'timeout' } }],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
const html = renderExecutionDetail(execution);
|
|
assert.ok(html.includes('SSH: 対象wav一覧取得'));
|
|
assert.ok(html.includes('IF: 未登録ファイルあり'));
|
|
assert.ok(html.includes('timeout'));
|
|
});
|
|
|
|
test('renderN8nPage embeds the folder tree and a container for execution details', () => {
|
|
const tree = [{ type: 'workflow', id: 'w1', name: 'ワークフローA', active: true }];
|
|
const html = renderN8nPage(tree);
|
|
assert.ok(html.includes('data-workflow-id="w1"'));
|
|
assert.ok(html.includes('id="executionList"'));
|
|
assert.ok(html.includes('id="executionDetail"'));
|
|
assert.ok(html.includes('/n8n.js'));
|
|
});
|