Skip to content

Commit 9abd124

Browse files
committed
inspection close ui
1 parent ebf8303 commit 9abd124

File tree

10 files changed

+141
-64
lines changed

10 files changed

+141
-64
lines changed

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ def change_status(cls, inspection_id, status):
381381
# Check for pending items before closing inspection
382382
if status_enum == InspectionStatusEnum.CLOSED:
383383
pending_items = cls.get_pending_items(inspection_id)
384-
_validate_inspection_can_be_closed(inspection_id, pending_items)
384+
_validate_inspection_can_be_closed(pending_items)
385385

386386
with session_scope() as session:
387387
InspectionModel.update_inspection(
@@ -527,7 +527,7 @@ def get_pending_items(cls, inspection_id: int):
527527
for mapping in enforcement_mappings:
528528
enforcement_action = mapping.enforcement_action
529529
enforcement_status = _check_enforcement_status(
530-
requirement.id, enforcement_action.id, enforcement_action.name
530+
requirement.id, enforcement_action.id
531531
)
532532

533533
if enforcement_status is not None:
@@ -549,11 +549,10 @@ def get_pending_items(cls, inspection_id: int):
549549
return pending_items
550550

551551

552-
def _validate_inspection_can_be_closed(inspection_id: int, pending_items: list):
552+
def _validate_inspection_can_be_closed(pending_items: list):
553553
"""Validate that an inspection can be closed by checking for pending items.
554554
555555
Args:
556-
inspection_id (int): The ID of the inspection to validate
557556
pending_items (list): The list of pending items
558557
559558
Raises:
@@ -1388,7 +1387,7 @@ def _make_requirement_detail_object_optimized(
13881387

13891388

13901389
def _check_enforcement_status(
1391-
requirement_id: int, enforcement_action_id: int, enforcement_name: str
1390+
requirement_id: int, enforcement_action_id: int
13921391
):
13931392
"""Check if an enforcement action exists and its status for a requirement."""
13941393

@@ -1404,9 +1403,8 @@ def _check_enforcement_status(
14041403
check_function = enforcement_map.get(enforcement_action_id)
14051404
if check_function:
14061405
return check_function(requirement_id)
1407-
else:
1408-
# For enforcement actions we don't track separately (like TO_BE_DETERMINED, NOT_APPLICABLE, etc.)
1409-
return None
1406+
# For enforcement actions we don't track separately (like TO_BE_DETERMINED, NOT_APPLICABLE, etc.)
1407+
return None
14101408

14111409

14121410
def _check_order_status(requirement_id: int):

compliance-api/tests/integration/api/test_inspection.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,7 @@ def test_inspection_close(
439439
result = client.patch(
440440
url, data=json.dumps({"status": "CLOSED"}), headers=auth_header_super_user
441441
)
442-
assert result.status_code == HTTPStatus.NO_CONTENT
443-
result = client.patch(
444-
url, data=json.dumps({"status": "OPEN"}), headers=auth_header_super_user
445-
)
446-
assert result.status_code == HTTPStatus.NO_CONTENT
442+
assert result.status_code == HTTPStatus.UNPROCESSABLE_ENTITY
447443
result = client.patch(
448444
url, data=json.dumps({"status": "CANCELED"}), headers=auth_header_super_user
449445
)

compliance-api/tests/unit/test_pending_enforcements_service.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,31 @@ class TestPendingEnforcementsService:
1212
"""Test class for pending enforcements service functionality."""
1313

1414
def test_schema_import(self):
15-
"""Test if we can import the PendingEnforcementSchema."""
15+
"""Test if we can import the PendingItemSchema."""
1616
try:
17-
from compliance_api.schemas.inspection import PendingEnforcementSchema
18-
print("✅ PendingEnforcementSchema import successful")
19-
assert PendingEnforcementSchema is not None
17+
from compliance_api.schemas.inspection import PendingItemSchema
18+
print("✅ PendingItemSchema import successful")
19+
assert PendingItemSchema is not None
2020
except ImportError as e:
21-
pytest.fail(f"Failed to import PendingEnforcementSchema: {e}")
21+
pytest.fail(f"Failed to import PendingItemSchema: {e}")
2222

2323
def test_schema_functionality(self):
2424
"""Test schema serialization functionality."""
2525
try:
26-
from compliance_api.schemas.inspection import PendingEnforcementSchema
26+
from compliance_api.schemas.inspection import PendingItemSchema
2727

28-
schema = PendingEnforcementSchema()
28+
schema = PendingItemSchema()
2929
test_data = {
3030
'requirement': {
3131
'id': 1,
3232
'summary': 'Test requirement'
3333
},
34-
'enforcement': {
34+
'item': {
3535
'id': 5,
3636
'name': 'Order'
3737
},
3838
'is_created': False,
39-
'enforcement_number': 'PROJ_001_O123'
39+
'item_number': 'PROJ_001_O123'
4040
}
4141

4242
result = schema.dump(test_data)
@@ -45,31 +45,31 @@ def test_schema_functionality(self):
4545

4646
# Validate all fields are present in result
4747
assert 'requirement' in result
48-
assert 'enforcement' in result
48+
assert 'item' in result
4949
assert 'is_created' in result
50-
assert 'enforcement_number' in result
50+
assert 'item_number' in result
5151

5252
# Validate nested object fields
5353
assert 'id' in result['requirement']
5454
assert 'summary' in result['requirement']
55-
assert 'id' in result['enforcement']
56-
assert 'name' in result['enforcement']
55+
assert 'id' in result['item']
56+
assert 'name' in result['item']
5757

5858
# Validate field values
5959
assert result['requirement']['id'] == 1
6060
assert result['requirement']['summary'] == 'Test requirement'
61-
assert result['enforcement']['id'] == 5
62-
assert result['enforcement']['name'] == 'Order'
61+
assert result['item']['id'] == 5
62+
assert result['item']['name'] == 'Order'
6363
assert result['is_created'] is False
64-
assert result['enforcement_number'] == 'PROJ_001_O123'
64+
assert result['item_number'] == 'PROJ_001_O123'
6565

6666
except (ImportError, AttributeError, AssertionError, KeyError) as e:
6767
pytest.fail(f"Schema functionality test failed: {e}")
6868

6969
def test_schema_export(self):
7070
"""Test schema export in __init__.py."""
7171
try:
72-
from compliance_api.schemas import PendingEnforcementSchema as ImportedSchema
72+
from compliance_api.schemas import PendingItemSchema as ImportedSchema
7373
print("✅ Schema export in __init__.py successful")
7474
assert ImportedSchema is not None
7575
except ImportError as e:
@@ -81,12 +81,12 @@ def test_service_method_exists(self):
8181
from compliance_api.services.inspection import InspectionService
8282

8383
# Check if the method exists
84-
assert hasattr(InspectionService, 'get_pending_enforcements'), \
85-
"InspectionService should have get_pending_enforcements method"
84+
assert hasattr(InspectionService, 'get_pending_items'), \
85+
"InspectionService should have get_pending_items method"
8686

8787
# Check if it's callable
88-
method = getattr(InspectionService, 'get_pending_enforcements')
89-
assert callable(method), "get_pending_enforcements should be callable"
88+
method = getattr(InspectionService, 'get_pending_items')
89+
assert callable(method), "get_pending_items should be callable"
9090

9191
print("✅ Service method exists and is callable")
9292

@@ -96,7 +96,7 @@ def test_service_method_exists(self):
9696
def test_helper_methods_exist(self):
9797
"""Test that helper methods exist."""
9898
try:
99-
from compliance_api.services.inspection import InspectionService
99+
from compliance_api.services import inspection as inspection_module
100100

101101
helper_methods = [
102102
'_check_enforcement_status',
@@ -105,20 +105,20 @@ def test_helper_methods_exist(self):
105105
'_check_administrative_penalty_status',
106106
'_check_violation_ticket_status',
107107
'_check_charge_recommendation_status',
108-
'_check_restorative_justice_status'
108+
'_check_inspection_record_status',
109109
]
110110

111111
for method_name in helper_methods:
112-
assert hasattr(InspectionService, method_name), \
113-
f"InspectionService should have {method_name} method"
112+
assert hasattr(inspection_module, method_name), \
113+
f"inspection module should have {method_name} function"
114114

115-
method = getattr(InspectionService, method_name)
115+
method = getattr(inspection_module, method_name)
116116
assert callable(method), f"{method_name} should be callable"
117117

118118
print("✅ All helper methods exist and are callable")
119119

120120
except ImportError as e:
121-
pytest.fail(f"Failed to import InspectionService: {e}")
121+
pytest.fail(f"Failed to import inspection module: {e}")
122122

123123

124124
def test_all_imports():
@@ -128,30 +128,30 @@ def test_all_imports():
128128
print("Testing imports...")
129129

130130
# Test schema import
131-
from compliance_api.schemas.inspection import PendingEnforcementSchema
132-
print("✅ PendingEnforcementSchema import successful")
131+
from compliance_api.schemas.inspection import PendingItemSchema
132+
print("✅ PendingItemSchema import successful")
133133

134134
# Test schema functionality
135-
schema = PendingEnforcementSchema()
135+
schema = PendingItemSchema()
136136
test_data = {
137137
'requirement': {
138138
'id': 1,
139139
'summary': 'Test requirement'
140140
},
141-
'enforcement': {
141+
'item': {
142142
'id': 5,
143143
'name': 'Order'
144144
},
145145
'is_created': False,
146-
'enforcement_number': 'PROJ_001_O123'
146+
'item_number': 'PROJ_001_O123'
147147
}
148148

149149
result = schema.dump(test_data)
150150
print("✅ Schema serialization successful")
151151
print(f" Result: {result}")
152152

153153
# Test schema import in init - using ImportedSchema to avoid F401
154-
from compliance_api.schemas import PendingEnforcementSchema as ImportedSchema
154+
from compliance_api.schemas import PendingItemSchema as ImportedSchema
155155
assert ImportedSchema is not None
156156
print("✅ Schema export in __init__.py successful")
157157

compliance-web/cypress/components/_components/_App/_Inspections/_Profile/InspectionFileActions.cy.tsx

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import InspectionFileActions from "@/components/App/Inspections/Profile/Inspecti
44
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
55
import { Inspection } from "@/models/Inspection";
66
import ModalProvider from "@/components/Shared/Modals/ModalProvider";
7+
import * as useInspectionsHook from "@/hooks/useInspections";
78

89
describe("InspectionFileActions Component", () => {
910
let queryClient: QueryClient;
@@ -14,6 +15,9 @@ describe("InspectionFileActions Component", () => {
1415
queries: {
1516
retry: false,
1617
},
18+
mutations: {
19+
retry: false,
20+
},
1721
},
1822
});
1923

@@ -120,20 +124,94 @@ describe("InspectionFileActions Component", () => {
120124
cy.contains("button", "Cancel").should("exist").click();
121125
});
122126

123-
it("handles Closed click", () => {
127+
it("handles Closed click with no pending items", () => {
128+
// Stub the useCheckPendingItems hook to return empty array
129+
const mockMutation = {
130+
mutate: cy.stub().callsFake((id, callbacks) => {
131+
// Simulate successful API call with empty result
132+
setTimeout(() => {
133+
callbacks.onSuccess([]);
134+
}, 100);
135+
}),
136+
isPending: false,
137+
};
138+
139+
cy.stub(useInspectionsHook, "useCheckPendingItems").returns(mockMutation);
140+
124141
mountComponent("open");
125142
cy.contains("button", "Actions").click();
126143
cy.get("li[id='Close']").last().click();
127144

128-
// Verify the confirmation dialog opens
145+
// Wait for the "Checking Pending Items..." modal to appear
146+
cy.contains("Checking Pending Items...").should("exist");
147+
148+
// Wait for the stubbed function to complete
149+
cy.wait(500);
150+
151+
// Verify the confirmation dialog opens after the check completes
129152
cy.contains("Close Inspection?").should("exist");
130153
cy.contains("Are you sure you want to close inspection?").should("exist");
131-
cy.contains("button", "Close Inspection").should("exist").click();
154+
cy.contains("button", "Close Inspection").should("exist");
155+
156+
// Close the modal to clean up
132157
cy.contains("button", "Cancel").should("exist").click();
158+
cy.contains("Close Inspection?").should("not.exist");
159+
});
160+
161+
162+
it("handles Closed click with pending items", () => {
163+
// Stub the useCheckPendingItems hook to return pending items
164+
const pendingItems = [
165+
{
166+
requirement: {
167+
id: 1,
168+
summary: "Test requirement",
169+
},
170+
item: {
171+
id: 5,
172+
name: "Order",
173+
},
174+
is_created: false,
175+
item_number: null,
176+
},
177+
];
178+
179+
const mockMutation = {
180+
mutate: cy.stub().callsFake((id, callbacks) => {
181+
// Simulate successful API call with pending items
182+
setTimeout(() => {
183+
callbacks.onSuccess(pendingItems);
184+
}, 100);
185+
}),
186+
isPending: false,
187+
};
188+
189+
cy.stub(useInspectionsHook, "useCheckPendingItems").returns(mockMutation);
190+
191+
mountComponent("open");
192+
cy.contains("button", "Actions").click();
193+
cy.get("li[id='Close']").last().click();
194+
195+
// Wait for the "Checking Pending Items..." modal to appear
196+
cy.contains("Checking Pending Items...").should("exist");
197+
198+
// Wait for the stubbed function to complete
199+
cy.wait(500);
200+
201+
// Verify the blocking modal appears
202+
cy.contains("Cannot Close Inspection").should("exist");
203+
cy.contains("button", "Return to Inspection").should("exist").click();
204+
205+
// Verify modal is closed
206+
cy.contains("Cannot Close Inspection").should("not.exist");
133207
});
134208

135209
it("handles Delete Inspection click", () => {
136210
mountComponent("open");
211+
212+
// Wait a bit to ensure any previous modals are fully closed
213+
cy.wait(200);
214+
137215
cy.contains("button", "Actions").click();
138216
cy.contains("Delete Inspection").click();
139217

@@ -142,7 +220,10 @@ describe("InspectionFileActions Component", () => {
142220
cy.contains(
143221
"You are about to delete this inspection. Are you sure?"
144222
).should("exist");
145-
cy.contains("button", "Delete").should("exist").click();
223+
cy.contains("button", "Delete").should("exist");
224+
225+
// Close the modal to clean up
146226
cy.contains("button", "Cancel").should("exist").click();
227+
cy.contains("Delete Inspection?").should("not.exist");
147228
});
148229
});

compliance-web/src/components/App/Inspections/Profile/Enforcements/Orders/OrderDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ const OrderDrawer: React.FC<OrderDrawerProps> = ({
182182
const onDeleteSuccess = useCallback(() => {
183183
onSubmit("Order deleted successfully!", true);
184184
reset();
185-
}, [onSubmit, reset, inspection.id]);
185+
}, [onSubmit, reset]);
186186

187187
const { mutate: deleteInspectionOrder } =
188188
useDeleteInspectionOrder(onDeleteSuccess);

compliance-web/src/components/App/Inspections/Profile/Enforcements/WarningLetters/WarningLetterDrawer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ const WarningLetterDrawer: React.FC<WarningLetterDrawerProps> = ({
166166
const onDeleteSuccess = useCallback(() => {
167167
onSubmit("Warning letter deleted successfully!", true);
168168
reset();
169-
}, [onSubmit, reset, inspection.id]);
169+
}, [onSubmit, reset]);
170170

171171
const { mutate: deleteWarningLetter } =
172172
useDeleteWarningLetter(onDeleteSuccess);

compliance-web/src/components/App/Inspections/Profile/InspectionFileActions.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,13 @@ const InspectionFileActions: React.FC<InspectionFileActionsProps> = ({
178178
if (checkPendingItemsMutation.isPending) {
179179
return; // Already checking
180180
}
181-
181+
182182
setOpen({
183183
content: (
184184
<ConfirmationModal
185185
title="Checking Pending Items..."
186186
description="Please wait while we check for pending items..."
187-
confirmButtonText="Please Wait"
187+
showActions={false}
188188
onConfirm={() => {}} // Disabled while loading
189189
/>
190190
),

0 commit comments

Comments
 (0)