"""Test for ows-product-workflow model.""" from unittest.mock import MagicMock from unittest.mock import patch from flexmock import flexmock from owsrequest import request import pytest from product_digital.constants import services from product_digital.models import ows_product_workflow from product_digital.utils import error_handling @pytest.fixture def release_approval_payload(): """Return a valid release approval payload.""" return { 'status': 'rejected', 'admin_approval': 'N'} @pytest.fixture def release_approval_id(): """Provide a product_id for testing.""" return '1234567' @pytest.fixture def rejections_data(): """A sample set of rejections data used for testing.""" return {'rejections': [{'rejection_id': 123, 'corrected': 'Y'}]} @pytest.fixture def rejections_update_message(): """A sample set of rejections data used for testing.""" return { 'rejections': [{ 'rejection_id': 123, 'field_name': 'general_comments', 'table_name': 'releases', 'comments': 'test', 'key_id': 0, 'corrected': 'Y'}]} def test_create_release_approval_queue_correct_call( release_approval_payload, release_approval_create_message, product_id): """Test correct call made to ows-product-workflow.""" workflow_payload = release_approval_create_message mock_response = MagicMock(status_code=201) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/release-approval'.format(product_id), json=release_approval_payload, ).and_return(mock_response)) ows_product_workflow.create_release_approval_queue( product_id, release_approval_payload) def test_create_release_approval_queue_expected_return( release_approval_payload, release_approval_create_message, product_id): """Test expected response body returned.""" workflow_payload = release_approval_create_message mock_response = MagicMock(status_code=201) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/release-approval'.format(product_id), json=release_approval_payload, ).and_return(mock_response)) result = ows_product_workflow.create_release_approval_queue( product_id, release_approval_payload) assert result.status == 201 assert result.message == workflow_payload def test_create_release_approval_queue_error_returned( release_approval_payload, product_id, ): """Test error result when error.""" mock_response = MagicMock(status_code=403) (flexmock(request).should_receive( 'post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/release-approval'.format(product_id), json=release_approval_payload, ).and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.create_release_approval_queue( product_id, release_approval_payload) assert result.status == 403 def test_get_last_release_approval_queue_correct_call( release_approval_get_message, product_id): """Test correct call made to ows-product-workflow.""" workflow_payload = release_approval_get_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'get').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/release-approval'.format(product_id), ).and_return(mock_response)) ows_product_workflow.get_last_release_approval_queue( product_id) def test_get_last_release_approval_queue_expected_return( release_approval_get_message, product_id): """Test correct call made to ows-product-workflow.""" workflow_payload = release_approval_get_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'get').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/release-approval'.format(product_id), ).and_return(mock_response)) result = ows_product_workflow.get_last_release_approval_queue( product_id) assert result.status == 200 assert result.message == workflow_payload def test_get_last_release_approval_queue_error_return(product_id): """Test correct call made to ows-product-workflow.""" mock_response = MagicMock(status_code=403) (flexmock(request).should_receive( 'get').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/release-approval'.format(product_id), ).and_return(mock_response)) result = ows_product_workflow.get_last_release_approval_queue( product_id) assert result.status == 403 def test_get_rejections_correct_call( get_rejections_message, release_approval_id): """Test correct call made to ows-product-workflow.""" workflow_payload = get_rejections_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'get').with_args( services.OWS_PRODUCT_WORKFLOW, '/release-approval/{}/rejections'.format(release_approval_id), ).and_return(mock_response)) ows_product_workflow.get_rejections( release_approval_id) def test_get_rejections_expected_return( get_rejections_message, release_approval_id): """Test correct call made to ows-product-workflow.""" workflow_payload = get_rejections_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'get').with_args( services.OWS_PRODUCT_WORKFLOW, '/release-approval/{}/rejections'.format(release_approval_id), ).and_return(mock_response)) result = ows_product_workflow.get_rejections( release_approval_id) assert result.status == 200 assert result.message == workflow_payload def test_get_rejections_error_return(release_approval_id): """Test correct call made to ows-product-workflow.""" mock_response = MagicMock(status_code=403) (flexmock(request).should_receive( 'get').with_args( services.OWS_PRODUCT_WORKFLOW, '/release-approval/{}/rejections'.format(release_approval_id), ).and_return(mock_response)) result = ows_product_workflow.get_rejections( release_approval_id) assert result.status == 403 def test_update_rejections_correct_call( rejections_data, rejections_update_message,): """Test correct call made to ows-product-workflow.""" workflow_payload = rejections_update_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'put').with_args( services.OWS_PRODUCT_WORKFLOW, '/release-approval/rejections', json=rejections_data, ).and_return(mock_response)) ows_product_workflow.update_rejections( rejections_data) def test_update_rejections_expected_return( rejections_data, rejections_update_message): """Test expected response body returned.""" workflow_payload = rejections_update_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request).should_receive( 'put').with_args( services.OWS_PRODUCT_WORKFLOW, '/release-approval/rejections', json=rejections_data, ).and_return(mock_response)) result = ows_product_workflow.update_rejections( rejections_data) assert result.status == 200 assert result.message == workflow_payload def test_update_rejections_error_returned( rejections_data): """Test error result when an error is returned.""" mock_response = MagicMock(status_code=403) (flexmock(request).should_receive( 'put').with_args( services.OWS_PRODUCT_WORKFLOW, '/release-approval/rejections', json=rejections_data, ).and_return(mock_response)) result = ows_product_workflow.update_rejections( rejections_data) assert result.status == 403 def test_get_last_release_correction_correct_call( product_id, release_correction_get_message ): """Test correct call made to ows-product-workflow.""" workflow_payload = release_correction_get_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request) .should_receive('get') .with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id)) .and_return(mock_response)) ows_product_workflow.get_last_release_correction( product_id, ) def test_get_last_release_correction_expected_return( product_id, release_correction_get_message ): """Test correct call made to ows-product-workflow.""" workflow_payload = release_correction_get_message mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=workflow_payload) (flexmock(request) .should_receive('get') .with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id)) .and_return(mock_response)) result = ows_product_workflow.get_last_release_correction( product_id, ) assert result.status == 200 assert result.message == workflow_payload def test_get_last_release_correction_error_return( product_id ): """Test correct call made to ows-product-workflow.""" mock_response = MagicMock(status_code=403) (flexmock(request) .should_receive('get') .with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id)) .and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.get_last_release_correction( product_id, ) assert result.status == 403 def test_create_correction_success(product_id): """Test response status and payload on successful correction creation.""" correction_data = { 'last_updated_by': 123, 'last_updated_type': 'alw' } response_payload = { 'release_correction_id': 153129, 'status': 'active', 'release_id': product_id } mock_response = MagicMock(status_code=201) mock_response.json = MagicMock(return_value=response_payload) (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id), json=correction_data).and_return(mock_response)) result = ows_product_workflow.create_release_correction( product_id, correction_data) assert result.status == 201 assert result.message == response_payload def test_create_correction_unexpected_status(product_id): """Test handling of unexpected status code on creation of a correction.""" correction_data = { 'last_updated_by': 123, 'last_updated_type': 'alw' } mock_response = MagicMock(status_code=418) (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/correction'.format(product_id), json=correction_data).and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.create_release_correction( product_id, correction_data) assert result.status == 500 assert result.errors == { 'code': 'internal_error', 'message': 'error saving correction' } def test_delete_correction_success(release_correction_id): """Test response status and payload on successful correction deletion.""" response_payload = { 'message': 'release correction successfully deleted' } mock_response = MagicMock(status_code=202) mock_response.json = MagicMock(return_value=response_payload) (flexmock(request).should_receive('delete').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), ).and_return(mock_response)) result = ows_product_workflow.delete_release_correction( release_correction_id) assert result.status == 202 assert result.message == response_payload def test_delete_correction_error(release_correction_id): """Test response status and payload on failing correction deletion.""" response_payload = { 'code': 'bad_request', 'message': "Can't delete a release correction with a submitted status" } mock_response = MagicMock(status_code=400) mock_response.json = MagicMock(return_value=response_payload) (flexmock(request).should_receive('delete').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), ).and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.delete_release_correction( release_correction_id) assert result.status == 400 assert result.message == response_payload def test_delete_correction_not_found(release_correction_id): """Test response status and payload on failing correction deletion.""" response_payload = { 'code': 'not_found_error', 'message': 'No release correction record found' } mock_response = MagicMock(status_code=404) mock_response.json = MagicMock(return_value=response_payload) (flexmock(request).should_receive('delete').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), ).and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.delete_release_correction( release_correction_id) assert result.status == 404 assert result.message == response_payload def test_delete_correction_failure(release_correction_id): """Test response status and payload on failing correction deletion.""" response_payload = { 'code': 'internal_error', 'message': 'db error' } mock_response = MagicMock(status_code=500) mock_response.json = MagicMock(return_value=response_payload) (flexmock(request).should_receive('delete').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), ).and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.delete_release_correction( release_correction_id) assert result.status == 500 assert result.message == response_payload def test_update_correction_success(release_correction_id): """Test response status and payload on successful correction update.""" correction_data = {'status': 'submitted'} response_payload = { 'release_correction_id': release_correction_id, 'status': 'submitted' } mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=response_payload) ( flexmock(request) .should_receive('put') .with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), json=correction_data ) .and_return(mock_response) ) result = ows_product_workflow.update_release_correction( release_correction_id, correction_data, ) assert result.status == 200 assert result.message == response_payload def test_update_correction_unexpected_status( release_correction_id ): """Test handling of unexpected status code on update of a correction.""" correction_data = {'status': 'submitted'} mock_response = MagicMock(status_code=404) ( flexmock(request) .should_receive('put') .with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}'.format(release_correction_id), json=correction_data ) .and_return(mock_response) ) ( flexmock(error_handling) .should_receive('log_unexpected_response') .once() .with_args( services.OWS_PRODUCT_WORKFLOW, mock_response ) ) result = ows_product_workflow.update_release_correction( release_correction_id, correction_data, ) assert result.status == 500 assert result.errors == { 'code': 'internal_error', 'message': 'cannot update a nonexistent release correction' } def test_create_correction_details_success( release_correction_id, correction_details_data, post_correction_details_ok_response): """Test response for successful correction details creation.""" mock_response = MagicMock(status_code=201) mock_response.json = MagicMock( return_value=post_correction_details_ok_response) (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}/details'.format(release_correction_id), json=correction_details_data) .and_return(mock_response)) result = ows_product_workflow.create_correction_details_records( release_correction_id, correction_details_data) assert result.status == 201 assert result.message == post_correction_details_ok_response def test_create_correction_details_success_on_400( release_correction_id, correction_details_data, post_correction_details_ok_response): """Test response for successful correction details creation on 400.""" mock_response = MagicMock(status_code=400) mock_response.json = MagicMock( return_value=post_correction_details_ok_response) (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}/details'.format(release_correction_id), json=correction_details_data) .and_return(mock_response)) result = ows_product_workflow.create_correction_details_records( release_correction_id, correction_details_data) assert result.status == 400 assert result.message == post_correction_details_ok_response def test_create_correction_details_unexpected_status( release_correction_id, correction_details_data): """Test unexpected status code on creation correction details.""" mock_response = MagicMock(status_code=420) (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/correction/{}/details'.format(release_correction_id), json=correction_details_data) .and_return(mock_response)) (flexmock(error_handling).should_receive( 'log_unexpected_response').once().with_args( services.OWS_PRODUCT_WORKFLOW, mock_response)) result = ows_product_workflow.create_correction_details_records( release_correction_id, correction_details_data) assert result.status == 500 assert result.errors == { 'code': 'internal_error', 'message': 'error saving correction details' } @patch.object(error_handling, 'log_unexpected_response') @pytest.mark.parametrize('status_code,logged', [ (200, False), (400, True), (404, False) ]) def test_get_release_correction_logging( log_mock, status_code, logged, request_engine, test_request_context): """Check that logging is correctly called in get release correction.""" request_engine[services.OWS_PRODUCT_WORKFLOW].add_spec( 'GET', '/product/1/correction', status=status_code) response = ows_product_workflow.get_last_release_correction(1) assert response.status == status_code assert log_mock.called == logged def test_product_unsubmission_success(product_id, account_id, account_type): """Test response status and payload on successful product unsubmission.""" response_payload = { 'message': 'release approval deleted' } mock_response = MagicMock(status_code=200) mock_response.json = MagicMock(return_value=response_payload) unsubmit_data = { 'account_id': account_id, 'account_type': account_type } (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/unsubmit'.format(product_id), json=unsubmit_data).and_return(mock_response)) result = ows_product_workflow.product_unsubmission( product_id, account_id, account_type) assert result.status == 200 assert result.message == response_payload @patch.object(error_handling, 'log_unexpected_response') def test_product_unsubmission_failure(log_mock, product_id, account_id, account_type): """Test response status and payload on failed product unsubmission.""" response_payload = { 'message': 'Product {} is not checked_in'.format(product_id) } mock_response = MagicMock(status_code=400) mock_response.json = MagicMock(return_value=response_payload) unsubmit_data = { 'account_id': account_id, 'account_type': account_type } (flexmock(request).should_receive('post').with_args( services.OWS_PRODUCT_WORKFLOW, '/product/{}/unsubmit'.format(product_id), json=unsubmit_data).and_return(mock_response)) result = ows_product_workflow.product_unsubmission(product_id, account_id, account_type) assert result.status == 400 assert result.errors['message'] == response_payload assert log_mock.called