"""Tests for ows-product Model.""" from collections import namedtuple from unittest.mock import MagicMock from unittest.mock import Mock from oto.response import Response from owsrequest import request as requests import pytest import sentry_sdk from ows_product_physical.constant import service_name from ows_product_physical.models import ows_product @pytest.mark.parametrize( ('status_code', 'expected_return_value'), [ (200, False), (404, True) ]) def test_is_upc_available(mocker, status_code, expected_return_value): """Test checking if upc is available.""" response = namedtuple('response', 'status_code') upc_to_check = '191018235048' mocker.patch.object( requests, 'head', return_value=response(status_code=status_code), autospec=True) assert ows_product.is_upc_available(upc_to_check) is expected_return_value requests.head.assert_called_once_with( service_name.OWS_PRODUCT, '/upc/{upc}'.format(upc=upc_to_check)) @pytest.mark.parametrize( ('status_code', 'expected_return_value', 'account_type', 'account_id', 'vendor_id', 'subaccount_id'), [ (200, True, 'subaccount', 667991, 567890, 667991), (404, False, 'subaccount', 667991, 567890, 667991), (200, True, 'vendor', 567890, 567890, 0), (404, False, 'vendor', 567890, 567890, 0) ]) def test_is_display_upc_available( mocker, status_code, expected_return_value, account_type, account_id, vendor_id, subaccount_id): """Test checking if display_upc is available.""" response = namedtuple('response', 'status_code') upc_to_check = '191018235048' mocker.patch.object( requests, 'head', return_value=response(status_code=status_code), autospec=True) assert ows_product.is_display_upc_available( upc_to_check, vendor_id, subaccount_id) is expected_return_value requests.head.assert_called_once_with( service_name.OWS_PRODUCT, ('/{account_type}/{account_id}/display_upc/{display_upc}/' 'available?context_type=physical').format( account_type=account_type, account_id=account_id, display_upc=upc_to_check)) @pytest.mark.parametrize( ('status_code', 'expected_return_value'), [ (200, Response(message=True)), (404, Response(message=False)) ]) def test_check_product_ownership( mocker, status_code, expected_return_value): """Test ownership of a product by vendor.""" response = namedtuple('response', 'status_code') product_id = 123 account_type = 'vendor' account_id = '7123' mocker.patch.object( requests, 'head', return_value=response(status_code=status_code), autospec=True) response = ows_product.check_product_ownership( product_id, account_type, account_id) assert response.message == expected_return_value.message assert response.status == 200 requests.head.assert_called_once_with( service_name.OWS_PRODUCT, '/{account_type}/{account_id}/product/{product_id}' .format( account_type=account_type, account_id=int(account_id), product_id=product_id)) def test_check_product_ownership_exception(mocker): """Test exception raise for connection error.""" product_id = 123 account_type = 'vendor' account_id = '7123' mocker.patch.object( sentry_sdk, 'capture_exception', autospec=True) response = ows_product.check_product_ownership( product_id, account_type, account_id) assert response.status == 500 assert response.errors.get('message') == 'connection error' assert sentry_sdk.capture_exception.called def test_generate_placeholder_upc(monkeypatch): """Test successful call to ows-product for a placeholder upc value.""" mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value={ 'placeholder_upc': 20000000000008}) monkeypatch.setattr(requests, 'post', MagicMock( return_value=mock_response)) upc_response = ows_product.generate_placeholder_upc() assert upc_response.status == 200 assert upc_response.message == 20000000000008 def test_generate_placeholder_upc_failure(monkeypatch): """Test unsuccessful cal to ows-product for a placeholder upc value.""" mock_response = Mock() mock_response.status_code = 400 monkeypatch.setattr(requests, 'post', MagicMock( return_value=mock_response)) upc_response = ows_product.generate_placeholder_upc() assert upc_response.status == 500 def test_get_product(ows_request_mocker): """Test successful product get.""" product_json = {'some': 'product'} product_id = 1234 ows_request_mocker.mock_response( service_name.OWS_PRODUCT, '/product/{}'.format(product_id), method='get', status=200, json=product_json ) product_response = ows_product.get_product(product_id) assert product_response.status == 200 assert product_response.message == product_json def test_get_product_with_error(ows_request_mocker): """Test product get with error.""" product_id = 1234 ows_request_mocker.mock_response( service_name.OWS_PRODUCT, '/product/{}'.format(product_id), method='get', status=404, ) product_response = ows_product.get_product(product_id) assert product_response.status == 500 assert product_response.errors == { 'code': 'internal_error', 'message': 'error fetching product'} def test_get_product_with_exception(mocker): """Test exception raise for connection error.""" product_id = 123 mocker.patch.object( sentry_sdk, 'capture_exception', autospec=True) mocker.patch.object(requests, 'get', side_effect=Exception) product_response = ows_product.get_product(product_id) assert product_response.status == 500 assert sentry_sdk.capture_exception.called assert product_response.errors == { 'code': 'internal_error', 'message': 'error fetching product'} @pytest.mark.parametrize( 'mark_used', [True, False] ) def test_get_provisioned_upc(mocker, mark_used): """Test get upc from upc provisioner endpoint.""" mocked_requests_obj = mocker.patch.object( requests, 'post' ) mocked_post_response = mocked_requests_obj.return_value mocked_post_response.status_code = 200 mocked_post_response.message = {'upc': '123456789101112'} mocked_post_response.json.return_value = { 'upc': '123456789101112'} upc_provisioner_response = ows_product.get_provisioned_upc( mark_used=mark_used) expected_post_payload = {'mark_used': mark_used} post_payload = mocked_requests_obj.call_args[1]['json'] assert post_payload == expected_post_payload assert upc_provisioner_response.status == 200 assert upc_provisioner_response.message == '123456789101112' def test_get_provisioned_upc_default_false(mocker): """Test get upc from upc provisioner endpoint.""" mocked_requests_obj = mocker.patch.object( requests, 'post' ) mocked_post_response = mocked_requests_obj.return_value mocked_post_response.status_code = 200 mocked_post_response.message = {'upc': '123456789101112'} mocked_post_response.json.return_value = { 'upc': '123456789101112'} upc_provisioner_response = ows_product.get_provisioned_upc() expected_post_payload = {'mark_used': False} post_payload = mocked_requests_obj.call_args[1]['json'] assert post_payload == expected_post_payload assert upc_provisioner_response.status == 200 assert upc_provisioner_response.message == '123456789101112' def test_get_provisioned_upc_with_error(mocker): """Test get upc from upc provisioner endpoint with error.""" expected_response_error = { 'code': 'internal_error', 'message': 'Error fetching upc' } mocked_requests_obj = mocker.patch.object( requests, 'post' ) mocked_post_response = mocked_requests_obj.return_value mocked_post_response.status_code = 404 mocked_post_response.json.return_value = {'upc': '123456789101112'} upc_provisioner_response = ows_product.get_provisioned_upc() expected_post_payload = {'mark_used': False} post_payload = mocked_requests_obj.call_args[1]['json'] assert post_payload == expected_post_payload assert upc_provisioner_response.status == 500 assert upc_provisioner_response.errors == expected_response_error def test_get_provisioned_upc_with_exception(mocker): """Test get upc from upc provisioner endpoint with exception.""" expected_response_error = { 'code': 'internal_error', 'message': 'Error fetching upc' } mocker.patch.object( sentry_sdk, 'capture_exception', autospec=True) mocked_requests_obj = mocker.patch.object( requests, 'post', side_effect=Exception) upc_provisioner_response = ows_product.get_provisioned_upc() expected_post_payload = {'mark_used': False} post_payload = mocked_requests_obj.call_args[1]['json'] assert post_payload == expected_post_payload assert upc_provisioner_response.status == 500 assert upc_provisioner_response.errors == expected_response_error