"""Tests for asset_upload logic module.""" from contextlib import nullcontext from typing import Any, ContextManager from unittest.mock import MagicMock, patch import pytest from flexmock import flexmock from sqlalchemy.exc import SQLAlchemyError from werkzeug.exceptions import NotFound from assets.constants import api, error from assets.logic import asset_upload from assets.models import asset_upload as asset_upload_model @pytest.fixture def fixture_user_id() -> str: """Return user id.""" return "oa:123" @pytest.fixture def fixture_post_asset_mocks(fixture_user_id: str) -> dict[str, Any]: """Fixture with correct mocks for update_asset_upload call.""" return { "get_asset_upload": {"user_id": fixture_user_id}, "update_asset_upload": {"asset_upload_id": 1}, } @pytest.fixture def fixture_update_asset_upload_args() -> dict[str, Any]: """Fixture with correct update_asset_upload args.""" return { "upc": 54321, "track_unique_id": 12321, "filename": "unique_filename.tif", "product_id": 12345, "original_filename": "original_filename.jpg", "is_correction": True, } def test_update_asset_upload_success( fixture_update_asset_upload_args: dict[str, Any], fixture_post_asset_mocks: dict[str, Any], fixture_user_id: str, ) -> None: """Test for success of update_asset_upload logic layer.""" ( flexmock(asset_upload_model) .should_receive("get_asset_upload") .with_args("unique_filename", api_version=api.API_VERSION_V2) .and_return(fixture_post_asset_mocks["get_asset_upload"]) .once() ) update_asset_args = fixture_update_asset_upload_args.copy() update_asset_args["filename"] = "unique_filename" update_asset_args["api_version"] = api.API_VERSION_V2 ( flexmock(asset_upload_model) .should_receive("update_asset_upload") .with_args(**update_asset_args) .and_return(fixture_post_asset_mocks["update_asset_upload"]) .once() ) result = asset_upload.update_asset_upload(**fixture_update_asset_upload_args) assert result == {"status": error.SUCCESS_CODE} def test_update_asset_upload_get_asset_upload_failure( fixture_update_asset_upload_args: dict[str, Any], ) -> None: """Test for failure of update_asset_upload logic layer.""" error_message = "Query error" ( flexmock(asset_upload_model) .should_receive("get_asset_upload") .and_raise(SQLAlchemyError(error_message)) ) with pytest.raises(SQLAlchemyError) as exc: asset_upload.update_asset_upload(**fixture_update_asset_upload_args) assert str(exc.value) == error_message def test_update_asset_upload_update_asset_upload_failure( fixture_update_asset_upload_args: dict[str, Any], fixture_post_asset_mocks: dict[str, Any], ) -> None: """Test for failure of update_asset_upload logic layer.""" error_message = "Query error" ( flexmock(asset_upload_model) .should_receive("get_asset_upload") .and_return(fixture_post_asset_mocks["get_asset_upload"]) ) ( flexmock(asset_upload_model) .should_receive("update_asset_upload") .and_raise(SQLAlchemyError(error_message)) ) with pytest.raises(SQLAlchemyError) as exc: asset_upload.update_asset_upload(**fixture_update_asset_upload_args) assert str(exc.value) == error_message @pytest.mark.parametrize( ( "test_description", "asset_upload_result", "expected_exception", "expected_context", "expected_status", "expected_result", "expected_message", ), [ ( "success", ["something"], None, nullcontext(), 200, ["something"], None, ), ( "failure", None, SQLAlchemyError("Query error"), pytest.raises(SQLAlchemyError), 500, None, "Query error", ), ( "nothing to apply", [], NotFound("No rows updated."), pytest.raises(NotFound, check=lambda e: e.code == 404), 404, None, "404 Not Found: No rows updated.", ), ], ) @patch("assets.models.asset_upload.apply_asset_corrections") def test_apply_asset_corrections( mock_asset_upload: MagicMock, test_description: str, asset_upload_result: list[Any], expected_exception: Exception, expected_context: ContextManager[None], expected_status: int, expected_result: list[Any] | None, expected_message: str | None, ) -> None: """Test for apply_asset_corrections call.""" mock_asset_upload.side_effect = expected_exception mock_asset_upload.return_value = asset_upload_result with expected_context as exc: result = asset_upload.apply_asset_corrections(1234) assert result == expected_result if exc: assert str(exc.value) == expected_message