feat: add online FAQ/KB sync without old bridge
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { extractFaqFromLdJson } = require('../src/faq-fetcher');
|
||||
const { updateMarkdownFile } = require('../src/faq-update');
|
||||
|
||||
test('faq: extracts FAQPage JSON-LD questions', () => {
|
||||
const html = `<script type="application/ld+json">{"@type":"FAQPage","mainEntity":[{"name":"Q1?","acceptedAnswer":{"text":"A1"}},{"name":"Q2?","acceptedAnswer":{"text":"A2"}}]}</script>`;
|
||||
const qs = extractFaqFromLdJson(html);
|
||||
assert.deepEqual(qs, [{ q: 'Q1?', a: 'A1' }, { q: 'Q2?', a: 'A2' }]);
|
||||
});
|
||||
|
||||
test('faq: updates existing answer and appends new question', () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'kb-faq-'));
|
||||
const file = path.join(dir, '01.md');
|
||||
fs.writeFileSync(file, '---\ntitle: T\n---\n### Q: Old?\nold answer\n');
|
||||
const r = updateMarkdownFile(file, [{ q: 'Old?', a: 'new answer' }, { q: 'New?', a: 'new q answer' }]);
|
||||
assert.equal(r.changed, true);
|
||||
assert.equal(r.updated, 1);
|
||||
assert.equal(r.added, 1);
|
||||
const out = fs.readFileSync(file, 'utf8');
|
||||
assert.match(out, /Old\?\nnew answer/);
|
||||
assert.match(out, /New\?\nnew q answer/);
|
||||
});
|
||||
|
||||
test('faq: normalized question match avoids duplicate append', () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'kb-faq-norm-'));
|
||||
const file = path.join(dir, '01.md');
|
||||
fs.writeFileSync(file, '---\ntitle: T\n---\n### Q: How does Brexit affect shipping\nold\n');
|
||||
const r = updateMarkdownFile(file, [{ q: 'How does Brexit affect shipping?', a: 'new' }]);
|
||||
assert.equal(r.added, 0);
|
||||
assert.equal(r.updated, 1);
|
||||
const out = fs.readFileSync(file, 'utf8');
|
||||
assert.equal((out.match(/### Q:/g) || []).length, 1);
|
||||
assert.match(out, /new/);
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const { parseFrontmatter, splitChunks, createParentChildChunks } = require('../src/kb-chunker');
|
||||
|
||||
test('kb chunker: parse frontmatter and split Q/A', () => {
|
||||
const md = `---\ntitle: Test\ncategory: test\nkeywords: [ring, gold]\nsource_url: https://www.yehwang.com/x.html\n---\n## Section\n### Q: What is it?\nLong answer ${'x'.repeat(600)}\n`;
|
||||
const { meta, body } = parseFrontmatter(md);
|
||||
assert.equal(meta.title, 'Test');
|
||||
assert.deepEqual(meta.keywords, ['ring', 'gold']);
|
||||
const chunks = splitChunks(body);
|
||||
assert.equal(chunks.length, 1);
|
||||
const { parent, children } = createParentChildChunks(chunks[0], meta, '01-test.md');
|
||||
assert.equal(parent.question, 'What is it?');
|
||||
assert.equal(parent.source_urls[0], 'https://www.yehwang.com/x.html');
|
||||
assert.equal(children.length, 2);
|
||||
});
|
||||
Reference in New Issue
Block a user