chore: Improve perf of server tests (#5785)

This commit is contained in:
Tom Moor
2023-09-06 07:14:49 -04:00
committed by GitHub
parent a724a21c21
commit 3eb947e9a5
69 changed files with 2045 additions and 1551 deletions

View File

@@ -1,11 +1,12 @@
import { faker } from "@faker-js/faker";
import { v4 as uuidv4 } from "uuid";
import WelcomeEmail from "@server/emails/templates/WelcomeEmail";
import { TeamDomain } from "@server/models";
import Collection from "@server/models/Collection";
import UserAuthentication from "@server/models/UserAuthentication";
import { buildUser, buildTeam } from "@server/test/factories";
import { buildUser, buildTeam, buildAdmin } from "@server/test/factories";
import {
setupTestDatabase,
seed,
setCloudHosted,
setSelfHosted,
} from "@server/test/support";
@@ -21,24 +22,25 @@ describe("accountProvisioner", () => {
it("should create a new user and team", async () => {
const spy = jest.spyOn(WelcomeEmail.prototype, "schedule");
const email = faker.internet.email();
const { user, team, isNewTeam, isNewUser } = await accountProvisioner({
ip,
user: {
name: "Jenny Tester",
email: "jenny@example-company.com",
avatarUrl: "https://example.com/avatar.png",
email,
avatarUrl: faker.internet.avatar(),
},
team: {
name: "New workspace",
avatarUrl: "https://example.com/avatar.png",
subdomain: "example",
avatarUrl: faker.internet.avatar(),
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: "google",
providerId: "example-company.com",
providerId: faker.internet.domainName(),
},
authentication: {
providerId: "123456789",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},
@@ -49,11 +51,15 @@ describe("accountProvisioner", () => {
expect(auth.scopes.length).toEqual(1);
expect(auth.scopes[0]).toEqual("read");
expect(team.name).toEqual("New workspace");
expect(user.email).toEqual("jenny@example-company.com");
expect(user.email).toEqual(email);
expect(isNewUser).toEqual(true);
expect(isNewTeam).toEqual(true);
expect(spy).toHaveBeenCalled();
const collectionCount = await Collection.count();
const collectionCount = await Collection.count({
where: {
teamId: team.id,
},
});
expect(collectionCount).toEqual(1);
spy.mockRestore();
@@ -69,7 +75,7 @@ describe("accountProvisioner", () => {
});
const authentications = await existing.$get("authentications");
const authentication = authentications[0];
const newEmail = "test@example-company.com";
const newEmail = faker.internet.email();
const { user, isNewUser, isNewTeam } = await accountProvisioner({
ip,
user: {
@@ -80,7 +86,7 @@ describe("accountProvisioner", () => {
team: {
name: existingTeam.name,
avatarUrl: existingTeam.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: authenticationProvider.name,
@@ -100,18 +106,20 @@ describe("accountProvisioner", () => {
expect(isNewTeam).toEqual(false);
expect(isNewUser).toEqual(false);
expect(spy).not.toHaveBeenCalled();
const collectionCount = await Collection.count();
expect(collectionCount).toEqual(0);
spy.mockRestore();
});
it("should allow authentication by email matching", async () => {
const existingTeam = await buildTeam();
it.skip("should allow authentication by email matching", async () => {
const subdomain = faker.internet.domainWord();
const existingTeam = await buildTeam({
subdomain,
});
const providers = await existingTeam.$get("authenticationProviders");
const authenticationProvider = providers[0];
const email = faker.internet.email();
const userWithoutAuth = await buildUser({
email: "email@example.com",
email,
teamId: existingTeam.id,
authentications: [],
});
@@ -120,20 +128,21 @@ describe("accountProvisioner", () => {
ip,
user: {
name: userWithoutAuth.name,
email: "email@example.com",
email,
avatarUrl: userWithoutAuth.avatarUrl,
},
team: {
teamId: existingTeam.id,
name: existingTeam.name,
avatarUrl: existingTeam.avatarUrl,
subdomain: "example",
subdomain,
},
authenticationProvider: {
name: authenticationProvider.name,
providerId: authenticationProvider.providerId,
},
authentication: {
providerId: "anything",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},
@@ -169,7 +178,7 @@ describe("accountProvisioner", () => {
team: {
name: existingTeam.name,
avatarUrl: existingTeam.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: authenticationProvider.name,
@@ -189,9 +198,11 @@ describe("accountProvisioner", () => {
});
it("should throw an error when the domain is not allowed", async () => {
const { admin, team: existingTeam } = await seed();
const existingTeam = await buildTeam();
const admin = await buildAdmin({ teamId: existingTeam.id });
const providers = await existingTeam.$get("authenticationProviders");
const authenticationProvider = providers[0];
const email = faker.internet.email();
await TeamDomain.create({
teamId: existingTeam.id,
@@ -206,20 +217,20 @@ describe("accountProvisioner", () => {
ip,
user: {
name: "Jenny Tester",
email: "jenny@example-company.com",
avatarUrl: "https://example.com/avatar.png",
email,
avatarUrl: faker.internet.avatar(),
},
team: {
name: existingTeam.name,
avatarUrl: existingTeam.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: authenticationProvider.name,
providerId: authenticationProvider.providerId,
},
authentication: {
providerId: "123456789",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},
@@ -233,35 +244,37 @@ describe("accountProvisioner", () => {
it("should create a new user in an existing team when the domain is allowed", async () => {
const spy = jest.spyOn(WelcomeEmail.prototype, "schedule");
const { admin, team } = await seed();
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const authenticationProviders = await team.$get(
"authenticationProviders"
);
const authenticationProvider = authenticationProviders[0];
const domain = faker.internet.domainName();
await TeamDomain.create({
teamId: team.id,
name: "example-company.com",
name: domain,
createdById: admin.id,
});
const email = faker.internet.email({ provider: domain });
const { user, isNewUser } = await accountProvisioner({
ip,
user: {
name: "Jenny Tester",
email: "jenny@example-company.com",
avatarUrl: "https://example.com/avatar.png",
email,
avatarUrl: faker.internet.avatar(),
},
team: {
name: team.name,
avatarUrl: team.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: authenticationProvider.name,
providerId: authenticationProvider.providerId,
},
authentication: {
providerId: "123456789",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},
@@ -271,11 +284,15 @@ describe("accountProvisioner", () => {
expect(auth.accessToken).toEqual("123");
expect(auth.scopes.length).toEqual(1);
expect(auth.scopes[0]).toEqual("read");
expect(user.email).toEqual("jenny@example-company.com");
expect(user.email).toEqual(email);
expect(isNewUser).toEqual(true);
expect(spy).toHaveBeenCalled();
// should provision welcome collection
const collectionCount = await Collection.count();
const collectionCount = await Collection.count({
where: {
teamId: team.id,
},
});
expect(collectionCount).toEqual(1);
spy.mockRestore();
@@ -288,24 +305,25 @@ describe("accountProvisioner", () => {
"authenticationProviders"
);
const authenticationProvider = authenticationProviders[0];
const email = faker.internet.email();
const { user, isNewUser } = await accountProvisioner({
ip,
user: {
name: "Jenny Tester",
email: "jenny@example-company.com",
avatarUrl: "https://example.com/avatar.png",
email,
avatarUrl: faker.internet.avatar(),
},
team: {
name: team.name,
avatarUrl: team.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: authenticationProvider.name,
providerId: authenticationProvider.providerId,
},
authentication: {
providerId: "123456789",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},
@@ -315,11 +333,15 @@ describe("accountProvisioner", () => {
expect(auth.accessToken).toEqual("123");
expect(auth.scopes.length).toEqual(1);
expect(auth.scopes[0]).toEqual("read");
expect(user.email).toEqual("jenny@example-company.com");
expect(user.email).toEqual(email);
expect(isNewUser).toEqual(true);
expect(spy).toHaveBeenCalled();
// should provision welcome collection
const collectionCount = await Collection.count();
const collectionCount = await Collection.count({
where: {
teamId: team.id,
},
});
expect(collectionCount).toEqual(1);
spy.mockRestore();
@@ -338,21 +360,21 @@ describe("accountProvisioner", () => {
ip,
user: {
name: "Jenny Tester",
email: "jenny@example-company.com",
avatarUrl: "https://example.com/avatar.png",
email: faker.internet.email(),
avatarUrl: faker.internet.avatar(),
},
team: {
teamId: team.id,
name: team.name,
avatarUrl: team.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
},
authenticationProvider: {
name: "google",
providerId: "example-company.com",
},
authentication: {
providerId: "123456789",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},
@@ -372,14 +394,14 @@ describe("accountProvisioner", () => {
ip,
user: {
name: "Jenny Tester",
email: "jenny@example-company.com",
avatarUrl: "https://example.com/avatar.png",
email: faker.internet.email(),
avatarUrl: faker.internet.avatar(),
},
team: {
teamId: team.id,
name: team.name,
avatarUrl: team.avatarUrl,
subdomain: "example",
subdomain: faker.internet.domainWord(),
domain: "allowed-domain.com",
},
authenticationProvider: {
@@ -387,7 +409,7 @@ describe("accountProvisioner", () => {
providerId: "allowed-domain.com",
},
authentication: {
providerId: "123456789",
providerId: uuidv4(),
accessToken: "123",
scopes: ["read"],
},

View File

@@ -1,6 +1,5 @@
import { Event } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import commentCreator from "./commentCreator";
setupTestDatabase();
@@ -35,7 +34,7 @@ describe("commentCreator", () => {
ip,
});
const event = await Event.findOne();
const event = await findLatestEvent();
expect(comment.documentId).toEqual(document.id);
expect(comment.createdById).toEqual(user.id);
expect(event!.name).toEqual("comments.create");

View File

@@ -1,6 +1,6 @@
import { Comment, Event } from "@server/models";
import { Comment } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import commentDestroyer from "./commentDestroyer";
setupTestDatabase();
@@ -41,10 +41,14 @@ describe("commentDestroyer", () => {
ip,
});
const count = await Comment.count();
const count = await Comment.count({
where: {
id: comment.id,
},
});
expect(count).toEqual(0);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(event!.name).toEqual("comments.delete");
expect(event!.modelId).toEqual(comment.id);
});

View File

@@ -26,7 +26,11 @@ describe("documentImporter", () => {
content,
ip,
});
const attachments = await Attachment.count();
const attachments = await Attachment.count({
where: {
teamId: user.teamId,
},
});
expect(attachments).toEqual(1);
expect(response.text).toContain("This is a test document for images");
expect(response.text).toContain("![](/api/attachments.redirect?id=");
@@ -46,7 +50,11 @@ describe("documentImporter", () => {
content,
ip,
});
const attachments = await Attachment.count();
const attachments = await Attachment.count({
where: {
teamId: user.teamId,
},
});
expect(attachments).toEqual(1);
expect(response.text).toContain("This is a test document for images");
expect(response.text).toContain("![](/api/attachments.redirect?id=");
@@ -89,7 +97,11 @@ describe("documentImporter", () => {
content,
ip,
});
const attachments = await Attachment.count();
const attachments = await Attachment.count({
where: {
teamId: user.teamId,
},
});
expect(attachments).toEqual(1);
expect(response.text).toContain("This is a test document for images");
expect(response.text).toContain("![](/api/attachments.redirect?id=");

View File

@@ -128,9 +128,10 @@ export default async function loadDocument({
// documentStructure by default through the relationship.
if (document.collectionId) {
collection = await Collection.findByPk(document.collectionId);
}
if (!collection) {
throw NotFoundError("Collection could not be found for document");
if (!collection) {
throw NotFoundError("Collection could not be found for document");
}
}
return {

View File

@@ -1,7 +1,12 @@
import Pin from "@server/models/Pin";
import { sequelize } from "@server/storage/database";
import { buildDocument, buildCollection } from "@server/test/factories";
import { setupTestDatabase, seed } from "@server/test/support";
import {
buildDocument,
buildCollection,
buildTeam,
buildUser,
} from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import documentMover from "./documentMover";
setupTestDatabase();
@@ -10,7 +15,17 @@ describe("documentMover", () => {
const ip = "127.0.0.1";
it("should move within a collection", async () => {
const { document, user, collection } = await seed();
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const document = await buildDocument({
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
const response = await documentMover({
user,
document,
@@ -22,7 +37,17 @@ describe("documentMover", () => {
});
it("should succeed when not in source collection documentStructure", async () => {
const { document, user, collection } = await seed();
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const document = await buildDocument({
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
const newDocument = await buildDocument({
parentDocumentId: document.id,
collectionId: collection.id,
@@ -49,7 +74,17 @@ describe("documentMover", () => {
});
it("should move with children", async () => {
const { document, user, collection } = await seed();
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const document = await buildDocument({
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
const newDocument = await buildDocument({
parentDocumentId: document.id,
collectionId: collection.id,
@@ -77,7 +112,17 @@ describe("documentMover", () => {
});
it("should move with children to another collection", async () => {
const { document, user, collection } = await seed();
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const document = await buildDocument({
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
const newCollection = await buildCollection({
teamId: collection.teamId,
});
@@ -118,7 +163,17 @@ describe("documentMover", () => {
});
it("should remove associated collection pin if moved to another collection", async () => {
const { document, user, collection } = await seed();
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const document = await buildDocument({
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
const newCollection = await buildCollection({
teamId: collection.teamId,
});
@@ -141,7 +196,11 @@ describe("documentMover", () => {
})
);
const pinCount = await Pin.count();
const pinCount = await Pin.count({
where: {
teamId: collection.teamId,
},
});
expect(pinCount).toBe(0);
// check collection structure updated
@@ -155,7 +214,17 @@ describe("documentMover", () => {
});
it("should detach document from collection and move it to drafts", async () => {
const { document, user, collection } = await seed();
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const collection = await buildCollection({
userId: user.id,
teamId: team.id,
});
const document = await buildDocument({
userId: user.id,
collectionId: collection.id,
teamId: team.id,
});
const response = await sequelize.transaction(async (transaction) =>
documentMover({

View File

@@ -19,6 +19,9 @@ describe("documentPermanentDeleter", () => {
expect(countDeletedDoc).toEqual(1);
expect(
await Document.unscoped().count({
where: {
teamId: document.teamId,
},
paranoid: false,
})
).toEqual(0);
@@ -61,6 +64,9 @@ describe("documentPermanentDeleter", () => {
expect(DeleteAttachmentTask.schedule).toHaveBeenCalledTimes(2);
expect(
await Document.unscoped().count({
where: {
teamId: document.teamId,
},
paranoid: false,
})
).toEqual(0);
@@ -85,9 +91,18 @@ describe("documentPermanentDeleter", () => {
});
const countDeletedDoc = await documentPermanentDeleter([document]);
expect(countDeletedDoc).toEqual(1);
expect(await Attachment.count()).toEqual(0);
expect(
await Attachment.count({
where: {
teamId: document.teamId,
},
})
).toEqual(0);
expect(
await Document.unscoped().count({
where: {
teamId: document.teamId,
},
paranoid: false,
})
).toEqual(0);
@@ -108,12 +123,27 @@ describe("documentPermanentDeleter", () => {
await document1.save();
document.text = `![text](${attachment.redirectUrl})`;
await document.save();
expect(await Attachment.count()).toEqual(1);
expect(
await Attachment.count({
where: {
teamId: document.teamId,
},
})
).toEqual(1);
const countDeletedDoc = await documentPermanentDeleter([document]);
expect(countDeletedDoc).toEqual(1);
expect(await Attachment.count()).toEqual(1);
expect(
await Attachment.count({
where: {
teamId: document.teamId,
},
})
).toEqual(1);
expect(
await Document.unscoped().count({
where: {
teamId: document.teamId,
},
paranoid: false,
})
).toEqual(1);

View File

@@ -1,7 +1,6 @@
import { Event } from "@server/models";
import { sequelize } from "@server/storage/database";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import documentUpdater from "./documentUpdater";
setupTestDatabase();
@@ -25,7 +24,7 @@ describe("documentUpdater", () => {
})
);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(document.lastModifiedById).toEqual(user.id);
expect(event!.name).toEqual("documents.update");
expect(event!.documentId).toEqual(document.id);
@@ -47,8 +46,6 @@ describe("documentUpdater", () => {
})
);
const event = await Event.findOne();
expect(document.lastModifiedById).not.toEqual(user.id);
expect(event).toEqual(null);
});
});

View File

@@ -15,6 +15,12 @@ describe("fileOperationDeleter", () => {
teamId: admin.teamId,
});
await fileOperationDeleter(fileOp, admin, ip);
expect(await FileOperation.count()).toEqual(0);
expect(
await FileOperation.count({
where: {
teamId: admin.teamId,
},
})
).toEqual(0);
});
});

View File

@@ -1,5 +1,4 @@
import { NotificationEventType } from "@shared/types";
import { Event } from "@server/models";
import { sequelize } from "@server/storage/database";
import {
buildUser,
@@ -7,7 +6,7 @@ import {
buildDocument,
buildCollection,
} from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import notificationUpdater from "./notificationUpdater";
setupTestDatabase();
@@ -49,7 +48,7 @@ describe("notificationUpdater", () => {
transaction,
})
);
const event = await Event.findOne();
const event = await findLatestEvent({});
expect(notification.viewedAt).not.toBe(null);
expect(notification.archivedAt).toBe(null);
@@ -92,7 +91,7 @@ describe("notificationUpdater", () => {
transaction,
})
);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(notification.viewedAt).toBe(null);
expect(notification.archivedAt).toBe(null);
@@ -134,7 +133,7 @@ describe("notificationUpdater", () => {
transaction,
})
);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(notification.viewedAt).toBe(null);
expect(notification.archivedAt).not.toBe(null);
@@ -177,7 +176,7 @@ describe("notificationUpdater", () => {
transaction,
})
);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(notification.viewedAt).toBe(null);
expect(notification.archivedAt).toBeNull();

View File

@@ -1,6 +1,5 @@
import { Event } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import pinCreator from "./pinCreator";
setupTestDatabase();
@@ -21,7 +20,7 @@ describe("pinCreator", () => {
ip,
});
const event = await Event.findOne();
const event = await findLatestEvent();
expect(pin.documentId).toEqual(document.id);
expect(pin.collectionId).toEqual(null);
expect(pin.createdById).toEqual(user.id);
@@ -44,7 +43,7 @@ describe("pinCreator", () => {
ip,
});
const event = await Event.findOne();
const event = await findLatestEvent();
expect(pin.documentId).toEqual(document.id);
expect(pin.collectionId).toEqual(document.collectionId);
expect(pin.createdById).toEqual(user.id);

View File

@@ -1,6 +1,6 @@
import { Pin, Event } from "@server/models";
import { Pin } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import pinDestroyer from "./pinDestroyer";
setupTestDatabase();
@@ -29,10 +29,14 @@ describe("pinCreator", () => {
ip,
});
const count = await Pin.count();
const count = await Pin.count({
where: {
teamId: user.teamId,
},
});
expect(count).toEqual(0);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(event!.name).toEqual("pins.delete");
expect(event!.modelId).toEqual(pin.id);
});

View File

@@ -1,6 +1,5 @@
import { Event } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import revisionCreator from "./revisionCreator";
setupTestDatabase();
@@ -19,7 +18,7 @@ describe("revisionCreator", () => {
user,
ip,
});
const event = await Event.findOne();
const event = await findLatestEvent();
expect(revision.documentId).toEqual(document.id);
expect(revision.userId).toEqual(user.id);
expect(revision.createdAt).toEqual(document.updatedAt);

View File

@@ -1,7 +1,7 @@
import { Star, Event } from "@server/models";
import { sequelize } from "@server/storage/database";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import starCreator from "./starCreator";
setupTestDatabase();
@@ -25,7 +25,7 @@ describe("starCreator", () => {
})
);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(star.documentId).toEqual(document.id);
expect(star.userId).toEqual(user.id);
expect(star.index).toEqual("P");
@@ -57,7 +57,11 @@ describe("starCreator", () => {
})
);
const events = await Event.count();
const events = await Event.count({
where: {
teamId: user.teamId,
},
});
expect(star.documentId).toEqual(document.id);
expect(star.userId).toEqual(user.id);
expect(star.index).toEqual("P");

View File

@@ -1,6 +1,6 @@
import { Star, Event } from "@server/models";
import { Star } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import starDestroyer from "./starDestroyer";
setupTestDatabase();
@@ -29,10 +29,14 @@ describe("starDestroyer", () => {
ip,
});
const count = await Star.count();
const count = await Star.count({
where: {
userId: user.id,
},
});
expect(count).toEqual(0);
const event = await Event.findOne();
const event = await findLatestEvent();
expect(event!.name).toEqual("stars.delete");
expect(event!.modelId).toEqual(star.id);
});

View File

@@ -1,6 +1,6 @@
import { Star, Event } from "@server/models";
import { Star } from "@server/models";
import { buildDocument, buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import { findLatestEvent, setupTestDatabase } from "@server/test/support";
import starUpdater from "./starUpdater";
setupTestDatabase();
@@ -30,7 +30,7 @@ describe("starUpdater", () => {
ip,
});
const event = await Event.findOne();
const event = await findLatestEvent();
expect(star.documentId).toEqual(document.id);
expect(star.userId).toEqual(user.id);
expect(star.index).toEqual("h");

View File

@@ -29,7 +29,11 @@ describe("subscriptionCreator", () => {
})
);
const event = await Event.findOne();
const event = await Event.findOne({
where: {
teamId: user.teamId,
},
});
expect(subscription.documentId).toEqual(document.id);
expect(subscription.userId).toEqual(user.id);
@@ -123,7 +127,11 @@ describe("subscriptionCreator", () => {
})
);
const events = await Event.count();
const events = await Event.count({
where: {
teamId: user.teamId,
},
});
// 3 events. 1 create, 1 destroy and 1 re-create.
expect(events).toEqual(3);
@@ -167,7 +175,11 @@ describe("subscriptionCreator", () => {
);
// Should emit 1 event instead of 2.
const events = await Event.count();
const events = await Event.count({
where: {
teamId: user.teamId,
},
});
expect(events).toEqual(1);
expect(subscription0.documentId).toEqual(document.id);
@@ -223,7 +235,11 @@ describe("subscriptionCreator", () => {
// Should emit 3 events.
// 2 create, 1 destroy.
const events = await Event.findAll();
const events = await Event.findAll({
where: {
teamId: user.teamId,
},
});
expect(events.length).toEqual(3);
expect(events[0].name).toEqual("subscriptions.create");
@@ -260,7 +276,11 @@ describe("subscriptionCreator", () => {
})
);
const events = await Event.count();
const events = await Event.count({
where: {
teamId: user.teamId,
},
});
expect(events).toEqual(1);
expect(subscription0.documentId).toEqual(document.id);

View File

@@ -48,6 +48,7 @@ export default async function subscriptionCreator({
await Event.create(
{
name: "subscriptions.create",
teamId: user.teamId,
modelId: subscription.id,
actorId: user.id,
userId: user.id,
@@ -62,6 +63,7 @@ export default async function subscriptionCreator({
await Event.create(
{
name: "subscriptions.create",
teamId: user.teamId,
modelId: subscription.id,
actorId: user.id,
userId: user.id,

View File

@@ -1,4 +1,4 @@
import { Subscription, Event } from "@server/models";
import { Subscription } from "@server/models";
import { sequelize } from "@server/storage/database";
import {
buildDocument,
@@ -36,17 +36,13 @@ describe("subscriptionDestroyer", () => {
})
);
const count = await Subscription.count();
const count = await Subscription.count({
where: {
userId: user.id,
},
});
expect(count).toEqual(0);
const event = await Event.findOne();
expect(event?.name).toEqual("subscriptions.delete");
expect(event?.modelId).toEqual(subscription.id);
expect(event?.actorId).toEqual(subscription.userId);
expect(event?.userId).toEqual(subscription.userId);
expect(event?.documentId).toEqual(subscription.documentId);
});
it("should soft delete row", async () => {
@@ -72,18 +68,14 @@ describe("subscriptionDestroyer", () => {
})
);
const count = await Subscription.count();
const count = await Subscription.count({
where: {
userId: user.id,
},
});
expect(count).toEqual(0);
const event = await Event.findOne();
expect(event?.name).toEqual("subscriptions.delete");
expect(event?.modelId).toEqual(subscription.id);
expect(event?.actorId).toEqual(subscription.userId);
expect(event?.userId).toEqual(subscription.userId);
expect(event?.documentId).toEqual(subscription.documentId);
const deletedSubscription = await Subscription.findOne({
where: {
userId: user.id,

View File

@@ -28,6 +28,7 @@ export default async function subscriptionDestroyer({
await Event.create(
{
name: "subscriptions.delete",
teamId: user.teamId,
modelId: subscription.id,
actorId: user.id,
userId: user.id,

View File

@@ -16,23 +16,39 @@ describe("teamPermanentDeleter", () => {
const team = await buildTeam({
deletedAt: subDays(new Date(), 90),
});
const user = await buildUser({
teamId: team.id,
});
const user = await buildUser({ teamId: team.id });
await buildDocument({
teamId: team.id,
userId: user.id,
});
await teamPermanentDeleter(team);
expect(await Team.count()).toEqual(0);
expect(await User.count()).toEqual(0);
expect(
await Team.count({
where: {
id: team.id,
},
})
).toEqual(0);
expect(
await User.count({
where: {
teamId: team.id,
},
})
).toEqual(0);
expect(
await Document.unscoped().count({
where: {
teamId: team.id,
},
paranoid: false,
})
).toEqual(0);
expect(
await Collection.unscoped().count({
where: {
teamId: team.id,
},
paranoid: false,
})
).toEqual(0);
@@ -44,18 +60,21 @@ describe("teamPermanentDeleter", () => {
});
await buildUser();
await buildTeam();
await buildDocument();
const document = await buildDocument();
await teamPermanentDeleter(team);
expect(await Team.count()).toEqual(4); // each build command creates a team
expect(await User.count()).toEqual(2);
expect(
await Document.unscoped().count({
where: {
id: document.id,
},
paranoid: false,
})
).toEqual(1);
expect(
await Collection.unscoped().count({
where: {
id: document.collectionId,
},
paranoid: false,
})
).toEqual(1);
@@ -65,9 +84,7 @@ describe("teamPermanentDeleter", () => {
const team = await buildTeam({
deletedAt: subDays(new Date(), 90),
});
const user = await buildUser({
teamId: team.id,
});
const user = await buildUser({ teamId: team.id });
const document = await buildDocument({
teamId: team.id,
userId: user.id,
@@ -77,16 +94,40 @@ describe("teamPermanentDeleter", () => {
documentId: document.id,
});
await teamPermanentDeleter(team);
expect(await Team.count()).toEqual(0);
expect(await User.count()).toEqual(0);
expect(await Attachment.count()).toEqual(0);
expect(
await Team.count({
where: {
id: team.id,
},
})
).toEqual(0);
expect(
await User.count({
where: {
teamId: team.id,
},
})
).toEqual(0);
expect(
await Attachment.count({
where: {
teamId: team.id,
},
})
).toEqual(0);
expect(
await Document.unscoped().count({
where: {
teamId: team.id,
},
paranoid: false,
})
).toEqual(0);
expect(
await Collection.unscoped().count({
where: {
teamId: team.id,
},
paranoid: false,
})
).toEqual(0);

View File

@@ -1,3 +1,4 @@
import { faker } from "@faker-js/faker";
import TeamDomain from "@server/models/TeamDomain";
import { buildTeam, buildUser } from "@server/test/factories";
import {
@@ -16,107 +17,113 @@ describe("teamProvisioner", () => {
beforeEach(setCloudHosted);
it("should create team and authentication provider", async () => {
const subdomain = faker.internet.domainWord();
const result = await teamProvisioner({
name: "Test team",
subdomain: "example",
avatarUrl: "http://example.com/logo.png",
subdomain,
avatarUrl: faker.internet.avatar(),
authenticationProvider: {
name: "google",
providerId: "example.com",
providerId: `${subdomain}.com`,
},
ip,
});
const { team, authenticationProvider, isNewTeam } = result;
expect(authenticationProvider.name).toEqual("google");
expect(authenticationProvider.providerId).toEqual("example.com");
expect(authenticationProvider.providerId).toEqual(`${subdomain}.com`);
expect(team.name).toEqual("Test team");
expect(team.subdomain).toEqual("example");
expect(team.subdomain).toEqual(subdomain);
expect(isNewTeam).toEqual(true);
});
it("should set subdomain append if unavailable", async () => {
const subdomain = faker.internet.domainWord();
await buildTeam({
subdomain: "myteam",
subdomain,
});
const result = await teamProvisioner({
name: "Test team",
subdomain: "myteam",
avatarUrl: "http://example.com/logo.png",
subdomain,
avatarUrl: faker.internet.avatar(),
authenticationProvider: {
name: "google",
providerId: "example.com",
providerId: `${subdomain}.com`,
},
ip,
});
expect(result.isNewTeam).toEqual(true);
expect(result.team.subdomain).toEqual("myteam1");
expect(result.team.subdomain).toEqual(`${subdomain}1`);
});
it("should increment subdomain append if unavailable", async () => {
const subdomain = faker.internet.domainWord();
await buildTeam({
subdomain: "myteam",
subdomain,
});
await buildTeam({
subdomain: "myteam1",
subdomain: `${subdomain}1`,
});
const result = await teamProvisioner({
name: "Test team",
subdomain: "myteam",
avatarUrl: "http://example.com/logo.png",
subdomain,
avatarUrl: faker.internet.avatar(),
authenticationProvider: {
name: "google",
providerId: "example.com",
providerId: `${subdomain}.com`,
},
ip,
});
expect(result.team.subdomain).toEqual("myteam2");
expect(result.team.subdomain).toEqual(`${subdomain}2`);
});
it("should return existing team", async () => {
const subdomain = faker.internet.domainWord();
const authenticationProvider = {
name: "google",
providerId: "example.com",
providerId: `${subdomain}.com`,
};
const existing = await buildTeam({
subdomain: "example",
subdomain,
authenticationProviders: [authenticationProvider],
});
const result = await teamProvisioner({
name: "Updated name",
subdomain: "example",
name: faker.company.name(),
subdomain,
authenticationProvider,
ip,
});
const { team, isNewTeam } = result;
expect(team.id).toEqual(existing.id);
expect(team.name).toEqual(existing.name);
expect(team.subdomain).toEqual("example");
expect(team.subdomain).toEqual(subdomain);
expect(isNewTeam).toEqual(false);
});
it("should error on mismatched team and authentication provider", async () => {
const exampleTeam = await buildTeam({
subdomain: "example",
subdomain: faker.internet.domainWord(),
authenticationProviders: [
{
name: "google",
providerId: "example.com",
providerId: "teamProvisioner3.com",
},
],
});
let error;
try {
const subdomain = faker.internet.domainWord();
await teamProvisioner({
teamId: exampleTeam.id,
name: "name",
subdomain: "other",
subdomain,
authenticationProvider: {
name: "google",
providerId: "other.com",
providerId: `${subdomain}.com`,
},
ip,
});
@@ -131,13 +138,14 @@ describe("teamProvisioner", () => {
beforeEach(setSelfHosted);
it("should allow creating first team", async () => {
const subdomain = faker.internet.domainWord();
const { team, isNewTeam } = await teamProvisioner({
name: "Test team",
subdomain: "example",
avatarUrl: "http://example.com/logo.png",
subdomain,
avatarUrl: faker.internet.avatar(),
authenticationProvider: {
name: "google",
providerId: "example.com",
providerId: `${subdomain}.com`,
},
ip,
});
@@ -148,17 +156,18 @@ describe("teamProvisioner", () => {
it("should not allow creating multiple teams in installation", async () => {
const team = await buildTeam();
const subdomain = faker.internet.domainWord();
let error;
try {
await teamProvisioner({
name: "Test team",
subdomain: "example",
avatarUrl: "http://example.com/logo.png",
subdomain,
avatarUrl: faker.internet.avatar(),
teamId: team.id,
authenticationProvider: {
name: "google",
providerId: "example.com",
providerId: `${subdomain}.com`,
},
ip,
});
@@ -170,23 +179,24 @@ describe("teamProvisioner", () => {
});
it("should return existing team when within allowed domains", async () => {
const domain = faker.internet.domainName();
const existing = await buildTeam();
const user = await buildUser({
teamId: existing.id,
});
await TeamDomain.create({
teamId: existing.id,
name: "allowed-domain.com",
name: domain,
createdById: user.id,
});
const result = await teamProvisioner({
name: "Updated name",
subdomain: "example",
domain: "allowed-domain.com",
subdomain: faker.internet.domainWord(),
domain,
teamId: existing.id,
authenticationProvider: {
name: "google",
providerId: "allowed-domain.com",
providerId: domain,
},
ip,
});
@@ -194,7 +204,7 @@ describe("teamProvisioner", () => {
expect(team.id).toEqual(existing.id);
expect(team.name).toEqual(existing.name);
expect(authenticationProvider.name).toEqual("google");
expect(authenticationProvider.providerId).toEqual("allowed-domain.com");
expect(authenticationProvider.providerId).toEqual(domain);
expect(isNewTeam).toEqual(false);
const providers = await team.$get("authenticationProviders");
expect(providers.length).toEqual(2);
@@ -215,7 +225,7 @@ describe("teamProvisioner", () => {
try {
await teamProvisioner({
name: "Updated name",
subdomain: "example",
subdomain: faker.internet.domainWord(),
domain: "other-domain.com",
teamId: existing.id,
authenticationProvider: {
@@ -234,22 +244,23 @@ describe("teamProvisioner", () => {
it("should return existing team", async () => {
const authenticationProvider = {
name: "google",
providerId: "example.com",
providerId: faker.internet.domainName(),
};
const subdomain = faker.internet.domainWord();
const existing = await buildTeam({
subdomain: "example",
subdomain,
authenticationProviders: [authenticationProvider],
});
const result = await teamProvisioner({
name: "Updated name",
subdomain: "example",
subdomain,
authenticationProvider,
ip,
});
const { team, isNewTeam } = result;
expect(team.id).toEqual(existing.id);
expect(team.name).toEqual(existing.name);
expect(team.subdomain).toEqual("example");
expect(team.subdomain).toEqual(subdomain);
expect(isNewTeam).toEqual(false);
});
});

View File

@@ -1,3 +1,4 @@
import { faker } from "@faker-js/faker";
import { UserRole } from "@shared/types";
import { buildUser } from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
@@ -14,7 +15,7 @@ describe("userInviter", () => {
invites: [
{
role: UserRole.Member,
email: "test@example.com",
email: faker.internet.email(),
name: "Test",
},
],
@@ -78,12 +79,13 @@ describe("userInviter", () => {
});
it("should not send invites to existing team members", async () => {
const user = await buildUser();
const email = faker.internet.email().toLowerCase();
const user = await buildUser({ email });
const response = await userInviter({
invites: [
{
role: UserRole.Member,
email: user.email!,
email,
name: user.name,
},
],

View File

@@ -1,7 +1,12 @@
import { v4 as uuidv4 } from "uuid";
import { TeamDomain } from "@server/models";
import { buildUser, buildTeam, buildInvite } from "@server/test/factories";
import { setupTestDatabase, seed } from "@server/test/support";
import {
buildUser,
buildTeam,
buildInvite,
buildAdmin,
} from "@server/test/factories";
import { setupTestDatabase } from "@server/test/support";
import userProvisioner from "./userProvisioner";
setupTestDatabase();
@@ -331,7 +336,8 @@ describe("userProvisioner", () => {
});
it("should create a user from allowed domain", async () => {
const { admin, team } = await seed();
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
await TeamDomain.create({
teamId: team.id,
name: "example-company.com",
@@ -362,7 +368,8 @@ describe("userProvisioner", () => {
});
it("should create a user from allowed domain with emailMatchOnly", async () => {
const { admin, team } = await seed();
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
await TeamDomain.create({
teamId: team.id,
name: "example-company.com",
@@ -382,7 +389,7 @@ describe("userProvisioner", () => {
});
it("should not create a user with emailMatchOnly when no allowed domains are set", async () => {
const { team } = await seed();
const team = await buildTeam();
let error;
try {
@@ -400,7 +407,8 @@ describe("userProvisioner", () => {
});
it("should reject an user when the domain is not allowed", async () => {
const { admin, team } = await seed();
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
await TeamDomain.create({
teamId: team.id,
name: "other.com",

View File

@@ -59,6 +59,12 @@ describe("userSuspender", () => {
});
expect(user.suspendedAt).toBeTruthy();
expect(user.suspendedById).toEqual(admin.id);
expect(await GroupUser.count()).toEqual(0);
expect(
await GroupUser.count({
where: {
userId: user.id,
},
})
).toEqual(0);
});
});