mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-15 19:32:20 +03:00
fix(docs): resolve relative markdown and wiki links across Fumadocs and GitHub wiki (#11834)
Resolução de links relativos entre Fumadocs e a wiki do GitHub, com dois arquivos de teste novos e bem focados (`docs-link-resolver.test.ts`, `sync-wiki.test.ts`). Validado no worktree combinado. Obrigado!
This commit is contained in:
107
tests/unit/docs-link-resolver.test.ts
Normal file
107
tests/unit/docs-link-resolver.test.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import {
|
||||
resolveDocHref,
|
||||
normalizeDocsMarkdownLinks,
|
||||
GITHUB_REPO_BLOB_URL,
|
||||
} from "../../src/lib/docsLinkResolver.js";
|
||||
|
||||
test("resolveDocHref: rewrites relative doc-to-doc links to extensionless Fumadocs paths", () => {
|
||||
assert.equal(
|
||||
resolveDocHref("../routing/AUTO-COMBO.md", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/routing/AUTO-COMBO"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("./RESILIENCE_GUIDE.md", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/architecture/RESILIENCE_GUIDE"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("getting-started/QUICK-START.md", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/getting-started/QUICK-START"
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocHref: preserves hash fragments in rewritten doc paths", () => {
|
||||
assert.equal(
|
||||
resolveDocHref("../routing/AUTO-COMBO.md#14-factors", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/routing/AUTO-COMBO#14-factors"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("./RESILIENCE_GUIDE.md#circuit-breaker", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/architecture/RESILIENCE_GUIDE#circuit-breaker"
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocHref: normalizes root-level /docs/... and docs/... links", () => {
|
||||
assert.equal(
|
||||
resolveDocHref("/docs/frameworks/MCP-SERVER.md", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/frameworks/MCP-SERVER"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("docs/frameworks/MCP-SERVER.md#canonical-tools", "architecture/ARCHITECTURE.md"),
|
||||
"/docs/frameworks/MCP-SERVER#canonical-tools"
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocHref: rewrites links escaping docs/ to GitHub repo blob URLs", () => {
|
||||
assert.equal(
|
||||
resolveDocHref("../../src/lib/db/core.ts", "architecture/ARCHITECTURE.md"),
|
||||
`${GITHUB_REPO_BLOB_URL}/src/lib/db/core.ts`
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("../../package.json", "architecture/ARCHITECTURE.md"),
|
||||
`${GITHUB_REPO_BLOB_URL}/package.json`
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("../../README.md", "architecture/ARCHITECTURE.md"),
|
||||
`${GITHUB_REPO_BLOB_URL}/README.md`
|
||||
);
|
||||
});
|
||||
|
||||
test("resolveDocHref: leaves external URLs and pure anchor links untouched", () => {
|
||||
assert.equal(
|
||||
resolveDocHref("https://github.com/diegosouzapw/OmniRoute", "architecture/ARCHITECTURE.md"),
|
||||
"https://github.com/diegosouzapw/OmniRoute"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("http://localhost:20128/v1", "architecture/ARCHITECTURE.md"),
|
||||
"http://localhost:20128/v1"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("mailto:support@example.com", "architecture/ARCHITECTURE.md"),
|
||||
"mailto:support@example.com"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("#pipeline", "architecture/ARCHITECTURE.md"),
|
||||
"#pipeline"
|
||||
);
|
||||
assert.equal(
|
||||
resolveDocHref("", "architecture/ARCHITECTURE.md"),
|
||||
""
|
||||
);
|
||||
});
|
||||
|
||||
test("normalizeDocsMarkdownLinks: rewrites inline, reference, and HTML links in markdown", () => {
|
||||
const md = `
|
||||
# Sample Docs
|
||||
|
||||
See the [Auto Combo](../routing/AUTO-COMBO.md) guide or [Resilience Docs](./RESILIENCE_GUIDE.md#layers).
|
||||
Check [DB Implementation](../../src/lib/db/core.ts) for details.
|
||||
Reference: [External][1] and [Internal Reference][2].
|
||||
Pure anchor: [Jump to top](#top).
|
||||
HTML link: <a href="../routing/AUTO-COMBO.md#scoring">Scoring</a>.
|
||||
|
||||
[1]: https://example.com "Example"
|
||||
[2]: ../frameworks/MCP-SERVER.md "MCP"
|
||||
`;
|
||||
|
||||
const out = normalizeDocsMarkdownLinks(md, "architecture/ARCHITECTURE.md");
|
||||
|
||||
assert.ok(out.includes("[Auto Combo](/docs/routing/AUTO-COMBO)"));
|
||||
assert.ok(out.includes("[Resilience Docs](/docs/architecture/RESILIENCE_GUIDE#layers)"));
|
||||
assert.ok(out.includes(`[DB Implementation](${GITHUB_REPO_BLOB_URL}/src/lib/db/core.ts)`));
|
||||
assert.ok(out.includes("[Jump to top](#top)"));
|
||||
assert.ok(out.includes('<a href="/docs/routing/AUTO-COMBO#scoring">Scoring</a>'));
|
||||
assert.ok(out.includes('[2]: /docs/frameworks/MCP-SERVER "MCP"'));
|
||||
assert.ok(out.includes('[1]: https://example.com "Example"'));
|
||||
});
|
||||
@@ -6,10 +6,13 @@ import {
|
||||
normKey,
|
||||
toWikiName,
|
||||
toWikiContent,
|
||||
rewriteWikiLinks,
|
||||
syncHomeCounts,
|
||||
parseWikiPage,
|
||||
WIKI_BANNER,
|
||||
NEW_PAGE_EXCLUDE,
|
||||
GITHUB_REPO_URL,
|
||||
GITHUB_RAW_URL,
|
||||
} from "../../scripts/docs/sync-wiki.mjs";
|
||||
|
||||
test("normKey: case/separator-insensitive fuzzy key (matches docs basename to curated wiki name)", () => {
|
||||
@@ -42,6 +45,83 @@ test("toWikiContent: a document without frontmatter is kept intact (plus banner)
|
||||
assert.equal(out, WIKI_BANNER + "# No Frontmatter\n\nHello.\n");
|
||||
});
|
||||
|
||||
test("rewriteWikiLinks: converts relative doc links to curated wiki page names", () => {
|
||||
const wikiKeyMap = new Map([
|
||||
["autocombo", "Auto-Combo"],
|
||||
["resilienceguide", "Resilience-Guide"],
|
||||
["mcpserver", "MCP-Server"],
|
||||
]);
|
||||
|
||||
const md = `
|
||||
# Architecture
|
||||
|
||||
See [Auto-Combo](../routing/AUTO-COMBO.md) and [Resilience](./RESILIENCE_GUIDE.md).
|
||||
With anchor: [14 Factors](../routing/AUTO-COMBO.md#14-factors).
|
||||
Ref style: [MCP][mcp-ref]
|
||||
HTML: <a href="../routing/AUTO-COMBO.md#strategies">Strategies</a>
|
||||
|
||||
[mcp-ref]: ../frameworks/MCP-SERVER.md "MCP Tools"
|
||||
`;
|
||||
|
||||
const out = rewriteWikiLinks(md, {
|
||||
srcFile: "docs/architecture/ARCHITECTURE.md",
|
||||
wikiKeyMap,
|
||||
});
|
||||
|
||||
assert.ok(out.includes("[Auto-Combo](Auto-Combo)"));
|
||||
assert.ok(out.includes("[Resilience](Resilience-Guide)"));
|
||||
assert.ok(out.includes("[14 Factors](Auto-Combo#14-factors)"));
|
||||
assert.ok(out.includes('[mcp-ref]: MCP-Server "MCP Tools"'));
|
||||
assert.ok(out.includes('<a href="Auto-Combo#strategies">Strategies</a>'));
|
||||
});
|
||||
|
||||
test("rewriteWikiLinks: converts repo code and root markdown links to GitHub blob URLs", () => {
|
||||
const md = `
|
||||
Refer to [DB Core](../../src/lib/db/core.ts) and [README](../README.md).
|
||||
Check [Package config](../../package.json) and [Auth Guard](../../src/server/authz/routeGuard.ts).
|
||||
`;
|
||||
|
||||
const out = rewriteWikiLinks(md, {
|
||||
srcFile: "docs/architecture/ARCHITECTURE.md",
|
||||
});
|
||||
|
||||
assert.ok(out.includes(`[DB Core](${GITHUB_REPO_URL}/blob/main/src/lib/db/core.ts)`));
|
||||
assert.ok(out.includes(`[README](${GITHUB_REPO_URL}/blob/main/docs/README.md)`));
|
||||
assert.ok(out.includes(`[Package config](${GITHUB_REPO_URL}/blob/main/package.json)`));
|
||||
assert.ok(out.includes(`[Auth Guard](${GITHUB_REPO_URL}/blob/main/src/server/authz/routeGuard.ts)`));
|
||||
});
|
||||
|
||||
test("rewriteWikiLinks: rewrites image links to GitHub raw content URLs", () => {
|
||||
const md = ``;
|
||||
const out = rewriteWikiLinks(md, {
|
||||
srcFile: "docs/architecture/ARCHITECTURE.md",
|
||||
});
|
||||
assert.equal(
|
||||
out,
|
||||
``
|
||||
);
|
||||
});
|
||||
|
||||
test("rewriteWikiLinks: preserves pure anchor links and external URLs", () => {
|
||||
const md = `[Top](#top) and [Website](https://example.com) and [Email](mailto:test@example.com)`;
|
||||
const out = rewriteWikiLinks(md, {
|
||||
srcFile: "docs/architecture/ARCHITECTURE.md",
|
||||
});
|
||||
assert.equal(out, md);
|
||||
});
|
||||
|
||||
test("rewriteWikiLinks: prepends locale prefix for localized wiki pages", () => {
|
||||
const wikiKeyMap = new Map([["autocombo", "Auto-Combo"]]);
|
||||
const md = `[Auto-Combo](../routing/AUTO-COMBO.md#scoring)`;
|
||||
const out = rewriteWikiLinks(md, {
|
||||
srcFile: "docs/i18n/pt-BR/routing/AUTO-COMBO.md",
|
||||
wikiKeyMap,
|
||||
locale: "pt-BR",
|
||||
});
|
||||
// U+2010 HYPHEN
|
||||
assert.equal(out, "[Auto-Combo](pt-BR\u2010Auto-Combo#scoring)");
|
||||
});
|
||||
|
||||
test("syncHomeCounts: rewrites the cover-page provider/strategy counts", () => {
|
||||
const home = "Connect every AI tool to 177 providers.\n**177 AI Providers** · **14 Routing Strategies**\n";
|
||||
const out = syncHomeCounts(home, { providers: 226, strategies: 15, mcpTools: null, locales: 42 });
|
||||
|
||||
Reference in New Issue
Block a user