Skip to content

Commit c272b1f

Browse files
committed
✨ - feat: permissions test
1 parent f1ec130 commit c272b1f

File tree

2 files changed

+162
-7
lines changed

2 files changed

+162
-7
lines changed

frontend/src/lib/api/destructionLists.ts

+12-7
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ export type DestructionList = {
1717
uuid: string;
1818
};
1919

20-
export type DestructionListStatus =
21-
| "ready_to_review"
22-
| "changes_requested"
23-
| "ready_to_delete"
24-
| "deleted"
25-
| "ready_for_archivist"
26-
| "internally_reviewed";
20+
// An array to be used in various parts of the application.
21+
export const DESTRUCTION_LIST_STATUSES = [
22+
"ready_to_review",
23+
"changes_requested",
24+
"ready_to_delete",
25+
"deleted",
26+
"ready_for_archivist",
27+
"internally_reviewed",
28+
] as const;
29+
30+
// Inferring the type of the array, so that we don't have to repeat the same.
31+
export type DestructionListStatus = (typeof DESTRUCTION_LIST_STATUSES)[number];
2732

2833
export type DestructionListAssignee = {
2934
user: User;
+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import {
2+
STATUSES_ELIGIBLE_FOR_EDIT,
3+
STATUSES_ELIGIBLE_FOR_REVIEW,
4+
} from "../../pages/destructionlist/detail/constants";
5+
import { User } from "../api/auth";
6+
import {
7+
DESTRUCTION_LIST_STATUSES,
8+
DestructionList,
9+
} from "../api/destructionLists";
10+
import {
11+
canMarkListAsFinal,
12+
canReviewDestructionList,
13+
canStartDestructionList,
14+
canUpdateDestructionList,
15+
canViewDestructionList,
16+
} from "./permissions";
17+
18+
/**
19+
* Helper function to generate user objects with different permissions
20+
* @param {boolean} canStartDestruction - Permission to start destruction
21+
* @param {boolean} canReviewDestruction - Permission to review destruction
22+
* @returns {User} - User object with specified permissions
23+
*/
24+
const generateUserWithPermissions = (
25+
canStartDestruction: boolean,
26+
canReviewDestruction: boolean,
27+
): User => ({
28+
pk: 1,
29+
username: "testuser",
30+
firstName: "Test",
31+
lastName: "User",
32+
33+
role: {
34+
name: "Test Role",
35+
canStartDestruction,
36+
canReviewDestruction,
37+
canViewCaseDetails: true,
38+
},
39+
});
40+
41+
describe("Permissions tests with all combinations", () => {
42+
DESTRUCTION_LIST_STATUSES.forEach((status) => {
43+
describe(`With destruction list status: ${status}`, () => {
44+
let destructionList: DestructionList;
45+
let user: User;
46+
let anotherUser: User;
47+
48+
beforeEach(() => {
49+
user = generateUserWithPermissions(true, true);
50+
anotherUser = { ...user, pk: 2 };
51+
destructionList = {
52+
pk: 1,
53+
assignee: user,
54+
assignees: [],
55+
author: user,
56+
containsSensitiveInfo: false,
57+
created: "2023-01-01T00:00:00Z",
58+
name: "Test Destruction List",
59+
status,
60+
statusChanged: null,
61+
uuid: "12345-abcde",
62+
};
63+
});
64+
65+
describe("canStartDestructionList", () => {
66+
it("should allow a user with the canStartDestruction role", () => {
67+
expect(canStartDestructionList(user)).toBe(true);
68+
});
69+
70+
it("should not allow a user without the canStartDestruction role", () => {
71+
user = generateUserWithPermissions(false, true);
72+
expect(canStartDestructionList(user)).toBe(false);
73+
});
74+
});
75+
76+
describe("canReviewDestructionList", () => {
77+
it("should allow a user to review if they have the role and status is eligible", () => {
78+
const isEligible = STATUSES_ELIGIBLE_FOR_REVIEW.includes(status);
79+
expect(canReviewDestructionList(user, destructionList)).toBe(
80+
isEligible,
81+
);
82+
});
83+
84+
it("should not allow a user to review if they lack the role", () => {
85+
user = generateUserWithPermissions(true, false);
86+
expect(canReviewDestructionList(user, destructionList)).toBe(false);
87+
});
88+
89+
it("should not allow a user to review if they are not the assignee", () => {
90+
destructionList.assignee = anotherUser;
91+
expect(canReviewDestructionList(user, destructionList)).toBe(false);
92+
});
93+
});
94+
95+
describe("canUpdateDestructionList", () => {
96+
it("should allow a user to update if they have the role and status is eligible", () => {
97+
const isEligible = STATUSES_ELIGIBLE_FOR_EDIT.includes(status);
98+
expect(canUpdateDestructionList(user, destructionList)).toBe(
99+
isEligible,
100+
);
101+
});
102+
103+
it("should not allow a user to update if they lack the role", () => {
104+
user = generateUserWithPermissions(false, true);
105+
expect(canUpdateDestructionList(user, destructionList)).toBe(false);
106+
});
107+
108+
it("should not allow a user to update if they are not the assignee", () => {
109+
destructionList.assignee = anotherUser;
110+
expect(canUpdateDestructionList(user, destructionList)).toBe(false);
111+
});
112+
});
113+
114+
describe("canViewDestructionList", () => {
115+
it("should allow the author to view the destruction list", () => {
116+
expect(canViewDestructionList(user, destructionList)).toBe(true);
117+
});
118+
119+
it("should not allow a user who is not the author to view the destruction list", () => {
120+
destructionList.author = anotherUser;
121+
expect(canViewDestructionList(user, destructionList)).toBe(false);
122+
});
123+
});
124+
125+
describe("canMarkListAsFinal", () => {
126+
it("should allow the author to mark the list as final if status is internally_reviewed and canStartDestruction is true", () => {
127+
const isEligible = status === "internally_reviewed";
128+
expect(canMarkListAsFinal(user, destructionList)).toBe(isEligible);
129+
});
130+
131+
it("should not allow marking as final if the user is not the author", () => {
132+
destructionList.author = anotherUser;
133+
expect(canMarkListAsFinal(user, destructionList)).toBe(false);
134+
});
135+
136+
it("should not allow marking as final if the status is not internally_reviewed", () => {
137+
const nonEligibleStatus = status !== "internally_reviewed";
138+
expect(canMarkListAsFinal(user, destructionList)).toBe(
139+
!nonEligibleStatus,
140+
);
141+
});
142+
143+
it("should not allow marking as final if the user lacks canStartDestruction permission", () => {
144+
user = generateUserWithPermissions(false, true);
145+
expect(canMarkListAsFinal(user, destructionList)).toBe(false);
146+
});
147+
});
148+
});
149+
});
150+
});

0 commit comments

Comments
 (0)