"""Tests for physical product logic.""" import datetime from oto import response import pytest from ows_product_physical.constant import field from ows_product_physical.logic import product_physical from ows_product_physical.models import ows_product from ows_product_physical.models import ows_project from ows_product_physical.models import persister def test_update_product_success_with_display_upc(mocker, feature_engine): """Test update product.""" expected_update_status_code = 200 mocker.patch.object( ows_product, 'is_display_upc_available', return_value=True, autospec=True) mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.DISPLAY_UPC: '111111111111', field.COUNTRY_OF_ORIGIN: 3 } ), autospec=True) mocker.patch.object(persister, 'update_product', autospec=True) mocker.patch.object( persister, 'get_release_by_product_code', return_value=response.Response(message=iter([])), autospec=True) mocker.patch( 'ows_product_physical.logic.product_physical.features.' 'is_ccm_physical_supplychaininfo_oa_enabled', return_value=False, ) data = {} today = datetime.datetime.today() today_plus_10 = datetime.timedelta(days=10) data['sale_start_date'] = (today + today_plus_10).strftime('%Y-%m-%d') data['display_upc'] = '1843563916741' data['country_of_origin'] = 3 update_response = product_physical.update(1234, data, None, None) assert persister.update_product.called fields = persister.update_product.call_args[0][1] assert fields.get(field.UPC) is None assert fields[field.DISPLAY_UPC] == '1843563916741' assert update_response.status == expected_update_status_code @pytest.mark.parametrize( ('upc_field_name', 'upc_field_value'), [ ('display_upc', '565685854679'), ('upc', '565685854679'), ('display_upc', None), ('upc', None) ]) def test_update_product_unable_to_assign_display_upc( mocker, feature_engine, upc_field_name, upc_field_value): """Test update product unable to assign display_upc.""" mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.DISPLAY_UPC: '125434578654', field.COUNTRY_OF_ORIGIN: 3 } ), autospec=True) mocker.patch.object(persister, 'update_product', autospec=True) mocker.patch.object( persister, 'get_release_by_product_code', return_value=response.Response(message=iter([])), autospec=True) mocker.patch.object( ows_product, 'is_display_upc_available', return_value=True, autospec=True) data = {'assign_display_upc': True, 'country_of_origin': 3} data[upc_field_name] = upc_field_value product_physical.update(1324, data, None, None) assert not persister.update_product.called def test_update_product_success_without_display_upc(mocker, feature_engine): """Test update product.""" mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.DISPLAY_UPC: '125434578654', field.COUNTRY_OF_ORIGIN: 3 } ), autospec=True) mocker.patch( 'ows_product_physical.logic.product_physical.features.' 'is_ccm_physical_supplychaininfo_oa_enabled', return_value=False, ) mocker.patch.object(persister, 'update_product', autospec=True) mocker.patch.object( persister, 'get_release_by_product_code', return_value=response.Response(message=iter([])), autospec=True) data = {} today = datetime.datetime.today() today_plus_10 = datetime.timedelta(days=10) data['sale_start_date'] = (today + today_plus_10).strftime('%Y-%m-%d') product_physical.update(1234, data, None, None) assert persister.update_product.called def test_update_product_product_fetch_failure(mocker): """Test update product.""" mocker.patch.object(product_physical, 'fetch_by_id', return_value=response.Response(status=403), autospec=True) mocker.patch.object(persister, 'update_product', autospec=True) product_physical.update(1234, {}, None, None) assert not persister.update_product.called def test_update_product_product_code_uniqueness_check_success( mocker, feature_engine): """Test update product with product code validation enabled - success.""" mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.PRODUCT_CODE: 'PHYS2', field.COUNTRY_OF_ORIGIN: 3 } ), autospec=True) mocker.patch.object( product_physical, 'check_vendor_product_code_uniqueness', return_value=True) mocker.spy(persister, 'update_product') mocker.patch.object( persister, 'get_release_by_product_code', return_value=response.Response(message=iter([])), autospec=True) product_physical.update(1234, { 'product_code': 'PHYS1', 'country_of_origin': 3}, None, None) assert persister.update_product.called def test_update_product_product_code_uniqueness_check_failure( mocker, feature_engine): """Test update product with product code validation enabled - failure.""" mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.PRODUCT_CODE: 'PHYS1', field.COUNTRY_OF_ORIGIN: 3 } ), autospec=True) mocker.patch.object( product_physical, 'check_subaccount_product_code_uniqueness', return_value=response.create_error_response( 'validation_error', 'Product Code in use')) mocker.spy(persister, 'update_product') mocker.patch.object( persister, 'get_release_by_product_code', return_value=response.Response(message=iter([])), autospec=True) product_physical.update(1234, { 'product_code': 'PHYS1', 'country_of_origin': 3}, None, None) assert not persister.update_product.called def test_update_product_check_country_of_origin_exists_success( mocker, feature_engine): """Test update product with country of origin in request - success.""" mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.COUNTRY_OF_ORIGIN: None, }), autospec=True) mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.spy(persister, 'update_product') product_physical.update(1234, {'country_of_origin': 4}, None, None) assert persister.update_product.called def test_update_product_check_country_of_origin_exists_in_DB_success( mocker, feature_engine): """Test update product with country of origin in DB - success.""" mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.COUNTRY_OF_ORIGIN: 12, }), autospec=True) mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.spy(persister, 'update_product') product_physical.update(1234, {'product_name': 'test_product'}, None, None) assert persister.update_product.called def test_update_product_check_country_of_origin_exists_failure( mocker, feature_engine): """Test update when country of origin not in request or DB.""" mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.COUNTRY_OF_ORIGIN: None, }), autospec=True) mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.spy(persister, 'update_product') product_physical.update(1234, {'product_name': 'test_product'}, None, None) assert not persister.update_product.called def test_update_product_updates_supply_chain_metadata_when_feature_enabled( mocker, feature_engine): """Test supply-chain metadata update runs when feature is enabled.""" expected_update_status_code = 200 mocker.patch.object( ows_product, 'is_display_upc_available', return_value=True, autospec=True) mocker.patch.object( ows_project, 'get_project_by_id', return_value=response.Response( message={ field.VENDOR_ID: 7123, field.SUBACCOUNT_ID: 555 }), autospec=True) mocker.patch.object( product_physical, 'fetch_by_id', return_value=response.Response( message={ field.PROJECT_ID: 123456, field.DISPLAY_UPC: '111111111111', field.COUNTRY_OF_ORIGIN: 3, field.UPC: '000111222333' }), autospec=True) mocker.patch.object( persister, 'get_release_by_product_code', return_value=response.Response(message=iter([])), autospec=True) mocker.patch.object( persister, 'update_product', return_value=response.Response(status=200), autospec=True) mock_update_supply_chain = mocker.patch.object( persister, 'update_product_physical_supply_chain_metadata', autospec=True) mocker.patch.object( product_physical.features, 'is_ccm_physical_supplychaininfo_oa_enabled', return_value=True, autospec=True) data = { field.SALE_START_DATE: '2026-06-01', field.DISPLAY_UPC: '1843563916741', field.COUNTRY_OF_ORIGIN: 3, } update_response = product_physical.update(1234, data, None, None) assert persister.update_product.called mock_update_supply_chain.assert_called_once_with( data, 1234, '000111222333' ) assert update_response.status == expected_update_status_code