"""Tests for hive text recognition logic.""" from contextlib import nullcontext from typing import Any from unittest.mock import call import pytest import pytest_mock from sqlalchemy.exc import SQLAlchemyError from assets.constants.error import ERROR_ASSET_FINAL_NOT_FOUND from assets.exceptions import AssetFinalNotFound, HiveTextRecognitionExists from assets.logic import hive_text_recognition as hive_text_recognition_logic from assets.models import ( asset_final as asset_final_model, hive_text_recognition as hive_text_recognition_model, ) @pytest.mark.parametrize( ( "asset_final_side_effect", "create_side_effect", "expected_raise", "expected_create_calls", ), [ pytest.param( AssetFinalNotFound(ERROR_ASSET_FINAL_NOT_FOUND), None, pytest.raises(AssetFinalNotFound), [], id="asset_final_not_found", ), pytest.param( None, None, nullcontext(), [call(555, "hello world")], id="success", ), pytest.param( None, HiveTextRecognitionExists("already exists"), pytest.raises(HiveTextRecognitionExists), [call(555, "hello world")], id="hive_model_error", ), ], ) def test_save_hive_text_recognition( mocker: pytest_mock.MockerFixture, asset_final_side_effect: Exception | None, create_side_effect: Exception | None, expected_raise: Any, expected_create_calls: list[Any], ) -> None: """Test save_hive_text_recognition with asset_final not found, success, and model error cases.""" payload = {"asset_final_id": 555, "block_text": "hello world"} mock_get_asset_final = mocker.patch.object( asset_final_model, "get_asset_final_by_id", side_effect=asset_final_side_effect, ) mock_create = mocker.patch.object( hive_text_recognition_model, "create_hive_text_recognition", side_effect=create_side_effect, ) with expected_raise: hive_text_recognition_logic.save_hive_text_recognition(payload) mock_get_asset_final.assert_called_once_with(555) assert mock_create.call_args_list == expected_create_calls @pytest.mark.parametrize( ( "model_return_value", "model_side_effect", "expected_result", "expected_raise", ), [ pytest.param( {"asset_final_id": 101, "block_text": "some text"}, None, {"asset_final_id": 101, "block_text": "some text"}, nullcontext(), id="success", ), pytest.param( None, SQLAlchemyError("db error"), None, pytest.raises(SQLAlchemyError), id="model_error", ), ], ) def test_get_hive_text_recognition_by_product( mocker: pytest_mock.MockerFixture, model_return_value: dict[str, Any] | None, model_side_effect: Exception | None, expected_result: dict[str, Any] | None, expected_raise: Any, ) -> None: """Test get_hive_text_recognition_by_product with success and model error cases.""" mock_get = mocker.patch.object( hive_text_recognition_model, "get_hive_text_recognition_by_product", return_value=model_return_value, side_effect=model_side_effect, ) with expected_raise: result = hive_text_recognition_logic.get_hive_text_recognition_by_product( product_id=1001 ) assert result == expected_result mock_get.assert_called_once_with(1001)