"""Test for copy_product assets module.""" import flexmock from oto import response import pytest from assets.constants import asset_legacy from assets.logic.legacy import copy_product_assets from assets.logic.legacy import import_asset as import_asset_logic from assets.logic.legacy import track from assets.models import ows_product @pytest.fixture def fixture_ok_response(): """Generic success response fixture.""" return response.Response('ok') @pytest.fixture def fixture_error_response(): """Generic error response fixture.""" return response.create_error_response('generic', 'error') @pytest.fixture def correct_ows_track_product_tracks(): """Correct data for _get_product_tracks.""" return { 'items': [ { 'tuid': 2232323232, 'product_id': 123, 'track_number': 1, 'volume_number': 1 } ] } def test_get_product_tracks_success(correct_ows_track_product_tracks): """Test for getting product tracks success.""" product_id = 123 (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .and_return(correct_ows_track_product_tracks)) result = copy_product_assets._get_product_tracks(product_id) assert result def test_get_product_tracks_failure(correct_ows_track_product_tracks): """Test for getting product tracks success.""" product_id = 123 (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .and_return(response.create_fatal_response('fatal_error'))) result = copy_product_assets._get_product_tracks(product_id) assert not result @pytest.fixture def correct_from_tracks(): """Correct source tracks data.""" return [ { 'track_unique_id': 123, 'volume': 1, 'track': 1 }, { 'track_unique_id': 124, 'volume': 1, 'track': 2 }, { 'track_unique_id': 125, 'volume': 2, 'track': 1 } ] @pytest.fixture def correct_to_tracks(): """Correct dest tracks data.""" return [ { 'track_unique_id': 223, 'volume': 1, 'track': 1 }, { 'track_unique_id': 225, 'volume': 2, 'track': 1 }, { 'track_unique_id': 224, 'volume': 1, 'track': 2 } ] def test_match_tracks_success(correct_from_tracks, correct_to_tracks): """Test for successful track matching.""" result = copy_product_assets._match_tracks( correct_from_tracks, correct_to_tracks) assert result message = result.message track_1 = message[123] assert track_1['to_tuid'] == 223 assert track_1['volume'] == 1 assert track_1['number'] == 1 track_2 = message[124] assert track_2['to_tuid'] == 224 assert track_2['volume'] == 1 assert track_2['number'] == 2 track_3 = message[125] assert track_3['to_tuid'] == 225 assert track_3['volume'] == 2 assert track_3['number'] == 1 def test_match_tracks_not_equal_failure( correct_from_tracks, correct_to_tracks): """Test for not equal track number failure.""" correct_from_tracks.pop(0) result = copy_product_assets._match_tracks( correct_from_tracks, correct_to_tracks) assert not result assert result.status == 500 error = 'Number of tracks are not equal: 2 <> 3' assert result.errors['message'] == error def test_match_tracks_missing_track(correct_from_tracks, correct_to_tracks): """Test for missing track match.""" correct_from_tracks[0]['volume'] = 3 result = copy_product_assets._match_tracks( correct_from_tracks, correct_to_tracks) assert not result assert result.status == 500 assert result.errors['message'] == 'Failed to match tracks for products.' @pytest.fixture def copy_product_assets_args(): """Correct data for copy_product_assets data.""" return { 'from_product_id': 1001, 'to_product_id': 2001, 'full_user_id': 'alw:12345' } @pytest.fixture def from_product_tracks_mock(): """Source product tracks mock.""" data = [ { 'track_unique_id': 101, 'volume': 1, 'track': 1 }, { 'track_unique_id': 102, 'volume': 1, 'track': 2 } ] return response.Response(message=data) @pytest.fixture def to_product_tracks_mock(): """Destination product tracks mock.""" data = [ { 'track_unique_id': 201, 'volume': 1, 'track': 1 }, { 'track_unique_id': 202, 'volume': 1, 'track': 2 } ] return response.Response(message=data) @pytest.fixture def copy_product_assets_mocks( from_product_tracks_mock, to_product_tracks_mock): """Mock methods for copy_product_assets subcalls.""" ok_response = response.Response() return { 'get_product_by_id_from': response.Response( {'upc': 11, 'status': 'label_processing'}), 'get_product_by_id_to': response.Response( {'upc': 21, 'status': 'label_processing'}), '_get_product_tracks_from': from_product_tracks_mock, '_get_product_tracks_to': to_product_tracks_mock, 'create_import_asset_batch': response.Response( {'import_asset_batch_id': 123} ), 'copy_product_track_assets': ok_response, 'copy_product_image_asset': ok_response, '_need_track_copy': ok_response } def test_copy_product_assets_success( copy_product_assets_args, copy_product_assets_mocks): """Test for copy_product_assets_success.""" (flexmock(ows_product) .should_receive('get_product_by_id') .with_args( 1001 ).ordered() .and_return( copy_product_assets_mocks['get_product_by_id_from'] )) (flexmock(ows_product) .should_receive('get_product_by_id') .with_args( 2001 ).ordered() .and_return( copy_product_assets_mocks['get_product_by_id_to'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .with_args( 1001 ) .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_from'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .with_args( 2001 ) .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_to'] )) (flexmock(import_asset_logic) .should_receive('create_import_asset_batch') .with_args( full_user_id='alw:12345', import_type=asset_legacy.IMPORT_TYPE_COPY ) .and_return( copy_product_assets_mocks['create_import_asset_batch'] )) (flexmock(copy_product_assets) .should_receive('_need_track_copy') .and_return(copy_product_assets_mocks['_need_track_copy'])) (flexmock(track) .should_receive('copy_product_track_assets') .with_args( { 101: { 'number': 1, 'volume': 1, 'to_tuid': 201 }, 102: { 'number': 2, 'volume': 1, 'to_tuid': 202 } }, { 'upc': 11, 'status': 'label_processing' }, { 'upc': 21, 'status': 'label_processing' }, 'alw:12345', asset_batch_data={'import_asset_batch_id': 123} ) .and_return(copy_product_assets_mocks['copy_product_track_assets'])) (flexmock(track) .should_receive('copy_product_image_asset') .with_args( 11, 21, 'alw:12345', asset_batch_data={'import_asset_batch_id': 123}) .and_return(copy_product_assets_mocks['copy_product_image_asset'])) result = copy_product_assets.copy_product_assets( **copy_product_assets_args ) assert result @pytest.mark.parametrize('failing_mock', [ 'get_product_by_id_from', 'get_product_by_id_to', '_get_product_tracks_from', '_get_product_tracks_to', 'copy_product_track_assets', 'copy_product_image_asset' ]) def test_copy_product_assets_failure( copy_product_assets_args, copy_product_assets_mocks, failing_mock): """Test for copy_product_assets failure.""" copy_product_assets_mocks[failing_mock] = response.create_fatal_response( message='%s_failure' % failing_mock ) (flexmock(ows_product) .should_receive('get_product_by_id') .ordered() .and_return( copy_product_assets_mocks['get_product_by_id_from'] )) (flexmock(ows_product) .should_receive('get_product_by_id') .ordered() .and_return( copy_product_assets_mocks['get_product_by_id_to'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_from'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_to'] )) (flexmock(import_asset_logic) .should_receive('create_import_asset_batch') .and_return( copy_product_assets_mocks['create_import_asset_batch'] )) (flexmock(copy_product_assets) .should_receive('_need_track_copy') .and_return(copy_product_assets_mocks['_need_track_copy'])) (flexmock(track) .should_receive('copy_product_track_assets') .and_return(copy_product_assets_mocks['copy_product_track_assets'])) (flexmock(track) .should_receive('copy_product_image_asset') .and_return(copy_product_assets_mocks['copy_product_image_asset'])) result = copy_product_assets.copy_product_assets( **copy_product_assets_args ) assert not result assert result.errors['message'] == '%s_failure' % failing_mock def test_copy_product_assets_no_user_failure( copy_product_assets_args, copy_product_assets_mocks): """Test for copy_product_assets failure.""" (flexmock(ows_product) .should_receive('get_product_by_id') .ordered() .and_return( copy_product_assets_mocks['get_product_by_id_from'] )) (flexmock(ows_product) .should_receive('get_product_by_id') .ordered() .and_return( copy_product_assets_mocks['get_product_by_id_to'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_from'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_to'] )) (flexmock(copy_product_assets) .should_receive('_need_track_copy') .and_return(copy_product_assets_mocks['_need_track_copy'])) (flexmock(track) .should_receive('copy_product_track_assets') .and_return(copy_product_assets_mocks['copy_product_track_assets'])) (flexmock(track) .should_receive('copy_product_image_asset') .and_return(copy_product_assets_mocks['copy_product_image_asset'])) copy_product_assets_args['full_user_id'] = None result = copy_product_assets.copy_product_assets( **copy_product_assets_args ) assert not result assert result.status == 400 @pytest.mark.parametrize('first_check, second_check, times', [ (fixture_ok_response(), fixture_error_response(), 0), (fixture_error_response(), fixture_ok_response(), 0), (fixture_error_response(), fixture_error_response(), 0), (fixture_ok_response(), fixture_ok_response(), 1), ]) def test_copy_product_image_only( copy_product_assets_args, copy_product_assets_mocks, first_check, second_check, times): """Test for copy product only executes image copy when digital.""" (flexmock(ows_product) .should_receive('get_product_by_id') .with_args( 1001 ).ordered() .and_return( copy_product_assets_mocks['get_product_by_id_from'] )) (flexmock(ows_product) .should_receive('get_product_by_id') .with_args( 2001 ).ordered() .and_return( copy_product_assets_mocks['get_product_by_id_to'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .with_args( 1001 ) .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_from'] )) (flexmock(copy_product_assets) .should_receive('_get_product_tracks') .with_args( 2001 ) .ordered() .and_return( copy_product_assets_mocks['_get_product_tracks_to'] )) (flexmock(import_asset_logic) .should_receive('create_import_asset_batch') .with_args( full_user_id='alw:12345', import_type=asset_legacy.IMPORT_TYPE_COPY ) .and_return( copy_product_assets_mocks['create_import_asset_batch'] )) (flexmock(copy_product_assets) .should_receive('_need_track_copy') .and_return(first_check) .and_return(second_check)) (flexmock(track) .should_receive('copy_product_track_assets') .and_return(copy_product_assets_mocks['copy_product_track_assets']) .times(times)) (flexmock(track) .should_receive('copy_product_image_asset') .with_args( 11, 21, 'alw:12345', asset_batch_data={'import_asset_batch_id': 123}) .and_return(copy_product_assets_mocks['copy_product_image_asset'])) result = copy_product_assets.copy_product_assets( **copy_product_assets_args ) assert result @pytest.mark.parametrize('product, expected', [ ({'context_type': 'digital'}, True), ({'context_type': 'DIGITAL'}, False), ({'context_type': 'not-digital'}, False), ({}, False)]) def test_need_track_copy(product, expected): """Test evaluation of whether product needs tracks copied.""" result = copy_product_assets._need_track_copy(product) if expected: assert result else: assert not result