mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
fix: Allow deleting failed and canceled imports (#12379)
* fix: Allow deleting failed and canceled imports The delete policy only permitted imports in the Completed state, so the overflow menu for Errored or Canceled imports rendered with no items. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * test: Cover Errored and Canceled in imports.delete Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,12 @@ import { User, Team, Import } from "@server/models";
|
||||
import { allow, can } from "./cancan";
|
||||
import { and, isTeamAdmin, isTeamMutable, or } from "./utils";
|
||||
|
||||
const TerminalStates = [
|
||||
ImportState.Completed,
|
||||
ImportState.Errored,
|
||||
ImportState.Canceled,
|
||||
];
|
||||
|
||||
allow(User, ["createImport", "listImports"], Team, (actor, team) =>
|
||||
and(isTeamAdmin(actor, team), isTeamMutable(actor))
|
||||
);
|
||||
@@ -14,7 +20,7 @@ allow(User, "read", Import, (actor, importModel) =>
|
||||
allow(User, "delete", Import, (actor, importModel) =>
|
||||
and(
|
||||
can(actor, "read", importModel),
|
||||
importModel?.state === ImportState.Completed
|
||||
!!importModel && TerminalStates.includes(importModel.state)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -177,24 +177,27 @@ describe("#imports.info", () => {
|
||||
});
|
||||
|
||||
describe("#imports.delete", () => {
|
||||
it("should delete the import", async () => {
|
||||
const admin = await buildAdmin();
|
||||
const importModel = await buildImport({
|
||||
state: ImportState.Completed,
|
||||
createdById: admin.id,
|
||||
teamId: admin.teamId,
|
||||
});
|
||||
it.each([ImportState.Completed, ImportState.Errored, ImportState.Canceled])(
|
||||
"should delete the import when in %s state",
|
||||
async (state) => {
|
||||
const admin = await buildAdmin();
|
||||
const importModel = await buildImport({
|
||||
state,
|
||||
createdById: admin.id,
|
||||
teamId: admin.teamId,
|
||||
});
|
||||
|
||||
const res = await server.post("/api/imports.delete", admin, {
|
||||
body: {
|
||||
id: importModel.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
const res = await server.post("/api/imports.delete", admin, {
|
||||
body: {
|
||||
id: importModel.id,
|
||||
},
|
||||
});
|
||||
const body = await res.json();
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.success).toEqual(true);
|
||||
});
|
||||
expect(res.status).toEqual(200);
|
||||
expect(body.success).toEqual(true);
|
||||
}
|
||||
);
|
||||
|
||||
it("should throw error when import is not in deletable state", async () => {
|
||||
const admin = await buildAdmin();
|
||||
|
||||
Reference in New Issue
Block a user