Skip to content

Commit

Permalink
Add e2e tests for image post #29
Browse files Browse the repository at this point in the history
  • Loading branch information
joelvdavies committed Oct 7, 2024
1 parent 9b971fc commit da51c18
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 6 deletions.
2 changes: 1 addition & 1 deletion object_storage_api/routers/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,6 @@ def create_image(
image_metadata = ImagePostMetadataSchema(entity_id=entity_id, title=title, description=description)

logger.debug("Image metadata: %s", image_metadata)
logger.debug("Image data: %s", upload_file)
logger.debug("Image upload file: %s", upload_file)

return image_service.create(image_metadata, upload_file)
1 change: 1 addition & 0 deletions object_storage_api/schemas/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ class ImageSchema(CreatedModifiedSchemaMixin, ImagePostMetadataSchema):
"""

id: str = Field(description="ID of the image")
file_name: str = Field(description="File name of the image")
2 changes: 1 addition & 1 deletion object_storage_api/stores/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def upload(self, image_id: str, image_metadata: ImagePostMetadataSchema, upload_
"""
Uploads a given image to object storage.
:param image_id: ID of the attachment to generate the URL for.
:param image_id: ID of the image being uploaded.
:param image_metadata: Metadata of the image to be uploaded.
:param upload_file: Upload file of the image to be uploaded.
:return: Object key of the image.
Expand Down
Binary file added test/e2e/files/image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 90 additions & 0 deletions test/e2e/test_image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""
End-to-End tests for the image router.
"""

from test.mock_data import (
IMAGE_GET_DATA_ALL_VALUES,
IMAGE_GET_DATA_REQUIRED_VALUES_ONLY,
IMAGE_POST_METADATA_DATA_ALL_VALUES,
IMAGE_POST_METADATA_DATA_REQUIRED_VALUES_ONLY,
)
from typing import Optional

import pytest
from fastapi.testclient import TestClient
from httpx import Response


class CreateDSL:
"""Base class for create tests."""

test_client: TestClient

_post_response_image: Response
_upload_response_image: Response

@pytest.fixture(autouse=True)
def setup(self, test_client):
"""Setup fixtures"""

self.test_client = test_client

def post_image(self, image_post_metadata_data: dict) -> Optional[str]:
"""
Posts an image with the given metadata and a test image file and returns the id of the created image if
successful.
:param image_post_metadata_data: Dictionary containing the image metadata data as would be required for an
`ImagePostMetadataSchema`.
:return: ID of the created image (or `None` if not successful).
"""

with open("test/e2e/files/image.jpg", mode="rb") as file:
self._post_response_image = self.test_client.post(
"/images", data={**image_post_metadata_data}, files={"upload_file": file}
)
return self._post_response_image.json()["id"] if self._post_response_image.status_code == 201 else None

def check_post_image_success(self, expected_image_get_data: dict) -> None:
"""
Checks that a prior call to `post_image` gave a successful response with the expected data returned.
:param expected_image_get_data: Dictionary containing the expected image data returned as would be
required for an `ImageSchema`.
"""

assert self._post_response_image.status_code == 201
assert self._post_response_image.json() == {**expected_image_get_data, "file_name": "image.jpg"}

def check_post_image_failed_with_detail(self, status_code: int, detail: str) -> None:
"""
Checks that a prior call to `post_image` gave a failed response with the expected code and error message.
:param status_code: Expected status code of the response.
:param detail: Expected detail given in the response.
"""

assert self._post_response_image.status_code == status_code
assert self._post_response_image.json()["detail"] == detail


class TestCreate(CreateDSL):
"""Tests for creating an image."""

def test_create_with_only_required_values_provided(self):
"""Test creating an image with only required values provided."""

self.post_image(IMAGE_POST_METADATA_DATA_REQUIRED_VALUES_ONLY)
self.check_post_image_success(IMAGE_GET_DATA_REQUIRED_VALUES_ONLY)

def test_create_with_all_values_provided(self):
"""Test creating an image with all values provided."""

self.post_image(IMAGE_POST_METADATA_DATA_ALL_VALUES)
self.check_post_image_success(IMAGE_GET_DATA_ALL_VALUES)

def test_create_with_invalid_entity_id(self):
"""Test creating an image with an invalid `entity_id`."""

self.post_image({**IMAGE_POST_METADATA_DATA_REQUIRED_VALUES_ONLY, "entity_id": "invalid-id"})
self.check_post_image_failed_with_detail(422, "Invalid `entity_id` given")
24 changes: 22 additions & 2 deletions test/mock_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,35 @@

# ---------------------------- IMAGES -----------------------------

IMAGE_POST_METADATA_DATA_ALL_VALUES = {
IMAGE_POST_METADATA_DATA_REQUIRED_VALUES_ONLY = {
"entity_id": str(ObjectId()),
"file_name": "report.txt",
}

IMAGE_GET_DATA_REQUIRED_VALUES_ONLY = {
**IMAGE_POST_METADATA_DATA_REQUIRED_VALUES_ONLY,
**CREATED_MODIFIED_GET_DATA_EXPECTED,
"id": ANY,
"file_name": "image.jpg",
"title": None,
"description": None,
}

IMAGE_POST_METADATA_DATA_ALL_VALUES = {
**IMAGE_POST_METADATA_DATA_REQUIRED_VALUES_ONLY,
"title": "Report Title",
"description": "A damage report.",
}

IMAGE_IN_DATA_ALL_VALUES = {
**IMAGE_POST_METADATA_DATA_ALL_VALUES,
"id": str(ObjectId()),
"file_name": "image.jpg",
"object_key": "images/65df5ee771892ddcc08bd28f/65e0a624d64aaae884abaaee",
}

IMAGE_GET_DATA_ALL_VALUES = {
**IMAGE_POST_METADATA_DATA_ALL_VALUES,
**CREATED_MODIFIED_GET_DATA_EXPECTED,
"id": ANY,
"file_name": "image.jpg",
}
2 changes: 1 addition & 1 deletion test/unit/services/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def mock_create(self, image_post_metadata_data: dict) -> None:
"""
Mocks repo & store methods appropriately to test the `create` service method.
:param image_post_metadata_data: Dictionary containing the image data as would be required for an
:param image_post_metadata_data: Dictionary containing the image metadata data as would be required for an
`ImagePostMetadataSchema`.
"""

Expand Down
2 changes: 1 addition & 1 deletion test/unit/stores/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def mock_upload(self, image_post_metadata_data: dict) -> None:
"""
Mocks object store methods appropriately to test the `upload` store method.
:param image_post_metadata_data: Dictionary containing the image data as would be required for an
:param image_post_metadata_data: Dictionary containing the image metadata data as would be required for an
`ImagePostMetadataSchema`.
"""

Expand Down

0 comments on commit da51c18

Please sign in to comment.