-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DOP-20049] add PATCH 'v1/locations/{location_id}' endpoint (#101)
* [DOP-20049] add PATCH 'v1/locations/{location_id}' endpoint * [DOP-20049] add test with external_id=None * [DOP-20049] rebase, fix naming * [DOP-20049] remove 'to_exception' method from horizon
- Loading branch information
Showing
12 changed files
with
217 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# SPDX-FileCopyrightText: 2024 MTS PJSC | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
from data_rentgen.exceptions.base import ApplicationError | ||
from data_rentgen.exceptions.entity import EntityNotFoundError | ||
|
||
__all__ = [ | ||
"ApplicationError", | ||
"EntityNotFoundError", | ||
] |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# SPDX-FileCopyrightText: 2024 MTS PJSC | ||
# SPDX-License-Identifier: Apache-2.0 | ||
from typing import Any | ||
|
||
from data_rentgen.exceptions.base import ApplicationError | ||
|
||
|
||
class EntityNotFoundError(ApplicationError): | ||
"""Entity not found. | ||
Examples | ||
-------- | ||
>>> from data_rentgen.exceptions import EntityNotFoundError | ||
>>> raise EntityNotFoundError("User", "username", "test") | ||
Traceback (most recent call last): | ||
data_rentgen.exceptions.entity.EntityNotFoundError: User with username='test' not found | ||
""" | ||
|
||
entity_type: str | ||
"""Entity type""" | ||
|
||
field: str | ||
"""Entity identifier field""" | ||
|
||
value: Any | ||
"""Entity identifier value""" | ||
|
||
def __init__(self, entity_type: str, field: str, value: Any): | ||
self.entity_type = entity_type | ||
self.field = field | ||
self.value = value | ||
|
||
@property | ||
def message(self) -> str: | ||
if self.field is not None: | ||
return f"{self.entity_type} with {self.field}={self.value!r} not found" | ||
return f"{self.entity_type} not found" | ||
|
||
@property | ||
def details(self) -> dict[str, Any]: | ||
return { | ||
"entity_type": self.entity_type, | ||
"field": self.field, | ||
"value": self.value, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
# SPDX-FileCopyrightText: 2024 MTS PJSC | ||
# SPDX-License-Identifier: Apache-2.0 | ||
from data_rentgen.server.errors.schemas.invalid_request import InvalidRequestSchema | ||
from data_rentgen.server.errors.schemas.not_found import NotFoundSchema | ||
|
||
__all__ = [ | ||
"InvalidRequestSchema", | ||
"NotFoundSchema", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# SPDX-FileCopyrightText: 2024 MTS PJSC | ||
# SPDX-License-Identifier: Apache-2.0 | ||
import http | ||
from typing import Any | ||
|
||
from pydantic import BaseModel | ||
from typing_extensions import Literal | ||
|
||
from data_rentgen.exceptions.entity import EntityNotFoundError | ||
from data_rentgen.server.errors.base import BaseErrorSchema | ||
from data_rentgen.server.errors.registration import register_error_response | ||
|
||
|
||
class NotFoundDetailsSchema(BaseModel): | ||
entity_type: str | ||
field: str | ||
value: Any | ||
|
||
|
||
@register_error_response( | ||
exception=EntityNotFoundError, | ||
status=http.HTTPStatus.NOT_FOUND, | ||
) | ||
class NotFoundSchema(BaseErrorSchema): | ||
code: Literal["not_found"] = "not_found" | ||
details: NotFoundDetailsSchema |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
tests/test_server/test_locations/test_patch_locations.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from http import HTTPStatus | ||
|
||
import pytest | ||
from httpx import AsyncClient | ||
from sqlalchemy.ext.asyncio import AsyncSession | ||
|
||
from data_rentgen.db.models import Location | ||
from tests.test_server.utils.enrich import enrich_locations | ||
|
||
pytestmark = [pytest.mark.server, pytest.mark.asyncio] | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"location", | ||
[ | ||
pytest.param({"external_id": None}), | ||
], | ||
indirect=True, | ||
) | ||
async def test_add_loction_external_id( | ||
test_client: AsyncClient, | ||
async_session: AsyncSession, | ||
location: Location, | ||
): | ||
[location] = await enrich_locations([location], async_session) | ||
assert location.external_id is None | ||
|
||
response = await test_client.patch( | ||
f"v1/locations/{location.id}", | ||
json={"external_id": "external_id"}, | ||
) | ||
[location] = await enrich_locations([location], async_session) | ||
|
||
assert response.status_code == HTTPStatus.OK, response.json() | ||
assert response.json() == { | ||
"name": location.name, | ||
"type": location.type, | ||
"addresses": [{"url": address.url} for address in location.addresses], | ||
"external_id": "external_id", | ||
} | ||
|
||
|
||
async def test_update_location_external_id( | ||
test_client: AsyncClient, | ||
async_session: AsyncSession, | ||
location: Location, | ||
): | ||
response = await test_client.patch( | ||
f"v1/locations/{location.id}", | ||
json={"external_id": "new_external_id"}, | ||
) | ||
[location] = await enrich_locations([location], async_session) | ||
|
||
assert response.status_code == HTTPStatus.OK, response.json() | ||
assert response.json() == { | ||
"name": location.name, | ||
"type": location.type, | ||
"addresses": [{"url": address.url} for address in location.addresses], | ||
"external_id": "new_external_id", | ||
} | ||
|
||
|
||
async def test_update_location_not_found( | ||
test_client: AsyncClient, | ||
new_location: Location, | ||
): | ||
response = await test_client.patch( | ||
f"v1/locations/{new_location.id}", | ||
json={"external_id": "new_external_id"}, | ||
) | ||
|
||
assert response.status_code == HTTPStatus.NOT_FOUND, response.json() | ||
assert response.json() == { | ||
"error": { | ||
"code": "not_found", | ||
"details": { | ||
"entity_type": "Location", | ||
"field": "id", | ||
"value": new_location.id, | ||
}, | ||
"message": f"Location with id={new_location.id} not found", | ||
}, | ||
} | ||
|
||
|
||
async def test_update_location_writing_null_to_external_id( | ||
test_client: AsyncClient, | ||
location: Location, | ||
): | ||
response = await test_client.patch( | ||
f"v1/locations/{location.id}", | ||
json={"external_id": None}, | ||
) | ||
|
||
assert response.status_code == HTTPStatus.OK, response.json() | ||
assert response.json() == { | ||
"name": location.name, | ||
"type": location.type, | ||
"addresses": [{"url": address.url} for address in location.addresses], | ||
"external_id": None, | ||
} |