Skip to content

Commit

Permalink
WIP: Add some types; Add tests for creating geostores
Browse files Browse the repository at this point in the history
  • Loading branch information
dmannarino committed Jan 21, 2025
1 parent e81934f commit e92968b
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 7 deletions.
2 changes: 1 addition & 1 deletion app/routes/geostore/geostore.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ async def add_new_geostore(
If request follows RW style forward to RW, otherwise create in Data API
"""
if isinstance(request, RWGeostoreIn):
result: RWGeostoreResponse = await create_rw_geostore(request.dict(), x_api_key)
result: RWGeostoreResponse = await create_rw_geostore(request, x_api_key)
return result
# Otherwise, meant for GFW Data API geostore
try:
Expand Down
9 changes: 5 additions & 4 deletions app/utils/rw_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
RWAdminListResponse,
RWCalcAreaForGeostoreResponse,
RWFindByIDsResponse,
RWGeostoreIn,
RWGeostoreResponse,
RWViewGeostoreResponse,
)
Expand Down Expand Up @@ -197,19 +198,19 @@ async def signup(name: str, email: str) -> User:


async def create_rw_geostore(
payload: Dict, x_api_key: str | None = None
payload: RWGeostoreIn, x_api_key: str | None = None
) -> RWGeostoreResponse:
url = f"{RW_API_URL}/v1/geostore"

async with AsyncClient() as client:
if x_api_key is not None:
response: HTTPXResponse = await client.post(
url, json=payload, headers={"x-api-key": x_api_key}
url, json=payload.dict(), headers={"x-api-key": x_api_key}
)
else:
response = await client.post(url, json=payload)
response = await client.post(url, json=payload.dict())

if response.status_code == 200:
if response.status_code == 201:
return RWGeostoreResponse.parse_obj(response.json())
else:
raise HTTPException(response.status_code, response.text)
Expand Down
210 changes: 208 additions & 2 deletions tests_v2/unit/app/routes/geostore/test_geostore.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from functools import partial
from unittest.mock import AsyncMock, MagicMock

import pytest
from _pytest.monkeypatch import MonkeyPatch
from httpx import AsyncClient, MockTransport, Request, Response

from app.models.pydantic.geostore import RWGeostoreResponse
from app.crud import geostore as crud_geostore
from app.models.pydantic.geostore import Geostore, RWGeostoreResponse
from app.routes.geostore import geostore
from app.utils import rw_api

Expand All @@ -18,11 +20,65 @@
{
"geostoreId": "23b11bc0d0b417d3af08bca543fc2d0b", # pragma: allowlist secret
"iso": "ABW",
}, # pragma: allowlist secret
},
]
}


example_admin_geostore_snipped = {
"data": {
"type": "geoStore",
"id": "851679102625f53c3254df99efbfba17", # pragma: allowlist secret
"attributes": {
"geojson": {
"crs": {},
"features": [
{
"geometry": {
"coordinates": [
[
[
[-102.44799041748, 21.6610717773437],
[-102.455261230469, 21.6625995635987],
[-102.460227966309, 21.6666717529297],
[-102.443138122558, 21.6583995819092],
[-102.44799041748, 21.6610717773437],
[-102.44799041748, 21.6610717773437],
]
]
],
"type": "MultiPolygon",
},
"properties": None,
"type": "Feature",
}
],
"type": "FeatureCollection",
},
"hash": "851679102625f53c3254df99efbfba17", # pragma: allowlist secret
"provider": {},
"areaHa": 168384.12865462166,
"bbox": [
-102.61302947998,
21.6217498779298,
-101.896156311035,
22.0676307678222,
],
"lock": False,
"info": {
"use": {},
"simplifyThresh": 0.00005,
"gadm": "3.6",
"name": "Aguascalientes",
"id2": 1,
"id1": 1,
"iso": "MEX",
},
},
}
}


example_geostore_resp = {
"data": {
"type": "geoStore",
Expand Down Expand Up @@ -63,6 +119,64 @@
}


create_rw_geostore_payload = {
"geojson": {
"type": "MultiPolygon",
"coordinates": [[[[8, 51], [11, 55], [12, 49], [8, 52]]]],
}
}


create_gfw_geostore_payload = {
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[[8, 51], [11, 55], [12, 49], [8, 52]]]],
}
}

create_rw_geostore_response = {
"data": {
"type": "geoStore",
"id": "b73a4b48eb305110b8bfa604fe58df82", # pragma: allowlist secret
"attributes": {
"geojson": {
"crs": {},
"type": "FeatureCollection",
"features": [
{
"geometry": {
"coordinates": [[[[8, 51], [11, 55], [12, 49], [8, 51]]]],
"type": "MultiPolygon",
},
"type": "Feature",
"properties": None,
}
],
},
"hash": "b73a4b48eb305110b8bfa604fe58df82", # pragma: allowlist secret
"provider": {},
"areaHa": 8354467.362218728,
"bbox": [8, 49, 12, 55],
"lock": False,
"info": {"use": {}},
},
}
}


create_gfw_geostore_data = {
"created_on": "2025-01-21T15:24:10.315976",
"updated_on": "2025-01-21T15:24:10.315986",
"gfw_geostore_id": "db2b4428-bad2-fc94-1ea8-041597dc482c",
"gfw_geojson": {
"type": "MultiPolygon",
"coordinates": [[[[8, 51], [11, 55], [12, 49], [8, 52]]]],
},
"gfw_area__ha": 8640517.2263933,
"gfw_bbox": [8.0, 49.0, 12.0, 55.0],
}


@pytest.mark.asyncio
async def test_wdpa_geostore_mock_helper(
async_client: AsyncClient, monkeypatch: MonkeyPatch
Expand Down Expand Up @@ -95,3 +209,95 @@ async def mock_resp_func(request: Request) -> Response:

assert response.json() == example_geostore_resp
assert response.status_code == 200


@pytest.mark.asyncio
async def test_get_admin_geostore(async_client: AsyncClient, monkeypatch: MonkeyPatch):
async def mock_resp_func(request: Request) -> Response:
return Response(status_code=200, json=example_admin_geostore_snipped)

transport = MockTransport(mock_resp_func)

mocked_client = partial(AsyncClient, transport=transport)
monkeypatch.setattr(rw_api, "AsyncClient", mocked_client)
response = await async_client.get("/geostore/admin/MEX/1/1")

assert response.json() == example_admin_geostore_snipped
assert response.status_code == 200


@pytest.mark.asyncio
async def test_add_geostore_rw_branch(
async_client: AsyncClient, monkeypatch: MonkeyPatch
):
url = "/geostore"

mock_create_rw_geostore = AsyncMock(
return_value=RWGeostoreResponse(**create_rw_geostore_response),
spec=geostore.create_rw_geostore,
)
monkeypatch.setattr(geostore, "create_rw_geostore", mock_create_rw_geostore)

mock_geostore_obj = MagicMock(spec=Geostore)
mock_create_gfw_geostore = AsyncMock(
return_value=mock_geostore_obj, spec=crud_geostore.create_user_area
)
monkeypatch.setattr(crud_geostore, "create_user_area", mock_create_gfw_geostore)

_ = await async_client.post(
url, json=create_rw_geostore_payload, follow_redirects=True
)

assert mock_create_rw_geostore.called is True
assert mock_create_gfw_geostore.called is False


@pytest.mark.asyncio
async def test_add_geostore_gfw_branch(
async_client: AsyncClient, monkeypatch: MonkeyPatch
):
url = "/geostore"

mock_create_rw_geostore = AsyncMock(
return_value=RWGeostoreResponse(**create_rw_geostore_response),
spec=geostore.create_rw_geostore,
)
monkeypatch.setattr(geostore, "create_rw_geostore", mock_create_rw_geostore)

mock_create_gfw_geostore = AsyncMock(
return_value=create_gfw_geostore_data, spec=crud_geostore.create_user_area
)
monkeypatch.setattr(crud_geostore, "create_user_area", mock_create_gfw_geostore)

_ = await async_client.post(
url, json=create_gfw_geostore_payload, follow_redirects=True
)

assert mock_create_rw_geostore.called is False
assert mock_create_gfw_geostore.called is True


# @pytest.mark.asyncio
# async def test_get_geostore_rw_branch(
# async_client: AsyncClient, monkeypatch: MonkeyPatch
# ):
# url = "/geostore/88db597b6bcd096fb80d1542cdc442be"
#
# mock_proxy_get_geostore = AsyncMock(
# return_value=Response(status_code=200),
# spec=geostore.proxy_get_geostore
# )
#
# monkeypatch.setattr(geostore, "proxy_get_geostore", mock_proxy_get_geostore)
#
# response = await async_client.post(
# url,
# json=RWGeostoreIn(**create_rw_geostore_payload).dict(),
# follow_redirects=True
# )
#
# assert response.json() == create_rw_geostore_output
# assert response.status_code == 200
#
#
#

0 comments on commit e92968b

Please sign in to comment.