diff --git a/server/lint-teleport-docs-links.test.ts b/server/lint-teleport-docs-links.test.ts new file mode 100644 index 0000000..2371f2d --- /dev/null +++ b/server/lint-teleport-docs-links.test.ts @@ -0,0 +1,48 @@ +import { describe, expect, test } from "@jest/globals"; +import { remarkLintTeleportDocsLinks } from "./lint-teleport-docs-links"; +import { VFile } from "vfile"; +import { remark } from "remark"; +import mdx from "remark-mdx"; + +const getReasons = (value: string) => { + return remark() + .use(mdx as any) + .use(remarkLintTeleportDocsLinks as any) + .processSync(new VFile({ value, path: "mypath.mdx" }) as any) + .messages.map((m) => m.reason); +}; + +describe("server/lint-absolute-docs-links", () => { + interface testCase { + description: string; + input: string; + expected: Array; + } + + const testCases: Array = [ + { + description: "absolute docs path in a Markdown link href", + input: "This is a [link](https://goteleport.com/docs/installation)", + expected: [ + "Link reference https://goteleport.com/docs/installation must be a relative link to an *.mdx page", + ], + }, + { + description: "absolute docs path in an a tag", + input: "here", + expected: [ + "Component href https://goteleport.com/docs/installation must be a relative link to an *.mdx page", + ], + }, + { + description: "JavaScript identifier as href value", + input: + "You can download our avatar to set as your Bot Icon.", + expected: [], + }, + ]; + + test.each(testCases)("$description", (tc) => { + expect(getReasons(tc.input)).toEqual(tc.expected); + }); +}); diff --git a/server/lint-teleport-docs-links.ts b/server/lint-teleport-docs-links.ts index 7e6e37a..49004eb 100644 --- a/server/lint-teleport-docs-links.ts +++ b/server/lint-teleport-docs-links.ts @@ -24,6 +24,11 @@ const isMdxComponentWithHref = (node: Node): node is MdxAnyElement => { }; const isAnAbsoluteDocsLink = (href: string): boolean => { + // The href is not a string value, and is likely an AST node object. Skip + // the absolute link check. + if (typeof href != "string") { + return false; + } return ( href.startsWith("/docs") || href.startsWith("https://goteleport.com/docs") ); @@ -35,7 +40,9 @@ export const remarkLintTeleportDocsLinks = lintRule( visit(root, undefined, (node: Node) => { if (node.type == "link" && isAnAbsoluteDocsLink((node as Link).url)) { vfile.message( - `Link reference ${(node as Link).url} must be a relative link to an *.mdx page`, + `Link reference ${ + (node as Link).url + } must be a relative link to an *.mdx page`, node.position ); return;