"""Functional tests for POST /action endpoint.""" from collections import namedtuple import copy import datetime import json from freezegun import freeze_time from oto import response import pytest from conflict_manager.constants import database as db_consts from conflict_manager.constants import error from conflict_manager.constants import header from conflict_manager.constants import schema as schema_consts from conflict_manager.logic import action as action_logic Account = namedtuple('Account', ['type', 'id']) @pytest.fixture def bulk_actions_payload(): """Fixture data for bulk actions.""" return { schema_consts.ACTIONS: [ { 'territory_standard': 'ISO_3166_2106', 'isrc': 'TL1234567890', 'tuid': 123, 'conflicting_owner': 'Ill Will', 'conflict_date': '2017-11-12', 'release_action': { 'conflict_ids': [1, 2], 'reason': 'release test', 'additional_information': 'release test' }, 'assert_action': { 'conflict_ids': [3, 4], 'reason': 'assert test', 'additional_information': 'assert test' } }, { 'territory_standard': 'ISO_3166_2106', 'isrc': 'TL1234567891', 'tuid': 345, 'conflicting_owner': 'Ill Will Not', 'conflict_date': '2017-11-12', 'release_action': { 'conflict_ids': [5, 6], 'reason': 'release test', 'additional_information': 'release test' }, 'assert_action': { 'conflict_ids': [7, 8], 'reason': 'assert test', 'additional_information': 'assert test' } } ] } @pytest.fixture def bulk_actions_headers(): """Fixture headers for bulk actions.""" return { header.GRASS_ACCOUNT_TYPE: 'vendor', header.GRASS_ACCOUNT_ID: '123', header.CORRELATION_ID: 'test id', header.CONTENT_TYPE: 'application/json' } @pytest.fixture def es_bulk_actions_payload(bulk_actions_payload): """Fixture data for conflicts in ElasticSearch.""" new_actions = copy.deepcopy(bulk_actions_payload) for index, conflict in enumerate( new_actions[schema_consts.ACTIONS]): conflict['es_id'] = 'test_es_id_' + str(index) return new_actions @freeze_time('2019-10-17') def test_bulk_create_actions_success( client, mocker, bulk_actions_payload, bulk_actions_headers, es_bulk_actions_payload, feature_engine, get_conflicts_territories_mock, bulk_remove_territories_mock, bulk_create_fingerprint_rules_mock, get_rules_mock): """Expect OK response.""" conflicts_count_for_bulk_actions = [ { 'conflict_ids': '1,2,3,4', 'isrc': 'TL1234567890', 'tuid': '123', 'conflicting_owner': 'Ill Will', 'conflict_date': '2017-11-12' }, { 'conflict_ids': '5,6,7,8,9,10', 'isrc': 'TL1234567891', 'tuid': '345', 'conflicting_owner': 'Ill Will Not', 'conflict_date': '2017-11-12' } ] create_response = [{db_consts.NUMBER_OF_ROWS_INSERTED: 2}] mocker.patch.object( action_logic.fact_conflict, 'get_conflicts_ids_for_bulk_actions', return_value=conflicts_count_for_bulk_actions) mock_action_model = mocker.patch.object( action_logic.action_model, 'create', return_value=response.Response(create_response)) mock_delete_action = mocker.patch.object( action_logic.fact_conflict_elasticsearch, 'delete_conflict', return_value=response.Response(status=200)) expected_date = datetime.datetime.utcnow().strftime( db_consts.SNOWFLAKE_DATE_FORMAT) expected_actions = [ { 'conflict_id': 1, 'action': 'release', 'action_date': expected_date, 'reason': 'release test', 'additional_information': 'release test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 123 }, { 'conflict_id': 2, 'action': 'release', 'action_date': expected_date, 'reason': 'release test', 'additional_information': 'release test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 123 }, { 'conflict_id': 3, 'action': 'assert', 'action_date': expected_date, 'reason': 'assert test', 'additional_information': 'assert test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 123 }, { 'conflict_id': 4, 'action': 'assert', 'action_date': expected_date, 'reason': 'assert test', 'additional_information': 'assert test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 123 }, { 'conflict_id': 5, 'action': 'release', 'action_date': expected_date, 'reason': 'release test', 'additional_information': 'release test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 345 }, { 'conflict_id': 6, 'action': 'release', 'action_date': expected_date, 'reason': 'release test', 'additional_information': 'release test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 345 }, { 'conflict_id': 7, 'action': 'assert', 'action_date': expected_date, 'reason': 'assert test', 'additional_information': 'assert test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 345 }, { 'conflict_id': 8, 'action': 'assert', 'action_date': expected_date, 'reason': 'assert test', 'additional_information': 'assert test', 'account_id': '123', 'account_type': 'vendor', 'es_id': '', 'tuid': 345 } ] result = client.post( 'action/bulk', headers=bulk_actions_headers, data=json.dumps(bulk_actions_payload)) assert result.status_code == 200 mock_action_model.assert_called_with(expected_actions) for index, action in enumerate(expected_actions): action['es_id'] = 'test_es_id_' + str(int(index / 4)) result = client.post( 'action/bulk', headers=bulk_actions_headers, data=json.dumps(es_bulk_actions_payload)) assert result.status_code == 200 mock_action_model.assert_called_with(expected_actions) mock_delete_action.assert_called_with( Account(type='vendor', id='123'), ['test_es_id_0', 'test_es_id_1']) get_conflicts_territories_mock.assert_called_with([1, 2, 5, 6]) bulk_remove_territories_mock.assert_called() bulk_create_fingerprint_rules_mock.assert_called() get_rules_mock.assert_called() def test_bulk_create_actions_validation_error( client, mocker, bulk_actions_payload, bulk_actions_headers): """Expect error response because of failed validation.""" conflicts_count_for_bulk_actions = [ { 'conflict_ids': '4', 'isrc': 'TL1234567890', 'tuid': '123', 'conflicting_owner': 'Ill Will', 'conflict_date': '2017-11-12' }, { 'conflict_ids': '3', 'isrc': 'TL1234567891', 'tuid': '345', 'conflicting_owner': 'Ill Will Not', 'conflict_date': '2017-11-12' } ] mocker.patch.object( action_logic.fact_conflict, 'get_conflicts_ids_for_bulk_actions', return_value=conflicts_count_for_bulk_actions) result = client.post( 'action/bulk', headers=bulk_actions_headers, data=json.dumps(bulk_actions_payload)) res_body = json.loads(result.data.decode()) assert result.status_code == 400 assert res_body['message'] == error.INVALID_TERRITORIES_MSG