import json from typing import Dict, List import pytest import requests_mock from juno_filters_messages import config from juno_filters_messages import constants from juno_filters_messages.clients.user_data_api import UserDataClientConfig from juno_filters_messages.handler import handler from juno_filters_messages.logger import get_logger def get_history_info(history) -> tuple: return history.method, history.path, history.json() def get_event(count: int = 1) -> dict: return { "Records": [{"body": json.dumps({"Message": json.dumps({"id": f"event_id_{i}"})})} for i in range(1, count + 1)] } def get_settings_list(count: int = 5) -> List[dict]: return [ { "account_id": 10 + i, "settings": { "data": { "juno_filters": { "filters": { f"filter_id_{i}_{j}": { "name": f"Filter_{i}_{j}", "country_code": ["us", "gb"], **({"isrc_country_code": ["ca", "li"]} if (i + j) % 2 else {}), **({"percent_change": 20 + i + j} if (i + j) % 2 else {}), **({"min_product_sale_days": 200 + i + j} if (i + j) % 3 else {}), **({"max_product_sale_days": 100 + i + j} if (i + j) % 2 == 0 else {}), **({"is_subscribed": (i + j) % 3 > 0} if (i + j) % 4 > 0 else {}), } for j in range(1, min(4, i)) } } }, "id": 40 + i, "type": "web", "version": "1" }, "user_id": f"user_id_{i}", } for i in range(1, count + 1) ] def get_message_list(index_map: Dict[int, List[int]]) -> List[dict]: return [ {"meta": {"filter_id": f"filter_id_{i}_{j}"}, "account_id": 10 + i} for i, sub_index_list in index_map.items() for j in sub_index_list ] def get_new_message_list(index_map: Dict[int, List[int]], event_index: int = 1): return { "public": config.MESSAGE_IS_PUBLIC, "data": [ { "ttl": constants.TTL, "event_id": f"event_id_{event_index}", "account_id": 10 + i, "meta": { "subject": "juno_digest", "views": ["juno_email"], "user_id": f"user_id_{i}", "settings_id": 40 + i, "filter_id": f"filter_id_{i}_{j}", }, "data": { "name": f"Filter_{i}_{j}", "country_code": ["us", "gb"], **({"isrc_country_code": ["ca", "li"]} if (i + j) % 2 else {}), **({"percent_change": 20 + i + j} if (i + j) % 2 else {}), **({"min_product_sale_days": 200 + i + j} if (i + j) % 3 else {}), **({"max_product_sale_days": 100 + i + j} if (i + j) % 2 == 0 else {}), }, } for i, sub_index_list in index_map.items() for j in sub_index_list ], } @pytest.mark.parametrize( "event_count,settings_count,message_map,call_count,expected_map", ( (0, 0, {}, 0, {}), (1, 5, {}, 3, {3: [2], 4: [1, 3], 5: [2]}), (1, 5, {4: [1], 5: [2]}, 3, {3: [2], 4: [3]}), (1, 5, {3: [2], 4: [1, 3], 5: [2]}, 2, {}), (2, 5, {}, 5, {3: [2], 4: [1, 3], 5: [2]}), ) ) @requests_mock.Mocker(kw="requests_mocker") def test_handler(event_count, settings_count, message_map, call_count, expected_map, **kwargs): requests_mocker = kwargs["requests_mocker"] user_data_config = UserDataClientConfig() requests_mocker.register_uri( "POST", f"{user_data_config._schema}://{user_data_config._host}/api/service/users/settings/list/", json={"data": get_settings_list(settings_count)}, ) requests_mocker.register_uri( "POST", f"{user_data_config._schema}://{user_data_config._host}/api/service/messages/list/", json={"data": get_message_list(message_map) if message_map else []}, ) requests_mocker.register_uri( "POST", f"{user_data_config._schema}://{user_data_config._host}/api/service/messages/", json={} ) handler(get_logger(), get_event(event_count)) history = requests_mocker.request_history assert len(history) == call_count if call_count: assert get_history_info(history[0]) == ( "POST", "/api/service/users/settings/list/", {"settings": {"type": "web", "version": "1"}} ) for index in range(event_count): expected_history = ( ("POST", "/api/service/messages/list/", {"event_id": f"event_id_{index + 1}"}), ("POST", "/api/service/messages/", get_new_message_list(expected_map, index + 1)), ) for call_index in range(min(call_count, 3) - 1): assert get_history_info(history[index * 2 + call_index + 1]) == expected_history[call_index]