Files
outline/server/queues/tasks/ImportJSONTask.test.ts
T
Tom Moor 091346dfe8 chore: Migrate to vitest (#12272)
* 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>
2026-05-06 21:10:51 -04:00

156 lines
4.7 KiB
TypeScript

import path from "node:path";
import { FileOperation, User } from "@server/models";
import {
buildFileOperation,
buildUser,
buildTeam,
buildAdmin,
} from "@server/test/factories";
import ImportJSONTask from "./ImportJSONTask";
// The fixture has these values for both documents:
// createdById: "ccec260a-e060-4925-ade8-17cfabaf2cac"
// createdByEmail: "hmac.devo@gmail.com"
const fixtureCreatedById = "ccec260a-e060-4925-ade8-17cfabaf2cac";
const fixtureCreatedByEmail = "hmac.devo@gmail.com";
const fixturePath = path.resolve(
__dirname,
"..",
"..",
"test",
"fixtures",
"outline-json.zip"
);
function mockHandle(fileOperation: FileOperation) {
Object.defineProperty(fileOperation, "handle", {
get() {
return {
path: fixturePath,
cleanup: async () => {},
};
},
});
vi.spyOn(FileOperation, "findByPk").mockResolvedValue(fileOperation);
}
describe("ImportJSONTask", () => {
it("should import the documents, attachments", async () => {
const fileOperation = await buildFileOperation();
mockHandle(fileOperation);
const task = new ImportJSONTask();
const response = await task.perform({
fileOperationId: fileOperation.id,
});
expect(response.collections.size).toEqual(1);
expect(response.documents.size).toEqual(2);
expect(response.attachments.size).toEqual(1);
});
describe("user mapping", () => {
it("should map createdById to an existing user by ID", async () => {
// Ensure a user exists with the fixture's createdById, handling the
// case where it may already exist from a prior test run.
let originalAuthor = await User.findByPk(fixtureCreatedById);
const teamId = originalAuthor?.teamId ?? (await buildTeam()).id;
if (!originalAuthor) {
originalAuthor = await buildUser({
id: fixtureCreatedById,
teamId,
});
}
const admin = await buildAdmin({ teamId });
const fileOperation = await buildFileOperation({
userId: admin.id,
teamId,
});
mockHandle(fileOperation);
const task = new ImportJSONTask();
const response = await task.perform({
fileOperationId: fileOperation.id,
});
for (const document of response.documents.values()) {
expect(document.createdById).toEqual(originalAuthor.id);
expect(document.lastModifiedById).toEqual(originalAuthor.id);
}
});
it("should fall back to email matching when ID does not match", async () => {
const team = await buildTeam();
// User has matching email but a different ID
const originalAuthor = await buildUser({
teamId: team.id,
email: fixtureCreatedByEmail,
});
const admin = await buildAdmin({ teamId: team.id });
const fileOperation = await buildFileOperation({
userId: admin.id,
teamId: team.id,
});
mockHandle(fileOperation);
const task = new ImportJSONTask();
const response = await task.perform({
fileOperationId: fileOperation.id,
});
for (const document of response.documents.values()) {
expect(document.createdById).toEqual(originalAuthor.id);
expect(document.lastModifiedById).toEqual(originalAuthor.id);
}
});
it("should fall back to importing user when no match is found", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const fileOperation = await buildFileOperation({
userId: admin.id,
teamId: team.id,
});
mockHandle(fileOperation);
const task = new ImportJSONTask();
const response = await task.perform({
fileOperationId: fileOperation.id,
});
for (const document of response.documents.values()) {
expect(document.createdById).toEqual(admin.id);
expect(document.lastModifiedById).toEqual(admin.id);
}
});
it("should not match users from a different team", async () => {
const team = await buildTeam();
const otherTeam = await buildTeam();
// Create user with matching email in a different team
await buildUser({
teamId: otherTeam.id,
email: fixtureCreatedByEmail,
});
const admin = await buildAdmin({ teamId: team.id });
const fileOperation = await buildFileOperation({
userId: admin.id,
teamId: team.id,
});
mockHandle(fileOperation);
const task = new ImportJSONTask();
const response = await task.perform({
fileOperationId: fileOperation.id,
});
for (const document of response.documents.values()) {
expect(document.createdById).toEqual(admin.id);
}
});
});
});