Skip to content

Commit c91719e

Browse files
authored
Add mock data tests for the socrata provider (geopython#1881)
* Skip soda live tests by default * Test socrata against a mock implementation * Add socrata live test to github action, but commented * Add copyright line for me in test file
1 parent a1c94fa commit c91719e

File tree

3 files changed

+292
-54
lines changed

3 files changed

+292
-54
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ jobs:
143143
pytest tests/test_rasterio_provider.py
144144
pytest tests/test_sensorthings_provider.py
145145
pytest tests/test_socrata_provider.py
146+
# pytest tests/test_socrata_provider_live.py.py # NOTE: these are skipped in the file but listed here for completeness
146147
pytest tests/test_sqlite_geopackage_provider.py
147148
pytest tests/test_tinydb_catalogue_provider.py
148149
pytest tests/test_tinydb_manager_for_parallel_requests.py

tests/test_socrata_provider.py

Lines changed: 126 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# =================================================================
22
#
33
# Authors: Benjamin Webb <bwebb@lincolninst.edu>
4+
# Authors: Bernhard Mallinger <bernhard.mallinger@eox.at>
45
#
56
# Copyright (c) 2022 Benjamin Webb
7+
# Copyright (c) 2024 Bernhard Mallinger
68
#
79
# Permission is hereby granted, free of charge, to any person
810
# obtaining a copy of this software and associated documentation
@@ -27,6 +29,9 @@
2729
#
2830
# =================================================================
2931

32+
import copy
33+
from unittest import mock
34+
3035
import pytest
3136

3237
from pygeoapi.provider.socrata import SODAServiceProvider
@@ -41,15 +46,129 @@ def config():
4146
return {
4247
'name': 'SODAServiceProvider',
4348
'type': 'feature',
44-
'data': 'https://soda.demo.socrata.com/',
49+
'data': 'https://example.com/',
4550
'resource_id': 'emdb-u46w',
4651
'id_field': 'earthquake_id',
4752
'time_field': 'datetime',
4853
'geom_field': 'location'
4954
}
5055

5156

52-
def test_query(config):
57+
@pytest.fixture
58+
def mock_socrata(dataset):
59+
60+
def fake_get(*args, **kwargs):
61+
if kwargs.get('select') == 'count(*)':
62+
count = 19 if kwargs.get('where') == 'region = "Nevada"' else 1006
63+
return [{'count': str(count)}]
64+
else:
65+
# get features
66+
if kwargs.get('order') == 'datetime ASC':
67+
dt = '2012-09-07T23:00:42.000'
68+
else:
69+
dt = '2012-09-14T22:38:01.000'
70+
feature = {
71+
'type': 'Feature',
72+
'geometry': {
73+
'type': 'Point',
74+
'coordinates': [-117.6135, 41.1085],
75+
},
76+
'properties': {
77+
'earthquake_id': '00388610',
78+
'datetime': dt,
79+
'magnitude': '2.7',
80+
},
81+
}
82+
return {
83+
'type': 'FeatureCollection',
84+
'features': [
85+
copy.deepcopy(feature)
86+
for _ in range(kwargs.get('limit', 10))
87+
],
88+
'crs': {
89+
'type': 'name',
90+
'properties': {
91+
'name': 'urn:ogc:def:crs:OGC:1.3:CRS84',
92+
}
93+
}
94+
}
95+
96+
with mock.patch(
97+
'sodapy.socrata.Socrata.get', new=fake_get,
98+
) as mock_get, mock.patch(
99+
'sodapy.socrata.Socrata.datasets', return_value=[dataset],
100+
):
101+
yield mock_get
102+
103+
104+
@pytest.fixture()
105+
def dataset():
106+
return {
107+
'resource': {
108+
'columns_datatype': ['Point',
109+
'Text',
110+
'Text',
111+
'Text',
112+
'Text',
113+
'Number',
114+
'Text',
115+
'Number',
116+
'Number',
117+
'Calendar date'],
118+
'columns_description': ['',
119+
'',
120+
'',
121+
'',
122+
'',
123+
'This column was automatically created '
124+
'in order to record in what polygon from '
125+
"the dataset 'Zip Codes' (k83t-ady5) the "
126+
"point in column 'location' is located. "
127+
'This enables the creation of region '
128+
'maps (choropleths) in the visualization '
129+
'canvas and data lens.',
130+
'',
131+
'',
132+
'',
133+
''],
134+
'columns_field_name': ['location',
135+
'earthquake_id',
136+
'location_zip',
137+
'location_city',
138+
'location_address',
139+
':@computed_region_k83t_ady5',
140+
'location_state',
141+
'depth',
142+
'magnitude',
143+
'datetime'],
144+
'columns_format': [{},
145+
{},
146+
{},
147+
{},
148+
{},
149+
{},
150+
{},
151+
{},
152+
{},
153+
{}],
154+
'columns_name': ['Location',
155+
'Earthquake ID',
156+
'Location (zip)',
157+
'Location (city)',
158+
'Location (address)',
159+
'Zip Codes',
160+
'Location (state)',
161+
'Depth',
162+
'Magnitude',
163+
'Datetime'],
164+
'contact_email': None,
165+
'type': 'dataset',
166+
'updatedAt': '2019-02-13T23:37:38.000Z'
167+
}
168+
}
169+
170+
171+
def test_query(config, mock_socrata):
53172
p = SODAServiceProvider(config)
54173

55174
results = p.query()
@@ -72,7 +191,7 @@ def test_query(config):
72191
assert results['numberMatched'] == 1006
73192

74193

75-
def test_geometry(config):
194+
def test_geometry(config, mock_socrata):
76195
p = SODAServiceProvider(config)
77196

78197
results = p.query()
@@ -82,56 +201,19 @@ def test_geometry(config):
82201
results = p.query(skip_geometry=True)
83202
assert results['features'][0]['geometry'] is None
84203

85-
bbox = [-109, 37, -102, 41]
86-
results = p.query(bbox=bbox)
87-
assert results['numberMatched'] == 0
88-
89-
bbox = [-178.2, 18.9, -66.9, 71.4]
90-
results = p.query(bbox=bbox)
91-
assert results['numberMatched'] == 817
92204

93-
feature = results['features'][0]
94-
x, y = feature['geometry']['coordinates']
95-
xmin, ymin, xmax, ymax = bbox
96-
assert xmin <= x <= xmax
97-
assert ymin <= y <= ymax
98-
99-
100-
def test_query_properties(config):
205+
def test_query_properties(config, mock_socrata):
101206
p = SODAServiceProvider(config)
102207

103208
results = p.query()
104-
assert len(results['features'][0]['properties']) == 11
209+
assert len(results['features'][0]['properties']) == 2
105210

106211
# Query by property
107212
results = p.query(properties=[('region', 'Nevada'), ])
108213
assert results['numberMatched'] == 19
109214

110-
results = p.query(properties=[('region', 'Northern California'), ])
111-
assert results['numberMatched'] == 119
112-
113-
# Query for property
114-
results = p.query(select_properties=['magnitude', ])
115-
assert len(results['features'][0]['properties']) == 1
116-
assert 'magnitude' in results['features'][0]['properties']
117215

118-
# Query with configured properties
119-
config['properties'] = ['region', 'datetime', 'magnitude']
120-
p = SODAServiceProvider(config)
121-
122-
results = p.query()
123-
props = results['features'][0]['properties']
124-
assert all(p in props for p in config['properties'])
125-
assert len(props) == 3
126-
127-
results = p.query(properties=[('region', 'Central California'), ])
128-
assert results['numberMatched'] == 92
129-
130-
results = p.query(select_properties=['region', ])
131-
assert len(results['features'][0]['properties']) == 1
132-
133-
134-
def test_query_sortby_datetime(config):
216+
def test_query_sortby_datetime(config, mock_socrata):
135217
p = SODAServiceProvider(config)
136218

137219
results = p.query(sortby=[{'property': 'datetime', 'order': '+'}])
@@ -142,18 +224,8 @@ def test_query_sortby_datetime(config):
142224
dt = results['features'][0]['properties']['datetime']
143225
assert dt == '2012-09-14T22:38:01.000'
144226

145-
results = p.query(datetime_='../2012-09-10T00:00:00.00Z',
146-
sortby=[{'property': 'datetime', 'order': '-'}])
147-
dt = results['features'][0]['properties']['datetime']
148-
assert dt == '2012-09-09T23:57:50.000'
149-
150-
results = p.query(datetime_='2012-09-10T00:00:00.00Z/..',
151-
sortby=[{'property': 'datetime', 'order': '+'}])
152-
dt = results['features'][0]['properties']['datetime']
153-
assert dt == '2012-09-10T00:04:44.000'
154-
155227

156-
def test_get(config):
228+
def test_get(config, mock_socrata):
157229
p = SODAServiceProvider(config)
158230

159231
result = p.get('00388610')

0 commit comments

Comments
 (0)