mirror of
https://github.com/outline/outline.git
synced 2026-06-13 03:14:59 +03:00
091346dfe8
* wip * Remove obsolete snapshots * simplify * chore(test): Convert mocks to TypeScript and tighten fetch mock types Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Remove unneccessary patches * Migrate to msw instead of custom fetch mock * Address PR review comments - Split chained vi.useFakeTimers().setSystemTime() into separate calls. - Switch test setup to dynamic imports so EventEmitter.defaultMaxListeners assignment runs before module init (static imports were hoisted above it). - Drop redundant NODE_ENV guard in monkeyPatchSequelizeErrorsForJest; its sole caller already gates on env.isTest. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
171 lines
4.3 KiB
TypeScript
171 lines
4.3 KiB
TypeScript
import { createContext } from "@server/context";
|
|
import { buildProseMirrorDoc, buildUser } from "@server/test/factories";
|
|
import { ProsemirrorHelper } from "./ProsemirrorHelper";
|
|
|
|
vi.mock("@server/storage/files");
|
|
|
|
describe("ProsemirrorHelper", () => {
|
|
describe("replaceImagesWithAttachments", () => {
|
|
it("should return the same document when there are no images", async () => {
|
|
const user = await buildUser();
|
|
const ctx = createContext({ user });
|
|
|
|
const doc = buildProseMirrorDoc([
|
|
{
|
|
type: "paragraph",
|
|
content: [{ type: "text", text: "No images here" }],
|
|
},
|
|
]);
|
|
|
|
const result = await ProsemirrorHelper.replaceImagesWithAttachments(
|
|
ctx,
|
|
doc,
|
|
user
|
|
);
|
|
|
|
expect(result.toJSON()).toEqual(doc.toJSON());
|
|
});
|
|
|
|
it("should correctly identify images in a document", () => {
|
|
const doc = buildProseMirrorDoc([
|
|
{
|
|
type: "paragraph",
|
|
content: [
|
|
{
|
|
type: "image",
|
|
attrs: {
|
|
src: "https://example.com/image.png",
|
|
alt: "Test image",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const images = ProsemirrorHelper.getImages(doc);
|
|
expect(images.length).toBe(1);
|
|
expect(images[0].attrs.src).toBe("https://example.com/image.png");
|
|
expect(images[0].attrs.alt).toBe("Test image");
|
|
});
|
|
|
|
it("should skip images with invalid URLs", async () => {
|
|
const user = await buildUser();
|
|
const ctx = createContext({ user });
|
|
|
|
const doc = buildProseMirrorDoc([
|
|
{
|
|
type: "paragraph",
|
|
content: [
|
|
{
|
|
type: "image",
|
|
attrs: {
|
|
src: "not-a-valid-url",
|
|
alt: "Invalid",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const result = await ProsemirrorHelper.replaceImagesWithAttachments(
|
|
ctx,
|
|
doc,
|
|
user
|
|
);
|
|
|
|
// Document should remain unchanged since URL is invalid
|
|
expect(result.toJSON()).toEqual(doc.toJSON());
|
|
});
|
|
|
|
it("should skip images with internal URLs", async () => {
|
|
const user = await buildUser();
|
|
const ctx = createContext({ user });
|
|
|
|
const doc = buildProseMirrorDoc([
|
|
{
|
|
type: "paragraph",
|
|
content: [
|
|
{
|
|
type: "image",
|
|
attrs: {
|
|
src: "/api/attachments.redirect?id=existing-id",
|
|
alt: "Internal",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const result = await ProsemirrorHelper.replaceImagesWithAttachments(
|
|
ctx,
|
|
doc,
|
|
user
|
|
);
|
|
|
|
// Document should remain unchanged since URL is internal
|
|
expect(result.toJSON()).toEqual(doc.toJSON());
|
|
});
|
|
|
|
it("should handle document with multiple node types", async () => {
|
|
const user = await buildUser();
|
|
const ctx = createContext({ user });
|
|
|
|
const doc = buildProseMirrorDoc([
|
|
{
|
|
type: "heading",
|
|
attrs: { level: 1 },
|
|
content: [{ type: "text", text: "Title" }],
|
|
},
|
|
{
|
|
type: "paragraph",
|
|
content: [{ type: "text", text: "Some text" }],
|
|
},
|
|
{
|
|
type: "paragraph",
|
|
content: [
|
|
{
|
|
type: "image",
|
|
attrs: {
|
|
src: "invalid-url",
|
|
alt: "Image",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
]);
|
|
|
|
const result = await ProsemirrorHelper.replaceImagesWithAttachments(
|
|
ctx,
|
|
doc,
|
|
user
|
|
);
|
|
|
|
// Document structure should be preserved
|
|
expect(result.content.childCount).toBe(3);
|
|
expect(result.content.child(0).type.name).toBe("heading");
|
|
expect(result.content.child(1).type.name).toBe("paragraph");
|
|
expect(result.content.child(2).type.name).toBe("paragraph");
|
|
});
|
|
|
|
it("should handle empty document", async () => {
|
|
const user = await buildUser();
|
|
const ctx = createContext({ user });
|
|
|
|
const doc = buildProseMirrorDoc([
|
|
{
|
|
type: "paragraph",
|
|
content: [],
|
|
},
|
|
]);
|
|
|
|
const result = await ProsemirrorHelper.replaceImagesWithAttachments(
|
|
ctx,
|
|
doc,
|
|
user
|
|
);
|
|
|
|
expect(result.toJSON()).toEqual(doc.toJSON());
|
|
});
|
|
});
|
|
});
|