from decimal import Decimal from boto3.dynamodb import conditions from moto import mock_aws import boto3 import pytest from masters_registry.constant import opcode_const from masters_registry.models import locks from masters_registry.models import ownership from tests import test_utils from masters_registry.connectors.dynamodb import client as outside_dynamodb_client dynamodb_resource = boto3.resource("dynamodb") def dynamodb_get_item_response_new_format(): """Response containing item from DynamoDB for given ISRC.""" item = { 'Item': { 'territories': { 'AF': [{'tuid': Decimal('11432391')}] }, 'locked_territories': {}, 'isrc': 'QA123', 'updated_timestamp': Decimal('1514457624.334598'), 'timestamp': Decimal('1489014691557.2031') }, 'ResponseMetadata': {} } return item def dynamodb_get_item_response_old_format(): """Response containing item from DynamoDB for given ISRC.""" item = { 'Item': { 'territories': { 'AF': {'tuid': Decimal('11684704')} }, 'locked_territories': {}, 'isrc': 'QA123', 'updated_timestamp': Decimal('1514457624.334598'), 'timestamp': Decimal('1489014691557.2031') }, 'ResponseMetadata': {} } return item @pytest.mark.parametrize('dynamodb_item', [ dynamodb_get_item_response_new_format, dynamodb_get_item_response_old_format, ]) @mock_aws def test_lock_territories( setup_masters_active_table, seed_masters_active_table, setup_new_audit_table, dynamodb_item, test_isrc): """Test lock territories method updates active and audit tables.""" from moto.core import patch_client, patch_resource patch_client(outside_dynamodb_client) patch_resource(dynamodb_resource) setup_masters_active_table(dynamodb_resource.meta.client) seed_masters_active_table( dynamodb_resource.meta.client, item=dynamodb_item()['Item'] ) setup_new_audit_table(dynamodb_resource.meta.client) expected_result = { opcode_const.REMOVE: ['AF'], opcode_const.LOCK: ['AF'], opcode_const.UNLOCK: [] } valid_correlation_id = '111' active_isrc = ownership.get_ownership(test_isrc).message lock_reason = 'Test reason' user_id = '22' result = locks.lock_territories( active_isrc, ['AF'], lock_reason, valid_correlation_id, user_id) assert result == expected_result updated_isrc = ownership.get_ownership(test_isrc).message assert updated_isrc['territories'] == {} assert updated_isrc['locked_territories'] == { 'AF': {'reason': lock_reason}} expected_remove_audit_entry = { 'territories': ['AF'], 'isrc': 'QA123', 'opcode': 'REMOVE', 'correlation_id': valid_correlation_id, 'user': user_id, 'timestamp': Decimal('1517923153788.647'), } expected_lock_audit_entry = { 'territories': ['AF'], 'timestamp': Decimal('1517923153788.661'), 'isrc': 'QA123', 'opcode': 'LOCK', 'correlation_id': valid_correlation_id, 'user': user_id, 'lock_reason': lock_reason } audit_entries = ownership.new_audit_table.query( KeyConditionExpression=conditions.Key('isrc').eq(test_isrc) )['Items'] assert len(audit_entries) == 2 remove_audit = next(_ for _ in audit_entries if _['opcode'] == 'REMOVE') lock_audit = next(_ for _ in audit_entries if _['opcode'] == 'LOCK') assert test_utils.equal_dicts( remove_audit, expected_remove_audit_entry, ['timestamp']) assert test_utils.equal_dicts( lock_audit, expected_lock_audit_entry, ['timestamp']) @pytest.mark.parametrize('dynamodb_item', [ dynamodb_get_item_response_new_format, dynamodb_get_item_response_old_format, ]) @mock_aws def test_lock_territories_no_ownership( setup_masters_active_table, seed_masters_active_table, setup_new_audit_table, dynamodb_item, test_isrc): """Test lock territories method updates active and audit tables.""" from moto.core import patch_client, patch_resource patch_client(outside_dynamodb_client) patch_resource(dynamodb_resource) setup_masters_active_table(dynamodb_resource.meta.client) seed_masters_active_table( dynamodb_resource.meta.client, item=dynamodb_item()['Item'] ) setup_new_audit_table(dynamodb_resource.meta.client) expected_result = { opcode_const.REMOVE: [], opcode_const.LOCK: ['AD'], opcode_const.UNLOCK: [] } valid_correlation_id = '111' active_isrc = ownership.get_ownership(test_isrc).message lock_reason = 'Test reason' user_id = '22' result = locks.lock_territories( active_isrc, ['AD'], lock_reason, valid_correlation_id, user_id) assert result == expected_result updated_isrc = ownership.get_ownership(test_isrc).message assert updated_isrc['locked_territories'] == { 'AD': {'reason': lock_reason}} expected_lock_audit_entry = { 'territories': ['AD'], 'timestamp': Decimal('1517923153788.661'), 'isrc': 'QA123', 'opcode': 'LOCK', 'correlation_id': valid_correlation_id, 'user': user_id, 'lock_reason': lock_reason } audit_entries = ownership.new_audit_table.query( KeyConditionExpression=conditions.Key('isrc').eq(test_isrc) )['Items'] assert len(audit_entries) == 1 lock_audit = next(_ for _ in audit_entries if _['opcode'] == 'LOCK') assert test_utils.equal_dicts( lock_audit, expected_lock_audit_entry, ['timestamp']) @pytest.mark.parametrize('dynamodb_item, expected_result', [ ( { 'territories': { 'AF': {'tuid': Decimal('11684704')} }, 'locked_territories': {}, 'isrc': 'QA123', 'updated_timestamp': Decimal('1514457624.334598'), 'timestamp': Decimal('1489014691557.2031') }, { opcode_const.REMOVE: ['AF'], opcode_const.LOCK: ['AF'], opcode_const.UNLOCK: [] } ), ( { 'territories': { 'AD': {'tuid': Decimal('11684704')} }, 'locked_territories': { 'AF': {'reason': 'other'} }, 'isrc': 'QA123', 'updated_timestamp': Decimal('1514457624.334598'), 'timestamp': Decimal('1489014691557.2031') }, { opcode_const.REMOVE: [], opcode_const.LOCK: ['AF'], opcode_const.UNLOCK: ['AF'] } ), ( { 'territories': { 'AD': {'tuid': Decimal('11684704')} }, 'locked_territories': { 'AF': {'reason': 'Test reason'} }, 'isrc': 'QA123', 'updated_timestamp': Decimal('1514457624.334598'), 'timestamp': Decimal('1489014691557.2031') }, { opcode_const.REMOVE: [], opcode_const.LOCK: [], opcode_const.UNLOCK: [] } ), ( { 'territories': { 'AD': {'tuid': Decimal('11684704')} }, 'locked_territories': {}, 'isrc': 'QA123', 'updated_timestamp': Decimal('1514457624.334598'), 'timestamp': Decimal('1489014691557.2031') }, { opcode_const.REMOVE: [], opcode_const.LOCK: ['AF'], opcode_const.UNLOCK: [] } ), ]) @mock_aws def test_lock_territories_result( setup_masters_active_table, seed_masters_active_table, setup_new_audit_table, dynamodb_item, test_isrc, expected_result): """Test lock territories method saves correct audit records.""" from moto.core import patch_client, patch_resource patch_client(outside_dynamodb_client) patch_resource(dynamodb_resource) setup_masters_active_table(dynamodb_resource.meta.client) seed_masters_active_table( dynamodb_resource.meta.client, item=dynamodb_item ) setup_new_audit_table(dynamodb_resource.meta.client) active_isrc = ownership.get_ownership(test_isrc).message result = locks.lock_territories( active_isrc, ['AF'], 'Test reason', '111', '22') assert result == expected_result