def test_get_all_observation_species_counts(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations/species_counts"), [ { "json": load_sample_data( "get_all_observation_species_counts_page1.json"), "status_code": 200, }, { "json": load_sample_data( "get_all_observation_species_counts_page2.json"), "status_code": 200, }, ], ) response = get_all_observation_species_counts(user_login="******", quality_grade="research") first_result = response[0] last_result = response[-1] assert first_result["count"] == 19 assert first_result["taxon"]["id"] == 27805 assert first_result["taxon"]["name"] == "Notophthalmus viridescens" assert last_result["count"] == 1 assert last_result["taxon"]["id"] == 39556 assert last_result["taxon"]["name"] == "Apalone spinifera"
def test_search(requests_mock): """Simulate /search results with one of each record type""" requests_mock.get( f'{API_V1_BASE_URL}/search', json=load_sample_data('get_search.json'), status_code=200, ) response = search([8348, 6432]) taxon_result = response['results'][0] place_result = response['results'][1] project_result = response['results'][2] user_result = response['results'][3] assert all( [isinstance(result['score'], float) for result in response['results']]) # Mainly just need to test type conversions assert taxon_result['type'] == 'Taxon' assert isinstance(taxon_result['record']['created_at'], datetime) assert place_result['type'] == 'Place' assert isinstance(place_result['record']['location'][0], float) assert isinstance(place_result['record']['location'][1], float) assert project_result['type'] == 'Project' assert isinstance(project_result['record']['last_post_at'], datetime) assert user_result['type'] == 'User' assert isinstance(user_result['record']['created_at'], datetime)
def test_get_non_existent_observation(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations"), json=load_sample_data("get_nonexistent_observation.json"), status_code=200, ) with pytest.raises(ObservationNotFound): get_observation(observation_id=99999999)
def test_to_gpx(): observations = load_sample_data('observation.json') gpx_xml = to_gpx(observations) gpx_dict = xmltodict.parse(gpx_xml) point = gpx_dict['gpx']['trk']['trkseg']['trkpt'] assert point['@lat'] == '50.646894' and point['@lon'] == '4.360086' assert point['time'] == '2018-09-05T14:06:00+0100' assert 'Lixus bardanae' in point['cmt'] and 'Sep 05, 2018' in point['cmt'] assert point['link']['@href'].startswith('https://static.inaturalist.org/photos/')
def test_to_geojson__custom_properties(): observations = load_sample_data('observation.json') geojson = to_geojson(observations, properties=['taxon.name', 'taxon.rank']) feature = geojson['features'][0] assert feature['properties']['taxon.name'] == 'Lixus bardanae' assert feature['properties']['taxon.rank'] == 'species' assert 'id' not in feature['properties'] and 'taxon.id' not in feature[ 'properties'] assert isinstance(feature, Feature) assert feature.is_valid
def test_create_observation(requests_mock): requests_mock.post( urljoin(INAT_BASE_URL, "observations.json"), json=load_sample_data("create_observation_result.json"), status_code=200, ) r = create_observation(species_guess="Pieris rapae", access_token="valid token") assert len(r) == 1 # We added a single one assert r[0]["latitude"] is None assert r[0]["taxon_id"] == 55626 # Pieris Rapae @ iNaturalist
def test_add_photo_to_observation(requests_mock): requests_mock.post( urljoin(INAT_BASE_URL, "observation_photos"), json=load_sample_data("add_photo_to_observation.json"), status_code=200, ) response = add_photo_to_observation(1234, BytesIO(), access_token="token") assert response["id"] == 1234 assert response["created_at"] == "2020-09-24T21:06:16.964-05:00" assert response["photo"]["native_username"] == "username"
def test_upload_sounds(requests_mock): requests_mock.post( f'{API_V0_BASE_URL}/observation_sounds', json=load_sample_data('post_observation_sounds.json'), status_code=200, ) response = upload_sounds(233946, BytesIO(), access_token='token') assert response[0]['id'] == 233946 assert response[0]['created_at'] == '2021-05-30T17:36:40.286-05:00' assert response[0]['sound']['file_content_type'] == 'audio/mpeg'
def test_upload_photos(requests_mock): requests_mock.post( f'{API_V0_BASE_URL}/observation_photos', json=load_sample_data('post_observation_photos.json'), status_code=200, ) response = upload_photos(1234, BytesIO(), access_token='token') assert response[0]['id'] == 1234 assert response[0]['created_at'] == '2020-09-24T21:06:16.964-05:00' assert response[0]['photo']['native_username'] == 'username'
def test_get_taxa_map_layers(requests_mock): requests_mock.get( f'{API_V1_BASE_URL}/taxa/47588/map_layers', json=load_sample_data('get_taxa_map_layers.json'), status_code=200, ) response = get_taxa_map_layers(47588) assert response['gbif_id'] == 2820380 assert response['gbif_url'] == 'https://www.gbif.org/species/2820380' assert response['ranges'] is False assert response['listed_places'] is True
def test_to_geojson(): observations = load_sample_data('observation.json') geojson = to_geojson(observations) feature = geojson['features'][0] assert isinstance(geojson, FeatureCollection) assert geojson.is_valid assert feature['geometry']['coordinates'] == [4.360086, 50.646894] assert feature['properties']['id'] == 16227955 assert feature['properties']['taxon.id'] == 493595 assert isinstance(feature, Feature) assert feature.is_valid
def test_get_identifications_by_id(requests_mock): # Not much to test here, pretty much exactly the same as get_identifications() mock_response = load_sample_data('get_identifications.json') mock_response['results'] = [mock_response['results'][0]] requests_mock.get( f'{API_V1_BASE_URL}/identifications/155554373', json=mock_response, status_code=200, ) response = get_identifications_by_id(155554373) assert response['results'][0]['id'] == 155554373
def test_get_observation(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations"), json=load_sample_data("get_observation.json"), status_code=200, ) obs_data = get_observation(observation_id=16227955) assert obs_data["quality_grade"] == "research" assert obs_data["id"] == 16227955 assert obs_data["user"]["login"] == "niconoe" assert len(obs_data["photos"]) == 2
def test_get_geojson_observations(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations"), json=load_sample_data("get_observation.json"), status_code=200, ) geojson = get_geojson_observations(observation_id=16227955) feature = geojson["features"][0] assert feature["geometry"]["coordinates"] == [4.360086, 50.646894] assert feature["properties"]["id"] == 16227955 assert feature["properties"]["taxon_id"] == 493595
def test_create_observation(requests_mock): requests_mock.post( f'{API_V0_BASE_URL}/observations.json', json=load_sample_data('create_observation_result.json'), status_code=200, ) response = create_observation(species_guess='Pieris rapae', observed_on_string='2021-09-09', access_token='valid token') assert len(response) == 1 assert response[0]['latitude'] is None assert response[0]['taxon_id'] == 55626
def test_get_observation_species_counts(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations/species_counts"), json=load_sample_data("get_observation_species_counts.json"), status_code=200, ) response = get_observation_species_counts(user_login="******", quality_grade="research") first_result = response["results"][0] assert first_result["count"] == 31 assert first_result["taxon"]["id"] == 48484 assert first_result["taxon"]["name"] == "Harmonia axyridis"
def test_get_geojson_observations__custom_properties(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations"), json=load_sample_data("get_observation.json"), status_code=200, ) properties = ["taxon_name", "taxon_rank"] geojson = get_geojson_observations(observation_id=16227955, properties=properties) print(geojson) feature = geojson["features"][0] assert feature["properties"]["taxon_name"] == "Lixus bardanae" assert feature["properties"]["taxon_rank"] == "species" assert "id" not in feature["properties"] and "taxon_id" not in feature["properties"]
def test_get_all_observations(sleep, requests_mock): # Make response appear as though there are more pages page_1 = load_sample_data("get_observations_node_page1.json") page_1["total_results"] = PER_PAGE_RESULTS + 1 page_2 = load_sample_data("get_observations_node_page2.json") requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "observations"), [ { "json": page_1, "status_code": 200 }, { "json": page_2, "status_code": 200 }, ], ) observations = get_all_observations(id=[57754375, 57707611]) assert type(observations) is list assert len(observations) == 2
def test_get_projects_by_id(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "projects/8348,6432"), json=load_sample_data("get_projects_by_id.json"), status_code=200, ) response = get_projects_by_id([8348, 6432]) first_result = response["results"][0] assert response["total_results"] == len(response["results"]) == 2 assert first_result["id"] == 8348 assert first_result[ "title"] == "Tucson High Native and Invasive Species Inventory" assert first_result["place_id"] == 96103 assert first_result["location"] == [32.2264416406, -110.9617278383]
def test_create_observation__with_datetime(post, requests_mock): """Just test that request param aliases work. Datetimes are converted to strings separately in prepare_request(). """ requests_mock.post( f'{API_V0_BASE_URL}/observations.json', json=load_sample_data('create_observation_result.json'), status_code=200, ) now = datetime.now() create_observation(species_guess='Pieris rapae', observed_on=now, access_token='valid token') request_params = post.call_args[1]['json']['observation'] assert request_params['observed_on_string'] == now
def test_get_places_autocomplete(requests_mock): requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "places/autocomplete"), json=load_sample_data("get_places_autocomplete.json"), status_code=200, ) response = get_places_autocomplete("springbok") result = response["results"][0] assert response["total_results"] == len(response["results"]) == 1 assert result["id"] == 93735 assert result["name"] == "Springbok" assert result["bbox_area"] == 0.000993854049 assert result["location"] == [-29.665119, 17.88583] assert len(result["ancestor_place_ids"]) == 4
def test_get_taxa_by_id(requests_mock): taxon_id = 70118 requests_mock.get( f'{API_V1_BASE_URL}/taxa/{taxon_id}', json=load_sample_data('get_taxa_by_id.json'), status_code=200, ) response = get_taxa_by_id(taxon_id) result = response['results'][0] assert response['total_results'] == len(response['results']) == 1 assert result['id'] == taxon_id assert result['name'] == 'Nicrophorus vespilloides' assert result['rank'] == 'species' assert result['is_active'] is True assert len(result['ancestors']) == 12
def test_get_taxa_by_id(requests_mock): taxon_id = 70118 requests_mock.get( urljoin(INAT_NODE_API_BASE_URL, "taxa/" + str(taxon_id)), json=load_sample_data("get_taxa_by_id.json"), status_code=200, ) response = get_taxa_by_id(taxon_id) result = response["results"][0] assert response["total_results"] == len(response["results"]) == 1 assert result["id"] == taxon_id assert result["name"] == "Nicrophorus vespilloides" assert result["rank"] == "species" assert result["is_active"] is True assert len(result["ancestors"]) == 12
def test_update_observation(requests_mock): requests_mock.put( "https://www.inaturalist.org/observations/17932425.json", json=load_sample_data("update_observation_result.json"), status_code=200, ) p = { "ignore_photos": 1, "observation": {"description": "updated description v2 !"}, } r = update_observation(observation_id=17932425, params=p, access_token="valid token") # If all goes well we got a single element representing the updated observation, enclosed in a list. assert len(r) == 1 assert r[0]["id"] == 17932425 assert r[0]["description"] == "updated description v2 !"
def test_get_taxa_autocomplete(requests_mock): requests_mock.get( f'{API_V1_BASE_URL}/taxa/autocomplete', json=load_sample_data('get_taxa_autocomplete.json'), status_code=200, ) response = get_taxa_autocomplete(q='vespi') first_result = response['results'][0] assert len(response['results']) == response['total_results'] == 10 assert first_result['matched_term'] == 'Vespidae' assert first_result['id'] == 52747 assert first_result['name'] == 'Vespidae' assert first_result['rank'] == 'family' assert first_result['is_active'] is True assert len(first_result['ancestor_ids']) == 11
def test_create_observation(requests_mock): requests_mock.post( "https://www.inaturalist.org/observations.json", json=load_sample_data("create_observation_result.json"), status_code=200, ) params = { "observation": {"species_guess": "Pieris rapae"}, } r = create_observations(params=params, access_token="valid token") assert len(r) == 1 # We added a single one assert ( r[0]["latitude"] is None ) # We have the field, but it's none since we didn't submitted anything assert r[0]["taxon_id"] == 55626 # Pieris Rapae @ iNaturalist
def test_update_observation(requests_mock): requests_mock.put( urljoin(INAT_BASE_URL, "observations/17932425.json"), json=load_sample_data("update_observation_result.json"), status_code=200, ) params = { "ignore_photos": 1, "description": "updated description v2 !", } r = update_observation(17932425, access_token="valid token", **params) # If all goes well we got a single element representing the updated observation, enclosed in a list. assert len(r) == 1 assert r[0]["id"] == 17932425 assert r[0]["description"] == "updated description v2 !"
def test_get_taxa(requests_mock): params = {'q': 'vespi', 'rank': 'genus,subgenus,species'} requests_mock.get( f'{API_V1_BASE_URL}/taxa?{urlencode(params)}', json=load_sample_data('get_taxa.json'), status_code=200, ) response = get_taxa(q='vespi', rank=['genus', 'subgenus', 'species']) first_result = response['results'][0] assert len(response['results']) == response['total_results'] == 30 assert first_result['id'] == 70118 assert first_result['name'] == 'Nicrophorus vespilloides' assert first_result['rank'] == 'species' assert first_result['is_active'] is True assert len(first_result['ancestor_ids']) == 14
def test_get_user_by_id(requests_mock): user_id = 1 requests_mock.get( f'{API_V1_BASE_URL}/users/{user_id}', json=load_sample_data('get_user_by_id.json'), status_code=200, ) user = get_user_by_id(user_id) assert user['id'] == user_id assert user['created_at'] == datetime(2008, 3, 20, 21, 15, 42, tzinfo=tzutc()) assert user['spam'] is False
def test_put_observation_field_values(requests_mock): requests_mock.put( "https://www.inaturalist.org/observation_field_values/31", json=load_sample_data("put_observation_field_value_result.json"), status_code=200, ) r = put_observation_field_values( observation_id=18166477, observation_field_id=31, # Animal behavior value="fouraging", access_token="valid token", ) assert r["id"] == 31 assert r["observation_field_id"] == 31 assert r["observation_id"] == 18166477 assert r["value"] == "fouraging"