fix: Documents in deleted collection should appear in trash (#1362)
* fix: Documents from deleted collection should show in trash * improve messaging * test: Add documents.move tests feat: Add ability to restore trashed documents from deleted collection * update store * fix * ui * lint * fix: Improve breadcrumb
This commit is contained in:
@@ -210,7 +210,7 @@ router.post("documents.deleted", auth(), pagination(), async (ctx) => {
|
||||
if (direction !== "ASC") direction = "DESC";
|
||||
|
||||
const user = ctx.state.user;
|
||||
const collectionIds = await user.collectionIds();
|
||||
const collectionIds = await user.collectionIds({ paranoid: false });
|
||||
|
||||
const collectionScope = { method: ["withCollection", user.id] };
|
||||
const documents = await Document.scope(collectionScope).findAll({
|
||||
@@ -444,7 +444,7 @@ router.post("documents.export", auth({ required: false }), async (ctx) => {
|
||||
});
|
||||
|
||||
router.post("documents.restore", auth(), async (ctx) => {
|
||||
const { id, revisionId } = ctx.body;
|
||||
const { id, collectionId, revisionId } = ctx.body;
|
||||
ctx.assertPresent(id, "id is required");
|
||||
|
||||
const user = ctx.state.user;
|
||||
@@ -453,6 +453,16 @@ router.post("documents.restore", auth(), async (ctx) => {
|
||||
paranoid: false,
|
||||
});
|
||||
|
||||
if (collectionId) {
|
||||
ctx.assertUuid(collectionId, "collectionId must be a uuid");
|
||||
authorize(user, "restore", document);
|
||||
|
||||
const collection = await Collection.findByPk(collectionId);
|
||||
authorize(user, "update", collection);
|
||||
|
||||
document.collectionId = collectionId;
|
||||
}
|
||||
|
||||
if (document.deletedAt) {
|
||||
authorize(user, "restore", document);
|
||||
|
||||
@@ -938,6 +948,9 @@ router.post("documents.move", auth(), async (ctx) => {
|
||||
const document = await Document.findByPk(id, { userId: user.id });
|
||||
authorize(user, "move", document);
|
||||
|
||||
const collection = await Collection.findByPk(collectionId);
|
||||
authorize(user, "update", collection);
|
||||
|
||||
if (parentDocumentId) {
|
||||
const parent = await Document.findByPk(parentDocumentId, {
|
||||
userId: user.id,
|
||||
|
||||
@@ -1137,7 +1137,109 @@ describe("#documents.pin", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("#documents.move", () => {
|
||||
it("should move the document", async () => {
|
||||
const { user, document } = await seed();
|
||||
const collection = await buildCollection({ teamId: user.teamId });
|
||||
|
||||
const res = await server.post("/api/documents.move", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: document.id,
|
||||
collectionId: collection.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.documents[0].collectionId).toEqual(collection.id);
|
||||
});
|
||||
|
||||
it("should not allow moving the document to a collection the user cannot access", async () => {
|
||||
const { user, document } = await seed();
|
||||
const collection = await buildCollection();
|
||||
|
||||
const res = await server.post("/api/documents.move", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: document.id,
|
||||
collectionId: collection.id,
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
|
||||
it("should require authentication", async () => {
|
||||
const res = await server.post("/api/documents.move");
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
|
||||
it("should require authorization", async () => {
|
||||
const { document, collection } = await seed();
|
||||
const user = await buildUser();
|
||||
const res = await server.post("/api/documents.move", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: document.id,
|
||||
collectionId: collection.id,
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#documents.restore", () => {
|
||||
it("should allow restore of trashed documents", async () => {
|
||||
const { user, document } = await seed();
|
||||
await document.destroy(user.id);
|
||||
|
||||
const res = await server.post("/api/documents.restore", {
|
||||
body: { token: user.getJwtToken(), id: document.id },
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.deletedAt).toEqual(null);
|
||||
});
|
||||
|
||||
it("should allow restore of trashed documents with collectionId", async () => {
|
||||
const { user, document } = await seed();
|
||||
const collection = await buildCollection({
|
||||
userId: user.id,
|
||||
teamId: user.teamId,
|
||||
});
|
||||
|
||||
await document.destroy(user.id);
|
||||
|
||||
const res = await server.post("/api/documents.restore", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: document.id,
|
||||
collectionId: collection.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.deletedAt).toEqual(null);
|
||||
expect(body.data.collectionId).toEqual(collection.id);
|
||||
});
|
||||
|
||||
it("should now allow restore of trashed documents to collection user cannot access", async () => {
|
||||
const { user, document } = await seed();
|
||||
const collection = await buildCollection();
|
||||
|
||||
await document.destroy(user.id);
|
||||
|
||||
const res = await server.post("/api/documents.restore", {
|
||||
body: {
|
||||
token: user.getJwtToken(),
|
||||
id: document.id,
|
||||
collectionId: collection.id,
|
||||
},
|
||||
});
|
||||
expect(res.status).toEqual(403);
|
||||
});
|
||||
|
||||
it("should allow restore of archived documents", async () => {
|
||||
const { user, document } = await seed();
|
||||
await document.archive(user.id);
|
||||
@@ -1146,6 +1248,8 @@ describe("#documents.restore", () => {
|
||||
body: { token: user.getJwtToken(), id: document.id },
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.archivedAt).toEqual(null);
|
||||
});
|
||||
|
||||
@@ -1164,6 +1268,8 @@ describe("#documents.restore", () => {
|
||||
body: { token: user.getJwtToken(), id: childDocument.id },
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.parentDocumentId).toEqual(undefined);
|
||||
expect(body.data.archivedAt).toEqual(null);
|
||||
});
|
||||
@@ -1184,6 +1290,8 @@ describe("#documents.restore", () => {
|
||||
body: { token: user.getJwtToken(), id: document.id, revisionId },
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.data.text).toEqual(previousText);
|
||||
});
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ router.post("events.list", auth(), pagination(), async (ctx) => {
|
||||
if (direction !== "ASC") direction = "DESC";
|
||||
|
||||
const user = ctx.state.user;
|
||||
const paranoid = false;
|
||||
const collectionIds = await user.collectionIds(paranoid);
|
||||
const collectionIds = await user.collectionIds({ paranoid: false });
|
||||
|
||||
let where = {
|
||||
name: Event.ACTIVITY_EVENTS,
|
||||
|
||||
Reference in New Issue
Block a user