diff --git a/connect_migration.py b/connect_migration.py index 876ebcf..63070db 100644 --- a/connect_migration.py +++ b/connect_migration.py @@ -8,25 +8,27 @@ We can use an instance of this class into our request processor, like this: :: - class ProductFulfillment(FulfillmentAutomation): + class PurchaseFlow(Flow): def __init__(self): - self.migration_handler = connect_migration.MigrationHandler({ + super().__init__(lambda request: request.type == 'purchase') + self.step('Checking if migration is need', PurchaseFlow._need_migration) + self.step('Provision real purchase order', PurchaseFlow._purchase) + self.step('Approving request', PurchaseFlow._approve_request) + + + + def _need_migration(self): + self.getRequest().migration_handler = MigrationHandler({ 'email': lambda data, request_id: data['teamAdminEmail'].upper(), 'team_id': lambda data, request_id: data['teamId'].upper(), 'team_name': lambda data, request_id: data['teamName'].upper(), 'num_licensed_users': lambda data, request_id: int(data['licNumber']) * 10 - }) - - def process_request(request): - if request.type == 'purchase': - request = self.migration_handler.migrate(request) - - # The migrate() method returns a new request object with - # the parameter values updated, we must update the parameters - # and approve the fulfillment + }) - self.update_parameters(request.id, request.asset.params) - return ActivationTileResponse('The data has been migrated :)') + if self.getRequest().needsMigration(): + req = self.migration_handler.migrate(self.getRequest()) + self.getRequest().asset.params = req.asset.params + self._approve_request() """ @@ -36,9 +38,8 @@ def process_request(request): import six from typing import List -from connect.exceptions import SkipRequest -from connect.logger import logger -from connect.models import Fulfillment +from connect import Env +from connect.models import AssetRequest class MigrationAbortError(Exception): @@ -64,7 +65,8 @@ class MigrationHandler(object): in the migration data on direct assignation flow. Default value is ``False``. """ - def __init__(self, transformations=None, migration_key='migration_info', serialize=False): + def __init__(self, transformations=None, migration_key='migration_info', + serialize=False): self._transformations = transformations or {} self._migration_key = migration_key self._serialize = serialize @@ -97,28 +99,30 @@ def serialize(self): def migrate(self, request): """ Call this function to perform migration of one request. - :param Fulfillment request: The request to migrate. + :param AssetRequest request: The request to migrate. :return: A new request object with the parameter values updated. - :rtype: Fulfillment - :raises SkipRequest: Raised if migration fails for some reason. + :rtype: AssetRequest :raises MigrationParamError: Raised if the value for a parameter is not a string. """ - if request.needs_migration(self.migration_key): - logger.info('[MIGRATION::{}] Running migration operations for request {}' - .format(request.id, request.id)) + if request.needsMigration(self.migration_key): + Env.getLogger().info( + '[MIGRATION::{}] Running migration operations for request {}' + .format(request.id, request.id)) request_copy = copy.deepcopy(request) raw_data = request.asset.get_param_by_id(self.migration_key).value - logger.debug('[MIGRATION::{}] Migration data `{}`: {}' - .format(request.id, self.migration_key, raw_data)) + Env.getLogger().debug('[MIGRATION::{}] Migration data `{}`: {}' + .format(request.id, self.migration_key, + raw_data)) try: try: parsed_data = json.loads(raw_data) except ValueError as ex: raise MigrationAbortError(str(ex)) - logger.debug('[MIGRATION::{}] Migration data `{}` parsed correctly' - .format(request.id, self.migration_key)) + Env.getLogger().debug( + '[MIGRATION::{}] Migration data `{}` parsed correctly' + .format(request.id, self.migration_key)) # These will keep track of processing status processed_params = [] @@ -127,7 +131,7 @@ def migrate(self, request): skipped_params = [] # Exclude param for migration_info from process list - params = [param for param in request_copy.asset.params + params = [param for param in request_copy.asset.params.toArray() if param.id != self.migration_key] for param in params: @@ -135,56 +139,65 @@ def migrate(self, request): try: if param.id in self.transformations: # Transformation is defined, so apply it - logger.info('[MIGRATION::{}] Running transformation for parameter {}' - .format(request.id, param.id)) - param.value = self.transformations[param.id](parsed_data, request.id) + Env.getLogger().info( + '[MIGRATION::{}] Running transformation for parameter {}' + .format(request.id, param.id)) + param.value = self.transformations[param.id]( + parsed_data, request.id) succeeded_params.append(param.id) elif param.id in parsed_data: # Parsed data contains the key, so assign it - if not isinstance(parsed_data[param.id], six.string_types): + if not isinstance(parsed_data[param.id], + six.string_types): if self.serialize: - parsed_data[param.id] = json.dumps(parsed_data[param.id]) + parsed_data[param.id] = json.dumps( + parsed_data[param.id]) else: - type_name = type(parsed_data[param.id]).__name__ + type_name = type( + parsed_data[param.id]).__name__ raise MigrationParamError( 'Parameter {} type must be str, but {} was given' - .format(param.id, type_name)) + .format(param.id, type_name)) param.value = parsed_data[param.id] succeeded_params.append(param.id) else: skipped_params.append(param.id) except MigrationParamError as ex: - logger.error('[MIGRATION::{}] {}'.format(request.id, ex)) + Env.getLogger().error( + '[MIGRATION::{}] {}'.format(request.id, ex)) failed_params.append(param.id) # Report processed param processed_params.append(param.id) - logger.info('[MIGRATION::{}] {} processed, {} succeeded{}, {} failed{}, ' - '{} skipped{}.' - .format( - request.id, - len(processed_params), - len(succeeded_params), - self._format_params(succeeded_params), - len(failed_params), - self._format_params(failed_params), - len(skipped_params), - self._format_params(skipped_params))) + Env.getLogger().info( + '[MIGRATION::{}] {} processed, {} succeeded{}, {} failed{}, ' + '{} skipped{}.' + .format( + request.id, + len(processed_params), + len(succeeded_params), + self._format_params(succeeded_params), + len(failed_params), + self._format_params(failed_params), + len(skipped_params), + self._format_params(skipped_params))) # Raise abort if any params failed if failed_params: raise MigrationAbortError( 'Processing of parameters {} failed, unable to complete migration.' - .format(', '.join(failed_params))) + .format(', '.join(failed_params))) except MigrationAbortError as ex: - logger.error('[MIGRATION::{}] {}'.format(request.id, ex)) - raise SkipRequest('Migration failed.') + Env.getLogger().error( + '[MIGRATION::{}] {}'.format(request.id, ex)) + raise return request_copy else: - logger.info('[MIGRATION::{}] Request does not need migration.' - .format(request.id)) + Env.getLogger().info( + '[MIGRATION::{}] AssetRequest does not need migration.' + .format(request.id)) return request @staticmethod diff --git a/requirements.txt b/requirements.txt index 1df45a1..63f76b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ -connect-sdk>=17.4 +connect-sdk-haxe-port==18.0.1 six==1.12.0 typing==3.6.6 +mock == 3.0.5 +pytest == 5.3.0 diff --git a/tests/test_migration_handler.py b/tests/test_migration_handler.py index 82e2cbc..796ec79 100644 --- a/tests/test_migration_handler.py +++ b/tests/test_migration_handler.py @@ -4,17 +4,15 @@ # Copyright (c) 2019 Ingram Micro. All Rights Reserved. import os - +import six import pytest from mock import patch, Mock, call from typing import Dict, Optional -import six - -from connect.exceptions import SkipRequest -from connect.models import Fulfillment - import connect_migration +from connect_migration import MigrationAbortError +from connect.models import Model, AssetRequest +from connect import Collection def _load_str(filename): @@ -43,56 +41,60 @@ def test_properties(): assert not handler.serialize -def test_needs_migration(): +def test_needsMigration(): # type: () -> None handler = connect_migration.MigrationHandler() # No migration needed response_no_migration = _load_str('response.json') - requests_no_migration = Fulfillment.deserialize(response_no_migration) - assert isinstance(requests_no_migration, list) - assert len(requests_no_migration) == 1 - assert isinstance(requests_no_migration[0], Fulfillment) - assert not requests_no_migration[0].needs_migration(handler.migration_key) + requests_no_migration = Model.parseArray(AssetRequest, + response_no_migration) + assert isinstance(requests_no_migration, Collection) + assert requests_no_migration.length() == 1 + assert isinstance(requests_no_migration.get(0), AssetRequest) + assert not requests_no_migration.get(0).needsMigration( + handler.migration_key) # Migration needed response_migration = _load_str('request.migrate.valid.json') - request = Fulfillment.deserialize(response_migration) - assert isinstance(request, Fulfillment) - assert request.needs_migration(handler.migration_key) + request = Model.parse(AssetRequest, response_migration) + assert isinstance(request, AssetRequest) + assert request.needsMigration(handler.migration_key) -@patch('connect_migration.logger.info') +@patch('connect.logger.Logger.info') def test_no_migration(info_mock): # type: (Mock) -> None response = _load_str('response.json') - requests = Fulfillment.deserialize(response) - assert isinstance(requests, list) - assert len(requests) == 1 + requests = Model.parseArray(AssetRequest, response) + assert isinstance(requests, Collection) + assert requests.length() == 1 handler = connect_migration.MigrationHandler() - request = handler.migrate(requests[0]) + request = handler.migrate(requests.get(0)) info_mock.assert_called_once_with('[MIGRATION::PR-5852-1608-0000] ' - 'Request does not need migration.') - assert request == requests[0] + 'AssetRequest does not need migration.') + assert request == requests.get(0) -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') -def test_migration_skip_all(info_mock, debug_mock): +@patch('connect.logger.Logger.info') +@patch('connect.logger.Logger.debug') +def test_migration_skip_all(debug_mock, info_mock): # type: (Mock, Mock) -> None response = _load_str('request.migrate.valid.json') - request = Fulfillment.deserialize(response) + request = Model.parse(AssetRequest, response) handler = connect_migration.MigrationHandler() request_out = handler.migrate(request) assert info_mock.call_count == 2 info_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' - 'PR-7001-1234-5678'), - call('[MIGRATION::PR-7001-1234-5678] 5 processed, 0 succeeded, 0 failed, 5 skipped ' - '(email, num_licensed_users, reseller_id, team_id, team_name).') + call( + '[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' + 'PR-7001-1234-5678'), + call( + '[MIGRATION::PR-7001-1234-5678] 5 processed, 0 succeeded, 0 failed, 5 skipped ' + '(email, num_licensed_users, reseller_id, team_id, team_name).') ]) assert debug_mock.call_count == 2 @@ -103,41 +105,45 @@ def test_migration_skip_all(info_mock, debug_mock): '"resellerId":["3ONEYO1234"],' '"teamName":"Migration Team",' '"licNumber":"10"}'), - call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') + call( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') ]) - - assert request_out != request + assert request_out.toString() == request.toString() assert request_out.id == 'PR-7001-1234-5678' assert request_out.asset.id == 'AS-146-621-424-3' - assert len(request_out.asset.params) == 6 - for i, _ in enumerate(request_out.asset.params): - assert request.asset.params[i].id == request_out.asset.params[i].id - assert request.asset.params[i].value == request_out.asset.params[i].value + assert len(request_out.asset.params.toArray()) == 6 + for i, _ in enumerate(request_out.asset.params.toArray()): + assert request.asset.params.get(i).id == request_out.asset.params.get( + i).id + assert request.asset.params.get( + i).value == request_out.asset.params.get(i).value -@patch('connect_migration.logger.error') -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') +@patch('connect.logger.Logger.error') +@patch('connect.logger.Logger.debug') +@patch('connect.logger.Logger.info') def test_migration_wrong_info(info_mock, debug_mock, error_mock): # type: (Mock, Mock, Mock) -> None response = _load_str('request.migrate.invalid.json') - request = Fulfillment.deserialize(response) + request = Model.parse(AssetRequest, response) handler = connect_migration.MigrationHandler() - with pytest.raises(SkipRequest): + with pytest.raises(MigrationAbortError): handler.migrate(request) assert info_mock.call_count == 1 - info_mock.assert_called_with('[MIGRATION::PR-7001-1234-5678] Running migration operations ' - 'for request PR-7001-1234-5678') + info_mock.assert_called_with( + '[MIGRATION::PR-7001-1234-5678] Running migration operations ' + 'for request PR-7001-1234-5678') assert debug_mock.call_count == 1 - debug_mock.assert_called_with('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info`: ' - '"teamAdminEmail":"example.migration@mailinator.com",' - '"teamId":"dbtid:AADaQq_w53nMDQbIPM_X123456PuzpcM2BI",' - '"resellerId":["3ONEYO1234"],' - '"teamName":"Migration Team",' - '"licNumber":"10"}') + debug_mock.assert_called_with( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info`: ' + '"teamAdminEmail":"example.migration@mailinator.com",' + '"teamId":"dbtid:AADaQq_w53nMDQbIPM_X123456PuzpcM2BI",' + '"resellerId":["3ONEYO1234"],' + '"teamName":"Migration Team",' + '"licNumber":"10"}') assert error_mock.call_count == 1 # The following assertion fails on macOS, so it has been disabled for now @@ -145,12 +151,12 @@ def test_migration_wrong_info(info_mock, debug_mock, error_mock): # 'line 1 column 17 - line 1 column 179 (char 16 - 178)') -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') -def test_migration_direct(info_mock, debug_mock): +@patch('connect.logger.Logger.info') +@patch('connect.logger.Logger.debug') +def test_migration_direct(debug_mock, info_mock): # type: (Mock, Mock) -> None response = _load_str('request.migrate.direct.success.json') - request = Fulfillment.deserialize(response) + request = Model.parse(AssetRequest, response) handler = connect_migration.MigrationHandler() request_out = handler.migrate(request) @@ -158,18 +164,21 @@ def test_migration_direct(info_mock, debug_mock): assert request_out != request assert request_out.id == 'PR-7001-1234-5678' assert request_out.asset.id == 'AS-146-621-424-3' - assert len(request_out.asset.params) == 6 - assert request_out.asset.get_param_by_id('email').value == 'example.migration@mailinator.com' + assert request_out.asset.params.length() == 6 + assert request_out.asset.get_param_by_id( + 'email').value == 'example.migration@mailinator.com' assert request_out.asset.get_param_by_id('num_licensed_users').value == '10' assert request_out.asset.get_param_by_id('reseller_id').value == '' - assert request_out.asset.get_param_by_id('team_id').value == 'dbtid:AADaQq_'\ + assert request_out.asset.get_param_by_id('team_id').value == 'dbtid:AADaQq_' \ 'w53nMDQbIPM_X123456PuzpcM2BI' - assert request_out.asset.get_param_by_id('team_name').value == 'Migration Team' + assert request_out.asset.get_param_by_id( + 'team_name').value == 'Migration Team' assert info_mock.call_count == 2 info_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' - 'PR-7001-1234-5678'), + call( + '[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' + 'PR-7001-1234-5678'), call('[MIGRATION::PR-7001-1234-5678] 5 processed, 4 succeeded ' '(email, num_licensed_users, team_id, team_name), 0 failed, 1 skipped (reseller_id).') ]) @@ -181,28 +190,38 @@ def test_migration_direct(info_mock, debug_mock): '"team_id":"dbtid:AADaQq_w53nMDQbIPM_X123456PuzpcM2BI",' '"team_name":"Migration Team",' '"num_licensed_users":"10"}'), - call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') + call( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') ]) -@patch('connect_migration.logger.error') -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') -def test_migration_direct_no_serialize(info_mock, debug_mock, error_mock): - # type: (Mock, Mock, Mock) -> None +@patch('connect.logger.Logger.info') +@patch('connect.logger.Logger.debug') +def test_migration_direct_serialize(debug_mock, info_mock): + # type: (Mock, Mock) -> None response = _load_str('request.migrate.direct.notserialized.json') - request = Fulfillment.deserialize(response) + request = Model.parse(AssetRequest, response) - handler = connect_migration.MigrationHandler() - with pytest.raises(SkipRequest): - handler.migrate(request) + handler = connect_migration.MigrationHandler(serialize=True) + request_out = handler.migrate(request) + + assert request_out != request + assert request_out.id == 'PR-7001-1234-5678' + assert request_out.asset.id == 'AS-146-621-424-3' + assert request_out.asset.params.length() == 6 + assert request_out.asset.get_param_by_id( + 'email').value == 'example.migration@mailinator.com' + team_name = request_out.asset.get_param_by_id('team_name').value + assert isinstance(team_name, six.string_types) + assert team_name == '["Some name"]' assert info_mock.call_count == 2 info_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Running migration operations ' - 'for request PR-7001-1234-5678'), - call('[MIGRATION::PR-7001-1234-5678] 5 processed, 1 succeeded (email), ' - '1 failed (team_name), 3 skipped (num_licensed_users, reseller_id, team_id).') + call( + '[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' + 'PR-7001-1234-5678'), + call('[MIGRATION::PR-7001-1234-5678] 5 processed, 2 succeeded ' + '(email, team_name), 0 failed, 3 skipped (num_licensed_users, reseller_id, team_id).') ]) assert debug_mock.call_count == 2 @@ -210,43 +229,29 @@ def test_migration_direct_no_serialize(info_mock, debug_mock, error_mock): call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info`: {' '"email":"example.migration@mailinator.com",' '"team_name":["Some name"]}'), - call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') - ]) - - assert error_mock.call_count == 2 - error_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Parameter team_name type must be str, ' - 'but list was given'), - call('[MIGRATION::PR-7001-1234-5678] Processing of parameters team_name failed, ' - 'unable to complete migration.') + call( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') ]) -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') -def test_migration_direct_serialize(info_mock, debug_mock): - # type: (Mock, Mock) -> None +@patch('connect.logger.Logger.error') +@patch('connect.logger.Logger.debug') +@patch('connect.logger.Logger.info') +def test_migration_direct_no_serialize(info_mock, debug_mock, error_mock): + # type: (Mock, Mock, Mock) -> None response = _load_str('request.migrate.direct.notserialized.json') - request = Fulfillment.deserialize(response) - - handler = connect_migration.MigrationHandler(serialize=True) - request_out = handler.migrate(request) + request = Model.parse(AssetRequest, response) - assert request_out != request - assert request_out.id == 'PR-7001-1234-5678' - assert request_out.asset.id == 'AS-146-621-424-3' - assert len(request_out.asset.params) == 6 - assert request_out.asset.get_param_by_id('email').value == 'example.migration@mailinator.com' - team_name = request_out.asset.get_param_by_id('team_name').value - assert isinstance(team_name, six.string_types) - assert team_name == '["Some name"]' + handler = connect_migration.MigrationHandler() + with pytest.raises(MigrationAbortError): + handler.migrate(request) assert info_mock.call_count == 2 info_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' - 'PR-7001-1234-5678'), - call('[MIGRATION::PR-7001-1234-5678] 5 processed, 2 succeeded ' - '(email, team_name), 0 failed, 3 skipped (num_licensed_users, reseller_id, team_id).') + call('[MIGRATION::PR-7001-1234-5678] Running migration operations ' + 'for request PR-7001-1234-5678'), + call('[MIGRATION::PR-7001-1234-5678] 5 processed, 1 succeeded (email), ' + '1 failed (team_name), 3 skipped (num_licensed_users, reseller_id, team_id).') ]) assert debug_mock.call_count == 2 @@ -254,45 +259,64 @@ def test_migration_direct_serialize(info_mock, debug_mock): call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info`: {' '"email":"example.migration@mailinator.com",' '"team_name":["Some name"]}'), - call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') + call( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') + ]) + + assert error_mock.call_count == 2 + error_mock.assert_has_calls([ + call( + '[MIGRATION::PR-7001-1234-5678] Parameter team_name type must be str, ' + 'but list was given'), + call( + '[MIGRATION::PR-7001-1234-5678] Processing of parameters team_name failed, ' + 'unable to complete migration.') ]) -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') -def test_migration_transform(info_mock, debug_mock): +@patch('connect.logger.Logger.info') +@patch('connect.logger.Logger.debug') +def test_migration_transform(debug_mock, info_mock): # type: (Mock, Mock) -> None response = _load_str('request.migrate.transformation.json') - request = Fulfillment.deserialize(response) + request = Model.parse(AssetRequest, response) handler = connect_migration.MigrationHandler({ 'email': lambda data, request_id: data['teamAdminEmail'].upper(), 'team_id': lambda data, request_id: data['teamId'].upper(), 'team_name': lambda data, request_id: data['teamName'].upper(), - 'num_licensed_users': lambda data, request_id: int(data['licNumber']) * 10 + 'num_licensed_users': lambda data, request_id: int( + data['licNumber']) * 10 }) request_out = handler.migrate(request) assert request_out != request assert request_out.id == 'PR-7001-1234-5678' assert request_out.asset.id == 'AS-146-621-424-3' - assert len(request_out.asset.params) == 6 - assert request_out.asset.get_param_by_id('email').value == 'EXAMPLE.MIGRATION@MAILINATOR.COM' + assert request_out.asset.params.length() == 6 + assert request_out.asset.get_param_by_id( + 'email').value == 'EXAMPLE.MIGRATION@MAILINATOR.COM' assert request_out.asset.get_param_by_id('num_licensed_users').value == 100 assert request_out.asset.get_param_by_id('reseller_id').value == '' - assert request_out.asset.get_param_by_id('team_id').value == 'DBTID:AADAQQ_'\ + assert request_out.asset.get_param_by_id('team_id').value == 'DBTID:AADAQQ_' \ 'W53NMDQBIPM_X123456PUZPCM2BI' - assert request_out.asset.get_param_by_id('team_name').value == 'MIGRATION TEAM' + assert request_out.asset.get_param_by_id( + 'team_name').value == 'MIGRATION TEAM' assert info_mock.call_count == 6 info_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' - 'PR-7001-1234-5678'), - call('[MIGRATION::PR-7001-1234-5678] Running transformation for parameter email'), - call('[MIGRATION::PR-7001-1234-5678] Running transformation for parameter ' - 'num_licensed_users'), - call('[MIGRATION::PR-7001-1234-5678] Running transformation for parameter team_id'), - call('[MIGRATION::PR-7001-1234-5678] Running transformation for parameter team_name'), + call( + '[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' + 'PR-7001-1234-5678'), + call( + '[MIGRATION::PR-7001-1234-5678] Running transformation for parameter email'), + call( + '[MIGRATION::PR-7001-1234-5678] Running transformation for parameter ' + 'num_licensed_users'), + call( + '[MIGRATION::PR-7001-1234-5678] Running transformation for parameter team_id'), + call( + '[MIGRATION::PR-7001-1234-5678] Running transformation for parameter team_name'), call('[MIGRATION::PR-7001-1234-5678] 5 processed, 4 succeeded ' '(email, num_licensed_users, team_id, team_name), 0 failed, 1 skipped (reseller_id).') ]) @@ -304,31 +328,34 @@ def test_migration_transform(info_mock, debug_mock): '"teamId":"dbtid:AADaQq_w53nMDQbIPM_X123456PuzpcM2BI",' '"teamName":"Migration Team",' '"licNumber":"10"}'), - call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') + call( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') ]) -@patch('connect_migration.logger.error') -@patch('connect_migration.logger.debug') -@patch('connect_migration.logger.info') +@patch('connect.logger.Logger.error') +@patch('connect.logger.Logger.debug') +@patch('connect.logger.Logger.info') def test_migration_transform_manual_fail(info_mock, debug_mock, error_mock): - # type: (Mock, Mock, Mock) -> None + # type: (Mock,Mock,Mock) -> None response = _load_str('request.migrate.transformation.json') - request = Fulfillment.deserialize(response) + request = Model.parse(AssetRequest, response) handler = connect_migration.MigrationHandler({ 'email': _raise_error }) - with pytest.raises(SkipRequest): + with pytest.raises(MigrationAbortError): handler.migrate(request) assert info_mock.call_count == 3 info_mock.assert_has_calls([ - call('[MIGRATION::PR-7001-1234-5678] Running migration operations for request ' - 'PR-7001-1234-5678'), - call('[MIGRATION::PR-7001-1234-5678] Running transformation for parameter email'), - call('[MIGRATION::PR-7001-1234-5678] 5 processed, 0 succeeded, 1 failed (email), ' - '4 skipped (num_licensed_users, reseller_id, team_id, team_name).') + call( + '[MIGRATION::PR-7001-1234-5678] Running migration operations for request PR-7001-1234-5678'), + call( + '[MIGRATION::PR-7001-1234-5678] Running transformation for parameter email'), + call( + '[MIGRATION::PR-7001-1234-5678] 5 processed, 0 succeeded, 1 failed (email), ' + '4 skipped (num_licensed_users, reseller_id, team_id, team_name).') ]) assert debug_mock.call_count == 2 @@ -338,14 +365,16 @@ def test_migration_transform_manual_fail(info_mock, debug_mock, error_mock): '"teamId":"dbtid:AADaQq_w53nMDQbIPM_X123456PuzpcM2BI",' '"teamName":"Migration Team",' '"licNumber":"10"}'), - call('[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') + call( + '[MIGRATION::PR-7001-1234-5678] Migration data `migration_info` parsed correctly') ]) assert error_mock.call_count == 2 error_mock.assert_has_calls([ call('[MIGRATION::PR-7001-1234-5678] Manual fail.'), - call('[MIGRATION::PR-7001-1234-5678] Processing of parameters email failed, ' - 'unable to complete migration.') + call( + '[MIGRATION::PR-7001-1234-5678] Processing of parameters email failed, ' + 'unable to complete migration.') ])