Skip to content

Commit f5e86e4

Browse files
authored
Merge pull request #106 from NHSDigital/DTOSS-12877-amend-mwl-response-when-worklist-item-exists
Amend create worklist item response when item already exists
2 parents ff20a06 + 99f6dff commit f5e86e4

4 files changed

Lines changed: 45 additions & 50 deletions

File tree

src/services/mwl/create_worklist_item.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
from models import WorklistItem
4-
from services.storage import DuplicateWorklistItemError, MWLStorage
4+
from services.storage import MWLStorage, WorklistItemExistsError
55

66
logger = logging.getLogger(__name__)
77

@@ -19,13 +19,14 @@ def call(self, payload: dict):
1919
params = payload.get("parameters", {})
2020

2121
item = params.get("worklist_item", {})
22+
accession_number = item.get("accession_number")
2223
participant = item.get("participant", {})
2324
scheduled = item.get("scheduled", {})
2425
procedure = item.get("procedure", {})
2526

2627
self.storage.store_worklist_item(
2728
WorklistItem(
28-
accession_number=item.get("accession_number"),
29+
accession_number=accession_number,
2930
patient_id=participant.get("nhs_number"),
3031
patient_name=participant.get("name"),
3132
patient_birth_date=participant.get("birth_date"),
@@ -37,13 +38,11 @@ def call(self, payload: dict):
3738
source_message_id=action_id,
3839
)
3940
)
40-
logger.info(f"Created worklist item: {item.get('accession_number')}")
41+
logger.info(f"Created worklist item: {accession_number}")
4142
return {"status": "created", "action_id": action_id}
42-
except DuplicateWorklistItemError:
43-
logger.warning(
44-
f"Duplicate worklist item ignored: accession_number={item.get('accession_number')!r}, action_id={action_id!r}"
45-
)
46-
return {"status": "duplicate", "action_id": action_id}
43+
except WorklistItemExistsError:
44+
logger.info(f"Worklist item exists: accession_number={accession_number}, action_id={action_id!r}")
45+
return {"status": "exists", "action_id": action_id}
4746
except Exception as e:
4847
logger.error(f"Failed to create worklist item: {e}")
4948
return {"status": "error", "action_id": action_id, "error": str(e)}

src/services/storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ class InvalidStatusTransitionError(Exception):
291291
pass
292292

293293

294-
class DuplicateWorklistItemError(Exception):
294+
class WorklistItemExistsError(Exception):
295295
"""Raised when a worklist item with the same accession number already exists."""
296296

297297
pass
@@ -346,7 +346,7 @@ def store_worklist_item(
346346
)
347347
conn.commit()
348348
except sqlite3.IntegrityError:
349-
raise DuplicateWorklistItemError(f"Worklist item already exists: {worklist_item.accession_number}")
349+
raise WorklistItemExistsError(f"Worklist item already exists: {worklist_item.accession_number}")
350350

351351
return worklist_item.accession_number
352352

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,47 @@
11
from unittest.mock import patch
22

3+
import pytest
4+
35
from services.mwl.create_worklist_item import CreateWorklistItem
4-
from services.storage import DuplicateWorklistItemError, WorklistItem
6+
from services.storage import MWLStorage
57

68

7-
@patch(f"{CreateWorklistItem.__module__}.MWLStorage")
89
class TestCreateWorklistItem:
9-
def test_call_success(self, mock_mwl_storage, listener_payload):
10-
mock_storage_instance = mock_mwl_storage.return_value
11-
subject = CreateWorklistItem(mock_storage_instance)
10+
@pytest.fixture
11+
def db_file(tmp_path):
12+
return f"{tmp_path}/test.db"
13+
14+
@pytest.fixture
15+
def mwl_storage(db_file):
16+
return MWLStorage(str(db_file))
17+
18+
def test_call_success(self, mwl_storage, listener_payload):
19+
subject = CreateWorklistItem(mwl_storage)
1220

1321
response = subject.call(listener_payload)
1422
assert response == {"action_id": "action-12345", "status": "created"}
1523

16-
mock_storage_instance.store_worklist_item.assert_called_once_with(
17-
WorklistItem(
18-
accession_number="ACC999999",
19-
patient_id="999123456",
20-
patient_name="SMITH^JANE",
21-
patient_birth_date="19900202",
22-
patient_sex="F",
23-
scheduled_date="20240615",
24-
scheduled_time="101500",
25-
modality="MG",
26-
study_description="MAMMOGRAPHY",
27-
source_message_id="action-12345",
28-
)
29-
)
30-
31-
def test_call_missing_action_id(self, mock_mwl_storage, listener_payload):
32-
mock_storage_instance = mock_mwl_storage.return_value
33-
subject = CreateWorklistItem(mock_storage_instance)
24+
def test_call_missing_action_id(self, mwl_storage, listener_payload):
25+
subject = CreateWorklistItem(mwl_storage)
3426

3527
del listener_payload["action_id"]
3628

3729
response = subject.call(listener_payload)
3830
assert response["status"] == "error"
3931
assert "Missing action_id" in response["error"]
4032

41-
mock_storage_instance.store_worklist_item.assert_not_called()
33+
def test_call_existing_worklist_item(self, mwl_storage, listener_payload):
34+
CreateWorklistItem(mwl_storage).call(listener_payload)
4235

43-
def test_call_duplicate_worklist_item(self, mock_mwl_storage, listener_payload):
44-
mock_storage_instance = mock_mwl_storage.return_value
45-
mock_storage_instance.store_worklist_item.side_effect = DuplicateWorklistItemError(
46-
"Worklist item already exists: ACC999999"
47-
)
48-
subject = CreateWorklistItem(mock_storage_instance)
36+
subject = CreateWorklistItem(mwl_storage)
4937

5038
response = subject.call(listener_payload)
51-
assert response == {"status": "duplicate", "action_id": "action-12345"}
52-
53-
mock_storage_instance.store_worklist_item.assert_called_once()
39+
assert response == {"status": "exists", "action_id": "action-12345"}
5440

55-
def test_call_storage_exception(self, mock_mwl_storage, listener_payload):
56-
mock_storage_instance = mock_mwl_storage.return_value
57-
mock_storage_instance.store_worklist_item.side_effect = Exception("DB error")
58-
subject = CreateWorklistItem(mock_storage_instance)
41+
@patch(f"{CreateWorklistItem.__module__}.MWLStorage.store_worklist_item", side_effect=Exception("DB error"))
42+
def test_call_storage_exception(self, _, mwl_storage, listener_payload):
43+
subject = CreateWorklistItem(mwl_storage)
5944

6045
response = subject.call(listener_payload)
6146
assert response["status"] == "error"
6247
assert "DB error" in response["error"]
63-
64-
mock_storage_instance.store_worklist_item.assert_called_once()

tests/services/test_storage.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@
66
from pydicom.uid import generate_uid
77

88
from models import WorklistItem
9-
from services.storage import InvalidStatusTransitionError, MWLStorage, PACSStorage, WorklistItemNotFoundError
9+
from services.storage import (
10+
InvalidStatusTransitionError,
11+
MWLStorage,
12+
PACSStorage,
13+
WorklistItemExistsError,
14+
WorklistItemNotFoundError,
15+
)
1016

1117

1218
@pytest.fixture
@@ -136,6 +142,13 @@ def test_store_worklist_item(self, mwl_storage, result):
136142
assert row is not None
137143
assert row["patient_id"] == item.patient_id
138144

145+
def test_store_worklist_item_already_exists(self, mwl_storage, result):
146+
item = WorklistItem(**result)
147+
mwl_storage.store_worklist_item(item)
148+
149+
with pytest.raises(WorklistItemExistsError):
150+
mwl_storage.store_worklist_item(item)
151+
139152
def test_find_worklist_items(self, mwl_storage, result):
140153
item = self._insert_item(mwl_storage, result)
141154

0 commit comments

Comments
 (0)