Skip to content

Commit f10f9c2

Browse files
authored
Create test_csw_provider_live.py (#2309)
* Create csw_live * Fix flake8
1 parent c787148 commit f10f9c2

2 files changed

Lines changed: 317 additions & 31 deletions

File tree

tests/provider/test_csw_provider.py

Lines changed: 164 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@
2929
#
3030
# =================================================================
3131

32+
from unittest import mock
3233
import pytest
3334

3435
from pygeoapi.provider.base import ProviderItemNotFoundError
3536
from pygeoapi.provider.csw_facade import CSWFacadeProvider
3637

38+
CSW_PROVIDER = 'pygeoapi.provider.csw_facade.CatalogueServiceWeb'
39+
3740

3841
@pytest.fixture()
3942
def config():
@@ -46,14 +49,166 @@ def config():
4649
}
4750

4851

49-
def test_domains(config):
52+
@pytest.fixture()
53+
def mock_csw_record():
54+
"""Mock owslib CSW record"""
55+
record = mock.MagicMock()
56+
record.identifier = 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f'
57+
record.title = 'Lorem ipsum'
58+
record.abstract = 'Lorem ipsum dolor sit amet'
59+
record.type = 'http://purl.org/dc/dcmitype/Image'
60+
record.subjects = ['Tourism--Greece']
61+
record.date = '2006-03-26'
62+
record.created = None
63+
record.modified = None
64+
record.rights = None
65+
record.language = None
66+
record.bbox = None # No geometry for first record
67+
record.references = []
68+
record.uris = []
69+
return record
70+
71+
72+
@pytest.fixture()
73+
def mock_csw_record_polygon():
74+
"""Mock owslib CSW record with polygon geometry"""
75+
record = mock.MagicMock()
76+
record.identifier = 'urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd'
77+
record.title = 'Maecenas enim'
78+
record.abstract = 'Maecenas enim'
79+
record.type = 'http://purl.org/dc/dcmitype/Text'
80+
record.subjects = []
81+
record.date = '2006-05-12'
82+
record.created = None
83+
record.modified = None
84+
record.rights = None
85+
record.language = None
86+
record.bbox = mock.MagicMock()
87+
record.bbox.minx = '13.754'
88+
record.bbox.miny = '60.042'
89+
record.bbox.maxx = '15.334'
90+
record.bbox.maxy = '61.645'
91+
record.references = []
92+
record.uris = []
93+
return record
94+
95+
96+
@pytest.fixture()
97+
def mock_csw_get_record():
98+
"""Mock owslib CSW record for get operations"""
99+
record = mock.MagicMock()
100+
record.identifier = 'urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2'
101+
record.title = 'Lorem ipsum dolor sit amet'
102+
record.abstract = 'Lorem ipsum dolor sit amet'
103+
record.type = 'http://purl.org/dc/dcmitype/Image'
104+
record.subjects = []
105+
record.date = None
106+
record.created = None
107+
record.modified = None
108+
record.rights = None
109+
record.language = None
110+
record.bbox = None
111+
record.references = []
112+
record.uris = []
113+
return record
114+
115+
116+
@pytest.fixture()
117+
def mock_csw(mock_csw_record, mock_csw_record_polygon, mock_csw_get_record):
118+
"""Mock CSW service"""
119+
with mock.patch(CSW_PROVIDER) as mock_csw_class:
120+
csw_instance = mock.MagicMock()
121+
mock_csw_class.return_value = csw_instance
122+
123+
def mock_getrecords2(*args, **kwargs):
124+
# Simulate different responses based on parameters
125+
limit = kwargs.get('maxrecords', 10)
126+
offset = kwargs.get('startposition', 0)
127+
constraints = kwargs.get('constraints', [])
128+
129+
# All available records
130+
all_records = [
131+
(
132+
'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f',
133+
mock_csw_record
134+
),
135+
(
136+
'urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd',
137+
mock_csw_record_polygon
138+
)
139+
]
140+
141+
# Simulate filtering based on query constraints
142+
filtered_records = all_records[:]
143+
144+
# Simulate different total counts based on constraints
145+
total_matches = 12 # Default total
146+
if constraints:
147+
# If there are constraints
148+
# simulate fewer matches
149+
constraint_str = str(constraints)
150+
if 'lorem' in constraint_str.lower():
151+
total_matches = 5
152+
# Keep both records for lorem search
153+
elif 'maecenas' in constraint_str.lower():
154+
total_matches = 1
155+
# Keep only the second record for maecenas search
156+
filtered_records = [all_records[1]]
157+
elif 'datetime' in constraint_str.lower():
158+
total_matches = 1 if '2006-05-12' in constraint_str else 3
159+
# Keep appropriate records based on date
160+
if '2006-05-12' in constraint_str:
161+
# Second record has matching date
162+
filtered_records = [all_records[1]]
163+
164+
# Apply offset and limit to filtered records
165+
paginated_records = filtered_records[offset:offset+limit]
166+
167+
# Convert to dictionary format expected by CSW
168+
csw_instance.records = {
169+
record_id: record for record_id, record in paginated_records
170+
}
171+
csw_instance.results = {
172+
'matches': total_matches,
173+
'returned': len(paginated_records)
174+
}
175+
176+
def mock_getrecordbyid(identifiers, **kwargs):
177+
identifier = identifiers[0]
178+
if identifier == 'urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2':
179+
csw_instance.records = {identifier: mock_csw_get_record}
180+
else:
181+
csw_instance.records = {}
182+
183+
def mock_getdomain(property_name, **kwargs):
184+
# Mock domain values for testing
185+
domain_values = {
186+
'type': [
187+
'http://purl.org/dc/dcmitype/Image',
188+
'http://purl.org/dc/dcmitype/Text',
189+
'http://purl.org/dc/dcmitype/Dataset',
190+
'http://purl.org/dc/dcmitype/Service'
191+
]
192+
}
193+
csw_instance.results = {
194+
'values': domain_values.get(property_name, [])
195+
}
196+
197+
csw_instance.getrecords2.side_effect = mock_getrecords2
198+
csw_instance.getrecordbyid.side_effect = mock_getrecordbyid
199+
csw_instance.getdomain.side_effect = mock_getdomain
200+
201+
yield csw_instance
202+
203+
204+
def test_domains(config, mock_csw):
50205
p = CSWFacadeProvider(config)
51206

52207
domains, current = p.get_domains()
53208

54209
assert current
55210

56-
expected_properties = ['description', 'keywords', 'title', 'type']
211+
expected_properties = ['date', 'description', 'keywords', 'title', 'type']
57212

58213
assert sorted(domains.keys()) == expected_properties
59214

@@ -66,7 +221,7 @@ def test_domains(config):
66221
assert list(domains.keys()) == ['type']
67222

68223

69-
def test_query(config):
224+
def test_query(config, mock_csw):
70225
p = CSWFacadeProvider(config)
71226

72227
fields = p.get_fields()
@@ -76,9 +231,9 @@ def test_query(config):
76231
assert value['type'] == 'string'
77232

78233
results = p.query()
79-
assert len(results['features']) == 10
234+
assert len(results['features']) == 2 # Mock returns 2 records
80235
assert results['numberMatched'] == 12
81-
assert results['numberReturned'] == 10
236+
assert results['numberReturned'] == 2
82237
assert results['features'][0]['id'] == 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f' # noqa
83238
assert results['features'][0]['geometry'] is None
84239
assert results['features'][0]['properties']['title'] == 'Lorem ipsum'
@@ -92,20 +247,11 @@ def test_query(config):
92247
assert len(results['features']) == 1
93248
assert results['features'][0]['id'] == 'urn:uuid:19887a8a-f6b0-4a63-ae56-7fba0e17801f' # noqa
94249

95-
results = p.query(offset=2, limit=1)
250+
results = p.query(offset=1, limit=1)
96251
assert len(results['features']) == 1
97252
assert results['features'][0]['id'] == 'urn:uuid:1ef30a8b-876d-4828-9246-c37ab4510bbd' # noqa
98253

99-
assert len(results['features'][0]['properties']) == 2
100-
101-
results = p.query(q='lorem')
102-
assert results['numberMatched'] == 5
103-
104-
results = p.query(q='lorem', sortby=[{'property': 'title', 'order': '-'}])
105-
assert results['numberMatched'] == 5
106-
107254
results = p.query(resulttype='hits')
108-
assert len(results['features']) == 0
109255
assert results['numberMatched'] == 12
110256

111257
results = p.query(bbox=[-10, 40, 0, 60])
@@ -115,23 +261,10 @@ def test_query(config):
115261
assert len(results['features']) == 2
116262

117263
results = p.query(properties=[('title', 'Maecenas enim')])
118-
assert len(results['features']) == 1
119-
120-
properties = [
121-
('title', 'Maecenas enim'),
122-
('type', 'http://purl.org/dc/dcmitype/Text')
123-
]
124-
results = p.query(properties=properties)
125-
assert len(results['features']) == 1
126-
127-
results = p.query(datetime_='2006-05-12')
128-
assert len(results['features']) == 1
129-
130-
results = p.query(datetime_='2004/2007')
131-
assert len(results['features']) == 3
264+
assert len(results['features']) == 2
132265

133266

134-
def test_get(config):
267+
def test_get(config, mock_csw):
135268
p = CSWFacadeProvider(config)
136269

137270
result = p.get('urn:uuid:a06af396-3105-442d-8b40-22b57a90d2f2')
@@ -146,7 +279,7 @@ def test_get(config):
146279
assert 'service=CSW' in xml_link['href']
147280

148281

149-
def test_get_not_existing_item_raise_exception(config):
282+
def test_get_not_existing_item_raise_exception(config, mock_csw):
150283
"""Testing query for a not existing object"""
151284
p = CSWFacadeProvider(config)
152285
with pytest.raises(ProviderItemNotFoundError):

0 commit comments

Comments
 (0)