Coverage for tests/test_search.py: 100%
279 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 (
11 StationmetaCore,
12 StationmetaGlobal,
13 StationmetaChangelog
14)
15from toardb.stationmeta.schemas import get_geom_from_coordinates, Coordinates
16from toardb.variables.models import Variable
17from toardb.contacts.models import Person, Organisation, Contact
18from toardb.auth_user.models import AuthUser
19# Required imports 'create_test_database'
20from toardb.test_base import (
21 client,
22 get_test_db,
23 create_test_database,
24 url,
25 get_test_engine,
26 test_db_session as db,
27)
29class TestApps:
30 def setup(self):
31 self.application_url = "/timeseries/"
33 """Set up all the data before each test
34 If you want the setup only once (per test module),
35 the scope argument is not working in the expected way, as discussed here:
36 https://stackoverflow.com/questions/45817153/py-test-fixture-use-function-fixture-in-scope-fixture
37 """
38 @pytest.fixture(autouse=True)
39 def setup_db_data(self, db):
40 _db_conn = get_test_engine()
41 # id_seq will not be reset automatically between tests!
42 fake_conn = _db_conn.raw_connection()
43 fake_cur = fake_conn.cursor()
44 fake_cur.execute("ALTER SEQUENCE auth_user_id_seq RESTART WITH 1")
45 fake_conn.commit()
46 fake_cur.execute("ALTER SEQUENCE variables_id_seq RESTART WITH 1")
47 fake_conn.commit()
48 fake_cur.execute("ALTER SEQUENCE stationmeta_core_id_seq RESTART WITH 1")
49 fake_conn.commit()
50 fake_cur.execute("ALTER SEQUENCE stationmeta_global_id_seq RESTART WITH 1")
51 fake_conn.commit()
52 fake_cur.execute("ALTER SEQUENCE stationmeta_roles_id_seq RESTART WITH 1")
53 fake_conn.commit()
54 fake_cur.execute("ALTER SEQUENCE stationmeta_annotations_id_seq RESTART WITH 1")
55 fake_conn.commit()
56 fake_cur.execute("ALTER SEQUENCE stationmeta_aux_doc_id_seq RESTART WITH 1")
57 fake_conn.commit()
58 fake_cur.execute("ALTER SEQUENCE stationmeta_aux_image_id_seq RESTART WITH 1")
59 fake_conn.commit()
60 fake_cur.execute("ALTER SEQUENCE stationmeta_aux_url_id_seq RESTART WITH 1")
61 fake_conn.commit()
62 fake_cur.execute("ALTER SEQUENCE persons_id_seq RESTART WITH 1")
63 fake_conn.commit()
64 fake_cur.execute("ALTER SEQUENCE organisations_id_seq RESTART WITH 1")
65 fake_conn.commit()
66 fake_cur.execute("ALTER SEQUENCE contacts_id_seq RESTART WITH 1")
67 fake_conn.commit()
68 fake_cur.execute("ALTER SEQUENCE timeseries_annotations_id_seq RESTART WITH 1")
69 fake_conn.commit()
70 fake_cur.execute("ALTER SEQUENCE timeseries_roles_id_seq RESTART WITH 3")
71 fake_conn.commit()
72 fake_cur.execute("ALTER SEQUENCE timeseries_programmes_id_seq RESTART WITH 1")
73 fake_conn.commit()
74 fake_cur.execute("ALTER SEQUENCE timeseries_id_seq RESTART WITH 1")
75 fake_conn.commit()
76 infilename = "tests/fixtures/auth_user/auth.json"
77 with open(infilename) as f:
78 metajson=json.load(f)
79 for entry in metajson:
80 new_auth_user = AuthUser(**entry)
81 db.add(new_auth_user)
82 db.commit()
83 db.refresh(new_auth_user)
84 infilename = "tests/fixtures/contacts/persons.json"
85 with open(infilename) as f:
86 metajson=json.load(f)
87 for entry in metajson:
88 new_person = Person(**entry)
89 db.add(new_person)
90 db.commit()
91 db.refresh(new_person)
92 infilename = "tests/fixtures/contacts/organisations.json"
93 with open(infilename) as f:
94 metajson=json.load(f)
95 for entry in metajson:
96 new_organisation = Organisation(**entry)
97 db.add(new_organisation)
98 db.commit()
99 db.refresh(new_organisation)
100 infilename = "tests/fixtures/contacts/contacts.json"
101 with open(infilename) as f:
102 metajson=json.load(f)
103 for entry in metajson:
104 new_contact = Contact(**entry)
105 db.add(new_contact)
106 db.commit()
107 db.refresh(new_contact)
108 infilename = "tests/fixtures/variables/variables.json"
109 with open(infilename) as f:
110 metajson=json.load(f)
111 for entry in metajson:
112 new_variable = Variable(**entry)
113 db.add(new_variable)
114 db.commit()
115 db.refresh(new_variable)
116 infilename = "tests/fixtures/stationmeta/stationmeta_core.json"
117 with open(infilename) as f:
118 metajson=json.load(f)
119 for entry in metajson:
120 new_stationmeta_core = StationmetaCore(**entry)
121 # there's a mismatch with coordinates --> how to automatically switch back and forth?!
122 tmp_coordinates = new_stationmeta_core.coordinates
123 new_stationmeta_core.coordinates = get_geom_from_coordinates(Coordinates(**new_stationmeta_core.coordinates))
124 db.add(new_stationmeta_core)
125 db.commit()
126 db.refresh(new_stationmeta_core)
127 infilename = "tests/fixtures/stationmeta/stationmeta_changelog.json"
128 with open(infilename) as f:
129 metajson=json.load(f)
130 for entry in metajson:
131 new_stationmeta_changelog = StationmetaChangelog(**entry)
132 db.add(new_stationmeta_changelog)
133 db.commit()
134 db.refresh(new_stationmeta_changelog)
135 infilename = "tests/fixtures/stationmeta/stationmeta_global.json"
136 with open(infilename) as f:
137 metajson=json.load(f)
138 for entry in metajson:
139 new_stationmeta_global = StationmetaGlobal(**entry)
140 db.add(new_stationmeta_global)
141 db.commit()
142 db.refresh(new_stationmeta_global)
143 infilename = "tests/fixtures/timeseries/timeseries_programmes.json"
144 with open(infilename) as f:
145 metajson=json.load(f)
146 for entry in metajson:
147 new_timeseries_programme = TimeseriesProgramme(**entry)
148 db.add(new_timeseries_programme)
149 db.commit()
150 db.refresh(new_timeseries_programme)
151 infilename = "tests/fixtures/timeseries/timeseries.json"
152 with open(infilename) as f:
153 metajson=json.load(f)
154 for entry in metajson:
155 new_timeseries = Timeseries(**entry)
156 db.add(new_timeseries)
157 db.commit()
158 db.refresh(new_timeseries)
159 infilename = "tests/fixtures/timeseries/timeseries_roles.json"
160 with open(infilename) as f:
161 metajson=json.load(f)
162 for entry in metajson:
163 new_timeseries_role = TimeseriesRole(**entry)
164 db.add(new_timeseries_role)
165 db.commit()
166 db.refresh(new_timeseries_role)
167 infilename = "tests/fixtures/timeseries/timeseries_timeseries_roles.json"
168 with open(infilename) as f:
169 metajson=json.load(f)
170 for entry in metajson:
171 db.execute(insert(timeseries_timeseries_roles_table).values(timeseries_id=entry["timeseries_id"], role_id=entry["role_id"]))
172 db.execute("COMMIT")
175 def test_search_no_arguments(self, client, db):
176 response = client.get("/search/")
177 expected_status_code = 200
178 assert response.status_code == expected_status_code
179 expected_resp = [{'id': 1,
180 'label': 'CMA',
181 'order': 1,
182 'sampling_frequency': 'hourly',
183 'aggregation': 'mean',
184 'data_start_date': '2003-09-07T15:30:00+00:00',
185 'data_end_date': '2016-12-31T14:30:00+00:00',
186 'data_origin': 'instrument',
187 'data_origin_type': 'measurement',
188 'provider_version': 'N/A',
189 'sampling_height': 7.0,
190 'additional_metadata': {"original_units": "ppb"},
191 'doi': '',
192 'coverage': -1.0,
193 'station': {'id': 2,
194 'codes': ['SDZ54421'],
195 'name': 'Shangdianzi',
196 'coordinates': {'lat': 40.65, 'lng': 117.106, 'alt': 293.9},
197 'coordinate_validation_status': 'not checked',
198 'country': 'China',
199 'state': 'Beijing Shi',
200 'type': 'unknown',
201 'type_of_area': 'unknown',
202 'timezone': 'Asia/Shanghai',
203 'additional_metadata': {'add_type': 'nature reservation'},
204 'aux_images': [],
205 'aux_docs': [],
206 'aux_urls': [],
207 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
208 'mean_topography_srtm_alt_1km_year1994': -999.0,
209 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
210 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
211 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
212 'climatic_zone_year2016': '6 (warm temperate dry)',
213 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
214 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
215 'landcover_description_25km_year2012': '',
216 'dominant_ecoregion_year2017': '-1 (undefined)',
217 'ecoregion_description_25km_year2017': '',
218 'distance_to_major_road_year2020': -999.0,
219 'mean_stable_nightlights_1km_year2013': -999.0,
220 'mean_stable_nightlights_5km_year2013': -999.0,
221 'max_stable_nightlights_25km_year2013': -999.0,
222 'max_stable_nightlights_25km_year1992': -999.0,
223 'mean_population_density_250m_year2015': -1.0,
224 'mean_population_density_5km_year2015': -1.0,
225 'max_population_density_25km_year2015': -1.0,
226 'mean_population_density_250m_year1990': -1.0,
227 'mean_population_density_5km_year1990': -1.0,
228 'max_population_density_25km_year1990': -1.0,
229 'mean_nox_emissions_10km_year2015': -999.0,
230 'mean_nox_emissions_10km_year2000': -999.0,
231 'toar1_category': 'unclassified',
232 'toar2_category': 'suburban'},
233 'changelog': [{'datetime': '2023-07-15T19:27:09.463245+00:00',
234 'description': 'station created',
235 'old_value': '',
236 'new_value': '',
237 'station_id': 2,
238 'author_id': 1,
239 'type_of_change': 'created'}]},
240 'variable': {'name': 'toluene',
241 'longname': 'toluene',
242 'displayname': 'Toluene',
243 'cf_standardname': 'mole_fraction_of_toluene_in_air',
244 'units': 'nmol mol-1',
245 'chemical_formula': 'C7H8',
246 'id': 7},
247 'programme': {'id': 0,
248 'name': '',
249 'longname': '',
250 'homepage': '',
251 'description': ''},
252 'roles': [{'id': 2,
253 'role': 'resource provider',
254 'status': 'active',
255 'contact': {'id': 4,
256 'organisation': {'id': 1,
257 'name': 'UBA',
258 'longname': 'Umweltbundesamt',
259 'kind': 'government',
260 'city': 'Dessau-Roßlau',
261 'postcode': '06844',
262 'street_address': 'Wörlitzer Platz 1',
263 'country': 'Germany',
264 'homepage': 'https://www.umweltbundesamt.de',
265 'contact_url': 'mailto:immission@uba.de'}}},
266 {'id': 3,
267 'role': 'principal investigator',
268 'status': 'active',
269 'contact': {'id': 3,
270 'person': {'email': 's.schroeder@fz-juelich.de',
271 'id': 3,
272 'isprivate': False,
273 'name': 'Sabine Schröder',
274 'orcid': '0000-0002-0309-8010',
275 'phone': '+49-2461-61-6397'}}}]},
276 {'id': 2,
277 'label': 'CMA',
278 'order': 1,
279 'sampling_frequency': 'hourly',
280 'aggregation': 'mean',
281 'data_start_date': '2003-09-07T15:30:00+00:00',
282 'data_end_date': '2016-12-31T14:30:00+00:00',
283 'data_origin': 'instrument',
284 'data_origin_type': 'measurement',
285 'provider_version': 'N/A',
286 'sampling_height': 7.0,
287 'additional_metadata': {'original_units': {'since_19740101000000': 'nmol/mol'},
288 'measurement_method': 'uv_abs',
289 'absorption_cross_section': 'Hearn 1961',
290 'ebas_metadata_19740101000000_29y':
291 {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
292 'Data level': '2',
293 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
294 'Station code': 'XXX',
295 'Station name': 'Secret'}},
296 'doi': '',
297 'coverage': -1.0,
298 'station': {'id': 3,
299 'codes': ['China_test8'],
300 'name': 'Test_China',
301 'coordinates': {'lat': 36.256, 'lng': 117.106, 'alt': 1534.0},
302 'coordinate_validation_status': 'not checked',
303 'country': 'China',
304 'state': 'Shandong Sheng',
305 'type': 'unknown',
306 'type_of_area': 'unknown',
307 'timezone': 'Asia/Shanghai',
308 'additional_metadata': {},
309 'aux_images': [],
310 'aux_docs': [],
311 'aux_urls': [],
312 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
313 'mean_topography_srtm_alt_1km_year1994': -999.0,
314 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
315 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
316 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
317 'climatic_zone_year2016': '6 (warm temperate dry)',
318 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
319 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
320 'landcover_description_25km_year2012': '',
321 'dominant_ecoregion_year2017': '-1 (undefined)',
322 'ecoregion_description_25km_year2017': '',
323 'distance_to_major_road_year2020': -999.0,
324 'mean_stable_nightlights_1km_year2013': -999.0,
325 'mean_stable_nightlights_5km_year2013': -999.0,
326 'max_stable_nightlights_25km_year2013': -999.0,
327 'max_stable_nightlights_25km_year1992': -999.0,
328 'mean_population_density_250m_year2015': -1.0,
329 'mean_population_density_5km_year2015': -1.0,
330 'max_population_density_25km_year2015': -1.0,
331 'mean_population_density_250m_year1990': -1.0,
332 'mean_population_density_5km_year1990': -1.0,
333 'max_population_density_25km_year1990': -1.0,
334 'mean_nox_emissions_10km_year2015': -999.0,
335 'mean_nox_emissions_10km_year2000': -999.0,
336 'toar1_category': 'unclassified',
337 'toar2_category': 'suburban'},
338 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
339 'description': 'station created',
340 'old_value': '',
341 'new_value': '',
342 'station_id': 3,
343 'author_id': 1,
344 'type_of_change': 'created'}]},
345 'variable': {'name': 'o3',
346 'longname': 'ozone',
347 'displayname': 'Ozone',
348 'cf_standardname': 'mole_fraction_of_ozone_in_air',
349 'units': 'nmol mol-1',
350 'chemical_formula': 'O3',
351 'id': 5},
352 'programme': {'id': 0,
353 'name': '',
354 'longname': '',
355 'homepage': '',
356 'description': ''},
357 'roles': [{'id': 1,
358 'role': 'resource provider',
359 'status': 'active',
360 'contact': {'id': 5,
361 'organisation':
362 {'id': 2,
363 'name': 'FZJ',
364 'longname': 'Forschungszentrum Jülich',
365 'kind': 'research',
366 'city': 'Jülich',
367 'postcode': '52425',
368 'street_address': 'Wilhelm-Johnen-Straße',
369 'country': 'Germany',
370 'homepage': 'https://www.fz-juelich.de',
371 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}]},
372 {'id': 18763,
373 'additional_metadata': {'original_units': 'ppb'},
374 'aggregation': 'mean',
375 'coverage': -1.0,
376 'data_end_date': '2025-02-25T14:00:00+00:00',
377 'data_origin': 'instrument',
378 'data_origin_type': 'measurement',
379 'data_start_date': '1991-01-01T00:00:00+00:00',
380 'doi': '',
381 'label': '',
382 'order': 1,
383 'programme': {
384 'description': '',
385 'homepage': '',
386 'id': 0,
387 'longname': '',
388 'name': '',
389 },
390 'provider_version': 'N/A',
391 'roles': [
392 {
393 'contact': {
394 'id': 5,
395 'organisation': {
396 'city': 'Jülich',
397 'contact_url': 'mailto:toar-data@fz-juelich.de',
398 'country': 'Germany',
399 'homepage': 'https://www.fz-juelich.de',
400 'id': 2,
401 'kind': 'research',
402 'longname': 'Forschungszentrum Jülich',
403 'name': 'FZJ',
404 'postcode': '52425',
405 'street_address': 'Wilhelm-Johnen-Straße',
406 },
407 },
408 'id': 1,
409 'role': 'resource provider',
410 'status': 'active',
411 },
412 ],
413 'sampling_frequency': 'hourly',
414 'sampling_height': 7.0,
415 'station': {
416 'additional_metadata': {
417 'add_type': 'nature reservation',
418 },
419 'aux_docs': [],
420 'aux_images': [],
421 'aux_urls': [],
422 'changelog': [
423 {
424 'author_id': 1,
425 'datetime': '2023-07-15T19:27:09.463245+00:00',
426 'description': 'station created',
427 'new_value': '',
428 'old_value': '',
429 'station_id': 2,
430 'type_of_change': 'created',
431 },
432 ],
433 'codes': [
434 'SDZ54421',
435 ],
436 'coordinate_validation_status': 'not checked',
437 'coordinates': {
438 'alt': 293.9,
439 'lat': 40.65,
440 'lng': 117.106,
441 },
442 'country': 'China',
443 'globalmeta': {
444 'climatic_zone_year2016': '6 (warm temperate dry)',
445 'distance_to_major_road_year2020': -999.0,
446 'dominant_ecoregion_year2017': '-1 (undefined)',
447 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
448 'ecoregion_description_25km_year2017': '',
449 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
450 'landcover_description_25km_year2012': '',
451 'max_population_density_25km_year1990': -1.0,
452 'max_population_density_25km_year2015': -1.0,
453 'max_stable_nightlights_25km_year1992': -999.0,
454 'max_stable_nightlights_25km_year2013': -999.0,
455 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
456 'mean_nox_emissions_10km_year2000': -999.0,
457 'mean_nox_emissions_10km_year2015': -999.0,
458 'mean_population_density_250m_year1990': -1.0,
459 'mean_population_density_250m_year2015': -1.0,
460 'mean_population_density_5km_year1990': -1.0,
461 'mean_population_density_5km_year2015': -1.0,
462 'mean_stable_nightlights_1km_year2013': -999.0,
463 'mean_stable_nightlights_5km_year2013': -999.0,
464 'mean_topography_srtm_alt_1km_year1994': -999.0,
465 'mean_topography_srtm_alt_90m_year1994': -999.0,
466 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
467 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
468 'toar1_category': 'unclassified',
469 'toar2_category': 'suburban',
470 },
471 'id': 2,
472 'name': 'Shangdianzi',
473 'state': 'Beijing Shi',
474 'timezone': 'Asia/Shanghai',
475 'type': 'unknown',
476 'type_of_area': 'unknown',
477 },
478 'variable': {
479 'cf_standardname': 'mole_fraction_of_ozone_in_air',
480 'chemical_formula': 'O3',
481 'displayname': 'Ozone',
482 'id': 5,
483 'longname': 'ozone',
484 'name': 'o3',
485 'units': 'nmol mol-1',
486 },
487 },
488 {
489 'additional_metadata': {
490 'original_units': 'ppb',
491 },
492 'aggregation': 'mean',
493 'coverage': -1.0,
494 'data_end_date': '2025-02-25T14:00:00+00:00',
495 'data_origin': 'instrument',
496 'data_origin_type': 'measurement',
497 'data_start_date': '1991-01-01T00:00:00+00:00',
498 'doi': '',
499 'id': 30890,
500 'label': '',
501 'order': 2,
502 'programme': {
503 'description': '',
504 'homepage': '',
505 'id': 0,
506 'longname': '',
507 'name': '',
508 },
509 'provider_version': 'N/A',
510 'roles': [
511 {
512 'contact': {
513 'id': 5,
514 'organisation': {
515 'city': 'Jülich',
516 'contact_url': 'mailto:toar-data@fz-juelich.de',
517 'country': 'Germany',
518 'homepage': 'https://www.fz-juelich.de',
519 'id': 2,
520 'kind': 'research',
521 'longname': 'Forschungszentrum Jülich',
522 'name': 'FZJ',
523 'postcode': '52425',
524 'street_address': 'Wilhelm-Johnen-Straße',
525 },
526 },
527 'id': 1,
528 'role': 'resource provider',
529 'status': 'active',
530 },
531 ],
532 'sampling_frequency': 'hourly',
533 'sampling_height': 7.0,
534 'station': {
535 'additional_metadata': {
536 'add_type': 'nature reservation',
537 },
538 'aux_docs': [],
539 'aux_images': [],
540 'aux_urls': [],
541 'changelog': [
542 {
543 'author_id': 1,
544 'datetime': '2023-07-15T19:27:09.463245+00:00',
545 'description': 'station created',
546 'new_value': '',
547 'old_value': '',
548 'station_id': 2,
549 'type_of_change': 'created',
550 },
551 ],
552 'codes': [
553 'SDZ54421',
554 ],
555 'coordinate_validation_status': 'not checked',
556 'coordinates': {
557 'alt': 293.9,
558 'lat': 40.65,
559 'lng': 117.106,
560 },
561 'country': 'China',
562 'globalmeta': {
563 'climatic_zone_year2016': '6 (warm temperate dry)',
564 'distance_to_major_road_year2020': -999.0,
565 'dominant_ecoregion_year2017': '-1 (undefined)',
566 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
567 'ecoregion_description_25km_year2017': '',
568 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
569 'landcover_description_25km_year2012': '',
570 'max_population_density_25km_year1990': -1.0,
571 'max_population_density_25km_year2015': -1.0,
572 'max_stable_nightlights_25km_year1992': -999.0,
573 'max_stable_nightlights_25km_year2013': -999.0,
574 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
575 'mean_nox_emissions_10km_year2000': -999.0,
576 'mean_nox_emissions_10km_year2015': -999.0,
577 'mean_population_density_250m_year1990': -1.0,
578 'mean_population_density_250m_year2015': -1.0,
579 'mean_population_density_5km_year1990': -1.0,
580 'mean_population_density_5km_year2015': -1.0,
581 'mean_stable_nightlights_1km_year2013': -999.0,
582 'mean_stable_nightlights_5km_year2013': -999.0,
583 'mean_topography_srtm_alt_1km_year1994': -999.0,
584 'mean_topography_srtm_alt_90m_year1994': -999.0,
585 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
586 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
587 'toar1_category': 'unclassified',
588 'toar2_category': 'suburban',
589 },
590 'id': 2,
591 'name': 'Shangdianzi',
592 'state': 'Beijing Shi',
593 'timezone': 'Asia/Shanghai',
594 'type': 'unknown',
595 'type_of_area': 'unknown',
596 },
597 'variable': {
598 'cf_standardname': 'mole_fraction_of_ozone_in_air',
599 'chemical_formula': 'O3',
600 'displayname': 'Ozone',
601 'id': 5,
602 'longname': 'ozone',
603 'name': 'o3',
604 'units': 'nmol mol-1',
605 },
606 },
607 {
608 'additional_metadata': {
609 'original_units': 'ppb',
610 },
611 'aggregation': 'mean',
612 'coverage': -1.0,
613 'data_end_date': '2025-02-25T14:00:00+00:00',
614 'data_origin': 'instrument',
615 'data_origin_type': 'measurement',
616 'data_start_date': '1991-01-01T00:00:00+00:00',
617 'doi': '',
618 'id': 434870,
619 'label': '',
620 'order': 2,
621 'programme': {
622 'description': '',
623 'homepage': '',
624 'id': 0,
625 'longname': '',
626 'name': '',
627 },
628 'provider_version': 'N/A',
629 'roles': [
630 {
631 'contact': {
632 'id': 4,
633 'organisation': {
634 'city': 'Dessau-Roßlau',
635 'contact_url': 'mailto:immission@uba.de',
636 'country': 'Germany',
637 'homepage': 'https://www.umweltbundesamt.de',
638 'id': 1,
639 'kind': 'government',
640 'longname': 'Umweltbundesamt',
641 'name': 'UBA',
642 'postcode': '06844',
643 'street_address': 'Wörlitzer Platz 1',
644 },
645 },
646 'id': 2,
647 'role': 'resource provider',
648 'status': 'active',
649 },
650 ],
651 'sampling_frequency': 'hourly',
652 'sampling_height': 7.0,
653 'station': {
654 'additional_metadata': {
655 'add_type': 'nature reservation',
656 },
657 'aux_docs': [],
658 'aux_images': [],
659 'aux_urls': [],
660 'changelog': [
661 {
662 'author_id': 1,
663 'datetime': '2023-07-15T19:27:09.463245+00:00',
664 'description': 'station created',
665 'new_value': '',
666 'old_value': '',
667 'station_id': 2,
668 'type_of_change': 'created',
669 },
670 ],
671 'codes': [
672 'SDZ54421',
673 ],
674 'coordinate_validation_status': 'not checked',
675 'coordinates': {
676 'alt': 293.9,
677 'lat': 40.65,
678 'lng': 117.106,
679 },
680 'country': 'China',
681 'globalmeta': {
682 'climatic_zone_year2016': '6 (warm temperate dry)',
683 'distance_to_major_road_year2020': -999.0,
684 'dominant_ecoregion_year2017': '-1 (undefined)',
685 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
686 'ecoregion_description_25km_year2017': '',
687 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
688 'landcover_description_25km_year2012': '',
689 'max_population_density_25km_year1990': -1.0,
690 'max_population_density_25km_year2015': -1.0,
691 'max_stable_nightlights_25km_year1992': -999.0,
692 'max_stable_nightlights_25km_year2013': -999.0,
693 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
694 'mean_nox_emissions_10km_year2000': -999.0,
695 'mean_nox_emissions_10km_year2015': -999.0,
696 'mean_population_density_250m_year1990': -1.0,
697 'mean_population_density_250m_year2015': -1.0,
698 'mean_population_density_5km_year1990': -1.0,
699 'mean_population_density_5km_year2015': -1.0,
700 'mean_stable_nightlights_1km_year2013': -999.0,
701 'mean_stable_nightlights_5km_year2013': -999.0,
702 'mean_topography_srtm_alt_1km_year1994': -999.0,
703 'mean_topography_srtm_alt_90m_year1994': -999.0,
704 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
705 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
706 'toar1_category': 'unclassified',
707 'toar2_category': 'suburban',
708 },
709 'id': 2,
710 'name': 'Shangdianzi',
711 'state': 'Beijing Shi',
712 'timezone': 'Asia/Shanghai',
713 'type': 'unknown',
714 'type_of_area': 'unknown',
715 },
716 'variable': {
717 'cf_standardname': 'mole_fraction_of_ozone_in_air',
718 'chemical_formula': 'O3',
719 'displayname': 'Ozone',
720 'id': 5,
721 'longname': 'ozone',
722 'name': 'o3',
723 'units': 'nmol mol-1',
724 },
725 }]
726 assert response.json() == expected_resp
729 def test_search_variable_wrong_syntax(self, client, db):
730 response = client.get("/search/?variable_id=ozone")
731 expected_status_code = 400
732 assert response.status_code == expected_status_code
733 expected_resp = "Wrong value (not int) given: variable_id"
734 assert response.json() == expected_resp
737 def test_search_with_variable_id(self, client, db):
738 response = client.get("/search/?variable_id=5")
739 expected_status_code = 200
740 assert response.status_code == expected_status_code
741 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
742 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
743 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
744 'data_origin': 'instrument', 'sampling_height': 7.0,
745 'provider_version': 'N/A',
746 'doi': '',
747 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
748 'measurement_method': 'uv_abs',
749 'original_units': {'since_19740101000000': 'nmol/mol'},
750 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
751 'Data level': '2',
752 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
753 'Station code': 'XXX',
754 'Station name': 'Secret' } },
755 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
756 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
757 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
758 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
759 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
760 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
761 'chemical_formula': 'O3', 'id': 5},
762 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
763 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
764 'coordinate_validation_status': 'not checked',
765 'country': 'China', 'state': 'Shandong Sheng',
766 'type': 'unknown', 'type_of_area': 'unknown',
767 'timezone': 'Asia/Shanghai',
768 'additional_metadata': {},
769 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
770 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
771 'distance_to_major_road_year2020': -999.0,
772 'dominant_ecoregion_year2017': '-1 (undefined)',
773 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
774 'ecoregion_description_25km_year2017': '',
775 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
776 'landcover_description_25km_year2012': '',
777 'max_stable_nightlights_25km_year1992': -999.0,
778 'max_stable_nightlights_25km_year2013': -999.0,
779 'max_population_density_25km_year1990': -1.0,
780 'max_population_density_25km_year2015': -1.0,
781 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
782 'mean_stable_nightlights_1km_year2013': -999.0,
783 'mean_stable_nightlights_5km_year2013': -999.0,
784 'mean_nox_emissions_10km_year2000': -999.0,
785 'mean_nox_emissions_10km_year2015': -999.0,
786 'mean_population_density_250m_year1990': -1.0,
787 'mean_population_density_250m_year2015': -1.0,
788 'mean_population_density_5km_year1990': -1.0,
789 'mean_population_density_5km_year2015': -1.0,
790 'mean_topography_srtm_alt_1km_year1994': -999.0,
791 'mean_topography_srtm_alt_90m_year1994': -999.0,
792 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
793 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
794 'toar1_category': 'unclassified',
795 'toar2_category': 'suburban'},
796 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
797 'description': 'station created',
798 'old_value': '',
799 'new_value': '',
800 'station_id': 3,
801 'author_id': 1,
802 'type_of_change': 'created'
803 }]},
804 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}},
805 {
806 'additional_metadata': {
807 'original_units': 'ppb',
808 },
809 'aggregation': 'mean',
810 'coverage': -1.0,
811 'data_end_date': '2025-02-25T14:00:00+00:00',
812 'data_origin': 'instrument',
813 'data_origin_type': 'measurement',
814 'data_start_date': '1991-01-01T00:00:00+00:00',
815 'doi': '',
816 'id': 18763,
817 'label': '',
818 'order': 1,
819 'programme': {
820 'description': '',
821 'homepage': '',
822 'id': 0,
823 'longname': '',
824 'name': '',
825 },
826 'provider_version': 'N/A',
827 'roles': [
828 {
829 'contact': {
830 'id': 5,
831 'organisation': {
832 'city': 'Jülich',
833 'contact_url': 'mailto:toar-data@fz-juelich.de',
834 'country': 'Germany',
835 'homepage': 'https://www.fz-juelich.de',
836 'id': 2,
837 'kind': 'research',
838 'longname': 'Forschungszentrum Jülich',
839 'name': 'FZJ',
840 'postcode': '52425',
841 'street_address': 'Wilhelm-Johnen-Straße',
842 },
843 },
844 'id': 1,
845 'role': 'resource provider',
846 'status': 'active',
847 },
848 ],
849 'sampling_frequency': 'hourly',
850 'sampling_height': 7.0,
851 'station': {
852 'additional_metadata': {
853 'add_type': 'nature reservation',
854 },
855 'aux_docs': [],
856 'aux_images': [],
857 'aux_urls': [],
858 'changelog': [
859 {
860 'author_id': 1,
861 'datetime': '2023-07-15T19:27:09.463245+00:00',
862 'description': 'station created',
863 'new_value': '',
864 'old_value': '',
865 'station_id': 2,
866 'type_of_change': 'created',
867 },
868 ],
869 'codes': [
870 'SDZ54421',
871 ],
872 'coordinate_validation_status': 'not checked',
873 'coordinates': {
874 'alt': 293.9,
875 'lat': 40.65,
876 'lng': 117.106,
877 },
878 'country': 'China',
879 'globalmeta': {
880 'climatic_zone_year2016': '6 (warm temperate dry)',
881 'distance_to_major_road_year2020': -999.0,
882 'dominant_ecoregion_year2017': '-1 (undefined)',
883 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
884 'ecoregion_description_25km_year2017': '',
885 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
886 'landcover_description_25km_year2012': '',
887 'max_population_density_25km_year1990': -1.0,
888 'max_population_density_25km_year2015': -1.0,
889 'max_stable_nightlights_25km_year1992': -999.0,
890 'max_stable_nightlights_25km_year2013': -999.0,
891 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
892 'mean_nox_emissions_10km_year2000': -999.0,
893 'mean_nox_emissions_10km_year2015': -999.0,
894 'mean_population_density_250m_year1990': -1.0,
895 'mean_population_density_250m_year2015': -1.0,
896 'mean_population_density_5km_year1990': -1.0,
897 'mean_population_density_5km_year2015': -1.0,
898 'mean_stable_nightlights_1km_year2013': -999.0,
899 'mean_stable_nightlights_5km_year2013': -999.0,
900 'mean_topography_srtm_alt_1km_year1994': -999.0,
901 'mean_topography_srtm_alt_90m_year1994': -999.0,
902 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
903 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
904 'toar1_category': 'unclassified',
905 'toar2_category': 'suburban',
906 },
907 'id': 2,
908 'name': 'Shangdianzi',
909 'state': 'Beijing Shi',
910 'timezone': 'Asia/Shanghai',
911 'type': 'unknown',
912 'type_of_area': 'unknown',
913 },
914 'variable': {
915 'cf_standardname': 'mole_fraction_of_ozone_in_air',
916 'chemical_formula': 'O3',
917 'displayname': 'Ozone',
918 'id': 5,
919 'longname': 'ozone',
920 'name': 'o3',
921 'units': 'nmol mol-1',
922 },
923 },
924 {
925 'additional_metadata': {
926 'original_units': 'ppb',
927 },
928 'aggregation': 'mean',
929 'coverage': -1.0,
930 'data_end_date': '2025-02-25T14:00:00+00:00',
931 'data_origin': 'instrument',
932 'data_origin_type': 'measurement',
933 'data_start_date': '1991-01-01T00:00:00+00:00',
934 'doi': '',
935 'id': 30890,
936 'label': '',
937 'order': 2,
938 'programme': {
939 'description': '',
940 'homepage': '',
941 'id': 0,
942 'longname': '',
943 'name': '',
944 },
945 'provider_version': 'N/A',
946 'roles': [
947 {
948 'contact': {
949 'id': 5,
950 'organisation': {
951 'city': 'Jülich',
952 'contact_url': 'mailto:toar-data@fz-juelich.de',
953 'country': 'Germany',
954 'homepage': 'https://www.fz-juelich.de',
955 'id': 2,
956 'kind': 'research',
957 'longname': 'Forschungszentrum Jülich',
958 'name': 'FZJ',
959 'postcode': '52425',
960 'street_address': 'Wilhelm-Johnen-Straße',
961 },
962 },
963 'id': 1,
964 'role': 'resource provider',
965 'status': 'active',
966 },
967 ],
968 'sampling_frequency': 'hourly',
969 'sampling_height': 7.0,
970 'station': {
971 'additional_metadata': {
972 'add_type': 'nature reservation',
973 },
974 'aux_docs': [],
975 'aux_images': [],
976 'aux_urls': [],
977 'changelog': [
978 {
979 'author_id': 1,
980 'datetime': '2023-07-15T19:27:09.463245+00:00',
981 'description': 'station created',
982 'new_value': '',
983 'old_value': '',
984 'station_id': 2,
985 'type_of_change': 'created',
986 },
987 ],
988 'codes': [
989 'SDZ54421',
990 ],
991 'coordinate_validation_status': 'not checked',
992 'coordinates': {
993 'alt': 293.9,
994 'lat': 40.65,
995 'lng': 117.106,
996 },
997 'country': 'China',
998 'globalmeta': {
999 'climatic_zone_year2016': '6 (warm temperate dry)',
1000 'distance_to_major_road_year2020': -999.0,
1001 'dominant_ecoregion_year2017': '-1 (undefined)',
1002 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
1003 'ecoregion_description_25km_year2017': '',
1004 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
1005 'landcover_description_25km_year2012': '',
1006 'max_population_density_25km_year1990': -1.0,
1007 'max_population_density_25km_year2015': -1.0,
1008 'max_stable_nightlights_25km_year1992': -999.0,
1009 'max_stable_nightlights_25km_year2013': -999.0,
1010 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1011 'mean_nox_emissions_10km_year2000': -999.0,
1012 'mean_nox_emissions_10km_year2015': -999.0,
1013 'mean_population_density_250m_year1990': -1.0,
1014 'mean_population_density_250m_year2015': -1.0,
1015 'mean_population_density_5km_year1990': -1.0,
1016 'mean_population_density_5km_year2015': -1.0,
1017 'mean_stable_nightlights_1km_year2013': -999.0,
1018 'mean_stable_nightlights_5km_year2013': -999.0,
1019 'mean_topography_srtm_alt_1km_year1994': -999.0,
1020 'mean_topography_srtm_alt_90m_year1994': -999.0,
1021 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1022 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1023 'toar1_category': 'unclassified',
1024 'toar2_category': 'suburban',
1025 },
1026 'id': 2,
1027 'name': 'Shangdianzi',
1028 'state': 'Beijing Shi',
1029 'timezone': 'Asia/Shanghai',
1030 'type': 'unknown',
1031 'type_of_area': 'unknown',
1032 },
1033 'variable': {
1034 'cf_standardname': 'mole_fraction_of_ozone_in_air',
1035 'chemical_formula': 'O3',
1036 'displayname': 'Ozone',
1037 'id': 5,
1038 'longname': 'ozone',
1039 'name': 'o3',
1040 'units': 'nmol mol-1',
1041 },
1042 },
1043 {
1044 'additional_metadata': {
1045 'original_units': 'ppb',
1046 },
1047 'aggregation': 'mean',
1048 'coverage': -1.0,
1049 'data_end_date': '2025-02-25T14:00:00+00:00',
1050 'data_origin': 'instrument',
1051 'data_origin_type': 'measurement',
1052 'data_start_date': '1991-01-01T00:00:00+00:00',
1053 'doi': '',
1054 'id': 434870,
1055 'label': '',
1056 'order': 2,
1057 'programme': {
1058 'description': '',
1059 'homepage': '',
1060 'id': 0,
1061 'longname': '',
1062 'name': '',
1063 },
1064 'provider_version': 'N/A',
1065 'roles': [
1066 {
1067 'contact': {
1068 'id': 4,
1069 'organisation': {
1070 'city': 'Dessau-Roßlau',
1071 'contact_url': 'mailto:immission@uba.de',
1072 'country': 'Germany',
1073 'homepage': 'https://www.umweltbundesamt.de',
1074 'id': 1,
1075 'kind': 'government',
1076 'longname': 'Umweltbundesamt',
1077 'name': 'UBA',
1078 'postcode': '06844',
1079 'street_address': 'Wörlitzer Platz 1',
1080 },
1081 },
1082 'id': 2,
1083 'role': 'resource provider',
1084 'status': 'active',
1085 },
1086 ],
1087 'sampling_frequency': 'hourly',
1088 'sampling_height': 7.0,
1089 'station': {
1090 'additional_metadata': {
1091 'add_type': 'nature reservation',
1092 },
1093 'aux_docs': [],
1094 'aux_images': [],
1095 'aux_urls': [],
1096 'changelog': [
1097 {
1098 'author_id': 1,
1099 'datetime': '2023-07-15T19:27:09.463245+00:00',
1100 'description': 'station created',
1101 'new_value': '',
1102 'old_value': '',
1103 'station_id': 2,
1104 'type_of_change': 'created',
1105 },
1106 ],
1107 'codes': [
1108 'SDZ54421',
1109 ],
1110 'coordinate_validation_status': 'not checked',
1111 'coordinates': {
1112 'alt': 293.9,
1113 'lat': 40.65,
1114 'lng': 117.106,
1115 },
1116 'country': 'China',
1117 'globalmeta': {
1118 'climatic_zone_year2016': '6 (warm temperate dry)',
1119 'distance_to_major_road_year2020': -999.0,
1120 'dominant_ecoregion_year2017': '-1 (undefined)',
1121 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
1122 'ecoregion_description_25km_year2017': '',
1123 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
1124 'landcover_description_25km_year2012': '',
1125 'max_population_density_25km_year1990': -1.0,
1126 'max_population_density_25km_year2015': -1.0,
1127 'max_stable_nightlights_25km_year1992': -999.0,
1128 'max_stable_nightlights_25km_year2013': -999.0,
1129 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1130 'mean_nox_emissions_10km_year2000': -999.0,
1131 'mean_nox_emissions_10km_year2015': -999.0,
1132 'mean_population_density_250m_year1990': -1.0,
1133 'mean_population_density_250m_year2015': -1.0,
1134 'mean_population_density_5km_year1990': -1.0,
1135 'mean_population_density_5km_year2015': -1.0,
1136 'mean_stable_nightlights_1km_year2013': -999.0,
1137 'mean_stable_nightlights_5km_year2013': -999.0,
1138 'mean_topography_srtm_alt_1km_year1994': -999.0,
1139 'mean_topography_srtm_alt_90m_year1994': -999.0,
1140 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1141 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1142 'toar1_category': 'unclassified',
1143 'toar2_category': 'suburban',
1144 },
1145 'id': 2,
1146 'name': 'Shangdianzi',
1147 'state': 'Beijing Shi',
1148 'timezone': 'Asia/Shanghai',
1149 'type': 'unknown',
1150 'type_of_area': 'unknown',
1151 },
1152 'variable': {
1153 'cf_standardname': 'mole_fraction_of_ozone_in_air',
1154 'chemical_formula': 'O3',
1155 'displayname': 'Ozone',
1156 'id': 5,
1157 'longname': 'ozone',
1158 'name': 'o3',
1159 'units': 'nmol mol-1',
1160 }
1161 }]
1162 assert response.json() == expected_resp
1165 def test_search_with_codes(self, client, db):
1166 response = client.get("/search/?codes=China_test8")
1167 expected_status_code = 200
1168 assert response.status_code == expected_status_code
1169 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1170 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1171 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1172 'data_origin': 'instrument', 'sampling_height': 7.0,
1173 'provider_version': 'N/A',
1174 'doi': '',
1175 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1176 'measurement_method': 'uv_abs',
1177 'original_units': {'since_19740101000000': 'nmol/mol'},
1178 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1179 'Data level': '2',
1180 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1181 'Station code': 'XXX',
1182 'Station name': 'Secret' } },
1183 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1184 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1185 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1186 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1187 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1188 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1189 'chemical_formula': 'O3', 'id': 5},
1190 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1191 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1192 'coordinate_validation_status': 'not checked',
1193 'country': 'China', 'state': 'Shandong Sheng',
1194 'type': 'unknown', 'type_of_area': 'unknown',
1195 'timezone': 'Asia/Shanghai', 'additional_metadata': {},
1196 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1197 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1198 'distance_to_major_road_year2020': -999.0,
1199 'dominant_ecoregion_year2017': '-1 (undefined)',
1200 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1201 'ecoregion_description_25km_year2017': '',
1202 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1203 'landcover_description_25km_year2012': '',
1204 'max_stable_nightlights_25km_year1992': -999.0,
1205 'max_stable_nightlights_25km_year2013': -999.0,
1206 'max_population_density_25km_year1990': -1.0,
1207 'max_population_density_25km_year2015': -1.0,
1208 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1209 'mean_stable_nightlights_1km_year2013': -999.0,
1210 'mean_stable_nightlights_5km_year2013': -999.0,
1211 'mean_nox_emissions_10km_year2000': -999.0,
1212 'mean_nox_emissions_10km_year2015': -999.0,
1213 'mean_population_density_250m_year1990': -1.0,
1214 'mean_population_density_250m_year2015': -1.0,
1215 'mean_population_density_5km_year1990': -1.0,
1216 'mean_population_density_5km_year2015': -1.0,
1217 'mean_topography_srtm_alt_1km_year1994': -999.0,
1218 'mean_topography_srtm_alt_90m_year1994': -999.0,
1219 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1220 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1221 'toar1_category': 'unclassified',
1222 'toar2_category': 'suburban'},
1223 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1224 'description': 'station created',
1225 'old_value': '',
1226 'new_value': '',
1227 'station_id': 3,
1228 'author_id': 1,
1229 'type_of_change': 'created'
1230 }]},
1231 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1232 assert response.json() == expected_resp
1235 def test_search_with_wrong_bounding_box(self, client, db):
1236 response = client.get("/search/?bounding_box=Asia")
1237 expected_status_code = 400
1238 assert response.status_code == expected_status_code
1239 expected_resp = "not enough values to unpack (expected 4, got 1)"
1240 assert response.json() == expected_resp
1243 def test_search_empty_bounding_box(self, client, db):
1244 response = client.get("/search/?bounding_box=117,36,118,37")
1245 expected_status_code = 200
1246 assert response.status_code == expected_status_code
1247 expected_resp = []
1248 assert response.json() == expected_resp
1251 def test_search_empty_bounding_box_and_fields(self, client, db):
1252 response = client.get("/search/?bounding_box=117,36,118,37&fields=station_id")
1253 expected_status_code = 200
1254 assert response.status_code == expected_status_code
1255 expected_resp = []
1256 assert response.json() == expected_resp
1259 def test_search_with_bounding_box(self, client, db):
1260 response = client.get("/search/?bounding_box=36,117,37,118")
1261 expected_status_code = 200
1262 assert response.status_code == expected_status_code
1263 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1264 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1265 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1266 'data_origin': 'instrument', 'sampling_height': 7.0,
1267 'provider_version': 'N/A',
1268 'doi': '',
1269 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1270 'measurement_method': 'uv_abs',
1271 'original_units': {'since_19740101000000': 'nmol/mol'},
1272 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1273 'Data level': '2',
1274 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1275 'Station code': 'XXX',
1276 'Station name': 'Secret' } },
1277 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1278 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1279 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1280 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1281 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1282 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1283 'chemical_formula': 'O3', 'id': 5},
1284 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1285 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1286 'coordinate_validation_status': 'not checked',
1287 'country': 'China', 'state': 'Shandong Sheng',
1288 'type': 'unknown', 'type_of_area': 'unknown',
1289 'timezone': 'Asia/Shanghai', 'additional_metadata': {},
1290 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1291 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1292 'distance_to_major_road_year2020': -999.0,
1293 'dominant_ecoregion_year2017': '-1 (undefined)',
1294 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1295 'ecoregion_description_25km_year2017': '',
1296 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1297 'landcover_description_25km_year2012': '',
1298 'max_stable_nightlights_25km_year1992': -999.0,
1299 'max_stable_nightlights_25km_year2013': -999.0,
1300 'max_population_density_25km_year1990': -1.0,
1301 'max_population_density_25km_year2015': -1.0,
1302 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1303 'mean_stable_nightlights_1km_year2013': -999.0,
1304 'mean_stable_nightlights_5km_year2013': -999.0,
1305 'mean_nox_emissions_10km_year2000': -999.0,
1306 'mean_nox_emissions_10km_year2015': -999.0,
1307 'mean_population_density_250m_year1990': -1.0,
1308 'mean_population_density_250m_year2015': -1.0,
1309 'mean_population_density_5km_year1990': -1.0,
1310 'mean_population_density_5km_year2015': -1.0,
1311 'mean_topography_srtm_alt_1km_year1994': -999.0,
1312 'mean_topography_srtm_alt_90m_year1994': -999.0,
1313 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1314 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1315 'toar1_category': 'unclassified',
1316 'toar2_category': 'suburban'},
1317 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1318 'description': 'station created',
1319 'old_value': '',
1320 'new_value': '',
1321 'station_id': 3,
1322 'author_id': 1,
1323 'type_of_change': 'created'
1324 }]},
1325 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1326 assert response.json() == expected_resp
1329 def test_search_with_time(self, client, db):
1330 response = client.get("/search/?variable_id=5&data_start_date=2003-09-07 15:30:00")
1331 expected_status_code = 200
1332 assert response.status_code == expected_status_code
1333 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1334 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1335 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1336 'data_origin': 'instrument', 'sampling_height': 7.0,
1337 'provider_version': 'N/A',
1338 'doi': '',
1339 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1340 'measurement_method': 'uv_abs',
1341 'original_units': {'since_19740101000000': 'nmol/mol'},
1342 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1343 'Data level': '2',
1344 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1345 'Station code': 'XXX',
1346 'Station name': 'Secret' } },
1347 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1348 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1349 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1350 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1351 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1352 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1353 'chemical_formula': 'O3', 'id': 5},
1354 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1355 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1356 'coordinate_validation_status': 'not checked',
1357 'country': 'China', 'state': 'Shandong Sheng',
1358 'type': 'unknown', 'type_of_area': 'unknown',
1359 'timezone': 'Asia/Shanghai', 'additional_metadata': {},
1360 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1361 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1362 'distance_to_major_road_year2020': -999.0,
1363 'dominant_ecoregion_year2017': '-1 (undefined)',
1364 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1365 'ecoregion_description_25km_year2017': '',
1366 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1367 'landcover_description_25km_year2012': '',
1368 'max_stable_nightlights_25km_year1992': -999.0,
1369 'max_stable_nightlights_25km_year2013': -999.0,
1370 'max_population_density_25km_year1990': -1.0,
1371 'max_population_density_25km_year2015': -1.0,
1372 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1373 'mean_stable_nightlights_1km_year2013': -999.0,
1374 'mean_stable_nightlights_5km_year2013': -999.0,
1375 'mean_nox_emissions_10km_year2000': -999.0,
1376 'mean_nox_emissions_10km_year2015': -999.0,
1377 'mean_population_density_250m_year1990': -1.0,
1378 'mean_population_density_250m_year2015': -1.0,
1379 'mean_population_density_5km_year1990': -1.0,
1380 'mean_population_density_5km_year2015': -1.0,
1381 'mean_topography_srtm_alt_1km_year1994': -999.0,
1382 'mean_topography_srtm_alt_90m_year1994': -999.0,
1383 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1384 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1385 'toar1_category': 'unclassified',
1386 'toar2_category': 'suburban'},
1387 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1388 'description': 'station created',
1389 'old_value': '',
1390 'new_value': '',
1391 'station_id': 3,
1392 'author_id': 1,
1393 'type_of_change': 'created'
1394 }]},
1395 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1396 assert response.json() == expected_resp
1399 def test_search_wrong_time_syntax(self, client, db):
1400 response = client.get("/search/?variable_id=5&data_start_date=2050-01-01T00:00:00Z")
1401 expected_status_code = 400
1402 assert response.status_code == expected_status_code
1403 expected_resp = "Wrong value for time given: 2050-01-01T00:00:00Z"
1404 assert response.json() == expected_resp
1407 def test_search_with_fields(self, client, db):
1408 response = client.get("/search/?fields=id,role,order,additional_metadata")
1409 expected_status_code = 200
1410 assert response.status_code == expected_status_code
1411 expected_resp = [{'additional_metadata': {'original_units': 'ppb'},
1412 'id': 1,
1413 'order': 1,
1414 'roles': {'contact_id': 3, 'role': 'principal investigator', 'status': 'active'}
1415 },
1416 {'id': 1,
1417 'order': 1,
1418 'additional_metadata': {"original_units": "ppb"},
1419 'roles': {'role': 'resource provider', 'status': 'active', 'contact_id': 4}
1420 },
1421 {'id': 2,
1422 'order': 1,
1423 'additional_metadata':{'original_units': {'since_19740101000000': 'nmol/mol'},
1424 'measurement_method': 'uv_abs',
1425 'absorption_cross_section': 'Hearn 1961',
1426 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1427 'Data level': '2',
1428 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1429 'Station code': 'XXX',
1430 'Station name': 'Secret'}
1431 },
1432 'roles': {'role': 'resource provider', 'status': 'active', 'contact_id': 5}
1433 },
1434 {
1435 'id': 18763,
1436 'order': 1,
1437 'additional_metadata': {'original_units': 'ppb'},
1438 'roles': {'role': 'resource provider', 'status': 'active', 'contact_id': 5}
1439 },
1440 {
1441 'id': 30890,
1442 'order': 2,
1443 'additional_metadata': {'original_units': 'ppb'},
1444 'roles': {'role': 'resource provider', 'status': 'active', 'contact_id': 5}
1445 },
1446 {
1447 'id': 434870,
1448 'order': 2,
1449 'additional_metadata': {'original_units': 'ppb'},
1450 'roles': {'role': 'resource provider', 'status': 'active', 'contact_id': 4}
1451 }
1452 ]
1453 set_expected_resp = {json.dumps(item, sort_keys=True) for item in expected_resp}
1454 set_response = {json.dumps(item, sort_keys=True) for item in response.json()}
1455 assert set_response == set_expected_resp
1458 def test_search_with_variable_id_in_fields(self, client, db):
1459 response = client.get("/search/?fields=variable_id")
1460 expected_status_code = 200
1461 assert response.status_code == expected_status_code
1462 expected_resp = [{'variable': {'id': 7}},
1463 {'variable': {'id': 5}}]
1464 set_expected_resp = {json.dumps(item, sort_keys=True) for item in expected_resp}
1465 set_response = {json.dumps(item, sort_keys=True) for item in response.json()}
1466 assert set_response == set_expected_resp
1469 def test_search_with_whole_variable_in_fields(self, client, db):
1470 response = client.get("/search/?fields=variable")
1471 expected_status_code = 400
1472 assert response.status_code == expected_status_code
1473 expected_resp = "Wrong field given: variable"
1474 assert response.json() == expected_resp
1477 def test_search_with_stationname(self, client, db):
1478 response = client.get("/search/?name=Test_China")
1479 expected_status_code = 200
1480 assert response.status_code == expected_status_code
1481 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1482 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1483 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1484 'data_origin': 'instrument', 'sampling_height': 7.0,
1485 'provider_version': 'N/A',
1486 'doi': '',
1487 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1488 'measurement_method': 'uv_abs',
1489 'original_units': {'since_19740101000000': 'nmol/mol'},
1490 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1491 'Data level': '2',
1492 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1493 'Station code': 'XXX',
1494 'Station name': 'Secret' } },
1495 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1496 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1497 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1498 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1499 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1500 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1501 'chemical_formula': 'O3', 'id': 5},
1502 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1503 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1504 'coordinate_validation_status': 'not checked',
1505 'country': 'China', 'state': 'Shandong Sheng',
1506 'type': 'unknown', 'type_of_area': 'unknown',
1507 'timezone': 'Asia/Shanghai', 'additional_metadata': {},
1508 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1509 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1510 'distance_to_major_road_year2020': -999.0,
1511 'dominant_ecoregion_year2017': '-1 (undefined)',
1512 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1513 'ecoregion_description_25km_year2017': '',
1514 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1515 'landcover_description_25km_year2012': '',
1516 'max_stable_nightlights_25km_year1992': -999.0,
1517 'max_stable_nightlights_25km_year2013': -999.0,
1518 'max_population_density_25km_year1990': -1.0,
1519 'max_population_density_25km_year2015': -1.0,
1520 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1521 'mean_stable_nightlights_1km_year2013': -999.0,
1522 'mean_stable_nightlights_5km_year2013': -999.0,
1523 'mean_nox_emissions_10km_year2000': -999.0,
1524 'mean_nox_emissions_10km_year2015': -999.0,
1525 'mean_population_density_250m_year1990': -1.0,
1526 'mean_population_density_250m_year2015': -1.0,
1527 'mean_population_density_5km_year1990': -1.0,
1528 'mean_population_density_5km_year2015': -1.0,
1529 'mean_topography_srtm_alt_1km_year1994': -999.0,
1530 'mean_topography_srtm_alt_90m_year1994': -999.0,
1531 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1532 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1533 'toar1_category': 'unclassified',
1534 'toar2_category': 'suburban'},
1535 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1536 'description': 'station created',
1537 'old_value': '',
1538 'new_value': '',
1539 'station_id': 3,
1540 'author_id': 1,
1541 'type_of_change': 'created'
1542 }]},
1543 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1544 assert response.json() == expected_resp
1547 def test_search_with_global_attributes(self, client, db):
1548 response = client.get("/search/?climatic_zone_year2016=WarmTemperateDry&htap_region_tier1_year2010=HTAPTier1SAF")
1549 expected_status_code = 200
1550 assert response.status_code == expected_status_code
1551 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1552 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1553 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1554 'data_origin': 'instrument', 'sampling_height': 7.0,
1555 'provider_version': 'N/A',
1556 'doi': '',
1557 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1558 'measurement_method': 'uv_abs',
1559 'original_units': {'since_19740101000000': 'nmol/mol'},
1560 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1561 'Data level': '2',
1562 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1563 'Station code': 'XXX',
1564 'Station name': 'Secret' } },
1565 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1566 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1567 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1568 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1569 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1570 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1571 'chemical_formula': 'O3', 'id': 5},
1572 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1573 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1574 'coordinate_validation_status': 'not checked',
1575 'country': 'China', 'state': 'Shandong Sheng',
1576 'type': 'unknown', 'type_of_area': 'unknown',
1577 'timezone': 'Asia/Shanghai', 'additional_metadata': {},
1578 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1579 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1580 'distance_to_major_road_year2020': -999.0,
1581 'dominant_ecoregion_year2017': '-1 (undefined)',
1582 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1583 'ecoregion_description_25km_year2017': '',
1584 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1585 'landcover_description_25km_year2012': '',
1586 'max_stable_nightlights_25km_year1992': -999.0,
1587 'max_stable_nightlights_25km_year2013': -999.0,
1588 'max_population_density_25km_year1990': -1.0,
1589 'max_population_density_25km_year2015': -1.0,
1590 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1591 'mean_stable_nightlights_1km_year2013': -999.0,
1592 'mean_stable_nightlights_5km_year2013': -999.0,
1593 'mean_nox_emissions_10km_year2000': -999.0,
1594 'mean_nox_emissions_10km_year2015': -999.0,
1595 'mean_population_density_250m_year1990': -1.0,
1596 'mean_population_density_250m_year2015': -1.0,
1597 'mean_population_density_5km_year1990': -1.0,
1598 'mean_population_density_5km_year2015': -1.0,
1599 'mean_topography_srtm_alt_1km_year1994': -999.0,
1600 'mean_topography_srtm_alt_90m_year1994': -999.0,
1601 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1602 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1603 'toar1_category': 'unclassified',
1604 'toar2_category': 'suburban'},
1605 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1606 'description': 'station created',
1607 'old_value': '',
1608 'new_value': '',
1609 'station_id': 3,
1610 'author_id': 1,
1611 'type_of_change': 'created'
1612 }]},
1613 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1614 assert response.json() == expected_resp
1617 def test_search_with_global_attributes2(self, client, db):
1618 response = client.get("/search/?dominant_landcover_year2012=CroplandRainfed&dominant_ecoregion_year2017=Undefined")
1619 expected_status_code = 200
1620 assert response.status_code == expected_status_code
1621 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1622 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1623 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1624 'data_origin': 'instrument', 'sampling_height': 7.0,
1625 'provider_version': 'N/A',
1626 'doi': '',
1627 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1628 'measurement_method': 'uv_abs',
1629 'original_units': {'since_19740101000000': 'nmol/mol'},
1630 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1631 'Data level': '2',
1632 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1633 'Station code': 'XXX',
1634 'Station name': 'Secret' } },
1635 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1636 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1637 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1638 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1639 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1640 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1641 'chemical_formula': 'O3', 'id': 5},
1642 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1643 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1644 'coordinate_validation_status': 'not checked',
1645 'country': 'China', 'state': 'Shandong Sheng',
1646 'type': 'unknown', 'type_of_area': 'unknown',
1647 'timezone': 'Asia/Shanghai', 'additional_metadata': {},
1648 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1649 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1650 'distance_to_major_road_year2020': -999.0,
1651 'dominant_ecoregion_year2017': '-1 (undefined)',
1652 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1653 'ecoregion_description_25km_year2017': '',
1654 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1655 'landcover_description_25km_year2012': '',
1656 'max_stable_nightlights_25km_year1992': -999.0,
1657 'max_stable_nightlights_25km_year2013': -999.0,
1658 'max_population_density_25km_year1990': -1.0,
1659 'max_population_density_25km_year2015': -1.0,
1660 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1661 'mean_stable_nightlights_1km_year2013': -999.0,
1662 'mean_stable_nightlights_5km_year2013': -999.0,
1663 'mean_nox_emissions_10km_year2000': -999.0,
1664 'mean_nox_emissions_10km_year2015': -999.0,
1665 'mean_population_density_250m_year1990': -1.0,
1666 'mean_population_density_250m_year2015': -1.0,
1667 'mean_population_density_5km_year1990': -1.0,
1668 'mean_population_density_5km_year2015': -1.0,
1669 'mean_topography_srtm_alt_1km_year1994': -999.0,
1670 'mean_topography_srtm_alt_90m_year1994': -999.0,
1671 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1672 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1673 'toar1_category': 'unclassified',
1674 'toar2_category': 'suburban'},
1675 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1676 'description': 'station created',
1677 'old_value': '',
1678 'new_value': '',
1679 'station_id': 3,
1680 'author_id': 1,
1681 'type_of_change': 'created'
1682 }]},
1683 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1684 assert response.json() == expected_resp
1687 def test_search_with_additional_metadata(self, client, db):
1688 response = client.get("/search/?additional_metadata->'absorption_cross_section'=Hearn1961")
1689 expected_status_code = 200
1690 assert response.status_code == expected_status_code
1691 expected_resp = [{'id': 2, 'label': 'CMA', 'order': 1,
1692 'sampling_frequency': 'hourly', 'aggregation': 'mean', 'data_origin_type': 'measurement',
1693 'data_start_date': '2003-09-07T15:30:00+00:00', 'data_end_date': '2016-12-31T14:30:00+00:00', 'coverage': -1.0,
1694 'data_origin': 'instrument', 'sampling_height': 7.0,
1695 'provider_version': 'N/A',
1696 'doi': '',
1697 'additional_metadata': {'absorption_cross_section': 'Hearn 1961',
1698 'measurement_method': 'uv_abs',
1699 'original_units': {'since_19740101000000': 'nmol/mol'},
1700 'ebas_metadata_19740101000000_29y': {'Submitter': 'Unknown, Lady, lady.unknown@unknown.com, some long division name, SHORT, , 111 Streetname, , zipcode, Boulder, CO, USA',
1701 'Data level': '2',
1702 'Frameworks': 'GAW-WDCRG NOAA-ESRL',
1703 'Station code': 'XXX',
1704 'Station name': 'Secret' } },
1705 'roles': [{'id': 1, 'role': 'resource provider', 'status': 'active',
1706 'contact': {'id': 5, 'organisation': {'id': 2, 'name': 'FZJ', 'longname': 'Forschungszentrum Jülich',
1707 'kind': 'research', 'city': 'Jülich', 'postcode': '52425', 'street_address': 'Wilhelm-Johnen-Straße',
1708 'country': 'Germany', 'homepage': 'https://www.fz-juelich.de', 'contact_url': 'mailto:toar-data@fz-juelich.de'}}}],
1709 'variable': {'name': 'o3', 'longname': 'ozone', 'displayname': 'Ozone',
1710 'cf_standardname': 'mole_fraction_of_ozone_in_air', 'units': 'nmol mol-1',
1711 'chemical_formula': 'O3', 'id': 5},
1712 'station': {'id': 3, 'codes': ['China_test8'], 'name': 'Test_China',
1713 'coordinates': {'alt': 1534.0, 'lat': 36.256, 'lng': 117.106},
1714 'coordinate_validation_status': 'not checked',
1715 'country': 'China', 'state': 'Shandong Sheng',
1716 'type': 'unknown', 'type_of_area': 'unknown',
1717 'timezone': 'Asia/Shanghai',
1718 'additional_metadata': {},
1719 'aux_images': [], 'aux_docs': [], 'aux_urls': [],
1720 'globalmeta': {'climatic_zone_year2016': '6 (warm temperate dry)',
1721 'distance_to_major_road_year2020': -999.0,
1722 'dominant_ecoregion_year2017': '-1 (undefined)',
1723 'dominant_landcover_year2012': '10 (Cropland, rainfed)',
1724 'ecoregion_description_25km_year2017': '',
1725 'htap_region_tier1_year2010': '10 (SAF Sub Saharan/sub Sahel Africa)',
1726 'landcover_description_25km_year2012': '',
1727 'max_stable_nightlights_25km_year1992': -999.0,
1728 'max_stable_nightlights_25km_year2013': -999.0,
1729 'max_population_density_25km_year1990': -1.0,
1730 'max_population_density_25km_year2015': -1.0,
1731 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1732 'mean_stable_nightlights_1km_year2013': -999.0,
1733 'mean_stable_nightlights_5km_year2013': -999.0,
1734 'mean_nox_emissions_10km_year2000': -999.0,
1735 'mean_nox_emissions_10km_year2015': -999.0,
1736 'mean_population_density_250m_year1990': -1.0,
1737 'mean_population_density_250m_year2015': -1.0,
1738 'mean_population_density_5km_year1990': -1.0,
1739 'mean_population_density_5km_year2015': -1.0,
1740 'mean_topography_srtm_alt_1km_year1994': -999.0,
1741 'mean_topography_srtm_alt_90m_year1994': -999.0,
1742 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1743 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1744 'toar1_category': 'unclassified',
1745 'toar2_category': 'suburban'},
1746 'changelog': [{'datetime': '2023-08-15T21:16:20.596545+00:00',
1747 'description': 'station created',
1748 'old_value': '',
1749 'new_value': '',
1750 'station_id': 3,
1751 'author_id': 1,
1752 'type_of_change': 'created'
1753 }]},
1754 'programme': {'id': 0, 'name': '', 'longname': '', 'homepage': '', 'description': ''}}]
1755 assert response.json() == expected_resp
1758 def test_search_with_additional_metadata2(self, client, db):
1759 response = client.get("/search/?additional_metadata->'absorption_cross_section'=Hearn1961"+
1760 "&additional_metadata->'sampling_type'=Continuous"+
1761 "&additional_metadata->'calibration_type'=Automatic")
1762 expected_status_code = 200
1763 assert response.status_code == expected_status_code
1764 expected_response = []
1765 assert response.json() == expected_response
1768 def test_search_with_additional_metadata3(self, client, db):
1769 response = client.get("/search/?additional_metadata->'original_units'=ppb")
1770 expected_status_code = 200
1771 assert response.status_code == expected_status_code
1772 expected_response = [{'id': 1,
1773 'label': 'CMA',
1774 'order': 1,
1775 'sampling_frequency': 'hourly',
1776 'aggregation': 'mean',
1777 'data_start_date': '2003-09-07T15:30:00+00:00',
1778 'data_end_date': '2016-12-31T14:30:00+00:00',
1779 'data_origin': 'instrument',
1780 'data_origin_type': 'measurement',
1781 'provider_version': 'N/A',
1782 'sampling_height': 7.0,
1783 'additional_metadata': {"original_units": "ppb"},
1784 'doi': '',
1785 'coverage': -1.0,
1786 'station': {'id': 2,
1787 'codes': ['SDZ54421'],
1788 'name': 'Shangdianzi',
1789 'coordinates': {'lat': 40.65, 'lng': 117.106, 'alt': 293.9},
1790 'coordinate_validation_status': 'not checked',
1791 'country': 'China',
1792 'state': 'Beijing Shi',
1793 'type': 'unknown',
1794 'type_of_area': 'unknown',
1795 'timezone': 'Asia/Shanghai',
1796 'additional_metadata': {'add_type': 'nature reservation'},
1797 'aux_images': [],
1798 'aux_docs': [],
1799 'aux_urls': [],
1800 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
1801 'mean_topography_srtm_alt_1km_year1994': -999.0,
1802 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1803 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1804 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1805 'climatic_zone_year2016': '6 (warm temperate dry)',
1806 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
1807 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
1808 'landcover_description_25km_year2012': '',
1809 'dominant_ecoregion_year2017': '-1 (undefined)',
1810 'ecoregion_description_25km_year2017': '',
1811 'distance_to_major_road_year2020': -999.0,
1812 'mean_stable_nightlights_1km_year2013': -999.0,
1813 'mean_stable_nightlights_5km_year2013': -999.0,
1814 'max_stable_nightlights_25km_year2013': -999.0,
1815 'max_stable_nightlights_25km_year1992': -999.0,
1816 'mean_population_density_250m_year2015': -1.0,
1817 'mean_population_density_5km_year2015': -1.0,
1818 'max_population_density_25km_year2015': -1.0,
1819 'mean_population_density_250m_year1990': -1.0,
1820 'mean_population_density_5km_year1990': -1.0,
1821 'max_population_density_25km_year1990': -1.0,
1822 'mean_nox_emissions_10km_year2015': -999.0,
1823 'mean_nox_emissions_10km_year2000': -999.0,
1824 'toar1_category': 'unclassified',
1825 'toar2_category': 'suburban'},
1826 'changelog': [{'datetime': '2023-07-15T19:27:09.463245+00:00', 'description': 'station created', 'old_value': '', 'new_value': '', 'station_id': 2, 'author_id': 1, 'type_of_change': 'created'}]},
1827 'variable': {'name': 'toluene',
1828 'longname': 'toluene',
1829 'displayname': 'Toluene',
1830 'cf_standardname': 'mole_fraction_of_toluene_in_air',
1831 'units': 'nmol mol-1',
1832 'chemical_formula': 'C7H8',
1833 'id': 7},
1834 'programme': {'id': 0,
1835 'name': '',
1836 'longname': '',
1837 'homepage': '',
1838 'description': ''},
1839 'roles': [{'id': 2,
1840 'role': 'resource provider',
1841 'status': 'active',
1842 'contact': {'id': 4,
1843 'organisation': {'id': 1,
1844 'name': 'UBA',
1845 'longname': 'Umweltbundesamt',
1846 'kind': 'government',
1847 'city': 'Dessau-Roßlau',
1848 'postcode': '06844',
1849 'street_address': 'Wörlitzer Platz 1',
1850 'country': 'Germany',
1851 'homepage': 'https://www.umweltbundesamt.de',
1852 'contact_url': 'mailto:immission@uba.de'}}},
1853 {'id': 3,
1854 'role': 'principal investigator',
1855 'status': 'active',
1856 'contact': {'id': 3,
1857 'person': {'email': 's.schroeder@fz-juelich.de',
1858 'id': 3,
1859 'isprivate': False,
1860 'name': 'Sabine Schröder',
1861 'orcid': '0000-0002-0309-8010',
1862 'phone': '+49-2461-61-6397'
1863 }
1864 }
1865 }]
1866 },
1867 {
1868 'additional_metadata': {
1869 'original_units': 'ppb',
1870 },
1871 'aggregation': 'mean',
1872 'coverage': -1.0,
1873 'data_end_date': '2025-02-25T14:00:00+00:00',
1874 'data_origin': 'instrument',
1875 'data_origin_type': 'measurement',
1876 'data_start_date': '1991-01-01T00:00:00+00:00',
1877 'doi': '',
1878 'id': 18763,
1879 'label': '',
1880 'order': 1,
1881 'programme': {
1882 'description': '',
1883 'homepage': '',
1884 'id': 0,
1885 'longname': '',
1886 'name': '',
1887 },
1888 'provider_version': 'N/A',
1889 'roles': [
1890 {
1891 'contact': {
1892 'id': 5,
1893 'organisation': {
1894 'city': 'Jülich',
1895 'contact_url': 'mailto:toar-data@fz-juelich.de',
1896 'country': 'Germany',
1897 'homepage': 'https://www.fz-juelich.de',
1898 'id': 2,
1899 'kind': 'research',
1900 'longname': 'Forschungszentrum Jülich',
1901 'name': 'FZJ',
1902 'postcode': '52425',
1903 'street_address': 'Wilhelm-Johnen-Straße',
1904 },
1905 },
1906 'id': 1,
1907 'role': 'resource provider',
1908 'status': 'active',
1909 },
1910 ],
1911 'sampling_frequency': 'hourly',
1912 'sampling_height': 7.0,
1913 'station': {
1914 'additional_metadata': {
1915 'add_type': 'nature reservation',
1916 },
1917 'aux_docs': [],
1918 'aux_images': [],
1919 'aux_urls': [],
1920 'changelog': [
1921 {
1922 'author_id': 1,
1923 'datetime': '2023-07-15T19:27:09.463245+00:00',
1924 'description': 'station created',
1925 'new_value': '',
1926 'old_value': '',
1927 'station_id': 2,
1928 'type_of_change': 'created',
1929 },
1930 ],
1931 'codes': [
1932 'SDZ54421',
1933 ],
1934 'coordinate_validation_status': 'not checked',
1935 'coordinates': {
1936 'alt': 293.9,
1937 'lat': 40.65,
1938 'lng': 117.106,
1939 },
1940 'country': 'China',
1941 'globalmeta': {
1942 'climatic_zone_year2016': '6 (warm temperate dry)',
1943 'distance_to_major_road_year2020': -999.0,
1944 'dominant_ecoregion_year2017': '-1 (undefined)',
1945 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
1946 'ecoregion_description_25km_year2017': '',
1947 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
1948 'landcover_description_25km_year2012': '',
1949 'max_population_density_25km_year1990': -1.0,
1950 'max_population_density_25km_year2015': -1.0,
1951 'max_stable_nightlights_25km_year1992': -999.0,
1952 'max_stable_nightlights_25km_year2013': -999.0,
1953 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
1954 'mean_nox_emissions_10km_year2000': -999.0,
1955 'mean_nox_emissions_10km_year2015': -999.0,
1956 'mean_population_density_250m_year1990': -1.0,
1957 'mean_population_density_250m_year2015': -1.0,
1958 'mean_population_density_5km_year1990': -1.0,
1959 'mean_population_density_5km_year2015': -1.0,
1960 'mean_stable_nightlights_1km_year2013': -999.0,
1961 'mean_stable_nightlights_5km_year2013': -999.0,
1962 'mean_topography_srtm_alt_1km_year1994': -999.0,
1963 'mean_topography_srtm_alt_90m_year1994': -999.0,
1964 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
1965 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
1966 'toar1_category': 'unclassified',
1967 'toar2_category': 'suburban',
1968 },
1969 'id': 2,
1970 'name': 'Shangdianzi',
1971 'state': 'Beijing Shi',
1972 'timezone': 'Asia/Shanghai',
1973 'type': 'unknown',
1974 'type_of_area': 'unknown',
1975 },
1976 'variable': {
1977 'cf_standardname': 'mole_fraction_of_ozone_in_air',
1978 'chemical_formula': 'O3',
1979 'displayname': 'Ozone',
1980 'id': 5,
1981 'longname': 'ozone',
1982 'name': 'o3',
1983 'units': 'nmol mol-1',
1984 },
1985 },
1986 {
1987 'additional_metadata': {
1988 'original_units': 'ppb',
1989 },
1990 'aggregation': 'mean',
1991 'coverage': -1.0,
1992 'data_end_date': '2025-02-25T14:00:00+00:00',
1993 'data_origin': 'instrument',
1994 'data_origin_type': 'measurement',
1995 'data_start_date': '1991-01-01T00:00:00+00:00',
1996 'doi': '',
1997 'id': 30890,
1998 'label': '',
1999 'order': 2,
2000 'programme': {
2001 'description': '',
2002 'homepage': '',
2003 'id': 0,
2004 'longname': '',
2005 'name': '',
2006 },
2007 'provider_version': 'N/A',
2008 'roles': [
2009 {
2010 'contact': {
2011 'id': 5,
2012 'organisation': {
2013 'city': 'Jülich',
2014 'contact_url': 'mailto:toar-data@fz-juelich.de',
2015 'country': 'Germany',
2016 'homepage': 'https://www.fz-juelich.de',
2017 'id': 2,
2018 'kind': 'research',
2019 'longname': 'Forschungszentrum Jülich',
2020 'name': 'FZJ',
2021 'postcode': '52425',
2022 'street_address': 'Wilhelm-Johnen-Straße',
2023 },
2024 },
2025 'id': 1,
2026 'role': 'resource provider',
2027 'status': 'active',
2028 },
2029 ],
2030 'sampling_frequency': 'hourly',
2031 'sampling_height': 7.0,
2032 'station': {
2033 'additional_metadata': {
2034 'add_type': 'nature reservation',
2035 },
2036 'aux_docs': [],
2037 'aux_images': [],
2038 'aux_urls': [],
2039 'changelog': [
2040 {
2041 'author_id': 1,
2042 'datetime': '2023-07-15T19:27:09.463245+00:00',
2043 'description': 'station created',
2044 'new_value': '',
2045 'old_value': '',
2046 'station_id': 2,
2047 'type_of_change': 'created',
2048 },
2049 ],
2050 'codes': [
2051 'SDZ54421',
2052 ],
2053 'coordinate_validation_status': 'not checked',
2054 'coordinates': {
2055 'alt': 293.9,
2056 'lat': 40.65,
2057 'lng': 117.106,
2058 },
2059 'country': 'China',
2060 'globalmeta': {
2061 'climatic_zone_year2016': '6 (warm temperate dry)',
2062 'distance_to_major_road_year2020': -999.0,
2063 'dominant_ecoregion_year2017': '-1 (undefined)',
2064 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
2065 'ecoregion_description_25km_year2017': '',
2066 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
2067 'landcover_description_25km_year2012': '',
2068 'max_population_density_25km_year1990': -1.0,
2069 'max_population_density_25km_year2015': -1.0,
2070 'max_stable_nightlights_25km_year1992': -999.0,
2071 'max_stable_nightlights_25km_year2013': -999.0,
2072 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
2073 'mean_nox_emissions_10km_year2000': -999.0,
2074 'mean_nox_emissions_10km_year2015': -999.0,
2075 'mean_population_density_250m_year1990': -1.0,
2076 'mean_population_density_250m_year2015': -1.0,
2077 'mean_population_density_5km_year1990': -1.0,
2078 'mean_population_density_5km_year2015': -1.0,
2079 'mean_stable_nightlights_1km_year2013': -999.0,
2080 'mean_stable_nightlights_5km_year2013': -999.0,
2081 'mean_topography_srtm_alt_1km_year1994': -999.0,
2082 'mean_topography_srtm_alt_90m_year1994': -999.0,
2083 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
2084 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
2085 'toar1_category': 'unclassified',
2086 'toar2_category': 'suburban',
2087 },
2088 'id': 2,
2089 'name': 'Shangdianzi',
2090 'state': 'Beijing Shi',
2091 'timezone': 'Asia/Shanghai',
2092 'type': 'unknown',
2093 'type_of_area': 'unknown',
2094 },
2095 'variable': {
2096 'cf_standardname': 'mole_fraction_of_ozone_in_air',
2097 'chemical_formula': 'O3',
2098 'displayname': 'Ozone',
2099 'id': 5,
2100 'longname': 'ozone',
2101 'name': 'o3',
2102 'units': 'nmol mol-1',
2103 },
2104 },
2105 {
2106 'additional_metadata': {
2107 'original_units': 'ppb',
2108 },
2109 'aggregation': 'mean',
2110 'coverage': -1.0,
2111 'data_end_date': '2025-02-25T14:00:00+00:00',
2112 'data_origin': 'instrument',
2113 'data_origin_type': 'measurement',
2114 'data_start_date': '1991-01-01T00:00:00+00:00',
2115 'doi': '',
2116 'id': 434870,
2117 'label': '',
2118 'order': 2,
2119 'programme': {
2120 'description': '',
2121 'homepage': '',
2122 'id': 0,
2123 'longname': '',
2124 'name': '',
2125 },
2126 'provider_version': 'N/A',
2127 'roles': [
2128 {
2129 'contact': {
2130 'id': 4,
2131 'organisation': {
2132 'city': 'Dessau-Roßlau',
2133 'contact_url': 'mailto:immission@uba.de',
2134 'country': 'Germany',
2135 'homepage': 'https://www.umweltbundesamt.de',
2136 'id': 1,
2137 'kind': 'government',
2138 'longname': 'Umweltbundesamt',
2139 'name': 'UBA',
2140 'postcode': '06844',
2141 'street_address': 'Wörlitzer Platz 1',
2142 },
2143 },
2144 'id': 2,
2145 'role': 'resource provider',
2146 'status': 'active',
2147 },
2148 ],
2149 'sampling_frequency': 'hourly',
2150 'sampling_height': 7.0,
2151 'station': {
2152 'additional_metadata': {
2153 'add_type': 'nature reservation',
2154 },
2155 'aux_docs': [],
2156 'aux_images': [],
2157 'aux_urls': [],
2158 'changelog': [
2159 {
2160 'author_id': 1,
2161 'datetime': '2023-07-15T19:27:09.463245+00:00',
2162 'description': 'station created',
2163 'new_value': '',
2164 'old_value': '',
2165 'station_id': 2,
2166 'type_of_change': 'created',
2167 },
2168 ],
2169 'codes': [
2170 'SDZ54421',
2171 ],
2172 'coordinate_validation_status': 'not checked',
2173 'coordinates': {
2174 'alt': 293.9,
2175 'lat': 40.65,
2176 'lng': 117.106,
2177 },
2178 'country': 'China',
2179 'globalmeta': {
2180 'climatic_zone_year2016': '6 (warm temperate dry)',
2181 'distance_to_major_road_year2020': -999.0,
2182 'dominant_ecoregion_year2017': '-1 (undefined)',
2183 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
2184 'ecoregion_description_25km_year2017': '',
2185 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
2186 'landcover_description_25km_year2012': '',
2187 'max_population_density_25km_year1990': -1.0,
2188 'max_population_density_25km_year2015': -1.0,
2189 'max_stable_nightlights_25km_year1992': -999.0,
2190 'max_stable_nightlights_25km_year2013': -999.0,
2191 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
2192 'mean_nox_emissions_10km_year2000': -999.0,
2193 'mean_nox_emissions_10km_year2015': -999.0,
2194 'mean_population_density_250m_year1990': -1.0,
2195 'mean_population_density_250m_year2015': -1.0,
2196 'mean_population_density_5km_year1990': -1.0,
2197 'mean_population_density_5km_year2015': -1.0,
2198 'mean_stable_nightlights_1km_year2013': -999.0,
2199 'mean_stable_nightlights_5km_year2013': -999.0,
2200 'mean_topography_srtm_alt_1km_year1994': -999.0,
2201 'mean_topography_srtm_alt_90m_year1994': -999.0,
2202 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
2203 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
2204 'toar1_category': 'unclassified',
2205 'toar2_category': 'suburban',
2206 },
2207 'id': 2,
2208 'name': 'Shangdianzi',
2209 'state': 'Beijing Shi',
2210 'timezone': 'Asia/Shanghai',
2211 'type': 'unknown',
2212 'type_of_area': 'unknown',
2213 },
2214 'variable': {
2215 'cf_standardname': 'mole_fraction_of_ozone_in_air',
2216 'chemical_formula': 'O3',
2217 'displayname': 'Ozone',
2218 'id': 5,
2219 'longname': 'ozone',
2220 'name': 'o3',
2221 'units': 'nmol mol-1',
2222 }
2223 }]
2224 assert response.json() == expected_response
2227 def test_search_with_additional_metadata_unknown(self, client, db):
2228 response = client.get("/search/?additional_metadata->'not_yet_defined'=42")
2229 expected_status_code = 200
2230 assert response.status_code == expected_status_code
2231 expected_response = []
2232 assert response.json() == expected_response
2235 def test_search_with_additional_metadata_station(self, client, db):
2236 response = client.get("/search/?station_additional_metadata->'add_type'=nature reservation")
2237 expected_status_code = 200
2238 assert response.status_code == expected_status_code
2239 expected_response = [{'id': 1,
2240 'label': 'CMA',
2241 'order': 1,
2242 'sampling_frequency': 'hourly',
2243 'aggregation': 'mean',
2244 'data_start_date': '2003-09-07T15:30:00+00:00',
2245 'data_end_date': '2016-12-31T14:30:00+00:00',
2246 'data_origin': 'instrument',
2247 'data_origin_type': 'measurement',
2248 'provider_version': 'N/A',
2249 'sampling_height': 7.0,
2250 'additional_metadata': {"original_units": "ppb"},
2251 'doi': '',
2252 'coverage': -1.0,
2253 'station': {'id': 2,
2254 'codes': ['SDZ54421'],
2255 'name': 'Shangdianzi',
2256 'coordinates': {'lat': 40.65, 'lng': 117.106, 'alt': 293.9},
2257 'coordinate_validation_status': 'not checked',
2258 'country': 'China',
2259 'state': 'Beijing Shi',
2260 'type': 'unknown',
2261 'type_of_area': 'unknown',
2262 'timezone': 'Asia/Shanghai',
2263 'additional_metadata': {'add_type': 'nature reservation'},
2264 'aux_images': [],
2265 'aux_docs': [],
2266 'aux_urls': [],
2267 'globalmeta': {'mean_topography_srtm_alt_90m_year1994': -999.0,
2268 'mean_topography_srtm_alt_1km_year1994': -999.0,
2269 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
2270 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
2271 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
2272 'climatic_zone_year2016': '6 (warm temperate dry)',
2273 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
2274 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
2275 'landcover_description_25km_year2012': '',
2276 'dominant_ecoregion_year2017': '-1 (undefined)',
2277 'ecoregion_description_25km_year2017': '',
2278 'distance_to_major_road_year2020': -999.0,
2279 'mean_stable_nightlights_1km_year2013': -999.0,
2280 'mean_stable_nightlights_5km_year2013': -999.0,
2281 'max_stable_nightlights_25km_year2013': -999.0,
2282 'max_stable_nightlights_25km_year1992': -999.0,
2283 'mean_population_density_250m_year2015': -1.0,
2284 'mean_population_density_5km_year2015': -1.0,
2285 'max_population_density_25km_year2015': -1.0,
2286 'mean_population_density_250m_year1990': -1.0,
2287 'mean_population_density_5km_year1990': -1.0,
2288 'max_population_density_25km_year1990': -1.0,
2289 'mean_nox_emissions_10km_year2015': -999.0,
2290 'mean_nox_emissions_10km_year2000': -999.0,
2291 'toar1_category': 'unclassified',
2292 'toar2_category': 'suburban'},
2293 'changelog': [{'datetime': '2023-07-15T19:27:09.463245+00:00', 'description': 'station created', 'old_value': '', 'new_value': '', 'station_id': 2, 'author_id': 1, 'type_of_change': 'created'}]},
2294 'variable': {'name': 'toluene',
2295 'longname': 'toluene',
2296 'displayname': 'Toluene',
2297 'cf_standardname': 'mole_fraction_of_toluene_in_air',
2298 'units': 'nmol mol-1',
2299 'chemical_formula': 'C7H8',
2300 'id': 7},
2301 'programme': {'id': 0,
2302 'name': '',
2303 'longname': '',
2304 'homepage': '',
2305 'description': ''},
2306 'roles': [{'id': 2,
2307 'role': 'resource provider',
2308 'status': 'active',
2309 'contact': {'id': 4,
2310 'organisation': {'id': 1,
2311 'name': 'UBA',
2312 'longname': 'Umweltbundesamt',
2313 'kind': 'government',
2314 'city': 'Dessau-Roßlau',
2315 'postcode': '06844',
2316 'street_address': 'Wörlitzer Platz 1',
2317 'country': 'Germany',
2318 'homepage': 'https://www.umweltbundesamt.de',
2319 'contact_url': 'mailto:immission@uba.de'}}},
2320 {'id': 3,
2321 'role': 'principal investigator',
2322 'status': 'active',
2323 'contact': {'id': 3,
2324 'person': {'email': 's.schroeder@fz-juelich.de',
2325 'id': 3,
2326 'isprivate': False,
2327 'name': 'Sabine Schröder',
2328 'orcid': '0000-0002-0309-8010',
2329 'phone': '+49-2461-61-6397'
2330 }
2331 }
2332 }]
2333 },
2334 {
2335 'additional_metadata': {
2336 'original_units': 'ppb',
2337 },
2338 'aggregation': 'mean',
2339 'coverage': -1.0,
2340 'data_end_date': '2025-02-25T14:00:00+00:00',
2341 'data_origin': 'instrument',
2342 'data_origin_type': 'measurement',
2343 'data_start_date': '1991-01-01T00:00:00+00:00',
2344 'doi': '',
2345 'id': 18763,
2346 'label': '',
2347 'order': 1,
2348 'programme': {
2349 'description': '',
2350 'homepage': '',
2351 'id': 0,
2352 'longname': '',
2353 'name': '',
2354 },
2355 'provider_version': 'N/A',
2356 'roles': [
2357 {
2358 'contact': {
2359 'id': 5,
2360 'organisation': {
2361 'city': 'Jülich',
2362 'contact_url': 'mailto:toar-data@fz-juelich.de',
2363 'country': 'Germany',
2364 'homepage': 'https://www.fz-juelich.de',
2365 'id': 2,
2366 'kind': 'research',
2367 'longname': 'Forschungszentrum Jülich',
2368 'name': 'FZJ',
2369 'postcode': '52425',
2370 'street_address': 'Wilhelm-Johnen-Straße',
2371 },
2372 },
2373 'id': 1,
2374 'role': 'resource provider',
2375 'status': 'active',
2376 },
2377 ],
2378 'sampling_frequency': 'hourly',
2379 'sampling_height': 7.0,
2380 'station': {
2381 'additional_metadata': {
2382 'add_type': 'nature reservation',
2383 },
2384 'aux_docs': [],
2385 'aux_images': [],
2386 'aux_urls': [],
2387 'changelog': [
2388 {
2389 'author_id': 1,
2390 'datetime': '2023-07-15T19:27:09.463245+00:00',
2391 'description': 'station created',
2392 'new_value': '',
2393 'old_value': '',
2394 'station_id': 2,
2395 'type_of_change': 'created',
2396 },
2397 ],
2398 'codes': [
2399 'SDZ54421',
2400 ],
2401 'coordinate_validation_status': 'not checked',
2402 'coordinates': {
2403 'alt': 293.9,
2404 'lat': 40.65,
2405 'lng': 117.106,
2406 },
2407 'country': 'China',
2408 'globalmeta': {
2409 'climatic_zone_year2016': '6 (warm temperate dry)',
2410 'distance_to_major_road_year2020': -999.0,
2411 'dominant_ecoregion_year2017': '-1 (undefined)',
2412 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
2413 'ecoregion_description_25km_year2017': '',
2414 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
2415 'landcover_description_25km_year2012': '',
2416 'max_population_density_25km_year1990': -1.0,
2417 'max_population_density_25km_year2015': -1.0,
2418 'max_stable_nightlights_25km_year1992': -999.0,
2419 'max_stable_nightlights_25km_year2013': -999.0,
2420 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
2421 'mean_nox_emissions_10km_year2000': -999.0,
2422 'mean_nox_emissions_10km_year2015': -999.0,
2423 'mean_population_density_250m_year1990': -1.0,
2424 'mean_population_density_250m_year2015': -1.0,
2425 'mean_population_density_5km_year1990': -1.0,
2426 'mean_population_density_5km_year2015': -1.0,
2427 'mean_stable_nightlights_1km_year2013': -999.0,
2428 'mean_stable_nightlights_5km_year2013': -999.0,
2429 'mean_topography_srtm_alt_1km_year1994': -999.0,
2430 'mean_topography_srtm_alt_90m_year1994': -999.0,
2431 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
2432 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
2433 'toar1_category': 'unclassified',
2434 'toar2_category': 'suburban',
2435 },
2436 'id': 2,
2437 'name': 'Shangdianzi',
2438 'state': 'Beijing Shi',
2439 'timezone': 'Asia/Shanghai',
2440 'type': 'unknown',
2441 'type_of_area': 'unknown',
2442 },
2443 'variable': {
2444 'cf_standardname': 'mole_fraction_of_ozone_in_air',
2445 'chemical_formula': 'O3',
2446 'displayname': 'Ozone',
2447 'id': 5,
2448 'longname': 'ozone',
2449 'name': 'o3',
2450 'units': 'nmol mol-1',
2451 },
2452 },
2453 {
2454 'additional_metadata': {
2455 'original_units': 'ppb',
2456 },
2457 'aggregation': 'mean',
2458 'coverage': -1.0,
2459 'data_end_date': '2025-02-25T14:00:00+00:00',
2460 'data_origin': 'instrument',
2461 'data_origin_type': 'measurement',
2462 'data_start_date': '1991-01-01T00:00:00+00:00',
2463 'doi': '',
2464 'id': 30890,
2465 'label': '',
2466 'order': 2,
2467 'programme': {
2468 'description': '',
2469 'homepage': '',
2470 'id': 0,
2471 'longname': '',
2472 'name': '',
2473 },
2474 'provider_version': 'N/A',
2475 'roles': [
2476 {
2477 'contact': {
2478 'id': 5,
2479 'organisation': {
2480 'city': 'Jülich',
2481 'contact_url': 'mailto:toar-data@fz-juelich.de',
2482 'country': 'Germany',
2483 'homepage': 'https://www.fz-juelich.de',
2484 'id': 2,
2485 'kind': 'research',
2486 'longname': 'Forschungszentrum Jülich',
2487 'name': 'FZJ',
2488 'postcode': '52425',
2489 'street_address': 'Wilhelm-Johnen-Straße',
2490 },
2491 },
2492 'id': 1,
2493 'role': 'resource provider',
2494 'status': 'active',
2495 },
2496 ],
2497 'sampling_frequency': 'hourly',
2498 'sampling_height': 7.0,
2499 'station': {
2500 'additional_metadata': {
2501 'add_type': 'nature reservation',
2502 },
2503 'aux_docs': [],
2504 'aux_images': [],
2505 'aux_urls': [],
2506 'changelog': [
2507 {
2508 'author_id': 1,
2509 'datetime': '2023-07-15T19:27:09.463245+00:00',
2510 'description': 'station created',
2511 'new_value': '',
2512 'old_value': '',
2513 'station_id': 2,
2514 'type_of_change': 'created',
2515 },
2516 ],
2517 'codes': [
2518 'SDZ54421',
2519 ],
2520 'coordinate_validation_status': 'not checked',
2521 'coordinates': {
2522 'alt': 293.9,
2523 'lat': 40.65,
2524 'lng': 117.106,
2525 },
2526 'country': 'China',
2527 'globalmeta': {
2528 'climatic_zone_year2016': '6 (warm temperate dry)',
2529 'distance_to_major_road_year2020': -999.0,
2530 'dominant_ecoregion_year2017': '-1 (undefined)',
2531 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
2532 'ecoregion_description_25km_year2017': '',
2533 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
2534 'landcover_description_25km_year2012': '',
2535 'max_population_density_25km_year1990': -1.0,
2536 'max_population_density_25km_year2015': -1.0,
2537 'max_stable_nightlights_25km_year1992': -999.0,
2538 'max_stable_nightlights_25km_year2013': -999.0,
2539 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
2540 'mean_nox_emissions_10km_year2000': -999.0,
2541 'mean_nox_emissions_10km_year2015': -999.0,
2542 'mean_population_density_250m_year1990': -1.0,
2543 'mean_population_density_250m_year2015': -1.0,
2544 'mean_population_density_5km_year1990': -1.0,
2545 'mean_population_density_5km_year2015': -1.0,
2546 'mean_stable_nightlights_1km_year2013': -999.0,
2547 'mean_stable_nightlights_5km_year2013': -999.0,
2548 'mean_topography_srtm_alt_1km_year1994': -999.0,
2549 'mean_topography_srtm_alt_90m_year1994': -999.0,
2550 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
2551 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
2552 'toar1_category': 'unclassified',
2553 'toar2_category': 'suburban',
2554 },
2555 'id': 2,
2556 'name': 'Shangdianzi',
2557 'state': 'Beijing Shi',
2558 'timezone': 'Asia/Shanghai',
2559 'type': 'unknown',
2560 'type_of_area': 'unknown',
2561 },
2562 'variable': {
2563 'cf_standardname': 'mole_fraction_of_ozone_in_air',
2564 'chemical_formula': 'O3',
2565 'displayname': 'Ozone',
2566 'id': 5,
2567 'longname': 'ozone',
2568 'name': 'o3',
2569 'units': 'nmol mol-1',
2570 },
2571 },
2572 {
2573 'additional_metadata': {
2574 'original_units': 'ppb',
2575 },
2576 'aggregation': 'mean',
2577 'coverage': -1.0,
2578 'data_end_date': '2025-02-25T14:00:00+00:00',
2579 'data_origin': 'instrument',
2580 'data_origin_type': 'measurement',
2581 'data_start_date': '1991-01-01T00:00:00+00:00',
2582 'doi': '',
2583 'id': 434870,
2584 'label': '',
2585 'order': 2,
2586 'programme': {
2587 'description': '',
2588 'homepage': '',
2589 'id': 0,
2590 'longname': '',
2591 'name': '',
2592 },
2593 'provider_version': 'N/A',
2594 'roles': [
2595 {
2596 'contact': {
2597 'id': 4,
2598 'organisation': {
2599 'city': 'Dessau-Roßlau',
2600 'contact_url': 'mailto:immission@uba.de',
2601 'country': 'Germany',
2602 'homepage': 'https://www.umweltbundesamt.de',
2603 'id': 1,
2604 'kind': 'government',
2605 'longname': 'Umweltbundesamt',
2606 'name': 'UBA',
2607 'postcode': '06844',
2608 'street_address': 'Wörlitzer Platz 1',
2609 },
2610 },
2611 'id': 2,
2612 'role': 'resource provider',
2613 'status': 'active',
2614 },
2615 ],
2616 'sampling_frequency': 'hourly',
2617 'sampling_height': 7.0,
2618 'station': {
2619 'additional_metadata': {
2620 'add_type': 'nature reservation',
2621 },
2622 'aux_docs': [],
2623 'aux_images': [],
2624 'aux_urls': [],
2625 'changelog': [
2626 {
2627 'author_id': 1,
2628 'datetime': '2023-07-15T19:27:09.463245+00:00',
2629 'description': 'station created',
2630 'new_value': '',
2631 'old_value': '',
2632 'station_id': 2,
2633 'type_of_change': 'created',
2634 },
2635 ],
2636 'codes': [
2637 'SDZ54421',
2638 ],
2639 'coordinate_validation_status': 'not checked',
2640 'coordinates': {
2641 'alt': 293.9,
2642 'lat': 40.65,
2643 'lng': 117.106,
2644 },
2645 'country': 'China',
2646 'globalmeta': {
2647 'climatic_zone_year2016': '6 (warm temperate dry)',
2648 'distance_to_major_road_year2020': -999.0,
2649 'dominant_ecoregion_year2017': '-1 (undefined)',
2650 'dominant_landcover_year2012': '11 (Cropland, rainfed, herbaceous cover)',
2651 'ecoregion_description_25km_year2017': '',
2652 'htap_region_tier1_year2010': '11 (MDE Middle East: S. Arabia, Oman, etc, Iran, Iraq)',
2653 'landcover_description_25km_year2012': '',
2654 'max_population_density_25km_year1990': -1.0,
2655 'max_population_density_25km_year2015': -1.0,
2656 'max_stable_nightlights_25km_year1992': -999.0,
2657 'max_stable_nightlights_25km_year2013': -999.0,
2658 'max_topography_srtm_relative_alt_5km_year1994': -999.0,
2659 'mean_nox_emissions_10km_year2000': -999.0,
2660 'mean_nox_emissions_10km_year2015': -999.0,
2661 'mean_population_density_250m_year1990': -1.0,
2662 'mean_population_density_250m_year2015': -1.0,
2663 'mean_population_density_5km_year1990': -1.0,
2664 'mean_population_density_5km_year2015': -1.0,
2665 'mean_stable_nightlights_1km_year2013': -999.0,
2666 'mean_stable_nightlights_5km_year2013': -999.0,
2667 'mean_topography_srtm_alt_1km_year1994': -999.0,
2668 'mean_topography_srtm_alt_90m_year1994': -999.0,
2669 'min_topography_srtm_relative_alt_5km_year1994': -999.0,
2670 'stddev_topography_srtm_relative_alt_5km_year1994': -999.0,
2671 'toar1_category': 'unclassified',
2672 'toar2_category': 'suburban',
2673 },
2674 'id': 2,
2675 'name': 'Shangdianzi',
2676 'state': 'Beijing Shi',
2677 'timezone': 'Asia/Shanghai',
2678 'type': 'unknown',
2679 'type_of_area': 'unknown',
2680 },
2681 'variable': {
2682 'cf_standardname': 'mole_fraction_of_ozone_in_air',
2683 'chemical_formula': 'O3',
2684 'displayname': 'Ozone',
2685 'id': 5,
2686 'longname': 'ozone',
2687 'name': 'o3',
2688 'units': 'nmol mol-1',
2689 }
2690 }]
2691 assert response.json() == expected_response