mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
82d7041b6b
* chore: Refactor Markdown importer to use new import pipeline --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
117 lines
3.4 KiB
TypeScript
117 lines
3.4 KiB
TypeScript
import {
|
|
rewriteAttachmentPaths,
|
|
rewriteInternalLinks,
|
|
} from "./MarkdownAPIImportTask";
|
|
|
|
describe("rewriteAttachmentPaths", () => {
|
|
it("replaces a direct encoded path with the placeholder", () => {
|
|
const out = rewriteAttachmentPaths(
|
|
"",
|
|
[{ id: "att-1", pathInZip: "My Collection/attachments/foo.png" }]
|
|
);
|
|
expect(out).toBe("");
|
|
});
|
|
|
|
it("normalizes legacy `uploads/` bucket layout", () => {
|
|
const out = rewriteAttachmentPaths("", [
|
|
{
|
|
id: "att-2",
|
|
pathInZip: "Some Collection/uploads/abc/file.png",
|
|
},
|
|
]);
|
|
expect(out).toBe("");
|
|
});
|
|
|
|
it("normalizes legacy `public/` bucket layout", () => {
|
|
const out = rewriteAttachmentPaths("", [
|
|
{
|
|
id: "att-3",
|
|
pathInZip: "Some Collection/public/abc/file.png",
|
|
},
|
|
]);
|
|
expect(out).toBe("");
|
|
});
|
|
|
|
it("handles arbitrary folder names like 'attachments/'", () => {
|
|
const out = rewriteAttachmentPaths("", [
|
|
{ id: "att-4", pathInZip: "Collection/attachments/foo.png" },
|
|
]);
|
|
expect(out).toBe("");
|
|
});
|
|
|
|
it("matches nested attachments folders", () => {
|
|
const out = rewriteAttachmentPaths("", [
|
|
{
|
|
id: "att-5",
|
|
pathInZip: "Collection/Doc/attachments/sub/bar.png",
|
|
},
|
|
]);
|
|
expect(out).toBe("");
|
|
});
|
|
|
|
it("substitutes multiple references in the same document", () => {
|
|
const out = rewriteAttachmentPaths(
|
|
" and ",
|
|
[
|
|
{ id: "id-a", pathInZip: "C/attachments/a.png" },
|
|
{ id: "id-b", pathInZip: "C/attachments/b.png" },
|
|
]
|
|
);
|
|
expect(out).toBe(" and ");
|
|
});
|
|
|
|
it("is a no-op when no attachments match", () => {
|
|
const out = rewriteAttachmentPaths("", [
|
|
{ id: "id-a", pathInZip: "C/attachments/a.png" },
|
|
]);
|
|
expect(out).toBe("");
|
|
});
|
|
});
|
|
|
|
describe("rewriteInternalLinks", () => {
|
|
it("rewrites a sibling .md link to a placeholder", () => {
|
|
const out = rewriteInternalLinks(
|
|
"see [other](./other.md)",
|
|
"Collection/parent.md",
|
|
{ "Collection/other.md": "doc-1" }
|
|
);
|
|
expect(out).toBe("see [other](<<doc-1>>)");
|
|
});
|
|
|
|
it("rewrites a nested .md link", () => {
|
|
const out = rewriteInternalLinks(
|
|
"see [child](./sub/child.md)",
|
|
"Collection/parent.md",
|
|
{ "Collection/sub/child.md": "doc-2" }
|
|
);
|
|
expect(out).toBe("see [child](<<doc-2>>)");
|
|
});
|
|
|
|
it("leaves unresolved .md links untouched", () => {
|
|
const out = rewriteInternalLinks(
|
|
"see [missing](./missing.md)",
|
|
"Collection/parent.md",
|
|
{}
|
|
);
|
|
expect(out).toBe("see [missing](./missing.md)");
|
|
});
|
|
|
|
it("ignores non-md links", () => {
|
|
const out = rewriteInternalLinks(
|
|
"see [site](https://example.com)",
|
|
"Collection/parent.md",
|
|
{ "Collection/parent.md": "doc-self" }
|
|
);
|
|
expect(out).toBe("see [site](https://example.com)");
|
|
});
|
|
|
|
it("decodes encoded path segments before lookup", () => {
|
|
const out = rewriteInternalLinks(
|
|
"see [other](./My%20Doc.md)",
|
|
"Collection/parent.md",
|
|
{ "Collection/My Doc.md": "doc-3" }
|
|
);
|
|
expect(out).toBe("see [other](<<doc-3>>)");
|
|
});
|
|
});
|