feat/overview-artifact/main #32

Merged
admin merged 8 commits from feat/overview-artifact/main into master 2026-09-17 06:24:24 +00:00
Showing only changes of commit 47529d33c2 - Show all commits
+78
View File
@@ -249,3 +249,81 @@ test('估算插在段落內容結尾,不會掉到下一個段落裡', async (t
'估算要留在關聯段落內',
);
});
// ── 總覽網頁的連結 ─────────────────────────────────────────────────
test('把總覽網頁的連結寫進總覽段落', async (t) => {
const stub = await withStub(t, {}, {
body: '## 總覽\n\n一句話總覽。\n\n## 關聯\n\n需求議題:#1\n',
});
await run(['--overview-url', 'https://example.com/artifact/abc'], stub);
const updated = patchOf(stub).body.body;
const overview = updated.slice(0, updated.indexOf('## 關聯'));
assert.match(overview, /圖解版總覽:https:\/\/example\.com\/artifact\/abc/);
});
test('連結旁註明 artifact 預設私有', async (t) => {
const stub = await withStub(t, {}, { body: '## 總覽\n\n一句話總覽。\n' });
await run(['--overview-url', 'https://example.com/a'], stub);
assert.match(patchOf(stub).body.body, /私有/);
assert.match(patchOf(stub).body.body, /組織外/);
});
test('議題原本的 markdown 白話總覽保留不動', async (t) => {
const stub = await withStub(t, {}, {
body: '## 總覽\n\n這段白話總覽不該被網頁取代。\n\n## 背景\n\n背景說明。\n',
});
await run(['--overview-url', 'https://example.com/a'], stub);
const updated = patchOf(stub).body.body;
assert.match(updated, /這段白話總覽不該被網頁取代。/);
assert.match(updated, /## 背景\n\n背景說明。/);
});
test('重跑時原地更新同一行,不會長出第二個連結', async (t) => {
const stub = await withStub(t, {}, {
body: '## 總覽\n\n一句話。\n圖解版總覽:https://example.com/old(此連結預設為私有,組織外無法開啟)\n',
});
await run(['--overview-url', 'https://example.com/new'], stub);
const updated = patchOf(stub).body.body;
assert.equal((updated.match(/圖解版總覽:/g) ?? []).length, 1);
assert.match(updated, /example\.com\/new/);
assert.equal(updated.includes('example.com/old'), false);
});
test('連結沒變時不重寫 body', async (t) => {
const stub = await withStub(t, {}, {
body: '## 總覽\n\n一句話。\n圖解版總覽:https://example.com/a(此連結預設為私有,組織外無法開啟)\n',
});
await run(['--overview-url', 'https://example.com/a'], stub);
assert.equal('body' in patchOf(stub).body, false);
});
test('不是網址時擋在打 Gitea 之前', async (t) => {
const stub = await withStub(t);
const { json } = await run(['--overview-url', '不是網址'], stub);
assert.equal(json.error.code, 'BAD_OVERVIEW_URL');
assert.equal(stub.requests.length, 0);
});
test('總覽網頁與其他欄位可以一次送出', async (t) => {
const stub = await withStub(t);
await run(['--overview-url', 'https://example.com/a', '--due-date', '2026-09-24'], stub);
const patches = stub.requests.filter((r) => r.method === 'PATCH' && !r.path.endsWith('/0'));
assert.equal(patches.length, 1);
assert.match(patches[0].body.body, /圖解版總覽/);
assert.equal(patches[0].body.due_date, '2026-09-24T00:00:00Z');
});