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.
115 lines
4.6 KiB
JavaScript
115 lines
4.6 KiB
JavaScript
// 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'
|
|
);
|
|
});
|