Coverage for tests/test_search_aggregations.py: 100%
197 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-03 20:32 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-03 20:32 +0000
1# SPDX-FileCopyrightText: 2021 Forschungszentrum Jülich GmbH
2# SPDX-License-Identifier: MIT
4import pytest
5import json
6from sqlalchemy import insert
7from toardb.timeseries.models import Timeseries, timeseries_timeseries_roles_table
8from toardb.timeseries.models_programme import TimeseriesProgramme
9from toardb.timeseries.models_role import TimeseriesRole
10from toardb.stationmeta.models import StationmetaCore, StationmetaGlobal, StationmetaChangelog
11from toardb.stationmeta.schemas import get_geom_from_coordinates, Coordinates
12from toardb.variables.models import Variable
13from toardb.contacts.models import Person, Organisation, Contact
14from toardb.auth_user.models import AuthUser
16# Required imports 'create_test_database'
17from toardb.test_base import (
18 client,
19 get_test_db,
20 create_test_database,
21 url,
22 get_test_engine,
23 test_db_session as db,
24)
27class TestApps:
28 def setup(self):
29 self.application_url = "/timeseries/"
31 """Set up all the data before each test
32 If you want the setup only once (per test module),
33 the scope argument is not working in the expected way, as discussed here:
34 https://stackoverflow.com/questions/45817153/py-test-fixture-use-function-fixture-in-scope-fixture
35 """
37 @pytest.fixture(autouse=True)
38 def setup_db_data(self, db):
39 _db_conn = get_test_engine()
40 # id_seq will not be reset automatically between tests!
41 fake_conn = _db_conn.raw_connection()
42 fake_cur = fake_conn.cursor()
43 fake_cur.execute("ALTER SEQUENCE auth_user_id_seq RESTART WITH 1")
44 fake_conn.commit()
45 fake_cur.execute("ALTER SEQUENCE variables_id_seq RESTART WITH 1")
46 fake_conn.commit()
47 fake_cur.execute("ALTER SEQUENCE stationmeta_core_id_seq RESTART WITH 1")
48 fake_conn.commit()
49 fake_cur.execute("ALTER SEQUENCE stationmeta_global_id_seq RESTART WITH 1")
50 fake_conn.commit()
51 fake_cur.execute("ALTER SEQUENCE stationmeta_roles_id_seq RESTART WITH 1")
52 fake_conn.commit()
53 fake_cur.execute("ALTER SEQUENCE stationmeta_annotations_id_seq RESTART WITH 1")
54 fake_conn.commit()
55 fake_cur.execute("ALTER SEQUENCE stationmeta_aux_doc_id_seq RESTART WITH 1")
56 fake_conn.commit()
57 fake_cur.execute("ALTER SEQUENCE stationmeta_aux_image_id_seq RESTART WITH 1")
58 fake_conn.commit()
59 fake_cur.execute("ALTER SEQUENCE stationmeta_aux_url_id_seq RESTART WITH 1")
60 fake_conn.commit()
61 fake_cur.execute("ALTER SEQUENCE persons_id_seq RESTART WITH 1")
62 fake_conn.commit()
63 fake_cur.execute("ALTER SEQUENCE organisations_id_seq RESTART WITH 1")
64 fake_conn.commit()
65 fake_cur.execute("ALTER SEQUENCE contacts_id_seq RESTART WITH 1")
66 fake_conn.commit()
67 fake_cur.execute("ALTER SEQUENCE timeseries_annotations_id_seq RESTART WITH 1")
68 fake_conn.commit()
69 fake_cur.execute("ALTER SEQUENCE timeseries_roles_id_seq RESTART WITH 3")
70 fake_conn.commit()
71 fake_cur.execute("ALTER SEQUENCE timeseries_programmes_id_seq RESTART WITH 1")
72 fake_conn.commit()
73 fake_cur.execute("ALTER SEQUENCE timeseries_id_seq RESTART WITH 1")
74 fake_conn.commit()
75 infilename = "tests/fixtures/auth_user/auth.json"
76 with open(infilename) as f:
77 metajson = json.load(f)
78 for entry in metajson:
79 new_auth_user = AuthUser(**entry)
80 db.add(new_auth_user)
81 db.commit()
82 db.refresh(new_auth_user)
83 infilename = "tests/fixtures/contacts/persons.json"
84 with open(infilename) as f:
85 metajson = json.load(f)
86 for entry in metajson:
87 new_person = Person(**entry)
88 db.add(new_person)
89 db.commit()
90 db.refresh(new_person)
91 infilename = "tests/fixtures/contacts/organisations.json"
92 with open(infilename) as f:
93 metajson = json.load(f)
94 for entry in metajson:
95 new_organisation = Organisation(**entry)
96 db.add(new_organisation)
97 db.commit()
98 db.refresh(new_organisation)
99 infilename = "tests/fixtures/contacts/contacts.json"
100 with open(infilename) as f:
101 metajson = json.load(f)
102 for entry in metajson:
103 new_contact = Contact(**entry)
104 db.add(new_contact)
105 db.commit()
106 db.refresh(new_contact)
107 infilename = "tests/fixtures/variables/variables.json"
108 with open(infilename) as f:
109 metajson = json.load(f)
110 for entry in metajson:
111 new_variable = Variable(**entry)
112 db.add(new_variable)
113 db.commit()
114 db.refresh(new_variable)
115 infilename = "tests/fixtures/stationmeta/stationmeta_core.json"
116 with open(infilename) as f:
117 metajson = json.load(f)
118 for entry in metajson:
119 new_stationmeta_core = StationmetaCore(**entry)
120 # there's a mismatch with coordinates --> how to automatically switch back and forth?!
121 tmp_coordinates = new_stationmeta_core.coordinates
122 new_stationmeta_core.coordinates = get_geom_from_coordinates(
123 Coordinates(**new_stationmeta_core.coordinates)
124 )
125 db.add(new_stationmeta_core)
126 db.commit()
127 db.refresh(new_stationmeta_core)
128 infilename = "tests/fixtures/stationmeta/stationmeta_changelog.json"
129 with open(infilename) as f:
130 metajson = json.load(f)
131 for entry in metajson:
132 new_stationmeta_changelog = StationmetaChangelog(**entry)
133 db.add(new_stationmeta_changelog)
134 db.commit()
135 db.refresh(new_stationmeta_changelog)
136 infilename = "tests/fixtures/stationmeta/stationmeta_global.json"
137 with open(infilename) as f:
138 metajson = json.load(f)
139 for entry in metajson:
140 new_stationmeta_global = StationmetaGlobal(**entry)
141 db.add(new_stationmeta_global)
142 db.commit()
143 db.refresh(new_stationmeta_global)
144 infilename = "tests/fixtures/timeseries/timeseries_programmes.json"
145 with open(infilename) as f:
146 metajson = json.load(f)
147 for entry in metajson:
148 new_timeseries_programme = TimeseriesProgramme(**entry)
149 db.add(new_timeseries_programme)
150 db.commit()
151 db.refresh(new_timeseries_programme)
152 infilename = "tests/fixtures/timeseries/timeseries.json"
153 with open(infilename) as f:
154 metajson = json.load(f)
155 for entry in metajson:
156 new_timeseries = Timeseries(**entry)
157 db.add(new_timeseries)
158 db.commit()
159 db.refresh(new_timeseries)
160 infilename = "tests/fixtures/timeseries/timeseries_roles.json"
161 with open(infilename) as f:
162 metajson = json.load(f)
163 for entry in metajson:
164 new_timeseries_role = TimeseriesRole(**entry)
165 db.add(new_timeseries_role)
166 db.commit()
167 db.refresh(new_timeseries_role)
168 infilename = "tests/fixtures/timeseries/timeseries_timeseries_roles.json"
169 with open(infilename) as f:
170 metajson = json.load(f)
171 for entry in metajson:
172 db.execute(
173 insert(timeseries_timeseries_roles_table).values(
174 timeseries_id=entry["timeseries_id"], role_id=entry["role_id"]
175 )
176 )
177 db.execute("COMMIT")
179 def test_search_base(self, client, db):
180 response = client.get("/search/a?")
181 expected_status_code = 200
182 assert response.status_code == expected_status_code
183 expected_resp = [{'id': 1,
184 'label': 'CMA',
185 'order': 1,
186 'sampling_frequency': 'hourly',
187 'aggregation': 'mean',
188 'data_start_date': '2003-09-07T15:30:00+00:00',
189 'data_end_date': '2016-12-31T14:30:00+00:00',
190 'data_origin': 'instrument',
191 'data_origin_type': 'measurement',
192 'provider_version': 'N/A',
193 'sampling_height': 7.0,
194 'additional_metadata': {"original_units": "ppb"},
195 'doi': '',
196 'coverage': -1.0,
197 'station': {'id': 2,
198 'codes': ['SDZ54421'],
199 'name': 'Shangdianzi',
200 'coordinates': {'lat': 40.65, 'lng': 117.106, 'alt': 293.9},
201 'coordinate_validation_status': 'not checked',
202 'country': 'China',
203 'state': 'Beijing Shi',
204 'type': 'unknown',
205 'type_of_area': 'unknown',
206 'timezone': 'Asia/Shanghai',
207 'additional_metadata': {'add_type': 'nature reservation'},
208 'aux_images': [],
209 'aux_docs': [],
210 'aux_urls': [],
211 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
212 'mean_topography_srtm_alt_1km_year1994': -999.0,
213 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
214 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
215 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
216 'climatic_zone_year2016': '6 (warm temperate dry)',
217 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
218 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
219 'landcover_description_25km_year2012': '',
220 'dominant_ecoregion_year2017': '-1 (undefined)',
221 'ecoregion_description_25km_year2017': '',
222 'distance_to_major_road_year2020': -999.0,
223 'mean_stable_nightlights_1km_year2013': -999.0,
224 'mean_stable_nightlights_5km_year2013': -999.0,
225 'max_stable_nightlights_25km_year2013': -999.0,
226 'max_stable_nightlights_25km_year1992': -999.0,
227 'mean_population_density_250m_year2015': -1.0,
228 'mean_population_density_5km_year2015': -1.0,
229 'max_population_density_25km_year2015': -1.0,
230 'mean_population_density_250m_year1990': -1.0,
231 'mean_population_density_5km_year1990': -1.0,
232 'max_population_density_25km_year1990': -1.0,
233 'mean_nox_emissions_10km_year2015': -999.0,
234 'mean_nox_emissions_10km_year2000': -999.0,
235 'toar1_category': 'unclassified',
236 'toar2_category': 'suburban'},
237 'changelog': [{'datetime': '2023-07-15T19:27:09.463245+00:00',
238 'description': 'station created',
239 'old_value': '',
240 'new_value': '',
241 'station_id': 2,
242 'author_id': 1,
243 'type_of_change': 'created'}]},
244 'variable': {'name': 'toluene',
245 'longname': 'toluene',
246 'displayname': 'Toluene',
247 'cf_standardname': 'mole_fraction_of_toluene_in_air',
248 'units': 'nmol mol-1',
249 'chemical_formula': 'C7H8',
250 'id': 7},
251 'programme': {'id': 0,
252 'name': '',
253 'longname': '',
254 'homepage': '',
255 'description': ''},
256 'roles': [{'id': 2,
257 'role': 'resource provider',
258 'status': 'active',
259 'contact': {'id': 4,
260 'organisation': {'id': 1,
261 'name': 'UBA',
262 'longname': 'Umweltbundesamt',
263 'kind': 'government',
264 'city': 'Dessau-Roßlau',
265 'postcode': '06844',
266 'street_address': 'Wörlitzer Platz 1',
267 'country': 'Germany',
268 'homepage': 'https://www.umweltbundesamt.de',
269 'contact_url': 'mailto:immission@uba.de'}}},
270 {'id': 3,
271 'role': 'principal investigator',
272 'status': 'active',
273 'contact': {'id': 3,
274 'person': {'email': 's.schroeder@fz-juelich.de',
275 'id': 3,
276 'isprivate': False,
277 'name': 'Sabine Schröder',
278 'orcid': '0000-0002-0309-8010',
279 'phone': '+49-2461-61-6397'}}}]},
280 {'id': 2,
281 'label': 'CMA',
282 'order': 1,
283 'sampling_frequency': 'hourly',
284 'aggregation': 'mean',
285 'data_start_date': '2003-09-07T15:30:00+00:00',
286 'data_end_date': '2016-12-31T14:30:00+00:00',
287 'data_origin': 'instrument',
288 'data_origin_type': 'measurement',
289 'provider_version': 'N/A',
290 'sampling_height': 7.0,
291 'additional_metadata': {'original_units': {'since_19740101000000': 'nmol/mol'},
292 'measurement_method': 'uv_abs',
293 'absorption_cross_section': 'Hearn 1961',
294 'ebas_metadata_19740101000000_29y':
295 {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
296 'Data level': '2',
297 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
298 'Station code': 'XXX',
299 'Station name': 'Secret'}},
300 'doi': '',
301 'coverage': -1.0,
302 'station': {'id': 3,
303 'codes': ['China_test8'],
304 'name': 'Test_China',
305 'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
306 'coordinate_validation_status': 'not checked',
307 'country': 'China',
308 'state': 'Shandong Sheng',
309 'type': 'unknown',
310 'type_of_area': 'unknown',
311 'timezone': 'Asia/Shanghai',
312 'additional_metadata': {},
313 'aux_images': [],
314 'aux_docs': [],
315 'aux_urls': [],
316 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
317 'mean_topography_srtm_alt_1km_year1994': -999.0,
318 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
319 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
320 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
321 'climatic_zone_year2016': '6 (warm temperate dry)',
322 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
323 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
324 'landcover_description_25km_year2012': '',
325 'dominant_ecoregion_year2017': '-1 (undefined)',
326 'ecoregion_description_25km_year2017': '',
327 'distance_to_major_road_year2020': -999.0,
328 'mean_stable_nightlights_1km_year2013': -999.0,
329 'mean_stable_nightlights_5km_year2013': -999.0,
330 'max_stable_nightlights_25km_year2013': -999.0,
331 'max_stable_nightlights_25km_year1992': -999.0,
332 'mean_population_density_250m_year2015': -1.0,
333 'mean_population_density_5km_year2015': -1.0,
334 'max_population_density_25km_year2015': -1.0,
335 'mean_population_density_250m_year1990': -1.0,
336 'mean_population_density_5km_year1990': -1.0,
337 'max_population_density_25km_year1990': -1.0,
338 'mean_nox_emissions_10km_year2015': -999.0,
339 'mean_nox_emissions_10km_year2000': -999.0,
340 'toar1_category': 'unclassified',
341 'toar2_category': 'suburban'},
342 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
343 'description': 'station created',
344 'old_value': '',
345 'new_value': '',
346 'station_id': 3,
347 'author_id': 1,
348 'type_of_change': 'created'}]},
349 'variable': {'name': 'o3',
350 'longname': 'ozone',
351 'displayname': 'Ozone',
352 'cf_standardname': 'mole_fraction_of_ozone_in_air',
353 'units': 'nmol mol-1',
354 'chemical_formula': 'O3',
355 'id': 5},
356 'programme': {'id': 0,
357 'name': '',
358 'longname': '',
359 'homepage': '',
360 'description': ''},
361 'roles': [{'id': 1,
362 'role': 'resource provider',
363 'status': 'active',
364 'contact': {'id': 5,
365 'organisation':
366 {'id': 2,
367 'name': 'FZJ',
368 'longname': 'Forschungszentrum Jülich',
369 'kind': 'research',
370 'city': 'Jülich',
371 'postcode': '52425',
372 'street_address': 'Wilhelm-Johnen-Straße',
373 'country': 'Germany',
374 'homepage': 'https://www.fz-juelich.de',
375 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}]},
376 {'id': 18763,
377 'additional_metadata': {'original_units': 'ppb'},
378 'aggregation': 'mean',
379 'coverage': -1.0,
380 'data_start_date': '1991-01-01T00:00:00+00:00',
381 'data_end_date': '2025-02-25T14:00:00+00:00',
382 'data_origin': 'instrument',
383 'data_origin_type': 'measurement',
384 'doi': '',
385 'label': '',
386 'order': 1,
387 'programme': {'description': '',
388 'homepage': '',
389 'id': 0,
390 'longname': '',
391 'name': ''},
392 'provider_version': 'N/A',
393 'roles': [{'contact': {'id': 5,
394 'organisation': {'city': 'Jülich',
395 'contact_url': 'mailto:toar-data@fz-juelich.de',
396 'country': 'Germany',
397 'homepage': 'https://www.fz-juelich.de',
398 'id': 2,
399 'kind': 'research',
400 'longname': 'Forschungszentrum '
401 'Jülich',
402 'name': 'FZJ',
403 'postcode': '52425',
404 'street_address': 'Wilhelm-Johnen-Straße'}},
405 'id': 1,
406 'role': 'resource provider',
407 'status': 'active'}],
408 'sampling_frequency': 'hourly',
409 'sampling_height': 7.0,
410 'station': {'additional_metadata': {'add_type': 'nature reservation'},
411 'aux_docs': [],
412 'aux_images': [],
413 'aux_urls': [],
414 'changelog': [{'author_id': 1,
415 'datetime': '2023-07-15T19:27:09.463245+00:00',
416 'description': 'station created',
417 'new_value': '',
418 'old_value': '',
419 'station_id': 2,
420 'type_of_change': 'created'}],
421 'codes': ['SDZ54421'],
422 'coordinate_validation_status': 'not checked',
423 'coordinates': {'alt': 293.9,
424 'lat': 40.65,
425 'lng': 117.106},
426 'country': 'China',
427 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
428 'distance_to_major_road_year2020': -999.0,
429 'dominant_ecoregion_year2017': '-1 (undefined)',
430 'dominant_landcover_year2012': '11 (Cropland, '
431 'rainfed, '
432 'herbaceous cover)',
433 'ecoregion_description_25km_year2017': '',
434 'htap_region_tier1_year2010': '11 (MDE Middle '
435 'East: S. Arabia, '
436 'Oman, etc, Iran, '
437 'Iraq)',
438 'landcover_description_25km_year2012': '',
439 'max_population_density_25km_year1990': -1.0,
440 'max_population_density_25km_year2015': -1.0,
441 'max_stable_nightlights_25km_year1992': -999.0,
442 'max_stable_nightlights_25km_year2013': -999.0,
443 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
444 'mean_nox_emissions_10km_year2000': -999.0,
445 'mean_nox_emissions_10km_year2015': -999.0,
446 'mean_population_density_250m_year1990': -1.0,
447 'mean_population_density_250m_year2015': -1.0,
448 'mean_population_density_5km_year1990': -1.0,
449 'mean_population_density_5km_year2015': -1.0,
450 'mean_stable_nightlights_1km_year2013': -999.0,
451 'mean_stable_nightlights_5km_year2013': -999.0,
452 'mean_topography_srtm_alt_1km_year1994': -999.0,
453 'mean_topography_srtm_alt_90m_year1994': -999.0,
454 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
455 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
456 'toar1_category': 'unclassified',
457 'toar2_category': 'suburban'},
458 'id': 2,
459 'name': 'Shangdianzi',
460 'state': 'Beijing Shi',
461 'timezone': 'Asia/Shanghai',
462 'type': 'unknown',
463 'type_of_area': 'unknown'},
464 'variable': {'cf_standardname': 'mole_fraction_of_ozone_in_air',
465 'chemical_formula': 'O3',
466 'displayname': 'Ozone',
467 'id': 5,
468 'longname': 'ozone',
469 'name': 'o3',
470 'units': 'nmol mol-1'}},
471 {'additional_metadata': {'original_units': 'ppb'},
472 'aggregation': 'mean',
473 'coverage': -1.0,
474 'data_end_date': '2025-02-25T14:00:00+00:00',
475 'data_origin': 'instrument',
476 'data_origin_type': 'measurement',
477 'data_start_date': '1991-01-01T00:00:00+00:00',
478 'doi': '',
479 'id': 30890,
480 'label': '',
481 'order': 2,
482 'programme': {'description': '',
483 'homepage': '',
484 'id': 0,
485 'longname': '',
486 'name': ''},
487 'provider_version': 'N/A',
488 'roles': [{'contact': {'id': 5,
489 'organisation': {'city': 'Jülich',
490 'contact_url': 'mailto:toar-data@fz-juelich.de',
491 'country': 'Germany',
492 'homepage': 'https://www.fz-juelich.de',
493 'id': 2,
494 'kind': 'research',
495 'longname': 'Forschungszentrum '
496 'Jülich',
497 'name': 'FZJ',
498 'postcode': '52425',
499 'street_address': 'Wilhelm-Johnen-Straße'}},
500 'id': 1,
501 'role': 'resource provider',
502 'status': 'active'}],
503 'sampling_frequency': 'hourly',
504 'sampling_height': 7.0,
505 'station': {'additional_metadata': {'add_type': 'nature reservation'},
506 'aux_docs': [],
507 'aux_images': [],
508 'aux_urls': [],
509 'changelog': [{'author_id': 1,
510 'datetime': '2023-07-15T19:27:09.463245+00:00',
511 'description': 'station created',
512 'new_value': '',
513 'old_value': '',
514 'station_id': 2,
515 'type_of_change': 'created'}],
516 'codes': ['SDZ54421'],
517 'coordinate_validation_status': 'not checked',
518 'coordinates': {'alt': 293.9,
519 'lat': 40.65,
520 'lng': 117.106},
521 'country': 'China',
522 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
523 'distance_to_major_road_year2020': -999.0,
524 'dominant_ecoregion_year2017': '-1 (undefined)',
525 'dominant_landcover_year2012': '11 (Cropland, '
526 'rainfed, '
527 'herbaceous cover)',
528 'ecoregion_description_25km_year2017': '',
529 'htap_region_tier1_year2010': '11 (MDE Middle '
530 'East: S. Arabia, '
531 'Oman, etc, Iran, '
532 'Iraq)',
533 'landcover_description_25km_year2012': '',
534 'max_population_density_25km_year1990': -1.0,
535 'max_population_density_25km_year2015': -1.0,
536 'max_stable_nightlights_25km_year1992': -999.0,
537 'max_stable_nightlights_25km_year2013': -999.0,
538 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
539 'mean_nox_emissions_10km_year2000': -999.0,
540 'mean_nox_emissions_10km_year2015': -999.0,
541 'mean_population_density_250m_year1990': -1.0,
542 'mean_population_density_250m_year2015': -1.0,
543 'mean_population_density_5km_year1990': -1.0,
544 'mean_population_density_5km_year2015': -1.0,
545 'mean_stable_nightlights_1km_year2013': -999.0,
546 'mean_stable_nightlights_5km_year2013': -999.0,
547 'mean_topography_srtm_alt_1km_year1994': -999.0,
548 'mean_topography_srtm_alt_90m_year1994': -999.0,
549 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
550 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
551 'toar1_category': 'unclassified',
552 'toar2_category': 'suburban'},
553 'id': 2,
554 'name': 'Shangdianzi',
555 'state': 'Beijing Shi',
556 'timezone': 'Asia/Shanghai',
557 'type': 'unknown',
558 'type_of_area': 'unknown'},
559 'variable': {'cf_standardname': 'mole_fraction_of_ozone_in_air',
560 'chemical_formula': 'O3',
561 'displayname': 'Ozone',
562 'id': 5,
563 'longname': 'ozone',
564 'name': 'o3',
565 'units': 'nmol mol-1'}},
566 {'additional_metadata': {'original_units': 'ppb'},
567 'aggregation': 'mean',
568 'coverage': -1.0,
569 'data_end_date': '2025-02-25T14:00:00+00:00',
570 'data_origin': 'instrument',
571 'data_origin_type': 'measurement',
572 'data_start_date': '1991-01-01T00:00:00+00:00',
573 'doi': '',
574 'id': 434870,
575 'label': '',
576 'order': 2,
577 'programme': {
578 'description': '',
579 'homepage': '',
580 'id': 0,
581 'longname': '',
582 'name': '',
583 },
584 'provider_version': 'N/A',
585 'roles': [
586 {
587 'contact': {
588 'id': 4,
589 'organisation': {
590 'city': 'Dessau-Roßlau',
591 'contact_url': 'mailto:immission@uba.de',
592 'country': 'Germany',
593 'homepage': 'https://www.umweltbundesamt.de',
594 'id': 1,
595 'kind': 'government',
596 'longname': 'Umweltbundesamt',
597 'name': 'UBA',
598 'postcode': '06844',
599 'street_address': 'Wörlitzer Platz 1',
600 },
601 },
602 'id': 2,
603 'role': 'resource provider',
604 'status': 'active',
605 },
606 ],
607 'sampling_frequency': 'hourly',
608 'sampling_height': 7.0,
609 'station': {
610 'additional_metadata': {'add_type': 'nature reservation'},
611 'aux_docs': [],
612 'aux_images': [],
613 'aux_urls': [],
614 'changelog': [
615 {
616 'author_id': 1,
617 'datetime': '2023-07-15T19:27:09.463245+00:00',
618 'description': 'station created',
619 'new_value': '',
620 'old_value': '',
621 'station_id': 2,
622 'type_of_change': 'created',
623 },
624 ],
625 'codes': [
626 'SDZ54421',
627 ],
628 'coordinate_validation_status': 'not checked',
629 'coordinates': {
630 'alt': 293.9,
631 'lat': 40.65,
632 'lng': 117.106
633 },
634 'country': 'China',
635 'globalmeta': {
636 'climatic_zone_year2016': '6 (warm temperate dry)',
637 'distance_to_major_road_year2020': -999.0,
638 'dominant_ecoregion_year2017': '-1 (undefined)',
639 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
640 'ecoregion_description_25km_year2017': '',
641 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
642 'landcover_description_25km_year2012': '',
643 'max_population_density_25km_year1990': -1.0,
644 'max_population_density_25km_year2015': -1.0,
645 'max_stable_nightlights_25km_year1992': -999.0,
646 'max_stable_nightlights_25km_year2013': -999.0,
647 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
648 'mean_nox_emissions_10km_year2000': -999.0,
649 'mean_nox_emissions_10km_year2015': -999.0,
650 'mean_population_density_250m_year1990': -1.0,
651 'mean_population_density_250m_year2015': -1.0,
652 'mean_population_density_5km_year1990': -1.0,
653 'mean_population_density_5km_year2015': -1.0,
654 'mean_stable_nightlights_1km_year2013': -999.0,
655 'mean_stable_nightlights_5km_year2013': -999.0,
656 'mean_topography_srtm_alt_1km_year1994': -999.0,
657 'mean_topography_srtm_alt_90m_year1994': -999.0,
658 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
659 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
660 'toar1_category': 'unclassified',
661 'toar2_category': 'suburban',
662 },
663 'id': 2,
664 'name': 'Shangdianzi',
665 'state': 'Beijing Shi',
666 'timezone': 'Asia/Shanghai',
667 'type': 'unknown',
668 'type_of_area': 'unknown',
669 },
670 'variable': {
671 'cf_standardname': 'mole_fraction_of_ozone_in_air',
672 'chemical_formula': 'O3',
673 'displayname': 'Ozone',
674 'id': 5,
675 'longname': 'ozone',
676 'name': 'o3',
677 'units': 'nmol mol-1' }}]
678 assert response.json() == expected_resp
681 def test_search_single(self, client, db):
682 response = client.get("/search/a?id=2")
683 expected_status_code = 200
684 assert response.status_code == expected_status_code
685 expected_resp = [
686 {'id': 2,
687 'label': 'CMA',
688 'order': 1,
689 'sampling_frequency': 'hourly',
690 'aggregation': 'mean',
691 'data_start_date': '2003-09-07T15:30:00+00:00',
692 'data_end_date': '2016-12-31T14:30:00+00:00',
693 'data_origin': 'instrument',
694 'data_origin_type': 'measurement',
695 'provider_version': 'N/A',
696 'sampling_height': 7.0,
697 'additional_metadata': {'original_units': {'since_19740101000000': 'nmol/mol'},
698 'measurement_method': 'uv_abs',
699 'absorption_cross_section': 'Hearn 1961',
700 'ebas_metadata_19740101000000_29y':
701 {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
702 'Data level': '2',
703 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
704 'Station code': 'XXX',
705 'Station name': 'Secret'}},
706 'doi': '',
707 'coverage': -1.0,
708 'station': {'id': 3,
709 'codes': ['China_test8'],
710 'name': 'Test_China',
711 'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
712 'coordinate_validation_status': 'not checked',
713 'country': 'China',
714 'state': 'Shandong Sheng',
715 'type': 'unknown',
716 'type_of_area': 'unknown',
717 'timezone': 'Asia/Shanghai',
718 'additional_metadata': {},
719 'aux_images': [],
720 'aux_docs': [],
721 'aux_urls': [],
722 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
723 'mean_topography_srtm_alt_1km_year1994': -999.0,
724 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
725 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
726 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
727 'climatic_zone_year2016': '6 (warm temperate dry)',
728 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
729 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
730 'landcover_description_25km_year2012': '',
731 'dominant_ecoregion_year2017': '-1 (undefined)',
732 'ecoregion_description_25km_year2017': '',
733 'distance_to_major_road_year2020': -999.0,
734 'mean_stable_nightlights_1km_year2013': -999.0,
735 'mean_stable_nightlights_5km_year2013': -999.0,
736 'max_stable_nightlights_25km_year2013': -999.0,
737 'max_stable_nightlights_25km_year1992': -999.0,
738 'mean_population_density_250m_year2015': -1.0,
739 'mean_population_density_5km_year2015': -1.0,
740 'max_population_density_25km_year2015': -1.0,
741 'mean_population_density_250m_year1990': -1.0,
742 'mean_population_density_5km_year1990': -1.0,
743 'max_population_density_25km_year1990': -1.0,
744 'mean_nox_emissions_10km_year2015': -999.0,
745 'mean_nox_emissions_10km_year2000': -999.0,
746 'toar1_category': 'unclassified',
747 'toar2_category': 'suburban'},
748 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
749 'description': 'station created',
750 'old_value': '',
751 'new_value': '',
752 'station_id': 3,
753 'author_id': 1,
754 'type_of_change': 'created'}]},
755 'variable': {'name': 'o3',
756 'longname': 'ozone',
757 'displayname': 'Ozone',
758 'cf_standardname': 'mole_fraction_of_ozone_in_air',
759 'units': 'nmol mol-1',
760 'chemical_formula': 'O3',
761 'id': 5},
762 'programme': {'id': 0,
763 'name': '',
764 'longname': '',
765 'homepage': '',
766 'description': ''},
767 'roles': [{'id': 1,
768 'role': 'resource provider',
769 'status': 'active',
770 'contact': {'id': 5,
771 'organisation':
772 {'id': 2,
773 'name': 'FZJ',
774 'longname': 'Forschungszentrum Jülich',
775 'kind': 'research',
776 'city': 'Jülich',
777 'postcode': '52425',
778 'street_address': 'Wilhelm-Johnen-Straße',
779 'country': 'Germany',
780 'homepage': 'https://www.fz-juelich.de',
781 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}]}]
782 assert response.json() == expected_resp
784 def test_search_plus(self, client, db):
785 response = client.get("/search/a?id=1+id=2")
786 expected_status_code = 200
787 assert response.status_code == expected_status_code
788 expected_resp = [
789 {
790 "id": 1,
791 "label": "CMA",
792 "order": 1,
793 "sampling_frequency": "hourly",
794 "aggregation": "mean",
795 "data_start_date": "2003-09-07T15:30:00+00:00",
796 "data_end_date": "2016-12-31T14:30:00+00:00",
797 "data_origin": "instrument",
798 "data_origin_type": "measurement",
799 "provider_version": "N/A",
800 "sampling_height": 7.0,
801 "additional_metadata": {
802 "original_units": "ppb",
803 },
804 "doi": "",
805 "coverage": -1.0,
806 "station": {
807 "id": 2,
808 "codes": ["SDZ54421"],
809 "name": "Shangdianzi",
810 "coordinates": {"lat": 40.65, "lng": 117.106, "alt": 293.9},
811 "coordinate_validation_status": "not checked",
812 "country": "China",
813 "state": "Beijing Shi",
814 "type": "unknown",
815 "type_of_area": "unknown",
816 "timezone": "Asia/Shanghai",
817 "additional_metadata": {"add_type": "nature reservation"},
818 "aux_images": [],
819 "aux_docs": [],
820 "aux_urls": [],
821 "globalmeta": {
822 "mean_topography_srtm_alt_90m_year1994": -999.0,
823 "mean_topography_srtm_alt_1km_year1994": -999.0,
824 "max_topography_srtm_relative_alt_5km_year1994": -999.0,
825 "min_topography_srtm_relative_alt_5km_year1994": -999.0,
826 "stddev_topography_srtm_relative_alt_5km_year1994": -999.0,
827 "climatic_zone_year2016": "6 (warm temperate dry)",
828 "htap_region_tier1_year2010": "11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)",
829 "dominant_landcover_year2012": "11 (Cropland, rainfed, herbaceous cover)",
830 "landcover_description_25km_year2012": "",
831 "dominant_ecoregion_year2017": "-1 (undefined)",
832 "ecoregion_description_25km_year2017": "",
833 "distance_to_major_road_year2020": -999.0,
834 "mean_stable_nightlights_1km_year2013": -999.0,
835 "mean_stable_nightlights_5km_year2013": -999.0,
836 "max_stable_nightlights_25km_year2013": -999.0,
837 "max_stable_nightlights_25km_year1992": -999.0,
838 "mean_population_density_250m_year2015": -1.0,
839 "mean_population_density_5km_year2015": -1.0,
840 "max_population_density_25km_year2015": -1.0,
841 "mean_population_density_250m_year1990": -1.0,
842 "mean_population_density_5km_year1990": -1.0,
843 "max_population_density_25km_year1990": -1.0,
844 "mean_nox_emissions_10km_year2015": -999.0,
845 "mean_nox_emissions_10km_year2000": -999.0,
846 "toar1_category": "unclassified",
847 "toar2_category": "suburban"
848 },
849 "changelog": [
850 {
851 "datetime": "2023-07-15T19:27:09.463245+00:00",
852 "description": "station created",
853 "old_value": "",
854 "new_value": "",
855 "station_id": 2,
856 "author_id": 1,
857 "type_of_change": "created",
858 }
859 ],
860 },
861 "variable": {
862 "name": "toluene",
863 "longname": "toluene",
864 "displayname": "Toluene",
865 "cf_standardname": "mole_fraction_of_toluene_in_air",
866 "units": "nmol mol-1",
867 "chemical_formula": "C7H8",
868 "id": 7,
869 },
870 "programme": {"id": 0, "name": "", "longname": "", "homepage": "", "description": ""},
871 "roles": [
872 {
873 "id": 2,
874 "role": "resource provider",
875 "status": "active",
876 "contact": {
877 "id": 4,
878 "organisation": {
879 "id": 1,
880 "name": "UBA",
881 "longname": "Umweltbundesamt",
882 "kind": "government",
883 "city": "Dessau-Roßlau",
884 "postcode": "06844",
885 "street_address": "Wörlitzer Platz 1",
886 "country": "Germany",
887 "homepage": "https://www.umweltbundesamt.de",
888 "contact_url": "mailto:immission@uba.de",
889 },
890 },
891 },
892 {
893 "id": 3,
894 "role": "principal investigator",
895 "status": "active",
896 "contact": {
897 "id": 3,
898 "person": {
899 "email": "s.schroeder@fz-juelich.de",
900 "id": 3,
901 "isprivate": False,
902 "name": "Sabine Schröder",
903 "orcid": "0000-0002-0309-8010",
904 "phone": "+49-2461-61-6397",
905 },
906 },
907 }
908 ],
909 },
910 {
911 "id": 2,
912 "label": "CMA",
913 "order": 1,
914 "sampling_frequency": "hourly",
915 "aggregation": "mean",
916 "data_start_date": "2003-09-07T15:30:00+00:00",
917 "data_end_date": "2016-12-31T14:30:00+00:00",
918 "data_origin": "instrument",
919 "data_origin_type": "measurement",
920 "provider_version": "N/A",
921 "sampling_height": 7.0,
922 "additional_metadata": {
923 "original_units": {"since_19740101000000": "nmol/mol"},
924 "measurement_method": "uv_abs",
925 "absorption_cross_section": "Hearn 1961",
926 "ebas_metadata_19740101000000_29y": {
927 "Submitter": "Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA",
928 "Data level": "2",
929 "Frameworks": "GAW-WDCRG NOAA-ESRL",
930 "Station code": "XXX",
931 "Station name": "Secret",
932 },
933 },
934 "doi": "",
935 "coverage": -1.0,
936 "station": {
937 "id": 3,
938 "codes": ["China_test8"],
939 "name": "Test_China",
940 "coordinates": {"lat": 36.256, "lng": 117.106, "alt": 1534.0},
941 "coordinate_validation_status": "not checked",
942 "country": "China",
943 "state": "Shandong Sheng",
944 "type": "unknown",
945 "type_of_area": "unknown",
946 "timezone": "Asia/Shanghai",
947 "additional_metadata": {},
948 "aux_images": [],
949 "aux_docs": [],
950 "aux_urls": [],
951 "globalmeta": {
952 "mean_topography_srtm_alt_90m_year1994": -999.0,
953 "mean_topography_srtm_alt_1km_year1994": -999.0,
954 "max_topography_srtm_relative_alt_5km_year1994": -999.0,
955 "min_topography_srtm_relative_alt_5km_year1994": -999.0,
956 "stddev_topography_srtm_relative_alt_5km_year1994": -999.0,
957 "climatic_zone_year2016": "6 (warm temperate dry)",
958 "htap_region_tier1_year2010": "10 (SAF Sub Saharan/sub Sahel Africa)",
959 "dominant_landcover_year2012": "10 (Cropland, rainfed)",
960 "landcover_description_25km_year2012": "",
961 "dominant_ecoregion_year2017": "-1 (undefined)",
962 "ecoregion_description_25km_year2017": "",
963 "distance_to_major_road_year2020": -999.0,
964 "mean_stable_nightlights_1km_year2013": -999.0,
965 "mean_stable_nightlights_5km_year2013": -999.0,
966 "max_stable_nightlights_25km_year2013": -999.0,
967 "max_stable_nightlights_25km_year1992": -999.0,
968 "mean_population_density_250m_year2015": -1.0,
969 "mean_population_density_5km_year2015": -1.0,
970 "max_population_density_25km_year2015": -1.0,
971 "mean_population_density_250m_year1990": -1.0,
972 "mean_population_density_5km_year1990": -1.0,
973 "max_population_density_25km_year1990": -1.0,
974 "mean_nox_emissions_10km_year2015": -999.0,
975 "mean_nox_emissions_10km_year2000": -999.0,
976 "toar1_category": "unclassified",
977 "toar2_category": "suburban"
978 },
979 "changelog": [
980 {
981 "datetime": "2023-08-15T21:16:20.596545+00:00",
982 "description": "station created",
983 "old_value": "",
984 "new_value": "",
985 "station_id": 3,
986 "author_id": 1,
987 "type_of_change": "created",
988 }
989 ],
990 },
991 "variable": {
992 "name": "o3",
993 "longname": "ozone",
994 "displayname": "Ozone",
995 "cf_standardname": "mole_fraction_of_ozone_in_air",
996 "units": "nmol mol-1",
997 "chemical_formula": "O3",
998 "id": 5,
999 },
1000 "programme": {"id": 0, "name": "", "longname": "", "homepage": "", "description": ""},
1001 "roles": [
1002 {
1003 "id": 1,
1004 "role": "resource provider",
1005 "status": "active",
1006 "contact": {
1007 "id": 5,
1008 "organisation": {
1009 "id": 2,
1010 "name": "FZJ",
1011 "longname": "Forschungszentrum Jülich",
1012 "kind": "research",
1013 "city": "Jülich",
1014 "postcode": "52425",
1015 "street_address": "Wilhelm-Johnen-Straße",
1016 "country": "Germany",
1017 "homepage": "https://www.fz-juelich.de",
1018 "contact_url": "mailto:toar-data@fz-juelich.de",
1019 },
1020 },
1021 }
1022 ],
1023 },
1024 ]
1025 assert response.json() == expected_resp
1027 def test_search_minus(self, client, db):
1028 response = client.get("/search/a?id=2-id=2")
1029 expected_status_code = 200
1030 assert response.status_code == expected_status_code
1031 expected_resp = []
1032 assert response.json() == expected_resp
1034 def test_search_distinct(self, client, db):
1035 response = client.get("/search/a?id=1+id=1+id=1+id=1")
1036 expected_status_code = 200
1037 assert response.status_code == expected_status_code
1038 expected_resp = [
1039 {
1040 "id": 1,
1041 "label": "CMA",
1042 "order": 1,
1043 "sampling_frequency": "hourly",
1044 "aggregation": "mean",
1045 "data_start_date": "2003-09-07T15:30:00+00:00",
1046 "data_end_date": "2016-12-31T14:30:00+00:00",
1047 "data_origin": "instrument",
1048 "data_origin_type": "measurement",
1049 "provider_version": "N/A",
1050 "sampling_height": 7.0,
1051 "additional_metadata": {"original_units": "ppb"},
1052 "doi": "",
1053 "coverage": -1.0,
1054 "station": {
1055 "id": 2,
1056 "codes": ["SDZ54421"],
1057 "name": "Shangdianzi",
1058 "coordinates": {"lat": 40.65, "lng": 117.106, "alt": 293.9},
1059 "coordinate_validation_status": "not checked",
1060 "country": "China",
1061 "state": "Beijing Shi",
1062 "type": "unknown",
1063 "type_of_area": "unknown",
1064 "timezone": "Asia/Shanghai",
1065 "additional_metadata": {"add_type": "nature reservation"},
1066 "aux_images": [],
1067 "aux_docs": [],
1068 "aux_urls": [],
1069 "globalmeta": {
1070 "mean_topography_srtm_alt_90m_year1994": -999.0,
1071 "mean_topography_srtm_alt_1km_year1994": -999.0,
1072 "max_topography_srtm_relative_alt_5km_year1994": -999.0,
1073 "min_topography_srtm_relative_alt_5km_year1994": -999.0,
1074 "stddev_topography_srtm_relative_alt_5km_year1994": -999.0,
1075 "climatic_zone_year2016": "6 (warm temperate dry)",
1076 "htap_region_tier1_year2010": "11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)",
1077 "dominant_landcover_year2012": "11 (Cropland, rainfed, herbaceous cover)",
1078 "landcover_description_25km_year2012": "",
1079 "dominant_ecoregion_year2017": "-1 (undefined)",
1080 "ecoregion_description_25km_year2017": "",
1081 "distance_to_major_road_year2020": -999.0,
1082 "mean_stable_nightlights_1km_year2013": -999.0,
1083 "mean_stable_nightlights_5km_year2013": -999.0,
1084 "max_stable_nightlights_25km_year2013": -999.0,
1085 "max_stable_nightlights_25km_year1992": -999.0,
1086 "mean_population_density_250m_year2015": -1.0,
1087 "mean_population_density_5km_year2015": -1.0,
1088 "max_population_density_25km_year2015": -1.0,
1089 "mean_population_density_250m_year1990": -1.0,
1090 "mean_population_density_5km_year1990": -1.0,
1091 "max_population_density_25km_year1990": -1.0,
1092 "mean_nox_emissions_10km_year2015": -999.0,
1093 "mean_nox_emissions_10km_year2000": -999.0,
1094 "toar1_category": "unclassified",
1095 "toar2_category": "suburban"
1096 },
1097 "changelog": [
1098 {
1099 "datetime": "2023-07-15T19:27:09.463245+00:00",
1100 "description": "station created",
1101 "old_value": "",
1102 "new_value": "",
1103 "station_id": 2,
1104 "author_id": 1,
1105 "type_of_change": "created",
1106 }
1107 ],
1108 },
1109 "variable": {
1110 "name": "toluene",
1111 "longname": "toluene",
1112 "displayname": "Toluene",
1113 "cf_standardname": "mole_fraction_of_toluene_in_air",
1114 "units": "nmol mol-1",
1115 "chemical_formula": "C7H8",
1116 "id": 7,
1117 },
1118 "programme": {"id": 0, "name": "", "longname": "", "homepage": "", "description": ""},
1119 "roles": [
1120 {
1121 "id": 2,
1122 "role": "resource provider",
1123 "status": "active",
1124 "contact": {
1125 "id": 4,
1126 "organisation": {
1127 "id": 1,
1128 "name": "UBA",
1129 "longname": "Umweltbundesamt",
1130 "kind": "government",
1131 "city": "Dessau-Roßlau",
1132 "postcode": "06844",
1133 "street_address": "Wörlitzer Platz 1",
1134 "country": "Germany",
1135 "homepage": "https://www.umweltbundesamt.de",
1136 "contact_url": "mailto:immission@uba.de",
1137 },
1138 },
1139 },
1140 {
1141 "id": 3,
1142 "role": "principal investigator",
1143 "status": "active",
1144 "contact": {
1145 "id": 3,
1146 "person": {
1147 "email": "s.schroeder@fz-juelich.de",
1148 "id": 3,
1149 "isprivate": False,
1150 "name": "Sabine Schröder",
1151 "orcid": "0000-0002-0309-8010",
1152 "phone": "+49-2461-61-6397",
1153 },
1154 },
1155 }
1156 ],
1157 }]
1158 assert response.json() == expected_resp
1160 def test_search_complex(self, client, db):
1161 response = client.get("/search/a?id=1+id=2-id=2")
1162 expected_status_code = 200
1163 assert response.status_code == expected_status_code
1164 expected_resp = [
1165 {
1166 "id": 1,
1167 "label": "CMA",
1168 "order": 1,
1169 "sampling_frequency": "hourly",
1170 "aggregation": "mean",
1171 "data_start_date": "2003-09-07T15:30:00+00:00",
1172 "data_end_date": "2016-12-31T14:30:00+00:00",
1173 "data_origin": "instrument",
1174 "data_origin_type": "measurement",
1175 "provider_version": "N/A",
1176 "sampling_height": 7.0,
1177 "additional_metadata": {"original_units": "ppb"},
1178 "doi": "",
1179 "coverage": -1.0,
1180 "station": {
1181 "id": 2,
1182 "codes": ["SDZ54421"],
1183 "name": "Shangdianzi",
1184 "coordinates": {"lat": 40.65, "lng": 117.106, "alt": 293.9},
1185 "coordinate_validation_status": "not checked",
1186 "country": "China",
1187 "state": "Beijing Shi",
1188 "type": "unknown",
1189 "type_of_area": "unknown",
1190 "timezone": "Asia/Shanghai",
1191 "additional_metadata": {"add_type": "nature reservation"},
1192 "aux_images": [],
1193 "aux_docs": [],
1194 "aux_urls": [],
1195 "globalmeta": {
1196 "mean_topography_srtm_alt_90m_year1994": -999.0,
1197 "mean_topography_srtm_alt_1km_year1994": -999.0,
1198 "max_topography_srtm_relative_alt_5km_year1994": -999.0,
1199 "min_topography_srtm_relative_alt_5km_year1994": -999.0,
1200 "stddev_topography_srtm_relative_alt_5km_year1994": -999.0,
1201 "climatic_zone_year2016": "6 (warm temperate dry)",
1202 "htap_region_tier1_year2010": "11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)",
1203 "dominant_landcover_year2012": "11 (Cropland, rainfed, herbaceous cover)",
1204 "landcover_description_25km_year2012": "",
1205 "dominant_ecoregion_year2017": "-1 (undefined)",
1206 "ecoregion_description_25km_year2017": "",
1207 "distance_to_major_road_year2020": -999.0,
1208 "mean_stable_nightlights_1km_year2013": -999.0,
1209 "mean_stable_nightlights_5km_year2013": -999.0,
1210 "max_stable_nightlights_25km_year2013": -999.0,
1211 "max_stable_nightlights_25km_year1992": -999.0,
1212 "mean_population_density_250m_year2015": -1.0,
1213 "mean_population_density_5km_year2015": -1.0,
1214 "max_population_density_25km_year2015": -1.0,
1215 "mean_population_density_250m_year1990": -1.0,
1216 "mean_population_density_5km_year1990": -1.0,
1217 "max_population_density_25km_year1990": -1.0,
1218 "mean_nox_emissions_10km_year2015": -999.0,
1219 "mean_nox_emissions_10km_year2000": -999.0,
1220 "toar1_category": "unclassified",
1221 "toar2_category": "suburban"
1222 },
1223 "changelog": [
1224 {
1225 "datetime": "2023-07-15T19:27:09.463245+00:00",
1226 "description": "station created",
1227 "old_value": "",
1228 "new_value": "",
1229 "station_id": 2,
1230 "author_id": 1,
1231 "type_of_change": "created",
1232 }
1233 ],
1234 },
1235 "variable": {
1236 "name": "toluene",
1237 "longname": "toluene",
1238 "displayname": "Toluene",
1239 "cf_standardname": "mole_fraction_of_toluene_in_air",
1240 "units": "nmol mol-1",
1241 "chemical_formula": "C7H8",
1242 "id": 7,
1243 },
1244 "programme": {"id": 0, "name": "", "longname": "", "homepage": "", "description": ""},
1245 "roles": [
1246 {
1247 "id": 2,
1248 "role": "resource provider",
1249 "status": "active",
1250 "contact": {
1251 "id": 4,
1252 "organisation": {
1253 "id": 1,
1254 "name": "UBA",
1255 "longname": "Umweltbundesamt",
1256 "kind": "government",
1257 "city": "Dessau-Roßlau",
1258 "postcode": "06844",
1259 "street_address": "Wörlitzer Platz 1",
1260 "country": "Germany",
1261 "homepage": "https://www.umweltbundesamt.de",
1262 "contact_url": "mailto:immission@uba.de",
1263 },
1264 },
1265 },
1266 {
1267 "id": 3,
1268 "role": "principal investigator",
1269 "status": "active",
1270 "contact": {
1271 "id": 3,
1272 "person": {
1273 "email": "s.schroeder@fz-juelich.de",
1274 "id": 3,
1275 "isprivate": False,
1276 "name": "Sabine Schröder",
1277 "orcid": "0000-0002-0309-8010",
1278 "phone": "+49-2461-61-6397",
1279 },
1280 },
1281 }
1282 ],
1283 }]
1284 assert response.json() == expected_resp
1286 def test_inconsistent_fields(self, client, db):
1287 response = client.get("/search/a?fields=id+fields=role")
1288 expected_status_code = 400
1289 assert response.status_code == expected_status_code
1291 def test_consistent_fields(self, client, db):
1292 response = client.get("/search/a?fields=id+fields=id")
1293 expected_status_code = 200
1294 assert response.status_code == expected_status_code
1295 expected_resp = [{'id': 2}, {'id': 30890}, {'id': 18763}, {'id': 1}, {'id': 434870}]
1296 set_expected_resp = {json.dumps(item, sort_keys=True) for item in expected_resp}
1297 set_response = {json.dumps(item, sort_keys=True) for item in response.json()}
1298 assert set_response == set_expected_resp