"""Image Model Tests.""" import json import httpretty import pytest from images import config from images.constants import errors from images.constants import workstation as workstation_constants from images.models import image php_session_cookie_value = 'somerandstring' @pytest.yield_fixture def call_prepare_for_bulk_upload_with_request_stub( filename, workstation_response_body): """Stub http request to workstation and call to prepare_for_bulk_upload. Sets up HTTPretty stubbing with stub and yields prepare_for_bulk_upload from the workstation service for use in tests. Decorators: pytest.yield_fixture  Yields: Response: The return from prepare_for_bulk_upload. """ httpretty.enable() httpretty.register_uri( httpretty.POST, config.WORKSTATION_URL + workstation_constants.GETDESTINATIONLIST_PATH, body=json.dumps(workstation_response_body), content_type='application/json') yield image.prepare_for_bulk_upload(filename, php_session_cookie_value) httpretty.disable() httpretty.reset() # Test for `prepare_for_bulk_upload` def test_prepare_for_bulk_upload_posts_query_param( filename, image_id, call_prepare_for_bulk_upload_with_request_stub): """Make a request to worksation with properly formated query param.""" expected_query_param = { 'bulk_upload': [ '[{{"filename":"{0}","folder":"","id":"{1}"}}]'.format( filename, image_id)], 'use_release_id': ['1']} assert httpretty.last_request().querystring == expected_query_param def test_prepare_for_bulk_upload_return_workstation_response( prepare_for_bulk_upload_message, call_prepare_for_bulk_upload_with_request_stub): """Make a request to workstation and returns a parsed response.""" response = call_prepare_for_bulk_upload_with_request_stub assert response.status == 200 assert response.message == prepare_for_bulk_upload_message def test_prepare_for_bulk_upload_makes_request_with_php_cookie( call_prepare_for_bulk_upload_with_request_stub): """Make a request to Workstation with the passed PHP session cookie.""" assert httpretty.last_request().headers['Cookie'] == '{0}={1}'.format( workstation_constants.PHP_SESSION_COOKIE_KEY, php_session_cookie_value) @httpretty.activate def test_prepare_for_bulk_upload_return_error_when_server_error( context, mocker, filename): """Respond with fatal response object when workstation 500s. Logs error with status code. """ httpretty.register_uri( httpretty.POST, config.WORKSTATION_URL + workstation_constants.GETDESTINATIONLIST_PATH, status=500) with context: mocker.spy(context.g.ows.log, 'error') response = image.prepare_for_bulk_upload( filename, php_session_cookie_value) expected_message = 'Workstation returned unexpected status code of 500' assert response.status == 500 assert response.errors.get('code') == 'internal_error' assert response.errors.get('message') == expected_message context.g.ows.log.error.assert_called_once_with(expected_message) @httpretty.activate def test_prepare_for_bulk_upload_return_error_when_bad_request( context, mocker, filename): """Respond with fatal response object when workstation 400s. Logs error with status code. """ httpretty.register_uri( httpretty.POST, config.WORKSTATION_URL + workstation_constants.GETDESTINATIONLIST_PATH, status=400) with context: mocker.spy(context.g.ows.log, 'error') response = image.prepare_for_bulk_upload( filename, php_session_cookie_value) expected_message = 'Workstation returned unexpected status code of 400' assert response.status == 500 assert response.errors.get('code') == 'internal_error' assert response.errors.get('message') == expected_message context.g.ows.log.error.assert_called_once_with(expected_message) @httpretty.activate def test_prepare_for_bulk_upload_return_error_when_meta_not_found( context, mocker, filename, meta_not_found_workstation_response_body): """Test prepare for bulk upload when meta not found. Respond with fatal response object when workstation responds with meta_not_found for filname. Logs error with status code. """ httpretty.register_uri( httpretty.POST, config.WORKSTATION_URL + workstation_constants.GETDESTINATIONLIST_PATH, body=json.dumps(meta_not_found_workstation_response_body), content_type='application/json') with context: mocker.spy(context.g.ows.log, 'error') response = image.prepare_for_bulk_upload( filename, php_session_cookie_value) expected_message = errors.META_NOT_FOUND_MESSAGE assert response.status == 500 assert response.errors.get('message') == expected_message context.g.ows.log.error.assert_called_once_with(expected_message) @httpretty.activate def test_prepare_for_bulk_upload_return_error_when_data_invalid( context, mocker, filename, meta_not_found_workstation_response_body): """Test prepare for bulk upload when invalid. Respond with fatal response object when workstation responds with invalid data. Logs error with status code. """ httpretty.register_uri( httpretty.POST, config.WORKSTATION_URL + workstation_constants.GETDESTINATIONLIST_PATH) with context: mocker.spy(context.g.ows.log, 'error') response = image.prepare_for_bulk_upload( filename, php_session_cookie_value) expected_message = 'Workstation returned an unexpected response.' assert response.status == 500 assert response.errors.get('message') == expected_message context.g.ows.log.error.assert_called_once_with(expected_message) # Tests for `log_and_create_fatal_response`. def test_log_and_create_fatal_response(context, mocker): """Log message and returns fatal response with message.""" message = 'Something wicked this way comes' with context: mocker.spy(context.g.ows.log, 'error') error_response = image.log_and_create_fatal_response(message) assert error_response.status == 500 assert error_response.errors.get('message') == message context.g.ows.log.error.assert_called_once_with(message) # Test for `validate_workstation_response`. @httpretty.activate def test_validate_workstation_response_when_500(mocker, context): """Test workstation response when server error. Logs message and returns fatal response with message when Workstation responds with 500 status code. """ class WorkstationRequestStub(): def __init__(self, status_code): self.status_code = status_code with context: mocker.spy(context.g.ows.log, 'error') validation_response = image.validate_workstation_response( WorkstationRequestStub(status_code=500), 'some_filename.jpg') expected_message = 'Workstation returned unexpected status code of 500' assert validation_response.status == 500 assert validation_response.errors.get('message') == expected_message context.g.ows.log.error.assert_called_once_with(expected_message) def test_validate_workstation_response_when_no_json(mocker, context): """Test workstation response when no json provided. Logs message and returns fatal response with message when Workstation responds without JSON. """ class WorkstationRequestStub(): def __init__(self, status_code): self.status_code = status_code with context: mocker.spy(context.g.ows.log, 'error') validation_response = image.validate_workstation_response( WorkstationRequestStub(status_code=200), 'some_filename.jpg') expected_message = 'Workstation returned an unexpected response.' assert validation_response.status == 500 assert validation_response.errors.get('message') == expected_message context.g.ows.log.error.assert_called_once_with(expected_message) def test_validate_workstation_response_when_meta_not_found(mocker, context): """Test workstation response when meta not found error. Logs message and returns fatal response with message when Workstation responds with `meta_not_found` attribute in response body. """ filename = 'some_filename.jpg' class WorkstationRequestStub(): def __init__(self, status_code): self.status_code = status_code def json(self): return {filename: {'upload_filename': 'meta_not_found'}} with context: mocker.spy(context.g.ows.log, 'error') validation_response = image.validate_workstation_response( WorkstationRequestStub(status_code=200), filename) error_message = 'Workstation could not associate the file with a product' assert validation_response.status == 500 assert validation_response.errors.get('message') == error_message context.g.ows.log.error.assert_called_once_with(error_message) def test_validate_workstation_response_when_valid(): """Test workstation response when success. Logs message and returns successful response when Workstation responds with 200 status code and valid JSON. """ filename = 'some_filename.jpg' class WorkstationRequestStub(): def __init__(self, status_code): self.status_code = status_code def json(self): return {filename: {'upload_filename': 'valid_filename.jpg'}} validation_response = image.validate_workstation_response( WorkstationRequestStub(status_code=200), filename) assert validation_response.status == 200 # Test for `format_bulk_upload` def test_format_bulk_upload_url_param(filename): """Format filename, and image_id into query param dict. Also passes feature flag to workstation. """ formatted_param = image.format_bulk_upload_url_param(filename) expected_bulk_upload_value = ('[{"filename":"something.tiff",' '"folder":"","id":"something.tiff"}]') assert formatted_param == { 'bulk_upload': expected_bulk_upload_value, 'use_release_id': '1'}