fix(ms-ai-architect): registry-herding Fase 1a — +5 sitemap-prefiks + skjemaløs URL-ekstraksjon
Update-mekanismen lot siterte URL-er stå som not_in_sitemap fordi deres docset aldri ble pollet, og skjemaløse citater (tabellceller: bare learn.microsoft.com/... uten https://) ble aldri ekstrahert. - Taxonomy: +5 docsets (graph, ai-builder, power-apps, power-automate, microsoftsearch) — hver ett child-sitemap, verifisert live mot indeksen. Bevist: 21/24 not_in_sitemap-URL-er i disse docsetene blir nå tracked. - url-normalize: extractUrls fanger skjemaløse citater-med-sti (krever /path etter domenet → avviser bare-domene-prosa og JSON-eksempler); normalizeUrl kanonikaliserer scheme til https. Bevist: +19 nye URL-er ekstraherbare. - Bugfix: backtick fra inline-kode-citat (`learn.microsoft.com/...`) lekket inn i URL-en — ekskludert i regex + trailing-strip. TDD: tests/kb-update/test-url-normalize.test.mjs (ny, 14) + test-taxonomy prefiks-count 18→23 + Fase 1a-assertion. Full suite 338/338, 0 regresjon. Registry-refresh (build-registry --merge + poll) bevisst utsatt — unngår 552KB re-order-churn; effekten er empirisk verifisert read-only.
This commit is contained in:
parent
6ae0ed5821
commit
e74646d395
4 changed files with 152 additions and 7 deletions
115
tests/kb-update/test-url-normalize.test.mjs
Normal file
115
tests/kb-update/test-url-normalize.test.mjs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// tests/kb-update/test-url-normalize.test.mjs
|
||||
// Unit tests for scripts/kb-update/lib/url-normalize.mjs.
|
||||
// Pins the canonical-URL contract that build-registry ↔ poll-sitemaps matching
|
||||
// depends on, AND the Fase 1a registry-herding extension: schema-less citations
|
||||
// (learn.microsoft.com/... without the https:// prefix) must be extracted and
|
||||
// canonicalised to https://, while bare-domain prose mentions (no path) and
|
||||
// JSON example strings must NOT be captured.
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { normalizeUrl, extractUrls } from '../../scripts/kb-update/lib/url-normalize.mjs';
|
||||
|
||||
// --- normalizeUrl: existing contract (regression guard) ---
|
||||
test('normalizeUrl — strips locale, fragment, query, trailing slash; lowercases', () => {
|
||||
assert.equal(
|
||||
normalizeUrl('https://learn.microsoft.com/en-us/azure/AI-Foundry/Overview/?view=x#sec'),
|
||||
'https://learn.microsoft.com/azure/ai-foundry/overview'
|
||||
);
|
||||
});
|
||||
|
||||
test('normalizeUrl — strips trailing markdown punctuation', () => {
|
||||
assert.equal(
|
||||
normalizeUrl('https://learn.microsoft.com/azure/foo).'),
|
||||
'https://learn.microsoft.com/azure/foo'
|
||||
);
|
||||
});
|
||||
|
||||
test('normalizeUrl — non-learn URL returns null', () => {
|
||||
assert.equal(normalizeUrl('https://example.com/azure/foo'), null);
|
||||
assert.equal(normalizeUrl(''), null);
|
||||
assert.equal(normalizeUrl(null), null);
|
||||
});
|
||||
|
||||
// --- normalizeUrl: Fase 1a — schema-less canonicalisation ---
|
||||
test('normalizeUrl — schema-less citation gets https:// prepended', () => {
|
||||
assert.equal(
|
||||
normalizeUrl('learn.microsoft.com/azure/api-management/genai-gateway-capabilities'),
|
||||
'https://learn.microsoft.com/azure/api-management/genai-gateway-capabilities'
|
||||
);
|
||||
});
|
||||
|
||||
test('normalizeUrl — schema-less with en-us locale is also canonicalised', () => {
|
||||
assert.equal(
|
||||
normalizeUrl('learn.microsoft.com/en-us/compliance/assurance/assurance-artificial-intelligence'),
|
||||
'https://learn.microsoft.com/compliance/assurance/assurance-artificial-intelligence'
|
||||
);
|
||||
});
|
||||
|
||||
test('normalizeUrl — idempotent on schema-less input', () => {
|
||||
const once = normalizeUrl('learn.microsoft.com/azure/foo');
|
||||
assert.equal(normalizeUrl(once), once);
|
||||
});
|
||||
|
||||
// --- extractUrls: existing contract (regression guard) ---
|
||||
test('extractUrls — extracts https markdown-link URL', () => {
|
||||
assert.deepEqual(
|
||||
extractUrls('See [docs](https://learn.microsoft.com/azure/foo) here.'),
|
||||
['https://learn.microsoft.com/azure/foo']
|
||||
);
|
||||
});
|
||||
|
||||
test('extractUrls — dedups same URL across forms', () => {
|
||||
const out = extractUrls(
|
||||
'https://learn.microsoft.com/azure/foo and learn.microsoft.com/azure/foo'
|
||||
);
|
||||
assert.deepEqual(out, ['https://learn.microsoft.com/azure/foo']);
|
||||
});
|
||||
|
||||
// --- extractUrls: Fase 1a — schema-less table-cell citations (the 2 named files) ---
|
||||
test('extractUrls — captures schema-less table-cell citation', () => {
|
||||
const row = '| **GenAI Gateway** | desc | learn.microsoft.com/azure/api-management/genai-gateway-capabilities |';
|
||||
assert.deepEqual(
|
||||
extractUrls(row),
|
||||
['https://learn.microsoft.com/azure/api-management/genai-gateway-capabilities']
|
||||
);
|
||||
});
|
||||
|
||||
test('extractUrls — captures multiple schema-less rows', () => {
|
||||
const text = [
|
||||
'| A | learn.microsoft.com/en-us/compliance/assurance/assurance-artificial-intelligence |',
|
||||
'| B | learn.microsoft.com/en-us/azure/cloud-adoption-framework/scenarios/ai/govern |',
|
||||
].join('\n');
|
||||
assert.deepEqual(extractUrls(text), [
|
||||
'https://learn.microsoft.com/compliance/assurance/assurance-artificial-intelligence',
|
||||
'https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/ai/govern',
|
||||
]);
|
||||
});
|
||||
|
||||
// --- extractUrls: must NOT capture bare-domain prose / JSON examples ---
|
||||
test('extractUrls — ignores bare-domain prose mention (no path)', () => {
|
||||
assert.deepEqual(
|
||||
extractUrls('All info fra offisiell dokumentasjon (learn.microsoft.com, blogs.microsoft.com).'),
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
test('extractUrls — ignores JSON example string with no path', () => {
|
||||
assert.deepEqual(extractUrls('{"url": "learn.microsoft.com"}'), []);
|
||||
});
|
||||
|
||||
test('extractUrls — strips wrapping backticks from inline-code citation', () => {
|
||||
// `learn.microsoft.com/agent-framework/` inside prose backticks must not leak
|
||||
// the backtick into the URL (would never match a sitemap entry).
|
||||
assert.deepEqual(
|
||||
extractUrls('verifisert mot `learn.microsoft.com/agent-framework/`).'),
|
||||
['https://learn.microsoft.com/agent-framework']
|
||||
);
|
||||
});
|
||||
|
||||
test('normalizeUrl — strips trailing backtick', () => {
|
||||
assert.equal(
|
||||
normalizeUrl('https://learn.microsoft.com/azure/foo`'),
|
||||
'https://learn.microsoft.com/azure/foo'
|
||||
);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue