"""Tests for lambda app module.""" from datetime import datetime from unittest.mock import Mock, patch import pytest from src import app from src.logic.utils import get_project_id_from_gql_response mock_db_conn = Mock() @pytest.mark.parametrize("db_operation_type", ["insert", "update", "delete"]) def test_get_raw_events_project( db_operation_type, fixture_maxwell_project_table_events ): """Test for project events check ok.""" unique_id = 12321 event = fixture_maxwell_project_table_events[db_operation_type] event["data"]["project_id"] = unique_id result = app.get_raw_events(event, mock_db_conn) assert len(result) == 1 assert result[0]["event_type"] == "PROJECT" assert result[0]["id"] == unique_id def test_get_raw_events_product(product_update_stream): """Test for product events check ok.""" for item in product_update_stream: mock_id = item["data"]["release_id"] mock_upc = "MOCK_UPC" patch_dict = { "microservice_lookup": { "handler": Mock( return_value=( mock_id, {"upc": mock_upc, "commercialType": "NOT_SPECIAL"}, ) ), "arg_data_key": "release_id", "result_key": "upc", "exclude": lambda data: data["commercialType"] == "SPECIAL", } } with patch.dict("src.app.DEFAULT_PRODUCT_LOOKUP", patch_dict): results = app.get_raw_events(item, None) assert len(results) == 1 result = results[0] assert result["event_type"] == "PRODUCT" assert result["id"] == mock_id assert result["business_key"] == mock_upc def test_get_raw_events_product_with_additional_info(single_product): """Test for product with additional info.""" mock_id = single_product["data"]["release_id"] mock_upc = "MOCK_UPC" mock_project_id = "2555661" additional_info = {"projectLocalId": mock_project_id} patch_dict = { "microservice_lookup": { "handler": Mock( return_value=( mock_id, { "upc": mock_upc, "commercialType": "NOT_SPECIAL", "project": {"ids": [{"localId": mock_project_id}]}, }, ) ), "arg_data_key": "release_id", "result_key": "upc", "include": get_project_id_from_gql_response, "exclude": lambda data: data["commercialType"] == "SPECIAL", } } with patch.dict("src.app.DEFAULT_PRODUCT_LOOKUP", patch_dict): results = app.get_raw_events(single_product, None) assert len(results) == 1 result = results[0] assert result["event_type"] == "PRODUCT" assert result["id"] == mock_id assert result["business_key"] == mock_upc assert result["additional_info"] == additional_info def test_get_raw_events_product_exclude_special(product_update_stream): """Test for product events excluding commercialType == SPECIAL.""" for item in product_update_stream: mock_id = item["data"]["release_id"] mock_upc = "MOCK_UPC" patch_dict = { "microservice_lookup": { "handler": Mock( return_value=( mock_id, {"upc": mock_upc, "commercialType": "SPECIAL"}, ) ), "arg_data_key": "release_id", "result_key": "upc", "exclude": lambda data: data["commercialType"] == "SPECIAL", } } with patch.dict("src.app.DEFAULT_PRODUCT_LOOKUP", patch_dict): results = app.get_raw_events(item, None) assert len(results) == 0 def test_get_raw_events_product_not_for_distribution( product_update_stream_distribution, ): """Test for product events not_for_distribution.""" item = product_update_stream_distribution[0] results = app.get_raw_events(item, None) assert len(results) == 1 result = results[0] assert result["event_type"] == "PRODUCT" assert result["id"] == 999999 assert result["business_key"] == "UPC1" def test_get_raw_events_product_yes_for_distribution( product_update_stream_distribution, ): """Test for product events not_for_distribution.""" item = product_update_stream_distribution[1] results = app.get_raw_events(item, None) assert len(results) == 0 def test_get_raw_events_track(track_update_stream): """Test for product events check ok.""" for item in track_update_stream: mock_id = 12345 mock_isrc = "MOCK_ISRC" table = item["table"] if table in ("track_publisher", "track_writer"): arg_data_key = "unique_track_id" else: arg_data_key = "track_id" patch_dict = { "microservice_lookup": { "handler": Mock(return_value=(mock_id, {"isrc": mock_isrc})), "arg_data_key": arg_data_key, "result_key": "isrc", } } with patch.dict("src.app.DEFAULT_TRACK_LOOKUP", patch_dict): results = app.get_raw_events(item, None) assert len(results) == 1 result = results[0] assert result["event_type"] == "TRACK" assert result["id"] == mock_id assert result["business_key"] == mock_isrc def test_get_raw_events_track_and_product(track_and_product_update_event): """Test for product events check ok.""" mock_product_id = 54321 mock_upc = "MOCK_UPC" patch_product_dict = { "microservice_lookup": { "handler": Mock(return_value=(mock_product_id, {"upc": mock_upc})), "arg_data_key": "release_id", "result_key": "upc", } } mock_track_id = 12345 mock_isrc = "MOCK_ISRC" patch_track_dict = { "microservice_lookup": { "handler": Mock(return_value=(mock_track_id, {"isrc": mock_isrc})), "arg_data_key": "track_id", "result_key": "isrc", } } with patch.dict("src.app.DEFAULT_PRODUCT_LOOKUP", patch_product_dict): with patch.dict("src.app.DEFAULT_TRACK_LOOKUP", patch_track_dict): results = app.get_raw_events(track_and_product_update_event, None) assert len(results) == 2 def test_get_raw_events_for_product_releases_table_with_project_id( product_update_with_project_id, ): """Test get_raw_events for a product and the releases table.""" expected = [ { "event_type": "PRODUCT", "ts": 1573731354, "id": 999999, "business_key": "UPC1", "additional_info": { "projectLocalId": 12345, }, } ] result = app.get_raw_events(product_update_with_project_id, None) assert result == expected def test_get_raw_events_unknown_table(fixture_maxwell_fake_table_update): """Test for no result for unknown table.""" result = app.get_raw_events(fixture_maxwell_fake_table_update, mock_db_conn) assert len(result) == 0 @patch("src.app.datetime") @patch("uuid.uuid4") def test_enrich_project_message( uuid_mock, datetime_mock, fixture_maxwell_project_table_update ): """Test for conversion of raw event body into Kafka message body.""" raw_message = {"event_type": "PROJECT", "ts": 1563813000, "id": 101} expected_uuid = "0a3d2f31-2faf-444d-85b6-4b441832fa8e" uuid_mock.return_value = expected_uuid datetime_mock.now.return_value = datetime(2019, 1, 11, 1, 1, 1) datetime_mock.strptime = datetime.strptime datetime_mock.utcfromtimestamp = datetime.utcfromtimestamp expected_message = { "sendingSystem": "ORCHARD", "entityType": "PROJECT", "messageType": "METADATA_UPDATE", "messageId": expected_uuid, "correlationId": expected_uuid, "messageCreatedDateTime": "2019-01-11T01:01:01.000Z", "entityUpdatedDateTime": "2019-07-22T16:30:00.000Z", "ids": [{"localId": "101", "system": "ORCHARD"}], } generated_message = app.enrich_message(raw_message) assert expected_message == generated_message @patch("src.app.datetime") @patch("uuid.uuid4") def test_enrich_project_message_with_additional_info( uuid_mock, datetime_mock, fixture_maxwell_project_table_update ): """Test for conversion of raw event body into Kafka message body.""" raw_message = { "event_type": "PROJECT", "ts": 1563813000, "id": 101, "additional_info": {"projectLocalId": "12345"}, } expected_uuid = "0a3d2f31-2faf-444d-85b6-4b441832fa8e" uuid_mock.return_value = expected_uuid datetime_mock.now.return_value = datetime(2019, 1, 11, 1, 1, 1) datetime_mock.strptime = datetime.strptime datetime_mock.utcfromtimestamp = datetime.utcfromtimestamp expected_message = { "sendingSystem": "ORCHARD", "entityType": "PROJECT", "messageType": "METADATA_UPDATE", "messageId": expected_uuid, "correlationId": expected_uuid, "messageCreatedDateTime": "2019-01-11T01:01:01.000Z", "entityUpdatedDateTime": "2019-07-22T16:30:00.000Z", "ids": [{"localId": "101", "system": "ORCHARD"}], "additionalInfo": raw_message["additional_info"], } generated_message = app.enrich_message(raw_message) assert expected_message == generated_message @patch("src.connectors.kafka.get_kafka_producer") def test_send_result_to_kafka(get_kafka_producer_mock): """Test for sending messages to Kafka.""" messages = [ {"event_type": "PROJECT", "id": 100, "ts": 1562084068}, {"event_type": "PROJECT", "id": 101, "ts": 1562084068}, { "event_type": "PRODUCT", "business_key": "key", "id": 12, "ts": 1562084068, }, # Invalid business_key { "event_type": "PRODUCT", "business_key": None, "id": 13, "ts": 1562084068, }, { "event_type": "TRACK", "business_key": "key", "id": 929, "ts": 1562084068, }, # Invalid business_key { "event_type": "TRACK", "business_key": "", "id": 836, "ts": 1562084068, }, ] client = Mock() get_kafka_producer_mock.return_value = client result = app.send_result_to_kafka(messages) assert get_kafka_producer_mock.call_count == 1 # Invalid business_key messages are not sent assert client.send.call_count == len(messages) - 2 assert result is True def test_clean_raw_events(): """Test for clean_raw_events.""" events = [ { "event_type": "PROJECT", "id": 100, "ts": 1000, "business_key": None, }, { "event_type": "PROJECT", "id": 100, "ts": 1001, "business_key": None, }, { "event_type": "PRODUCT", "id": 102, "ts": 1000, "business_key": "000000000000", }, { "event_type": "PRODUCT", "id": 102, "ts": 999, "business_key": "000000000000", }, { "event_type": "TRACK", "id": 102, "ts": 999, "business_key": None, }, { "event_type": "TRACK", "id": 102, "ts": 999, "business_key": "000000000000", "additional_info": {"projectLocalId": "12345"}, }, ] result = app.clean_raw_events(events) assert len(result) == 4 assert events[1] in result assert events[2] in result assert events[4] in result assert events[5] in result def test_get_track_artist_localized_metadata_track_event( track_artist_localized_metadata_event, ): """Test for track_artist_localized_metadata_event events check ok.""" mock_id = 12345 mock_isrc = "MOCK_ISRC" patch_dict = { "microservice_lookup": { "handler": Mock(return_value=(mock_id, {"isrc": mock_isrc})), "arg_data_key": "track_artist_id", "result_key": "isrc", } } with patch.dict("src.app.TRACK_BY_TRACK_ARTIST_LOOKUP", patch_dict): results = app.get_raw_events(track_artist_localized_metadata_event, None) assert len(results) == 1 result = results[0] assert result["event_type"] == "TRACK" assert result["id"] == mock_id assert result["business_key"] == mock_isrc def test_get_release_artist_localized_metadata_track_event( release_artist_localized_metadata_event, ): """Test for release_artist_localized_metadata_event events check ok.""" mock_id = 12345 mock_upc = "MOCK_UPC" patch_dict = { "microservice_lookup": { "handler": Mock(return_value=(mock_id, {"upc": mock_upc})), "arg_data_key": "release_artist_id", "result_key": "upc", } } with patch.dict("src.app.PRODUCT_BY_RELEASE_ARTIST_LOOKUP", patch_dict): results = app.get_raw_events(release_artist_localized_metadata_event, None) assert len(results) == 1 result = results[0] assert result["event_type"] == "PRODUCT" assert result["id"] == mock_id assert result["business_key"] == mock_upc def test_get_track_handlers_mapping(): """Test for correct handlers mapping.""" result = app.get_handlers_mapping() track_handlers = result["TRACK"] key = track_handlers["track_artist"]["microservice_lookup"]["arg_data_key"] assert key == "track_id" key = track_handlers["track_localized_metadata"]["microservice_lookup"][ "arg_data_key" ] # noqa assert key == "track_id" key = track_handlers["track_writer"]["microservice_lookup"]["arg_data_key"] # noqa assert key == "unique_track_id" key = track_handlers["track_publisher"]["microservice_lookup"]["arg_data_key"] # noqa assert key == "unique_track_id"