Files
outline/server/routes/api/pins/pins.test.ts
2023-06-22 15:57:00 +05:30

411 lines
12 KiB
TypeScript

import { Collection, Document, Pin, User } from "@server/models";
import {
buildAdmin,
buildCollection,
buildDocument,
buildDraftDocument,
buildPin,
buildUser,
} from "@server/test/factories";
import { getTestServer } from "@server/test/support";
const server = getTestServer();
describe("#pins.create", () => {
let admin: User;
let user: User;
let anotherUser: User;
let document: Document;
let collection: Collection;
beforeEach(async () => {
admin = await buildAdmin();
[user, anotherUser] = await Promise.all([
buildUser({ teamId: admin.teamId }),
buildUser(),
]);
collection = await buildCollection({
createdById: admin.id,
teamId: admin.teamId,
});
document = await buildDocument({
createdById: admin.id,
teamId: admin.teamId,
collectionId: collection.id,
});
});
it("should fail with status 401 unauthorized when user token is missing", async () => {
const res = await server.post("/api/pins.create", {
body: {
documentId: "foo",
},
});
const body = await res.json();
expect(res.status).toEqual(401);
expect(body.message).toEqual("Authentication required");
});
it("should fail with status 400 bad request when documentId is not suppled", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: user.getJwtToken(),
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("documentId: required");
});
it("should fail with status 400 bad request when documentId is invalid", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: user.getJwtToken(),
documentId: "foo",
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("documentId: must be uuid or url slug");
});
it("should fail with status 400 bad request when index is invalid", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: user.getJwtToken(),
documentId: "foo1234567",
index: "😀",
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("index: must be between x20 to x7E ASCII");
});
it("should fail with status 403 forbidden when user is disallowed to read the document", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: anotherUser.getJwtToken(),
documentId: document.id,
},
});
const body = await res.json();
expect(res.status).toEqual(403);
expect(body.message).toEqual("Authorization error");
});
it("should fail with status 403 forbidden when user is disallowed to update the collection", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: user.getJwtToken(),
documentId: document.id,
collectionId: collection.id,
},
});
const body = await res.json();
expect(res.status).toEqual(403);
expect(body.message).toEqual("Authorization error");
});
it("should fail with status 403 forbidden when user is disallowed to pin the document", async () => {
const draft = await buildDraftDocument({
createdById: admin.id,
teamId: admin.teamId,
collectionId: collection.id,
});
const res = await server.post("/api/pins.create", {
body: {
token: admin.getJwtToken(),
// A draft document cannot be pinned, neither by a member nor by an admin
documentId: draft.id,
collectionId: collection.id,
},
});
const body = await res.json();
expect(res.status).toEqual(403);
expect(body.message).toEqual("Authorization error");
});
it("should fail with status 403 forbidden when user is disallowed to pin the document to home page", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: user.getJwtToken(),
documentId: document.id,
},
});
const body = await res.json();
expect(res.status).toEqual(403);
expect(body.message).toEqual("Authorization error");
});
it("should succeed with status 200 ok when user is allowed to pin", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: admin.getJwtToken(),
documentId: document.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data).toBeTruthy();
expect(body.data.documentId).toEqual(document.id);
expect(body.data.collectionId).toBeNull();
});
it("should succeed with status 200 ok when valid collectionId is supplied", async () => {
const res = await server.post("/api/pins.create", {
body: {
token: admin.getJwtToken(),
documentId: document.id,
collectionId: collection.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data).toBeTruthy();
expect(body.data.documentId).toEqual(document.id);
expect(body.data.collectionId).toEqual(collection.id);
});
});
describe("#pins.list", () => {
let user: User;
let pins: Pin[];
let docs: Document[];
let collection: Collection;
beforeEach(async () => {
user = await buildUser();
collection = await buildCollection({
teamId: user.teamId,
createdById: user.id,
});
docs = await Promise.all([
buildDocument({
teamId: user.teamId,
collectionId: collection.id,
}),
buildDocument({
teamId: user.teamId,
collectionId: collection.id,
}),
]);
pins = await Promise.all([
buildPin({
createdById: user.id,
documentId: docs[0].id,
teamId: user.teamId,
}),
buildPin({
createdById: user.id,
documentId: docs[1].id,
teamId: user.teamId,
}),
]);
});
it("should fail with status 401 unauthorized when user token is missing", async () => {
const res = await server.post("/api/pins.list", {
body: {},
});
const body = await res.json();
expect(res.status).toEqual(401);
expect(body.message).toEqual("Authentication required");
});
it("should succeed with status 200 ok returning pinned documents", async () => {
const res = await server.post("/api/pins.list", {
body: {
token: user.getJwtToken(),
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data).toBeTruthy();
expect(body.data.pins).toBeTruthy();
expect(body.data.pins).toHaveLength(2);
const pinIds = body.data.pins.map((p: any) => p.id);
expect(pinIds).toContain(pins[0].id);
expect(pinIds).toContain(pins[1].id);
const docIds = body.data.documents.map((d: any) => d.id);
expect(docIds).toContain(docs[0].id);
expect(docIds).toContain(docs[1].id);
});
it("should succeed with status 200 ok returning pinned documents filtered by collectionId supplied", async () => {
const res = await server.post("/api/pins.list", {
body: {
token: user.getJwtToken(),
collectionId: collection.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data).toBeTruthy();
expect(body.data.pins).toBeTruthy();
expect(body.data.pins).toHaveLength(0);
});
});
describe("#pins.update", () => {
let user: User;
let admin: User;
let pin: Pin;
beforeEach(async () => {
user = await buildUser();
admin = await buildAdmin();
const collection = await buildCollection({
createdById: admin.id,
teamId: admin.teamId,
});
const doc = await buildDocument({
createdById: admin.id,
teamId: admin.teamId,
collectionId: collection.id,
});
pin = await buildPin({
teamId: admin.teamId,
createdById: admin.id,
documentId: doc.id,
index: "a",
});
});
it("should fail with status 401 unauthorized when user token is missing", async () => {
const res = await server.post("/api/pins.update", {
body: {
id: pin.id,
index: "i",
},
});
const body = await res.json();
expect(res.status).toEqual(401);
expect(body.message).toEqual("Authentication required");
});
it("should fail with status 400 bad request when id is missing", async () => {
const res = await server.post("/api/pins.update", {
body: {
token: admin.getJwtToken(),
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("id: Required");
});
it("should fail with status 400 bad request when index is missing", async () => {
const res = await server.post("/api/pins.update", {
body: {
token: admin.getJwtToken(),
id: pin.id,
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("index: Required");
});
it("should fail with status 400 bad request when an invalid index is sent", async () => {
const res = await server.post("/api/pins.update", {
body: {
token: admin.getJwtToken(),
id: pin.id,
index: "😀",
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("index: must be between x20 to x7E ASCII");
});
it("should fail with status 403 forbidden when user is disallowed to update the pin", async () => {
const res = await server.post("/api/pins.update", {
body: {
token: user.getJwtToken(),
id: pin.id,
index: "b",
},
});
const body = await res.json();
expect(res.status).toEqual(403);
expect(body.message).toEqual("Authorization error");
});
it("should succeed with status 200 ok and when user is allowed to update the pin", async () => {
const res = await server.post("/api/pins.update", {
body: {
token: admin.getJwtToken(),
id: pin.id,
index: "b",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data).toBeTruthy();
expect(body.data.id).toEqual(pin.id);
expect(body.data.index).toEqual("b");
});
});
describe("#pins.delete", () => {
let admin: User;
let pin: Pin;
beforeEach(async () => {
admin = await buildAdmin();
pin = await buildPin({
teamId: admin.teamId,
createdById: admin.id,
});
});
it("should fail with status 401 unauthorized when user token is missing", async () => {
const res = await server.post("/api/pins.delete", {
body: {},
});
const body = await res.json();
expect(res.status).toEqual(401);
expect(body.message).toEqual("Authentication required");
});
it("should fail with status 400 bad request when id is missing", async () => {
const res = await server.post("/api/pins.delete", {
body: {
token: admin.getJwtToken(),
},
});
const body = await res.json();
expect(res.status).toEqual(400);
expect(body.message).toEqual("id: Required");
});
it("should fail with status 403 forbidden when user is disallowed to delete the pin", async () => {
const user = await buildUser({
teamId: admin.teamId,
});
const res = await server.post("/api/pins.delete", {
body: {
token: user.getJwtToken(),
id: pin.id,
},
});
const body = await res.json();
expect(res.status).toEqual(403);
expect(body.message).toEqual("Authorization error");
});
it("should succeed with status 200 ok when user is allowed to delete the pin", async () => {
const res = await server.post("/api/pins.delete", {
body: {
token: admin.getJwtToken(),
id: pin.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.success).toEqual(true);
});
});