GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。 NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは 別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
66 lines
2.7 KiB
JavaScript
66 lines
2.7 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert');
|
|
const Module = require('module');
|
|
|
|
function withMocked(modulePath, mockExports, fn) {
|
|
const resolved = require.resolve(modulePath);
|
|
const original = require.cache[resolved];
|
|
require.cache[resolved] = new Module(resolved);
|
|
require.cache[resolved].exports = mockExports;
|
|
return Promise.resolve(fn()).finally(() => {
|
|
if (original) {
|
|
require.cache[resolved] = original;
|
|
} else {
|
|
delete require.cache[resolved];
|
|
}
|
|
});
|
|
}
|
|
|
|
test('buildCards skips composes without a valid PORTAL_APP_TYPE and reports fetch errors separately', async () => {
|
|
delete require.cache[require.resolve('../src/dashboard')];
|
|
await withMocked('../src/dokployClient', {
|
|
listComposes: async () => [
|
|
{ composeId: 'c1', name: 'auth-redirect', composeStatus: 'done' },
|
|
{ composeId: 'c2', name: 'gitea', composeStatus: 'done' },
|
|
{ composeId: 'c3', name: 'broken-app', composeStatus: 'error' },
|
|
],
|
|
getComposeEnv: async (composeId) => {
|
|
if (composeId === 'c1') return { env: 'PORTAL_APP_TYPE=web\nPORTAL_APP_URL=https://x', appName: 'auth-redirect-uzt5hx' };
|
|
if (composeId === 'c2') return { env: null, appName: 'gitea-xyz' };
|
|
throw new Error('boom');
|
|
},
|
|
getContainers: async () => [{ containerId: 'abc', state: 'running' }],
|
|
}, async () => {
|
|
const { buildCards } = require('../src/dashboard');
|
|
const cards = await buildCards('env-1');
|
|
assert.strictEqual(cards.length, 2);
|
|
assert.strictEqual(cards[0].composeId, 'c1');
|
|
assert.strictEqual(cards[0].meta.appType, 'web');
|
|
assert.strictEqual(cards[0].containerState, 'running');
|
|
assert.deepStrictEqual(cards[1], { error: true, composeId: 'c3', name: 'broken-app' });
|
|
});
|
|
});
|
|
|
|
test('renderCard escapes HTML in labels and shows a "trigger" button for batch apps', () => {
|
|
delete require.cache[require.resolve('../src/dashboard')];
|
|
const { renderCard } = require('../src/dashboard');
|
|
const html = renderCard({
|
|
composeId: 'c1',
|
|
appName: 'sample',
|
|
composeStatus: 'done',
|
|
containerState: 'running',
|
|
meta: { appType: 'batch', label: '<script>bad</script>', url: 'http://sample:3000', triggerPath: '/trigger' },
|
|
});
|
|
assert.ok(!html.includes('<script>bad</script>'));
|
|
assert.ok(html.includes('<script>'));
|
|
assert.ok(html.includes('data-action="trigger"'));
|
|
assert.ok(!html.includes('data-action="start"'));
|
|
});
|
|
|
|
test('renderCard shows an "状態取得失敗" message for error cards', () => {
|
|
const { renderCard } = require('../src/dashboard');
|
|
const html = renderCard({ error: true, composeId: 'c3', name: 'broken-app' });
|
|
assert.ok(html.includes('状態取得失敗'));
|
|
assert.ok(html.includes('broken-app'));
|
|
});
|