From 97ee4376c162fa0acf804de158c72d1583cb4713 Mon Sep 17 00:00:00 2001 From: Moritz Schott Date: Mon, 8 Jul 2024 11:26:48 +0200 Subject: [PATCH] fix(response): assert tags are exploded even if not present in the response (#159) by None-filling them closes #149 --- ohsome/response.py | 2 +- ohsome/test/conftest.py | 22 ++++++++++ ohsome/test/test_response.py | 80 ++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/ohsome/response.py b/ohsome/response.py index ebc02ea..c6880b1 100644 --- a/ohsome/response.py +++ b/ohsome/response.py @@ -94,7 +94,7 @@ def _as_geodataframe( for feature in self.data["features"]: properties = feature["properties"] tags = {} - new_properties = {} + new_properties = {k: None for k in explode_tags} for k in properties.keys(): if ( (k.startswith("@")) diff --git a/ohsome/test/conftest.py b/ohsome/test/conftest.py index 9b460f5..2b7ee16 100644 --- a/ohsome/test/conftest.py +++ b/ohsome/test/conftest.py @@ -4,10 +4,14 @@ import logging from unittest.mock import patch, PropertyMock +import geopandas as gpd import pytest +from requests import Response +from shapely import Point from urllib3 import Retry import ohsome +from ohsome import OhsomeResponse logger = logging.getLogger(__name__) @@ -95,3 +99,21 @@ def vcr_config(): "headers", ] } + + +@pytest.fixture() +def dummy_ohsome_response() -> OhsomeResponse: + """Mocked ohsome response with a single point geometry.""" + test_gdf = gpd.GeoDataFrame( + data={ + "highway": ["primary"], + "width": ["10"], + "@snapshotTimestamp": ["2024-01-01"], + "@osmId": ["node/1234"], + }, + geometry=[Point(0, 0)], + crs="EPSG:4326", + ) + response = Response() + response._content = test_gdf.to_json().encode() + return OhsomeResponse(response=response) diff --git a/ohsome/test/test_response.py b/ohsome/test/test_response.py index 69a9692..e1514d4 100644 --- a/ohsome/test/test_response.py +++ b/ohsome/test/test_response.py @@ -2,10 +2,13 @@ # -*- coding: utf-8 -*- """Tests for ohsome API response""" import warnings +from datetime import datetime import geopandas as gpd import pandas as pd import pytest +from geopandas.testing import assert_geodataframe_equal +from shapely import Point @pytest.mark.vcr @@ -463,3 +466,80 @@ def test_all_columns_with_timestamps_to_be_without_timezone(base_client): assert at_timestamp.tz is None assert timestamp.tz is None assert at_snapshotTimestamp.tz is None + + +def test_explode_tags(dummy_ohsome_response): + """Test if the explode_tags parameter explodes tags.""" + expected_df = gpd.GeoDataFrame( + data={ + "highway": ["primary"], + "@other_tags": [{"width": "10"}], + "@snapshotTimestamp": [datetime(2024, 1, 1)], + "@osmId": ["node/1234"], + }, + geometry=[Point(0, 0)], + crs="EPSG:4326", + ) + + computed_df = dummy_ohsome_response.as_dataframe( + explode_tags=("highway",), multi_index=False + ) + + assert_geodataframe_equal(computed_df, expected_df, check_like=True) + + +def test_explode_tags_none(dummy_ohsome_response): + """Test if the explode_tags parameter can be set to explode all (to get previous behaviour).""" + expected_df = gpd.GeoDataFrame( + data={ + "highway": ["primary"], + "width": ["10"], + "@snapshotTimestamp": [datetime(2024, 1, 1)], + "@osmId": ["node/1234"], + }, + geometry=[Point(0, 0)], + crs="EPSG:4326", + ) + + computed_df = dummy_ohsome_response.as_dataframe( + explode_tags=None, multi_index=False + ) + + assert_geodataframe_equal(computed_df, expected_df, check_like=True) + + +def test_explode_tags_empy(dummy_ohsome_response): + """Test if explode_tags parameter can be disabled.""" + expected_df = gpd.GeoDataFrame( + data={ + "@other_tags": [{"width": "10", "highway": "primary"}], + "@snapshotTimestamp": [datetime(2024, 1, 1)], + "@osmId": ["node/1234"], + }, + geometry=[Point(0, 0)], + crs="EPSG:4326", + ) + + computed_df = dummy_ohsome_response.as_dataframe(explode_tags=(), multi_index=False) + + assert_geodataframe_equal(computed_df, expected_df, check_like=True) + + +def test_explode_tags_missing_in_response(dummy_ohsome_response): + """Test if the explode_tags keys are always present in the result, even if they are not part of the response.""" + expected_df = gpd.GeoDataFrame( + data={ + "this_key_does_not_exist": [None], + "@other_tags": [{"width": "10", "highway": "primary"}], + "@snapshotTimestamp": [datetime(2024, 1, 1)], + "@osmId": ["node/1234"], + }, + geometry=[Point(0, 0)], + crs="EPSG:4326", + ) + + computed_df = dummy_ohsome_response.as_dataframe( + explode_tags=("this_key_does_not_exist",), multi_index=False + ) + + assert_geodataframe_equal(computed_df, expected_df, check_like=True)