"""Unit tests for the upc logic functions.""" from oto import response import pytest from product.logic import upc as upc_logic from product.models import product as product_model from product.models import upc as upc_model from product.models import upc_provisioner def mock_upc_found(mocker, payload='override if needed'): """Mock a 200 response from the Upc model.""" upc_response = response.Response(status=200, message=payload) mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=upc_response) def mock_upc_not_found(mocker): """Mock a 404 response from the Upc model.""" upc_response = response.Response(status=404) mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=upc_response) def mock_product_found(mocker, payload='override if needed'): """Mock a 200 response from the Product model.""" product_response = response.Response(status=200, message=payload) mocker.patch.object( product_model, 'get_product_by_upc', return_value=product_response) def mock_product_upc_found(mocker): """Mock a 200 response from the Product model.""" mocker.patch.object( product_model, 'filter_upcs_with_existing_products', return_value=response.Response(message=['123456123456']) ) def mock_product_not_found(mocker): """Mock a 404 response from the Product model.""" product_response = response.Response(status=404) mocker.patch.object( product_model, 'get_product_by_upc', return_value=product_response) def test_upc_exists_fatal_model_response(mocker): """Test fatal response from model is returned.""" fatal_response = response.create_fatal_response() mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=fatal_response) upc_exists_response = upc_logic.upc_exists(123) assert upc_exists_response == fatal_response def test_upc_exists_upc_found(mocker, test_upc): """Test that 200 is returned if UPC model is found.""" mock_upc_found(mocker) result = upc_logic.upc_exists(test_upc) assert result.status == 200 assert result.message is True def test_upc_exists_product_found(mocker, test_upc): """Test that 200 is returned if a product is found with the UPC.""" mock_upc_not_found(mocker) mock_product_found(mocker) result = upc_logic.upc_exists(test_upc) assert result.status == 200 assert result.message is True def test_upc_exists_not_found(mocker, test_upc): """Test that 404 is returned if UPC is not found.""" mock_upc_not_found(mocker) mock_product_not_found(mocker) result = upc_logic.upc_exists(test_upc) assert result.status == 404 assert result.message is False def test_upcs_available_product_and_upc_not_found(mocker): """Test upcs_available.""" available_upcs = [1, 2, 3] mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=response.Response(message=[]) ) mocker.patch.object( product_model, 'filter_upcs_with_existing_products', return_value=response.Response(message=[]) ) result = upc_logic.upcs_available(available_upcs) assert result.status == 200 assert result.message == {'available_upcs': available_upcs} def test_upcs_available_mix_of_found_and_unfound(mocker): """Test that only unfound UPCs are returned.""" upcs_in_upcs_table = [1, 2] upcs_in_products_table = [3, 4] unused_upcs = [5, 6] mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=response.Response(message=list(map(lambda x: {'upc': x}, upcs_in_upcs_table))) ) mocker.patch.object( product_model, 'filter_upcs_with_existing_products', return_value=response.Response(message=upcs_in_products_table) ) result = upc_logic.upcs_available(upcs_in_upcs_table + upcs_in_products_table + unused_upcs) assert result.status == 200 assert result.message == {'available_upcs': unused_upcs} def test_upc_available_fatal_model_response(mocker): """Test fatal response from model is returned.""" fatal_response = response.create_fatal_response() mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=fatal_response) upc_available_response = upc_logic.upc_available(123) assert upc_available_response == fatal_response def test_upc_available_upc_found(mocker, test_upc): """Test upc_available that 404 is returned when upc found.""" mock_upc_found(mocker) mock_product_not_found(mocker) result = upc_logic.upc_available(test_upc) assert result.status == 403 def test_upc_available_product_found(mocker, test_upc): """Test upc_available that 404 is returned when product with upc found.""" mock_upc_not_found(mocker) mock_product_upc_found(mocker) result = upc_logic.upc_available(test_upc) assert result.status == 403 def test_upc_available_product_and_upc_not_found(mocker, test_upc): """Test upc_available that 404 is returned when product with upc found.""" mock_upc_not_found(mocker) mock_product_not_found(mocker) result = upc_logic.upc_available(test_upc) assert result.status == 200 @pytest.mark.parametrize( ('get_upcs_by_values_response_status', 'is_orchard_upc'), [ (200, True), (404, False) ]) def test_is_orchard_upc( get_upcs_by_values_response_status, is_orchard_upc, mocker, test_upc): """Test is_orchard_upc.""" get_upcs_by_values_response = response.Response( status=get_upcs_by_values_response_status) mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=get_upcs_by_values_response) is_orchard_upc_response = upc_logic.is_orchard_upc(test_upc) assert is_orchard_upc_response.status == 200 assert is_orchard_upc_response.message == { 'is_orchard_upc': is_orchard_upc} def test_is_orchard_upc_fatal_model_response(mocker): """Test fatal response from model is returned.""" fatal_response = response.create_fatal_response() mocker.patch.object( upc_model, 'get_upcs_by_values', return_value=fatal_response) is_orchard_upc_response = upc_logic.is_orchard_upc(123) assert is_orchard_upc_response == fatal_response @pytest.mark.parametrize('mark_used', [False, None]) def test_retrieve_upc_mark_used_false_success(mocker, mark_used): """Test upc status update successful; mark_used is False or None.""" _mock_upc_provisioner_response(mocker) _mock_set_claimed_upc_status(mocker) result = upc_logic.retrieve_upc(mark_used) assert result.message == {'upc': '1234'} assert upc_provisioner.set_claimed_upc_to_used.call_count == 0 def test_retrieve_upc_mark_used_true_success(mocker): """Test upc status update successful when mark_used is True.""" _mock_upc_provisioner_response(mocker) mocker.patch.object( upc_provisioner, 'set_claimed_upc_to_used', return_value=1 ) result = upc_logic.retrieve_upc(True) assert result.message == {'upc': '1234'} assert upc_provisioner.set_claimed_upc_to_used.call_count == 1 def test_retrieve_upc_success_status_failure(mocker): """Test error 500 when provisioner works but status update fails.""" _mock_upc_provisioner_response(mocker) mocker.patch.object( upc_provisioner, 'set_claimed_upc_to_used', return_value=0 ) mocker.patch.object( upc_provisioner, 'log_upc_status_info', return_value='Could not set claimed UPC as used' ) result = upc_logic.retrieve_upc(True) assert upc_provisioner.set_claimed_upc_to_used.call_count == 1 assert result.status == 500 @pytest.mark.parametrize('mark_used', [True, False, None]) def test_retrieve_upc_returns_500(mocker, mark_used): """Test upc_provisioner.retrieve_upc() returns 500.""" mocker.patch.object( upc_provisioner, 'retrieve_upc', return_value=response.Response(status=500) ) _mock_set_claimed_upc_status(mocker) provisioner_response = upc_logic.retrieve_upc(mark_used) assert provisioner_response.status == 500 assert upc_provisioner.set_claimed_upc_to_used.call_count == 0 @pytest.mark.parametrize('mark_used', [True, False, None]) def test_retrieve_upc_returns_404(mocker, mark_used): """Test upc_provisioner.retrieve_upc() returns 404.""" mocker.patch.object( upc_provisioner, 'retrieve_upc', return_value=response.Response(status=404)) _mock_set_claimed_upc_status(mocker) provisioner_response = upc_logic.retrieve_upc(mark_used) assert provisioner_response.status == 404 assert upc_provisioner.set_claimed_upc_to_used.call_count == 0 def _mock_upc_provisioner_response(mocker): mocker.patch.object( upc_provisioner, 'retrieve_upc', return_value=response.Response(message={'upc': '1234'}) ) def _mock_set_claimed_upc_status(mocker): mocker.patch.object( upc_provisioner, 'set_claimed_upc_to_used' )