Skip to content

Commit d77af04

Browse files
committed
Improves core tests
1 parent 36cbcf6 commit d77af04

8 files changed

Lines changed: 98 additions & 21 deletions

File tree

dicomtrolley/core.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ def download_study(self, study_instance_uid, output_dir):
5858
)
5959
)
6060
storage = DICOMStorageDir(output_dir)
61-
for dataset in self.get_all_datasets(mint_objects=[study]):
61+
for dataset in self.fetch_all_datasets(mint_objects=[study]):
6262
storage.save(dataset)
6363

64-
def get_all_datasets(self, mint_objects: List[MintObject]):
64+
def fetch_all_datasets(self, mint_objects: List[MintObject]):
6565
"""Get full DICOM dataset for each instance in study. Calls mint and wado
6666
6767
Parameters
@@ -115,6 +115,7 @@ def __str__(self):
115115

116116
def save(self, dataset):
117117
"""Write dataset. Creates sub-folders if needed"""
118+
118119
slice_path = Path(self.path) / self.generate_path(dataset)
119120
slice_path.parent.mkdir(parents=True, exist_ok=True)
120121
dataset.save_as(slice_path)

dicomtrolley/https.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ def get_session(self, user, password, realm):
4343
session = requests.Session()
4444
response = session.post(
4545
self.url,
46-
headers={"X-Userid": user, "X-Password": password, "X-Realm": realm},
46+
headers={
47+
"X-Userid": user,
48+
"X-Password": password,
49+
"X-Realm": realm,
50+
},
4751
)
4852
if response.status_code == 401:
4953
raise DICOMTrolleyException(

dicomtrolley/mint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def __repr__(self):
3030
return self.uid
3131

3232
def all_instances(self):
33-
pass
33+
raise NotImplementedError()
3434

3535

3636
class MintInstance(MintObject):

tests/conftest.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import pytest
22
import requests
33

4-
from dicomtrolley.mint import MintStudy, parse_mint_studies_response
4+
from dicomtrolley.mint import Mint, MintStudy, parse_mint_studies_response
5+
from dicomtrolley.wado import Wado
56
from tests.mockresponses import (
67
LOGIN_DENIED,
78
LOGIN_SUCCESS,
89
MINT_SEARCH_INSTANCE_LEVEL,
910
MINT_SEARCH_SERIES_LEVEL,
1011
MINT_SEARCH_STUDY_LEVEL,
12+
MockUrls,
1113
)
1214

1315

@@ -40,6 +42,16 @@ def mock_mint_responses(requests_mock):
4042
set_mock_response(requests_mock, mock)
4143

4244

45+
@pytest.fixture
46+
def a_mint(a_session):
47+
return Mint(session=a_session, url=MockUrls.MINT_URL)
48+
49+
50+
@pytest.fixture
51+
def a_wado(a_session):
52+
return Wado(session=a_session, url=MockUrls.WADO_URL)
53+
54+
4355
@pytest.fixture
4456
def a_study_with_instances() -> MintStudy:
4557
"""An example MintStudy object"""
@@ -54,6 +66,11 @@ def a_study_without_instances() -> MintStudy:
5466
return studies[0]
5567

5668

69+
@pytest.fixture
70+
def some_studies(a_study_with_instances, a_study_without_instances):
71+
return [a_study_with_instances, a_study_with_instances]
72+
73+
5774
def set_mock_response(requests_mock, response):
5875
"""Register the given MockResponse with requests_mock"""
5976
requests_mock.register_uri(**response.as_dict())

tests/factories.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ def quick_dataset(*_, **kwargs) -> Dataset:
2222
2323
"""
2424
dataset = Dataset()
25+
dataset.is_little_endian = True # required common meta header choice
26+
dataset.is_implicit_VR = False # required common meta header choice
2527
for tag_name, value in kwargs.items():
2628
Tag(tag_name) # assert valid dicom keyword. pydicom will not do this.
2729
dataset.__setattr__(tag_name, value)

tests/test_core.py

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
from pathlib import Path
2+
from unittest.mock import Mock
23

34
import pytest
45

5-
from dicomtrolley.core import DICOMStorageDir
6+
from dicomtrolley.core import DICOMStorageDir, Trolley
7+
from dicomtrolley.query import Query
68
from tests.factories import quick_dataset
79

810

11+
@pytest.fixture
12+
def a_trolley(a_mint, a_wado) -> Trolley:
13+
"""Trolley instance that will not hit any server"""
14+
return Trolley(mint=a_mint, wado=a_wado)
15+
16+
917
@pytest.mark.parametrize(
1018
"dataset, expected_path",
1119
[
@@ -22,6 +30,50 @@
2230
(quick_dataset(), "/tmp/unknown/unknown/unknown"),
2331
],
2432
)
25-
def test_storage_dir(dataset, expected_path):
33+
def test_storage_dir_generate_path(dataset, expected_path):
2634
storage = DICOMStorageDir("/tmp")
2735
assert storage.generate_path(dataset) == Path("/tmp") / expected_path
36+
37+
38+
def test_storage_dir_write(tmpdir):
39+
"""Make sure writing to disk works. Seems slight overkill. But coverage."""
40+
expected_path = Path(str(tmpdir)) / "unknown/unknown/unknown"
41+
assert not expected_path.exists()
42+
DICOMStorageDir(str(tmpdir)).save(quick_dataset())
43+
assert expected_path.exists()
44+
45+
46+
def test_trolley_find(a_trolley, some_studies):
47+
a_trolley.mint.find_studies = Mock(return_value=some_studies)
48+
assert a_trolley.find_studies(query=Query()) == some_studies
49+
50+
51+
def test_trolley_download_study(a_trolley, some_studies, tmpdir):
52+
a_trolley.mint.find_studies = Mock(return_value=some_studies[:1])
53+
a_trolley.wado.get_dataset = Mock(
54+
return_value=quick_dataset(
55+
StudyInstanceUID="foo",
56+
SeriesInstanceUID="baz",
57+
SOPInstanceUID="bimini",
58+
)
59+
)
60+
61+
expected_path = Path(str(tmpdir)) / "foo/baz/bimini"
62+
assert not expected_path.exists()
63+
a_trolley.download_study(study_instance_uid="1", output_dir=tmpdir)
64+
assert expected_path.exists()
65+
66+
67+
def test_trolley_get_dataset(a_trolley, some_studies, tmpdir):
68+
a_trolley.mint.find_studies = Mock(return_value=some_studies)
69+
a_trolley.wado.get_dataset = Mock(
70+
return_value=quick_dataset(
71+
StudyInstanceUID="foo",
72+
SeriesInstanceUID="baz",
73+
SOPInstanceUID="bimini",
74+
)
75+
)
76+
77+
datasets = list(a_trolley.fetch_all_datasets(some_studies))
78+
assert len(datasets) == 28
79+
assert datasets[0].SOPInstanceUID == "bimini"

tests/test_mint.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
from datetime import date, datetime
2+
from unittest.mock import Mock
23
from xml.etree.ElementTree import Element
34

45
import pytest
56

7+
from dicomtrolley.exceptions import DICOMTrolleyException
68
from dicomtrolley.mint import (
7-
Mint,
89
MintAttribute,
910
MintSeries,
1011
parse_attribs,
1112
)
1213
from dicomtrolley.query import Query, QueryLevels
13-
from tests.mockresponses import MockUrls
14-
15-
16-
@pytest.fixture
17-
def a_mint(a_session):
18-
return Mint(session=a_session, url=MockUrls.MINT_URL)
1914

2015

2116
def test_search_study_level(a_mint, mock_mint_responses):
@@ -40,6 +35,13 @@ def test_search_instance_level(a_mint, mock_mint_responses):
4035
assert len(response[0].series[1].instances) == 13
4136

4237

38+
def test_find_study_exception(a_mint, some_studies):
39+
"""Using a find_study query that returns multiple studies is not allowed"""
40+
a_mint.find_studies = Mock(return_value=some_studies)
41+
with pytest.raises(DICOMTrolleyException):
42+
a_mint.find_study(Query())
43+
44+
4345
@pytest.mark.parametrize(
4446
"query_params",
4547
(
@@ -114,3 +116,9 @@ def test_study_instance_iterator(
114116

115117
assert len([x for x in a_study_with_instances.all_instances()]) == 14
116118
assert len([x for x in a_study_without_instances.all_instances()]) == 0
119+
120+
121+
def test_study_dump(a_study_with_instances):
122+
dump = a_study_with_instances.dump_content()
123+
assert "BEELDENZORG" in dump
124+
assert "85551.608" in dump

tests/test_wado.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
import pytest
22

3-
from dicomtrolley.wado import Wado
43
from tests.conftest import set_mock_response
54
from tests.mockresponses import (
6-
MockUrls,
75
MockWadoParameters,
86
WADO_RESPONSE_DICOM,
97
)
108

119

12-
@pytest.fixture
13-
def a_wado(a_session):
14-
return Wado(session=a_session, url=MockUrls.WADO_URL)
15-
16-
1710
@pytest.fixture
1811
def mock_wado_response(requests_mock):
1912
set_mock_response(requests_mock, WADO_RESPONSE_DICOM)

0 commit comments

Comments
 (0)