"""Test for ows_assets model.""" from unittest.mock import MagicMock import pytest from flexmock import flexmock from owsrequest import request from product_digital.constants import header, services from product_digital.models import ows_assets from product_digital.utils import error_handling @pytest.fixture def product_id(): """Provide a product_id for testing.""" return '1234567' def test_get_assets_correct_call( mocker, valid_headers, product_id, orchard_user_id): """Test expected call made to assets endpoint.""" mock_assets_response = MagicMock(status_code=200) mock_assets_response.json = MagicMock(return_value={}) mocker.patch.object(request, 'get', return_value=mock_assets_response) headers = { header.ORCHARD_USER_ID: orchard_user_id } ows_assets.get_assets(product_id, orchard_user_id) request.get.assert_called_with( services.OWS_ASSETS, '/asset/product/{}'.format(product_id), headers=headers) def test_get_assets_correct_call_without_orchard_user_id( mocker, valid_headers, product_id): """Test ORCHARD_USER_ID header is omitted when orchard_user_id is empty.""" mock_assets_response = MagicMock(status_code=200) mock_assets_response.json = MagicMock(return_value={}) mocker.patch.object(request, 'get', return_value=mock_assets_response) ows_assets.get_assets(product_id, '') request.get.assert_called_with( services.OWS_ASSETS, '/asset/product/{}'.format(product_id), headers={}) def test_get_assets_correct_call_with_account_headers( mocker, valid_headers, product_id, orchard_user_id): """Test expected call includes account headers when provided.""" mock_assets_response = MagicMock(status_code=200) mock_assets_response.json = MagicMock(return_value={}) mocker.patch.object(request, 'get', return_value=mock_assets_response) expected_headers = { header.ORCHARD_USER_ID: orchard_user_id, header.GRASS_ACCOUNT_TYPE: 'vendor', header.GRASS_ACCOUNT_ID: '12345', } ows_assets.get_assets(product_id, orchard_user_id, account_type='vendor', account_id='12345') request.get.assert_called_with( services.OWS_ASSETS, '/asset/product/{}'.format(product_id), headers=expected_headers) def test_get_assets_success_return( valid_assets_message, mocker, valid_headers, orchard_user_id, product_id): """Test expected message returned from assets endpoint.""" mock_assets_response = MagicMock(status_code=200) mock_assets_response.json = MagicMock( return_value=valid_assets_message) mocker.patch.object(request, 'get', return_value=mock_assets_response) result = ows_assets.get_assets(product_id, orchard_user_id) assert result.status == 200 assert result.message == valid_assets_message def test_get_assets_error_return( mocker, valid_headers, product_id, orchard_user_id): """Test error message returned from assets endpoint.""" error_payload = { 'code': 'ows_product_error', 'message': 'User is forbidden'} mock_assets_response = MagicMock(status_code=403) mock_assets_response.json = MagicMock(return_value=error_payload) mocker.patch.object(request, 'get', return_value=mock_assets_response) result = ows_assets.get_assets(product_id, orchard_user_id) assert result.status == 403 assert result.errors.get('code') == error_payload.get('code') assert result.errors.get('message') == error_payload.get('message') def test_get_correction_image_correct_call(mocker, product_id, orchard_user_id): """Test expected call made to large cover correction endpoint.""" mock_image_response = MagicMock(status_code=200) mock_image_response.text = MagicMock(return_value='image.example.com') mocker.patch.object(request, 'get', return_value=mock_image_response) ows_assets.get_correction_image(product_id, orchard_user_id) request.get.assert_called_with( services.OWS_ASSETS, '/image/product/large_cover_correction/{}/location'.format(product_id), ) def test_get_correction_success_return(mocker, product_id, orchard_user_id): """Test expected message returned from assets endpoint.""" image_url = 'image.example.com' mock_image_response = MagicMock(status_code=200, text=image_url) mocker.patch.object(request, 'get', return_value=mock_image_response) result = ows_assets.get_correction_image(product_id, orchard_user_id) assert result.status == 200 assert result.message == {'image': image_url} def test_get_corrections_error_return(mocker, product_id, orchard_user_id): """Test error message returned from large cover correction endpoint.""" error_payload = { 'code': 'not_found_error', 'message': 'Image not found.' } mock_image_response = MagicMock(status_code=404) mock_image_response.json = MagicMock(return_value=error_payload) mocker.patch.object(request, 'get', return_value=mock_image_response) result = ows_assets.get_correction_image(product_id, orchard_user_id) assert result.status == 404 assert result.errors.get('code') == error_payload.get('code') assert result.errors.get('message') == error_payload.get('message') def test_validate_artwork_success_return( mocker, valid_headers, product_id): """Test expected message returned from artwork validation endpoint.""" mock_assets_response = MagicMock(status_code=200) mock_assets_response.json = MagicMock(side_effect=Exception()) mocker.patch.object(request, 'get', return_value=mock_assets_response) result = ows_assets.validate_artwork(product_id) assert result.status == 200 def test_validate_artwork_image_not_found_return( mocker, valid_headers, product_id): """Test error message returned from artwork validationendpoint.""" error_payload = { 'code': 'not_found_error', 'message': 'Image not found.'} mock_assets_response = MagicMock(status_code=404) mock_assets_response.json = MagicMock(return_value=error_payload) mocker.patch.object(request, 'get', return_value=mock_assets_response) result = ows_assets.validate_artwork(product_id) assert result.status == 404 def test_validate_artwork_error_no_payload_raise_exception( mocker, valid_headers, product_id): """Test error message with no payload raises exception.""" mock_assets_response = MagicMock(status_code=404) mock_assets_response.json = MagicMock(side_effect=Exception()) mocker.patch.object(request, 'get', return_value=mock_assets_response) result = ows_assets.validate_artwork(product_id) assert result.status == 500 assert result.errors.get('message') == 'assets error' def test_validate_artwork_v2_success(product_id): """Test that the v2 endpoint is called.""" assets_response = MagicMock( status_code=200, json=MagicMock(return_value={'foo': 'bar'}) ) (flexmock(request) .should_receive('get') .once() .with_args( services.OWS_ASSETS, '/v2/validators/product/{}/artwork'.format(product_id), params={}) .and_return(assets_response)) result = ows_assets.validate_artwork_v2(product_id) assert result.status == 200 def test_validate_artwork_v2_not_found(product_id): """Test that a 404 status is returned if the endpoint returns 404.""" assets_response = MagicMock( status_code=404, json=MagicMock(return_value={'foo': 'bar'}) ) (flexmock(request) .should_receive('get') .with_args( services.OWS_ASSETS, '/v2/validators/product/{}/artwork'.format(product_id), params={}) .and_return(assets_response)) result = ows_assets.validate_artwork_v2(product_id) assert result.status == 404 assert result.errors == { 'code': 'not_found_error', 'message': 'Artwork incomplete' } def test_validate_artwork_v2_unexpected(product_id): """Test that an unexpected status is logged and results in a 500.""" teapot_response = MagicMock(status_code=418) (flexmock(request) .should_receive('get') .with_args( services.OWS_ASSETS, '/v2/validators/product/{}/artwork'.format(product_id), params={}) .and_return(teapot_response)) (flexmock(error_handling) .should_receive('log_unexpected_response') .once() .with_args(services.OWS_ASSETS, teapot_response)) result = ows_assets.validate_artwork_v2(product_id) assert result.status == 500 assert result.errors == { 'code': 'internal_error', 'message': 'Unexpected response from ows-assets' } def test_validate_artwork_v2_require_v1(product_id): """Test that the require_v1 param is included when requested.""" assets_response = MagicMock(status_code=200) expected_params = {'require_v1': '1'} (flexmock(request) .should_receive('get') .once() .with_args( services.OWS_ASSETS, '/v2/validators/product/{}/artwork'.format(product_id), params=expected_params) .and_return(assets_response)) result = ows_assets.validate_artwork_v2( product_id, require_v1=True) assert result.status == 200 def test_validate_artwork_v2_bad_request(product_id): """Test that a 400 status is treated as artwork incomplete.""" assets_response = MagicMock( status_code=400, json=MagicMock(return_value={'foo': 'bar'}) ) (flexmock(request) .should_receive('get') .with_args( services.OWS_ASSETS, '/v2/validators/product/{}/artwork'.format(product_id), params={}) .and_return(assets_response)) result = ows_assets.validate_artwork_v2(product_id) assert result.status == 404 assert result.errors == { 'code': 'not_found_error', 'message': 'Artwork incomplete' }