mirror of
https://github.com/outline/outline.git
synced 2026-02-14 14:58:46 -06:00
* Conversion of User to event system * fix * warning * fixes * Skip lastActiveAt in changeset * fix: Skip count in view changeset * refactor: Remove userDestroyer * refactor: Remove userSuspender * refactor: Remove userUnsuspender * tests
413 lines
13 KiB
TypeScript
413 lines
13 KiB
TypeScript
import { DocumentPermission, NotificationEventType } from "@shared/types";
|
|
import { UserMembership } from "@server/models";
|
|
import {
|
|
buildComment,
|
|
buildDocument,
|
|
buildDraftDocument,
|
|
buildSubscription,
|
|
buildUser,
|
|
} from "@server/test/factories";
|
|
import NotificationHelper from "./NotificationHelper";
|
|
|
|
describe("NotificationHelper", () => {
|
|
describe("getCommentNotificationRecipients", () => {
|
|
it("should only return users who have notification enabled for comment creation and are subscribed to the document in case of new thread", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const notificationEnabledUser = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
const notificationDisabledUser = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: false },
|
|
});
|
|
await Promise.all([
|
|
buildSubscription({
|
|
userId: documentAuthor.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationEnabledUser.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationDisabledUser.id,
|
|
documentId: document.id,
|
|
}),
|
|
]);
|
|
|
|
const comment = await buildComment({
|
|
documentId: document.id,
|
|
userId: documentAuthor.id,
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getCommentNotificationRecipients(
|
|
document,
|
|
comment,
|
|
comment.createdById
|
|
);
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(notificationEnabledUser.id);
|
|
});
|
|
|
|
it("should only return users who have notification enabled for comment creation and are subscribed to the document in case of new thread in draft", async () => {
|
|
const documentAuthor = await buildUser();
|
|
|
|
// create a draft
|
|
const document = await buildDraftDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
collectionId: null,
|
|
});
|
|
|
|
// add a bunch of users as direct members
|
|
const user = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
const user2 = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
const user3 = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
await UserMembership.create({
|
|
documentId: document.id,
|
|
userId: user.id,
|
|
permission: DocumentPermission.Read,
|
|
createdById: user.id,
|
|
});
|
|
await UserMembership.create({
|
|
documentId: document.id,
|
|
userId: user2.id,
|
|
permission: DocumentPermission.Read,
|
|
createdById: user.id,
|
|
});
|
|
await UserMembership.create({
|
|
documentId: document.id,
|
|
userId: user3.id,
|
|
permission: DocumentPermission.Read,
|
|
createdById: user.id,
|
|
});
|
|
|
|
// Add a subscription for only one of those users
|
|
await Promise.all([
|
|
buildSubscription({
|
|
userId: user.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: user2.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: user3.id,
|
|
documentId: document.id,
|
|
}),
|
|
]);
|
|
|
|
const comment = await buildComment({
|
|
documentId: document.id,
|
|
userId: documentAuthor.id,
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getCommentNotificationRecipients(
|
|
document,
|
|
comment,
|
|
comment.createdById
|
|
);
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(user3.id);
|
|
});
|
|
|
|
it("should only return users who have notification enabled for comment creation and are in the thread in case of child comment", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const notificationEnabledUserInThread = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
const notificationEnabledUserNotInThread = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
const notificationDisabledUser = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: {
|
|
[NotificationEventType.CreateComment]: false,
|
|
},
|
|
});
|
|
await Promise.all([
|
|
buildSubscription({
|
|
userId: documentAuthor.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationEnabledUserInThread.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationEnabledUserNotInThread.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationDisabledUser.id,
|
|
documentId: document.id,
|
|
}),
|
|
]);
|
|
const parentComment = await buildComment({
|
|
documentId: document.id,
|
|
userId: notificationEnabledUserInThread.id,
|
|
});
|
|
const childComment = await buildComment({
|
|
documentId: document.id,
|
|
userId: documentAuthor.id,
|
|
parentCommentId: parentComment.id,
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getCommentNotificationRecipients(
|
|
document,
|
|
childComment,
|
|
childComment.createdById
|
|
);
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(notificationEnabledUserInThread.id);
|
|
});
|
|
|
|
it("should not return users who have notification disabled for comment creation and are in the thread in case of child comment", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const notificationEnabledUserInThread = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: false },
|
|
});
|
|
const notificationEnabledUserNotInThread = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
const notificationDisabledUser = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: {
|
|
[NotificationEventType.CreateComment]: false,
|
|
},
|
|
});
|
|
await Promise.all([
|
|
buildSubscription({
|
|
userId: documentAuthor.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationEnabledUserInThread.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationEnabledUserNotInThread.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: notificationDisabledUser.id,
|
|
documentId: document.id,
|
|
}),
|
|
]);
|
|
const parentComment = await buildComment({
|
|
documentId: document.id,
|
|
userId: notificationEnabledUserInThread.id,
|
|
});
|
|
const childComment = await buildComment({
|
|
documentId: document.id,
|
|
userId: documentAuthor.id,
|
|
parentCommentId: parentComment.id,
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getCommentNotificationRecipients(
|
|
document,
|
|
childComment,
|
|
childComment.createdById
|
|
);
|
|
|
|
expect(recipients.length).toEqual(0);
|
|
});
|
|
|
|
it("should return users who have notification enabled and are in the thread but not explicitly subscribed to document", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const notificationEnabledUserInThread = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.CreateComment]: true },
|
|
});
|
|
await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: {
|
|
[NotificationEventType.CreateComment]: false,
|
|
},
|
|
});
|
|
const parentComment = await buildComment({
|
|
documentId: document.id,
|
|
userId: notificationEnabledUserInThread.id,
|
|
});
|
|
const childComment = await buildComment({
|
|
documentId: document.id,
|
|
userId: documentAuthor.id,
|
|
parentCommentId: parentComment.id,
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getCommentNotificationRecipients(
|
|
document,
|
|
childComment,
|
|
childComment.createdById
|
|
);
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(notificationEnabledUserInThread.id);
|
|
});
|
|
});
|
|
|
|
describe("getDocumentNotificationRecipients", () => {
|
|
it("should return users who have subscribed to the document", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const subscribedUser = await buildUser({ teamId: document.teamId });
|
|
await buildSubscription({
|
|
userId: subscribedUser.id,
|
|
documentId: document.id,
|
|
});
|
|
|
|
const deletedUser = await buildUser({ teamId: document.teamId });
|
|
await buildSubscription({
|
|
userId: deletedUser.id,
|
|
documentId: document.id,
|
|
});
|
|
await deletedUser.destroy({ hooks: false });
|
|
|
|
const recipients =
|
|
await NotificationHelper.getDocumentNotificationRecipients({
|
|
document,
|
|
notificationType: NotificationEventType.UpdateDocument,
|
|
actorId: documentAuthor.id,
|
|
});
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(subscribedUser.id);
|
|
});
|
|
|
|
it("should return users who have subscribed to the collection", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const subscribedUser = await buildUser({ teamId: document.teamId });
|
|
await buildSubscription({
|
|
userId: subscribedUser.id,
|
|
collectionId: document.collectionId!,
|
|
});
|
|
await buildSubscription({
|
|
userId: subscribedUser.id,
|
|
documentId: document.id,
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getDocumentNotificationRecipients({
|
|
document,
|
|
notificationType: NotificationEventType.UpdateDocument,
|
|
actorId: documentAuthor.id,
|
|
});
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(subscribedUser.id);
|
|
});
|
|
|
|
it("should return users who have subscribed to either the document or the containing collection", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const [documentSubscribedUser, collectionSubscribedUser] =
|
|
await Promise.all([
|
|
buildUser({
|
|
teamId: document.teamId,
|
|
}),
|
|
buildUser({
|
|
teamId: document.teamId,
|
|
}),
|
|
]);
|
|
await Promise.all([
|
|
buildSubscription({
|
|
userId: documentSubscribedUser.id,
|
|
documentId: document.id,
|
|
}),
|
|
buildSubscription({
|
|
userId: collectionSubscribedUser.id,
|
|
collectionId: document.collectionId!,
|
|
}),
|
|
]);
|
|
|
|
const recipients =
|
|
await NotificationHelper.getDocumentNotificationRecipients({
|
|
document,
|
|
notificationType: NotificationEventType.UpdateDocument,
|
|
actorId: documentAuthor.id,
|
|
});
|
|
|
|
expect(recipients.length).toEqual(2);
|
|
|
|
const recipientIds = recipients.map((u) => u.id);
|
|
expect(recipientIds).toContain(collectionSubscribedUser.id);
|
|
expect(recipientIds).toContain(documentSubscribedUser.id);
|
|
});
|
|
|
|
it("should not return suspended users", async () => {
|
|
const documentAuthor = await buildUser();
|
|
const document = await buildDocument({
|
|
userId: documentAuthor.id,
|
|
teamId: documentAuthor.teamId,
|
|
});
|
|
const notificationEnabledUser = await buildUser({
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.PublishDocument]: true },
|
|
});
|
|
// suspended user
|
|
await buildUser({
|
|
suspendedAt: new Date(),
|
|
teamId: document.teamId,
|
|
notificationSettings: { [NotificationEventType.PublishDocument]: true },
|
|
});
|
|
|
|
const recipients =
|
|
await NotificationHelper.getDocumentNotificationRecipients({
|
|
document,
|
|
notificationType: NotificationEventType.PublishDocument,
|
|
actorId: documentAuthor.id,
|
|
});
|
|
|
|
expect(recipients.length).toEqual(1);
|
|
expect(recipients[0].id).toEqual(notificationEnabledUser.id);
|
|
});
|
|
});
|
|
});
|