"""Tests for canned_response model.""" import datetime import json from contextlib import nullcontext as does_not_raise import pytest from freezegun import freeze_time from freezegun.api import FakeDatetime from product_review.api import db from product_review.models import canned_response as canned_response_model from tests.utils.db_utils import ( create_test_canned_response_category, create_test_canned_response_item, create_test_canned_response_note, ) CANNED_RESPONSE_CATEGORY_DB_ITEMS = [ {"category_id": 1, "name": "cat 1"}, {"category_id": 2, "name": "cat 2"}, ] CANNED_RESPONSE_DB_ITEMS = [ { "canned_response_id": 1, "category_id": 1, "keyword": "abc", "review_context": "approval", "modified_by_user_id": "user-1", }, { "canned_response_id": 2, "category_id": 1, "keyword": "def", "review_context": "approval", "modified_by_user_id": "user-4", }, { "canned_response_id": 3, "category_id": 2, "keyword": "ghi", "review_context": "rejection", "modified_by_user_id": "user-1", }, { "canned_response_id": 4, "category_id": 2, "keyword": "abc", "review_context": "rejection", "modified_by_user_id": "user-4", "for_deletion": 1, }, ] CANNED_RESPONSE_NOTE_DB_ITEMS = [ { "canned_response_id": 1, "note_keyword": "abc", "note_text": "tiempo de la mariposa", "language_code": "es", "modified_by_user_id": "user-1", }, { "canned_response_id": 2, "note_keyword": "def", "note_text": "goodbye", "language_code": "en", "modified_by_user_id": "user-4", }, { "canned_response_id": 3, "note_keyword": "ghi", "note_text": "annyeong", "language_code": "ko", "modified_by_user_id": "user-1", }, ] @pytest.mark.parametrize( ( "test_description", "filter_category_id", "filter_modified_by_user_id", "filter_review_context", "filter_language_code", "expected_row_result", ), [ ("filter by category id", 2, None, None, None, 2), ("filter by modified by user id", None, "user-4", None, None, 1), ("filter by review context", None, None, "rejection", None, 2), ("filter by language code", None, None, None, "ko", 2), ], ) def test_get_items( test_description, filter_category_id, filter_modified_by_user_id, filter_review_context, filter_language_code, expected_row_result, ): """Test get_items.""" for item in CANNED_RESPONSE_CATEGORY_DB_ITEMS: create_test_canned_response_category(**item) mock_canned_response_items = list( map( lambda item: create_test_canned_response_item(**item), CANNED_RESPONSE_DB_ITEMS, ) ) for item in CANNED_RESPONSE_NOTE_DB_ITEMS: create_test_canned_response_note(**item) results, total_records = canned_response_model.get_items( category_id=filter_category_id, modified_by_user_id=filter_modified_by_user_id, review_context=filter_review_context, language_code=filter_language_code, ) assert results == [mock_canned_response_items[expected_row_result]] assert total_records == 1 @pytest.mark.parametrize( ( "test_description", "canned_response_id", "language_code", "expected_raise", "expected_raise_message", "expected_result", ), [ ( "no filter args", 1, None, does_not_raise(), "None", { "canned_response_id": 1, "keyword": "abc", "review_context": "approval", "modified_by_user_id": "user-1", "canned_response_category": {"category_id": 1, "name": "cat 1"}, "language_codes": ["es"], "for_deletion": False, "last_updated": FakeDatetime(1234, 2, 3, 0, 20), }, ), ( "filter by language code", 1, "es", does_not_raise(), "None", { "canned_response_id": 1, "keyword": "abc", "review_context": "approval", "modified_by_user_id": "user-1", "canned_response_category": {"category_id": 1, "name": "cat 1"}, "language_codes": ["es"], "note": { "note_id": 1, "canned_response_id": 1, "note_keyword": "abc", "note_text": "tiempo de la mariposa", "language_code": "es", "modified_by_user_id": "user-1", "last_updated": FakeDatetime(1234, 2, 3, 0, 20), }, "for_deletion": False, "last_updated": FakeDatetime(1234, 2, 3, 0, 20), }, ), ( "item not found", 5, None, pytest.raises(Exception), '{"status": 404, "code": "not_found", "message": "Not Found"}', None, ), ( "language_code not found", 1, "en", pytest.raises(Exception), '{"status": 404, "code": "not_found", "message": "Not Found"}', None, ), ], ) @freeze_time("1234-02-03 00:20:00") def test_get_canned_response_item( test_description, canned_response_id, language_code, expected_raise, expected_raise_message, expected_result, ): """Test get_canned_response_item.""" create_test_canned_response_category(**CANNED_RESPONSE_CATEGORY_DB_ITEMS[0]) create_test_canned_response_item(**CANNED_RESPONSE_DB_ITEMS[0]), create_test_canned_response_note(**CANNED_RESPONSE_NOTE_DB_ITEMS[0]) result = None with expected_raise as er: result = canned_response_model.get_canned_response_item( canned_response_id, language_code ) assert str(getattr(er, "value", None)) == expected_raise_message assert result == expected_result def test_create_canned_response(): """Test create_canned_response.""" create_test_canned_response_category(**CANNED_RESPONSE_CATEGORY_DB_ITEMS[0]) result = canned_response_model.create_canned_response( category_id=1, keyword="abc", review_context="rejection", modified_by_user_id="user-1", ) db.session.commit() assert result.canned_response_id == 1 assert isinstance(result.last_updated, datetime.datetime) assert result.for_deletion is False def test_create_canned_response_failure(): """Test create_canned_response failure.""" create_test_canned_response_category(**CANNED_RESPONSE_CATEGORY_DB_ITEMS[0]) create_test_canned_response_item(**CANNED_RESPONSE_DB_ITEMS[0]) with pytest.raises(Exception) as er: canned_response_model.create_canned_response( category_id=1, keyword="abc", review_context="rejection", modified_by_user_id="user-1", ) assert str(getattr(er, "value", None)) == json.dumps( { "status": 400, "code": "canned_response_not_created", "message": "Duplicate canned response category_id/ keyword combination.", } ) @pytest.mark.parametrize( ("test_description", "mock_value", "expected_for_deletion"), [("update item", None, False), ("update item for deletion", True, True)], ) def test_update_canned_response(test_description, mock_value, expected_for_deletion): """Test update_canned_response.""" create_test_canned_response_category(**CANNED_RESPONSE_CATEGORY_DB_ITEMS[0]) create_test_canned_response_item(**CANNED_RESPONSE_DB_ITEMS[0]), create_test_canned_response_note(**CANNED_RESPONSE_NOTE_DB_ITEMS[0]) if mock_value is None: canned_response_model.update_canned_response(1, "user-2") else: canned_response_model.update_canned_response( 1, "user-2", for_deletion=mock_value ) item = canned_response_model.get_canned_response_item(1) assert isinstance(item.pop("last_updated"), datetime.datetime) assert item == { "canned_response_id": 1, "keyword": "abc", "language_codes": ["es"], "review_context": "approval", "modified_by_user_id": "user-2", "canned_response_category": {"category_id": 1, "name": "cat 1"}, "for_deletion": expected_for_deletion, } def test_update_canned_response_not_found(): """Test update_canned_response not found.""" with pytest.raises(Exception) as er: canned_response_model.update_canned_response(1, "user-2") assert ( str(getattr(er, "value", None)) == '{"status": 404, "code": "not_found", "message": "Not Found"}' )