Skip to content

Commit 96f6989

Browse files
authored
COMP-564: Closing Case File (#525)
* COMP-564: Closing Case File * test fix
1 parent e51aea0 commit 96f6989

File tree

7 files changed

+297
-96
lines changed

7 files changed

+297
-96
lines changed

compliance-api/src/compliance_api/services/case_file.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Service for handle CaseFile."""
22

3+
# pylint: disable=too-many-lines
4+
35
from datetime import datetime
46
from io import BytesIO
57

@@ -272,6 +274,12 @@ def change_case_file_status(cls, case_file_id, status_data):
272274
_access_check_for_update(case_file)
273275
case_file = CaseFileModel.find_by_id(case_file_id)
274276
status_enum = CaseFileStatusEnum(status_data.get("status"))
277+
if status_enum == CaseFileStatusEnum.CLOSED:
278+
close_check = cls.get_open_enforcement_actions(case_file_id)
279+
if close_check and close_check.get("has_open_items"):
280+
raise UnprocessableEntityError(
281+
"The case file contains open items."
282+
)
275283
if status_enum == case_file.case_file_status:
276284
raise UnprocessableEntityError(
277285
f"The case file is already in {status_enum.value} status."

compliance-web/cypress/components/_components/_App/_CaseFiles/_Profile/CaseFileInspectionsTable.cy.tsx

Lines changed: 92 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { mount } from "cypress/react18";
22
import CaseFileInspectionsTable from "@/components/App/CaseFiles/Profile/CaseFileInspectionsTable";
33
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4-
import {
5-
RouterProvider,
4+
import {
5+
RouterProvider,
66
createMemoryHistory,
77
createRootRoute,
88
createRoute,
9-
createRouter
10-
} from '@tanstack/react-router';
9+
createRouter,
10+
} from "@tanstack/react-router";
1111
import { CaseFile } from "@/models/CaseFile";
12-
import { INITIATION, EnforcementActionEnum } from "@/utils/constants";
12+
import { EnforcementActionEnum, INITIATION } from "@/utils/constants";
1313
import { InspectionMoreDetails } from "@/models/Inspection";
1414

1515
describe("CaseFileInspectionsTable", () => {
@@ -68,11 +68,13 @@ describe("CaseFileInspectionsTable", () => {
6868
id: EnforcementActionEnum.ORDER,
6969
name: "Test Order",
7070
number: "ORDER_001",
71+
approval_status: { id: "APPROVED", name: "Approved" },
72+
status: { id: "OPEN", name: "Open" },
7173
progress: {
7274
id: "ISSUED",
73-
name: "Issued"
74-
}
75-
}
75+
name: "Issued",
76+
},
77+
},
7678
},
7779
{
7880
requirement_id: 2,
@@ -84,13 +86,14 @@ describe("CaseFileInspectionsTable", () => {
8486
id: EnforcementActionEnum.WARNING_LETTER,
8587
name: "Test Warning Letter",
8688
number: "WL_001",
89+
approval_status: { id: "APPROVED", name: "Approved" },
8790
progress: {
8891
id: "DRAFTING",
89-
name: "Drafting"
90-
}
91-
}
92-
}
93-
]
92+
name: "Drafting",
93+
},
94+
},
95+
},
96+
],
9497
},
9598
{
9699
id: 2,
@@ -123,53 +126,59 @@ describe("CaseFileInspectionsTable", () => {
123126
requirement_sort_order: 1,
124127
requirement_number: "REQ_003",
125128
requirement_source_name: "Section",
126-
enforcement_action: undefined
127-
}
128-
]
129+
enforcement_action: undefined,
130+
},
131+
],
129132
},
130133
];
131134

132135
beforeEach(() => {
133136
queryClient = new QueryClient();
134-
137+
135138
// Set up the query data before mounting
136-
queryClient.setQueryData(["inspections-details-by-caseFileId", 1], mockInspections);
139+
queryClient.setQueryData(
140+
["inspections-details-by-caseFileId", 1],
141+
mockInspections
142+
);
137143
queryClient.setQueryData(["staff-users"], []);
138144

139145
// Create a simple router for testing
140146
const rootRoute = createRootRoute();
141-
147+
142148
const inspectionsRoute = createRoute({
143149
getParentRoute: () => rootRoute,
144-
path: '/ce-database/inspections/$inspectionNumber',
145-
component: () => <div>Inspection Detail Page</div>
150+
path: "/ce-database/inspections/$inspectionNumber",
151+
component: () => <div>Inspection Detail Page</div>,
146152
});
147-
153+
148154
const indexRoute = createRoute({
149155
getParentRoute: () => rootRoute,
150-
path: '/',
156+
path: "/",
151157
component: () => (
152158
<QueryClientProvider client={queryClient}>
153159
<CaseFileInspectionsTable caseFile={mockCaseFile} />
154160
</QueryClientProvider>
155-
)
161+
),
156162
});
157163

158164
const routeTree = rootRoute.addChildren([indexRoute, inspectionsRoute]);
159-
165+
160166
const memoryHistory = createMemoryHistory({
161-
initialEntries: ['/'],
167+
initialEntries: ["/"],
162168
});
163-
169+
164170
const router = createRouter({
165171
routeTree,
166172
history: memoryHistory,
167173
});
168174

169175
// Debug: Log the query data to ensure it's set correctly
170-
cy.log('Setting up test with inspections data:', JSON.stringify(mockInspections));
171-
cy.log('Case file initiation ID:', mockCaseFile.initiation.id);
172-
cy.log('INITIATION.INSPECTION_ID:', INITIATION.INSPECTION_ID);
176+
cy.log(
177+
"Setting up test with inspections data:",
178+
JSON.stringify(mockInspections)
179+
);
180+
cy.log("Case file initiation ID:", mockCaseFile.initiation.id);
181+
cy.log("INITIATION.INSPECTION_ID:", INITIATION.INSPECTION_ID);
173182

174183
mount(<RouterProvider router={router as never} />);
175184
});
@@ -180,10 +189,10 @@ describe("CaseFileInspectionsTable", () => {
180189

181190
it("displays inspection accordions with correct inspection numbers", () => {
182191
// Debug: Check what's actually rendered
183-
cy.get('body').then(($body) => {
184-
cy.log('Body content:', $body.html());
192+
cy.get("body").then(($body) => {
193+
cy.log("Body content:", $body.html());
185194
});
186-
195+
187196
cy.contains("IR_123").should("exist");
188197
cy.contains("IR_124").should("exist");
189198
});
@@ -207,113 +216,119 @@ describe("CaseFileInspectionsTable", () => {
207216
it("expands accordion when clicked", () => {
208217
// Click on the first accordion to expand it
209218
cy.get('[role="button"]').first().click();
210-
219+
211220
// Should show expanded content with requirement details
212221
cy.contains("Requirement Summary").should("exist");
213222
cy.contains("#").should("exist");
214223
cy.contains("Source").should("exist");
215224
cy.contains("Enforcement Action").should("exist");
216225
cy.contains("Enf. Status").should("exist");
217-
226+
218227
// Should show ExpandLessRounded icon when expanded
219228
cy.get('[data-testid="ExpandLessRoundedIcon"]').should("exist");
220229
});
221230

222231
it("displays requirement details when expanded", () => {
223232
// Expand the first accordion
224233
cy.get('[role="button"]').first().click();
225-
234+
226235
// Check for requirement summaries
227236
cy.contains("#1. Test Requirement 1").should("exist");
228237
cy.contains("#2. Test Requirement 2").should("exist");
229-
238+
230239
// Check for requirement numbers
231240
cy.contains("001").should("exist"); // From REQ_001 split
232241
cy.contains("002").should("exist"); // From REQ_002 split
233-
242+
234243
// Check for requirement sources
235244
cy.contains("Order").should("exist");
236245
cy.contains("Condition").should("exist");
237-
246+
238247
// Check for enforcement actions
239248
cy.contains("Test Order").should("exist");
240249
cy.contains("Test Warning Letter").should("exist");
241-
250+
242251
// Check for enforcement status chips
243252
cy.contains("Open").should("exist");
244253
cy.contains("Drafting").should("exist");
245254
});
246255

247256
it("shows inspection links with correct routing", () => {
248-
cy.get('a').contains("IR_123").should("exist");
249-
cy.get('a').contains("IR_124").should("exist");
257+
cy.get("a").contains("IR_123").should("exist");
258+
cy.get("a").contains("IR_124").should("exist");
250259
});
251260

252261
it("has correct link to inspection detail", () => {
253-
cy.get('a').contains("IR_123").should('have.attr', 'href')
254-
.and('include', '/ce-database/inspections/');
262+
cy.get("a")
263+
.contains("IR_123")
264+
.should("have.attr", "href")
265+
.and("include", "/ce-database/inspections/");
255266
});
256267

257268
it("navigates to inspection detail when link is clicked", () => {
258269
// Just check that the link has the correct href
259-
cy.get('a').contains("IR_123").should('have.attr', 'href')
260-
.and('include', '/ce-database/inspections/');
261-
270+
cy.get("a")
271+
.contains("IR_123")
272+
.should("have.attr", "href")
273+
.and("include", "/ce-database/inspections/");
274+
262275
// And that clicking doesn't throw errors
263-
cy.get('a').contains("IR_123").click();
276+
cy.get("a").contains("IR_123").click();
264277
});
265278

266279
it("collapses accordion when clicked again", () => {
267280
// Expand the first accordion
268281
cy.get('[role="button"]').first().click();
269-
282+
270283
// Verify it's expanded
271284
cy.contains("Requirement Summary").should("exist");
272-
285+
273286
// Click again to collapse
274287
cy.get('[role="button"]').first().click();
275-
288+
276289
// Verify it's collapsed (content should not be visible)
277290
cy.contains("Requirement Summary").should("not.be.visible");
278291
});
279292

280293
it("shows no inspections message when there are no inspections", () => {
281294
// Set empty inspections data
282295
queryClient.setQueryData(["inspections-details-by-caseFileId", 1], []);
283-
296+
284297
// Re-mount with empty data
285298
const rootRoute = createRootRoute();
286299
const indexRoute = createRoute({
287300
getParentRoute: () => rootRoute,
288-
path: '/',
301+
path: "/",
289302
component: () => (
290303
<QueryClientProvider client={queryClient}>
291304
<CaseFileInspectionsTable caseFile={mockCaseFile} />
292305
</QueryClientProvider>
293-
)
306+
),
294307
});
295308
const routeTree = rootRoute.addChildren([indexRoute]);
296-
const memoryHistory = createMemoryHistory({ initialEntries: ['/'] });
309+
const memoryHistory = createMemoryHistory({ initialEntries: ["/"] });
297310
const router = createRouter({ routeTree, history: memoryHistory });
298-
311+
299312
mount(<RouterProvider router={router as never} />);
300-
301-
cy.contains("You do not have any created inspections on this file.").should("exist");
313+
314+
cy.contains("You do not have any created inspections on this file.").should(
315+
"exist"
316+
);
302317
});
303318

304319
it("handles requirement source links correctly", () => {
305320
// Expand the first accordion
306321
cy.get('[role="button"]').first().click();
307-
322+
308323
// Check that order requirement numbers are clickable links
309-
cy.get('a').contains("001").should("exist");
310-
cy.get('a').contains("002").should("not.exist");
324+
cy.get("a").contains("001").should("exist");
325+
cy.get("a").contains("002").should("not.exist");
311326
});
312327

313328
it("displays enforcement action status chips with correct colors", () => {
314329
// Expand the first accordion
315330
cy.get('[role="button"]').first().click();
316-
331+
317332
// Check for enforcement status chips
318333
cy.contains("Open").should("exist");
319334
cy.contains("Drafting").should("exist");
@@ -328,40 +343,43 @@ describe("CaseFileInspectionsTable", () => {
328343
location_description: "Test Location 3",
329344
start_date: "2023-04-17T12:00:00Z",
330345
primary_officer: { name: "Bob Johnson" },
331-
requirement_details: []
332-
}
346+
requirement_details: [],
347+
},
333348
];
334349

335-
queryClient.setQueryData(["inspections-details-by-caseFileId", 1], inspectionsWithoutRequirements);
336-
350+
queryClient.setQueryData(
351+
["inspections-details-by-caseFileId", 1],
352+
inspectionsWithoutRequirements
353+
);
354+
337355
// Re-mount with data without requirements
338356
const rootRoute = createRootRoute();
339357
const indexRoute = createRoute({
340358
getParentRoute: () => rootRoute,
341-
path: '/',
359+
path: "/",
342360
component: () => (
343361
<QueryClientProvider client={queryClient}>
344362
<CaseFileInspectionsTable caseFile={mockCaseFile} />
345363
</QueryClientProvider>
346-
)
364+
),
347365
});
348366
const routeTree = rootRoute.addChildren([indexRoute]);
349-
const memoryHistory = createMemoryHistory({ initialEntries: ['/'] });
367+
const memoryHistory = createMemoryHistory({ initialEntries: ["/"] });
350368
const router = createRouter({ routeTree, history: memoryHistory });
351-
369+
352370
mount(<RouterProvider router={router as never} />);
353-
371+
354372
// Should still show the inspection
355373
cy.contains("IR_125").should("exist");
356-
374+
357375
// Expand the accordion
358376
cy.get('[role="button"]').first().click();
359-
377+
360378
// Should show headers but no requirement data
361379
cy.contains("Requirement Summary").should("exist");
362380
cy.contains("#").should("exist");
363381
cy.contains("Source").should("exist");
364382
cy.contains("Enforcement Action").should("exist");
365383
cy.contains("Enf. Status").should("exist");
366384
});
367-
});
385+
});

0 commit comments

Comments
 (0)