"""Tests for copy product logic.""" from unittest.mock import MagicMock from oto import response from owsrequest import request import pytest from product.constants import error from product.logic import localization from product.logic import product as product_logic from product.logic import product_copy as product_copy_logic from product.logic import upc as upc_logic from product.models import ows_assets from product.models import ows_carveouts from product.models import ows_marketing from product.models import ows_pricing from product.models import ows_product_digital as opd_model from product.models import ows_product_physical as opp_model from product.models import ows_track orchard_user_id = 'alw:56789' opp_track_response = { 'label': 'label', 'genre_id': 1, 'subgenre_id': 1, 'cline': 'cline', 'product_highlights': 'product_highlights', 'release_date': 'release_date', 'sale_start_date': 'sale_start_date', 'primary_artist': 'primary_artist', 'pline': 'pline', 'explicit': 'N' } def _general_copy_physical_patch(mocker, expected_response): mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) mocker.patch.object( opp_model, 'copy_product_tracks', return_value=response.Response(status=201)) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201)) mocker.patch.object( ows_marketing, 'copy_product_highlights', return_value=response.Response(status=201)) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200)) def test_logic_copy_physical_product_success(mocker): """Test copy product success.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} _general_copy_physical_patch(mocker, expected_response) result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 200 assert result.message == expected_response def test_logic_copy_physical_product_opp_down(mocker, context): """Test copy product when ows-product-physical returns an error.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} expected_status = 500 expected_response = 'The oops message ows-product-physical returned.' mocker.patch.object( opp_model, 'copy_product', return_value=response.Response( status=expected_status, message=expected_response)) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == expected_status assert result.message == expected_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product (ows-product-physical)') def test_logic_copy_physical_product_tracks_copy_fail(mocker, context): """Test copy product when ows-product-physical fails on tracks copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) copy_tracks_response = response.create_fatal_response() mocker.patch.object( opp_model, 'copy_product_tracks', return_value=copy_tracks_response ) delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=response.Response() ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) delete_product.assert_called_once_with(new_product_id) assert result is copy_tracks_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product tracks (ows-product-physical)') def test_logic_copy_physical_product_carveouts_copy_fail(mocker, context): """Test copy product when ows-product-physical fails on tracks copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) mocker.patch.object( opp_model, 'copy_product_tracks', return_value=response.Response(status=201) ) copy_carveouts_response = response.create_fatal_response() mocker.patch.object( ows_carveouts, 'copy', return_value=copy_carveouts_response ) delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=response.Response() ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) delete_product.assert_called_once_with(new_product_id) assert result is copy_carveouts_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product carveouts (ows-carveouts)') def test_logic_copy_physical_product_highlights_copy_fail(mocker, context): """Test copy product when ows-marketing fails on highlights copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=response.Response() ) mocker.patch.object( opp_model, 'copy_product_tracks', return_value=response.Response(status=201) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) copy_highlights_response = response.create_fatal_response() mocker.patch.object( ows_marketing, 'copy_product_highlights', return_value=copy_highlights_response ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) delete_product.assert_called_once_with(new_product_id) assert result is copy_highlights_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product highlights (ows-marketing)') def test_logic_copy_physical_product_assets_copy_fail(mocker, context): """Test copy product when ows-marketing fails on highlights copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=response.Response() ) mocker.patch.object( opp_model, 'copy_product_tracks', return_value=response.Response(status=201) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_marketing, 'copy_product_highlights', return_value=response.Response(status=201) ) copy_assets_response = response.create_fatal_response() mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=copy_assets_response ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) delete_product.assert_called_once_with(new_product_id) assert result is copy_assets_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product assets (ows-assets)') def test_logic_copy_physical_product_tracks_copy_fail_delete_fail( mocker, context): """Test copy product when ows-product-physical fails on tracks copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) copy_tracks_response = response.create_fatal_response() mocker.patch.object( opp_model, 'copy_product_tracks', return_value=copy_tracks_response ) delete_product_response = response.create_fatal_response() delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=delete_product_response ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) delete_product.assert_called_once_with(new_product_id) assert result is delete_product_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product tracks (ows-product-physical)') def test_logic_copy_product_not_found(mocker): """Test copy product when product is not found.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response(status=404)) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 404 def test_logic_copy_digital_product_success( mocker): """Test copy digital product success.""" existing_product_id = 93 account_type = 'vendor' account_id = 123 product_data_changes = { 'some_key': 'some value', 'upc': 'cool upc', 'product_code': 'cool code'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( upc_logic, 'upc_available', return_value=response.Response()) mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response(message={'context_type': 'digital'})) mocker.patch.object( product_logic, 'product_code_found_for_account', return_value=response.create_not_found_response()) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=200) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) artwork_mock = mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id, account_type, account_id) assert result.status == 200 assert result.message == expected_response assert artwork_mock.called def test_logic_copy_digital_product_fail_product_code( mocker): """Test copy digital fail because of product code.""" existing_product_id = 93 account_type = 'vendor' account_id = 123 product_data_changes = {'product_code': 'cool code'} mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response(message={'context_type': 'digital'})) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id, account_type, account_id) assert result.status == 400 def test_logic_copy_digital_product_no_account_data_success( mocker): """Test copy digital product success without account_id and type.""" existing_product_id = 93 product_data_changes = { 'some_key': 'some value', 'upc': 'cool upc'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( upc_logic, 'upc_available', return_value=response.Response()) mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response(message={'context_type': 'digital'})) product_code_available = mocker.patch.object( product_logic, 'product_code_found_for_account', return_value=response.Response()) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=200) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 200 assert result.message == expected_response product_code_available.assert_not_called() def test_logic_copy_digital_product_no_product_code_success( mocker): """Test copy digital product success without product code.""" existing_product_id = 93 account_type = 'vendor' account_id = 123 product_data_changes = { 'some_key': 'some value', 'upc': 'cool upc'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( upc_logic, 'upc_available', return_value=response.Response()) mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response(message={'context_type': 'digital'})) product_code_available = mocker.patch.object( product_logic, 'product_code_found_for_account', return_value=response.Response()) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=200) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id, account_type, account_id) assert result.status == 200 assert result.message == expected_response product_code_available.assert_not_called() def test_logic_copy_digital_product_no_upc_success(mocker): """Test copy digital product success without upc in request body.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( upc_logic, 'upc_available', return_value=response.Response()) mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response(message={'context_type': 'digital'})) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=200) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 200 assert result.message == expected_response def test_logic_copy_digital_product_product_code_unavailable(mocker, context): """Test copy product when product_code from request is unavailable.""" existing_product_id = 93 product_data_changes = { 'some_key': 'some value', 'product_code': 'some_unavailable_code'} account_type = 'vendor' account_id = 1 expected_status = 200 mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( product_logic, 'product_code_found_for_account', return_value=response.Response(status=expected_status)) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id, account_type, account_id) assert result.status == 400 assert result.errors.get('message') == ( error.ERROR_MESSAGE_PRODUCT_CODE_UNAVAILABLE) def test_logic_copy_digital_product_upc_unavailable(mocker, context): """Test copy product when upc from request is unavailable.""" existing_product_id = 93 product_data_changes = { 'some_key': 'some value', 'upc': 'some_unavailable_upc'} expected_status = 400 expected_response = 'Provided upc is already in use.' mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( upc_logic, 'upc_available', return_value=response.Response( status=expected_status, message=expected_response)) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == expected_status assert result.errors.get('message') == error.ERROR_MESSAGE_UPC_UNAVAILABLE context.g.ows.log.warning.assert_called_with( 'Error: upc some_unavailable_upc is unavailable') def test_logic_copy_digital_product_opd_down(mocker, context): """Test copy product when ows-product-digital returns an error.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} expected_status = 500 expected_response = 'The oops message ows-product-digital returned.' mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response( status=expected_status, message=expected_response)) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == expected_status assert result.message == expected_response context.g.ows.log.warning.assert_called_with( 'Error 500 copying product (ows-product-digital)') def test_logic_copy_digital_product_localization_copy_fail(mocker, context): """Test copy product when ows-product fails on localization copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) copy_localization_response = response.create_fatal_response() mocker.patch.object( localization, 'copy_localization', return_value=copy_localization_response) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=201) ) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result context.g.ows.log.warning.assert_called_with( 'Error 500 copying product localization (ows-product)') def test_logic_copy_digital_product_tracks_copy_fail(mocker, context): """Test copy product when ows-track fails on tracks copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) copy_tracks_response = response.create_fatal_response() mocker.patch.object( ows_track, 'copy_product_tracks', return_value=copy_tracks_response ) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result context.g.ows.log.warning.assert_called_with( 'Error 500 copying product tracks (ows-track)') def test_logic_copy_digital_product_pricing_copy_fail(mocker, context): """Test copy product when ows-pricing fails on pricing copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=200) ) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.create_fatal_response()) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result context.g.ows.log.warning.assert_called_with( 'Error 500 copying product pricing (ows-pricing)') def test_logic_copy_digital_product_carveouts_copy_fail(mocker, context): """Test copy product when ows-carveouts fails on territory copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'digital'})) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response(message=expected_response)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=200)) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=201) ) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=200)) copy_carveouts_response = response.create_fatal_response() mocker.patch.object( ows_carveouts, 'copy', return_value=copy_carveouts_response ) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=200) ) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result context.g.ows.log.warning.assert_called_with( 'Error 500 copying product carveouts (ows-carveouts)') def test_logic_copy_physical_product_assets_copy_not_found_failure( mocker, context): """Test copy physical product when ows-assets fails on assets copy.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} new_product_id = 98765 expected_response = {'product_id': new_product_id} mocker.patch.object( opp_model, 'copy_product', return_value=response.Response(message=expected_response)) delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=response.Response() ) mocker.patch.object( opp_model, 'copy_product_tracks', return_value=response.Response(status=201) ) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=201) ) mocker.patch.object( ows_marketing, 'copy_product_highlights', return_value=response.Response(status=201) ) copy_assets_response = response.create_not_found_response() mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=copy_assets_response ) result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) delete_product.assert_not_called() assert result.status == 200 def test_logic_copy_product_physical_context_success(mocker): """Test success copy product when context type if physical.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'physical'})) mocker.patch.object(product_copy_logic, '_copy_physical_product', return_value=response.Response()) result = product_copy_logic.copy_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 200 def test_logic_copy_physical_product_pricing_tier(mocker): """Test copy product phys product fail with wrong pricing response.""" existing_product_id = 93 product_data_changes = { 'some_key': 'some value', 'orchard_pricing_tier': 1} new_product_id = 98765 expected_response = {'product_id': new_product_id} _general_copy_physical_patch(mocker, expected_response) post_tier = mocker.patch.object( request, 'put', return_value=MagicMock(status_code=200)) result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 200 post_tier.assert_called_with( 'ows-pricing', '/product/98765/pricing-family/4/orchard_pricing_tier', json={'orchard_pricing_tier_id': 1}) def test_logic_copy_physical_product_fail_on_pricing( mocker, context): """Test copy product phys product fail with wrong pricing response.""" existing_product_id = 93 product_data_changes = { 'some_key': 'some value', 'orchard_pricing_tier': 1} new_product_id = 98765 expected_response = {'product_id': new_product_id} _general_copy_physical_patch(mocker, expected_response) post_tier = mocker.patch.object(request, 'put', side_effect=Exception) delete_product = mocker.patch.object( product_logic, 'delete_product', return_value=response.Response()) result = product_copy_logic._copy_physical_product( existing_product_id, product_data_changes, orchard_user_id) assert result.status == 500 assert delete_product.called post_tier.assert_called_with( 'ows-pricing', '/product/98765/pricing-family/4/orchard_pricing_tier', json={'orchard_pricing_tier_id': 1}) @pytest.mark.parametrize( ('product_code', 'upc', 'product_status', 'product_message', 'l10n', 'artwork', 'tracks', 'pricing', 'carveouts', 'marketing', 'expected_result', 'log'), [ (404, 200, 200, {'product_id': 234567}, 200, 200, 200, 200, 200, 201, response.Response({'product_id': 234567}), ''), (200, 0, 0, '', 0, 0, 0, 0, 0, 200, response.create_error_response( code=error.ERROR_CODE_PRODUCT_CODE_UNAVAILABLE, message=error.ERROR_MESSAGE_PRODUCT_CODE_UNAVAILABLE), ''), (404, 403, 0, '', 0, 0, 0, 0, 0, 200, response.create_error_response( code=error.ERROR_CODE_UPC_UNAVAILABLE, message=error.ERROR_MESSAGE_UPC_UNAVAILABLE), 'Error: upc 123456789123 is unavailable'), (404, 200, 400, 'oops', 200, 200, 200, 200, 200, 200, response.Response(status=400, message='oops'), 'Error 400 copying product (ows-product-digital)'), (404, 200, 200, {'product_id': 234567}, 400, 200, 200, 200, 200, 201, response.Response(message={'product_id': 234567}), 'Error 400 copying product localization (ows-product)'), (404, 200, 200, {'product_id': 234567}, 200, 400, 200, 200, 200, 201, response.Response(message={'product_id': 234567}), 'Error 400 copying product assets (ows-assets)'), (404, 200, 200, {'product_id': 234567}, 200, 200, 400, 200, 200, 201, response.Response(message={'product_id': 234567}), 'Error 400 copying product tracks (ows-track)'), (404, 200, 200, {'product_id': 234567}, 200, 200, 200, 400, 200, 201, response.Response(message={'product_id': 234567}), 'Error 400 copying product pricing (ows-pricing)'), (404, 200, 200, {'product_id': 234567}, 200, 200, 200, 200, 400, 201, response.Response(message={'product_id': 234567}), 'Error 400 copying product carveouts (ows-carveouts)'), ]) def test__copy_digital_product( product_code, upc, product_status, product_message, l10n, artwork, tracks, pricing, carveouts, marketing, expected_result, log, mocker, context): """Test _copy_digital_product.""" mocker.patch.object( product_logic, 'product_code_found_for_account', return_value=response.Response(status=product_code)) mocker.patch.object( upc_logic, 'upc_available', return_value=response.Response(status=upc, message='upc')) mocker.patch.object( opd_model, 'copy_digital_product', return_value=response.Response( status=product_status, message=product_message)) mocker.patch.object( localization, 'copy_localization', return_value=response.Response(status=l10n, message='l10n')) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=artwork, message='artwork')) mocker.patch.object( ows_track, 'copy_product_tracks', return_value=response.Response(status=tracks, message='tracks')) mocker.patch.object( ows_pricing, 'copy_product_pricing', return_value=response.Response(status=pricing, message='pricing')) mocker.patch.object( ows_carveouts, 'copy', return_value=response.Response(status=carveouts, message='carveouts')) field_overrides = { 'product_code': 'code_cool', 'upc': 123456789123 } with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic._copy_digital_product( 123456, field_overrides, 'alw:123456', 'vendor', 123456) if log: context.g.ows.log.warning.assert_called_with(log) assert result.status == expected_result.status assert result.message == expected_result.message assert result.errors == expected_result.errors @pytest.mark.parametrize( ('from_context_type', 'to_context_type', 'status', 'message'), [ ('physical', 'physical', 200, 'p2p'), ('physical', 'digital', 200, 'p2d'), ('digital', 'digital', 200, 'd2d'), ('digital', 'physical', 400, 'Unsupported copy type') ]) def test_logic_copy_product_flexible( from_context_type, to_context_type, status, message, mocker): """Test copy_product_flexible.""" mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response({ 'context_type': from_context_type, 'project_id': '456' })) mocker.patch.object( product_copy_logic, '_copy_physical_product', return_value=response.Response('p2p')) mocker.patch.object( product_copy_logic, '_copy_physical_to_digital', return_value=response.Response('p2d')) mocker.patch.object( product_copy_logic, '_copy_digital_product', return_value=response.Response('d2d')) field_overrides = { 'testing': 123 } result = product_copy_logic.copy_product_flexible( 123, to_context_type, field_overrides, 'alw:789', 'vendor', 101) assert result.status == status assert result.message == message def test_logic_copy_product_flexible_to_phys_success(mocker): """Test success copy product when context type if physical.""" existing_product_id = 93 product_data_changes = {'some_key': 'some value'} mocker.patch.object(product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'physical'})) mocker.patch.object(product_copy_logic, '_copy_physical_product', return_value=response.Response()) result = product_copy_logic.copy_product_flexible( existing_product_id, 'physical', product_data_changes, orchard_user_id) assert result.status == 200 flexible_success = (200, 200, 200, 200, 200, 200, 200, 200, 200) get_product_fails = (500, 500, 200, 200, 200, 200, 200, 200, 200) create_digital_fails = (500, 200, 500, 200, 200, 200, 200, 200, 200) update_digital_fails = (500, 200, 200, 500, 200, 200, 200, 200, 200) copy_assets_fails = (500, 200, 200, 200, 500, 200, 200, 200, 200) get_product_physical_fails = (500, 200, 200, 200, 200, 500, 200, 200, 200) get_tracks_fails = (500, 200, 200, 200, 200, 200, 500, 200, 200) create_product_track_fails = (500, 200, 200, 200, 200, 200, 200, 500, 200) update_product_track_fails = (500, 200, 200, 200, 200, 200, 200, 200, 500) @pytest.mark.parametrize( 'status,get_product_by_product_id,create_digital_product,' + 'update_digital_product,copy_product_artwork,' + 'get_product_by_product_id_physical,get_tracks,' + 'create_product_track,update_product_track', [ flexible_success, get_product_fails, create_digital_fails, update_digital_fails, copy_assets_fails, get_product_physical_fails, get_tracks_fails, create_product_track_fails, update_product_track_fails ]) def test_logic_copy_product_flexible_to_dig( context, mocker, status, get_product_by_product_id, create_digital_product, update_digital_product, copy_product_artwork, get_product_by_product_id_physical, get_tracks, create_product_track, update_product_track ): """Test success copy product when context type if physical.""" new_product_id = 1 existing_product_id = 93 product_data_changes = {'some_key': 'some value'} account_id = '123' account_type = 'subaccount' mocker.patch.object( product_logic, 'get_product_by_product_id', return_value=response.Response( message={'context_type': 'physical'}, status=get_product_by_product_id )) mocker.patch.object( opd_model, 'create_digital_product', return_value=response.Response( message={'product_id': new_product_id}, status=create_digital_product )) mocker.patch.object( opd_model, 'update_digital_product', return_value=response.Response(status=update_digital_product)) mocker.patch.object( ows_assets, 'copy_product_artwork', return_value=response.Response(status=copy_product_artwork)) mocker.patch.object( opp_model, 'get_product_by_product_id', return_value=response.Response( message=opp_track_response, status=get_product_by_product_id_physical)) mocker.patch.object( opp_model, 'get_tracks', return_value=response.Response( status=get_tracks, message={'items': [{ 'track_name': 'Porridge', 'performer': ['PorridgeFace'], 'isrc': 'isrc' }]})) mocker.patch.object( ows_track, 'create_product_track', return_value=response.Response( message={'tuid': 3}, status=create_product_track )) mocker.patch.object( ows_track, 'update_product_track', return_value=response.Response( status=update_product_track )) with context: mocker.spy(context.g.ows.log, 'warning') result = product_copy_logic.copy_product_flexible( existing_product_id, 'digital', product_data_changes, orchard_user_id, account_type, account_id ) assert result.status == status if status == 200: assert result.message['product_id'] == new_product_id