"""Unit tests for product-workflow logic.""" from flexmock import flexmock from oto import response from oto.response import create_not_found_response import pytest from product_workflow.constants import error from product_workflow.logic import product_submission from product_workflow.logic import release_approval_queue from product_workflow.models import ows_lyrics as ows_lyrics_model from product_workflow.models import ows_product_review \ as ows_product_review_model from product_workflow.models import release_approval_queue \ as release_approval_queue_model from product_workflow.models import release_correction \ as release_correction_model @pytest.fixture def release_approval_create_message(): """Return a dictionary of release approval queue properties for testing.""" return { 'release_approval_id': 1, 'release_id': 123, 'status': 'transfer_to_content'} @pytest.fixture def release_approval_create_properties(): """Return a dictionary of release approval queue properties for testing.""" return { 'release_id': 123, 'status': 'rejected', 'admin_approval': 'N'} @pytest.fixture def release_approval_create_response(release_approval_create_message): """Return a dictionary of release approval queue properties for testing.""" return response.Response(release_approval_create_message) @pytest.fixture def release_id(): """Create a release id for testing.""" return 123 @pytest.fixture def get_last_release_approval_message(release_id): """Return a dictionary of last approval queue properties for testing.""" return { 'release_approval_id': 1, 'release_id': release_id, 'status': 'rejected'} @pytest.fixture def get_last_release_approval_response(get_last_release_approval_message): """Return a dictionary of release approval queue properties for testing.""" return response.Response(get_last_release_approval_message) @pytest.fixture def correction_details(release_correction_id): """Return a list of the correction details properties for testing.""" return [ { 'release_correction_id': release_correction_id, 'table_name': 'randy', 'field_name': 'butternubs', 'key_id': 123, 'key_value': 'track_1.wav', }, { 'release_correction_id': release_correction_id, 'table_name': 'track', 'field_name': 'lyrics', 'key_id': 124, 'key_value': 'Test Track lyrics', }, { 'release_correction_id': release_correction_id, 'table_name': 'jake', 'field_name': 'the_doge', 'key_id': 125, 'key_value': 808, } ] @pytest.fixture def get_last_release_correction_details_message( release_correction_id, release_id, correction_details): """Return a dictionary of last release correction details.""" return { 'release_correction_id': release_correction_id, 'release_id': release_id, 'status': 'submitted', 'items': correction_details } @pytest.fixture def get_last_release_correction_details_update_message( release_correction_id, release_id, correction_details): """Return a dictionary of last release correction details.""" return { 'release_correction_id': release_correction_id, 'release_id': release_id, 'status': 'active', 'items': correction_details } @pytest.fixture def get_last_release_correction_response( get_last_release_correction_details_message): """Return a release correction get message for testing.""" return response.Response(get_last_release_correction_details_message) @pytest.fixture def approve_release_response(get_ows_lyrics_message): """Return a dictionary of release approval queue properties for testing.""" return response.Response(get_ows_lyrics_message) @pytest.fixture def get_release_correction_response_without_details(): """Return a release correction get message for testing.""" return create_not_found_response( message='No release correction record found') @pytest.fixture def ows_product_review_unsubmit_product_message(release_id): """ows_product_review_unsubmit_product_message.""" return {'message': 'release approval deleted'} @pytest.fixture def ows_product_review_unsubmit_product_response( ows_product_review_unsubmit_product_message): """ows_product_review_unsubmit_product_response.""" return response.Response( message=ows_product_review_unsubmit_product_message) @pytest.fixture def ows_product_review_unsubmit_product_404_message(release_id): """ows_product_review_unsubmit_product_404_message.""" return error.ERROR_MESSAGE_PRODUCT_APPROVAL_NOT_FOUND.format(release_id) @pytest.fixture def ows_product_review_unsubmit_product_404_response( ows_product_review_unsubmit_product_404_message): """ows_product_review_unsubmit_product_404_response.""" return response.create_not_found_response( message=ows_product_review_unsubmit_product_404_message) @pytest.fixture def delete_last_release_approval_message(release_id): """Return a dictionary of deleted last approval queue.""" return {'message': 'release approval deleted'} @pytest.fixture def delete_last_release_approval_response(delete_last_release_approval_message): """Return a response of a deleted release approval queue.""" return response.Response(message=delete_last_release_approval_message) @pytest.fixture def delete_last_release_approval_404_message(release_id): """delete_last_release_approval_404_message.""" return error.ERROR_MESSAGE_PRODUCT_APPROVAL_NOT_FOUND.format(release_id) @pytest.fixture def delete_last_release_approval_404_response( delete_last_release_approval_404_message): """delete_last_release_approval_404_response.""" return response.create_not_found_response( message=delete_last_release_approval_404_message) @pytest.fixture def product_review_404_errors(release_id): """Common 404 errors body. For both legacy release approval and new product review. """ return { 'code': 'not_found_error', 'message': error.ERROR_MESSAGE_PRODUCT_APPROVAL_NOT_FOUND.format( release_id) } def test_create_release_approval_queue_success( release_approval_create_properties, release_approval_payload, release_approval_create_response, product_id, release_approval_create_message): """Test that model layer create function is called and 200 response.""" (flexmock(release_approval_queue_model).should_receive( 'create').with_args( release_approval_create_properties).and_return( release_approval_create_response).once()) result = release_approval_queue.create_release_approval_queue_record( product_id, release_approval_payload) assert result.status == 201 assert result.message == release_approval_create_message def test_create_release_approval_queue_failure( release_approval_create_properties, generic_error_response, product_id, release_approval_create_message, release_approval_payload): """Test that model layer create function is called and 400 response.""" (flexmock(release_approval_queue_model).should_receive( 'create').with_args(release_approval_create_properties).and_return( generic_error_response).once()) result = release_approval_queue.create_release_approval_queue_record( product_id, release_approval_payload) assert result.status == 400 assert result.errors == generic_error_response.errors def test_get_last_release_approval_queue_success( release_id, get_last_release_approval_response, get_last_release_approval_message): """Test that model layer get last function is called and 200 response.""" (flexmock(release_approval_queue_model).should_receive( 'get_last_approval').with_args( release_id).and_return( get_last_release_approval_response).once()) result = release_approval_queue.get_last_approval(release_id) assert result.status == 200 assert result.message == get_last_release_approval_message def test_get_last_release_approval_queue_failure( release_id, generic_error_response): """Test that model layer get last function is called and 400 response.""" (flexmock(release_approval_queue_model).should_receive( 'get_last_approval').with_args( release_id).and_return( generic_error_response).once()) result = release_approval_queue.get_last_approval(release_id) assert result.status == 400 assert result.errors == generic_error_response.errors def test_approve_product_success( release_id, get_last_release_correction_response, lyrics_correction_details, approve_release_response): """Test approval endpoint with 200 response.""" (flexmock(release_correction_model).should_receive( 'get_last_release_correction').with_args( release_id).and_return( get_last_release_correction_response).once()) (flexmock(ows_lyrics_model).should_receive( 'apply_track_lyrics').with_args( lyrics_correction_details).and_return( approve_release_response)) result = release_approval_queue.approve_product(release_id) assert result.status == 200 def test_approve_product_without_correction( release_id, get_release_correction_response_without_details): """Test approval endpoint for 404 code.""" (flexmock(release_correction_model).should_receive( 'get_last_release_correction').with_args( release_id).and_return( get_release_correction_response_without_details).once()) result = release_approval_queue.approve_product(release_id) assert result.status == 404 assert result.message == \ get_release_correction_response_without_details.message def test_approve_product_failure( release_id, get_last_release_correction_response, lyrics_correction_details, generic_error_response): """Test approval endpoint for 400 code.""" (flexmock(release_correction_model).should_receive( 'get_last_release_correction').with_args( release_id).and_return( get_last_release_correction_response).once()) (flexmock(ows_lyrics_model).should_receive( 'apply_track_lyrics').with_args( lyrics_correction_details).and_return( generic_error_response)) result = release_approval_queue.approve_product(release_id) assert result.status == 400 assert result.message == generic_error_response.message def test_unsubmit_content_review_product_success( release_id, account_id, account_type, ows_product_review_unsubmit_product_response, ows_product_review_unsubmit_product_message ): """Test unsubmit endpoint with 200 response.""" (flexmock(ows_product_review_model).should_receive( 'unsubmit_product').with_args( release_id).and_return( ows_product_review_unsubmit_product_response).once()) (flexmock(release_correction_model).should_receive( 'get_last_release_correction').with_args( release_id).and_return( response.Response(status=404)).once()) submit_data = { 'account_id': account_id, 'account_type': account_type } result = product_submission.unsubmit_digital_product( release_id, submit_data) assert result.status == 200 assert result.message == ows_product_review_unsubmit_product_message def test_unsubmit_error_correction_product_review_success( release_id, account_id, account_type, ows_product_review_unsubmit_product_response, ows_product_review_unsubmit_product_message, get_last_release_correction_response, get_last_release_correction_details_update_message ): """Unsubmit error correction from product review.""" (flexmock(ows_product_review_model).should_receive( 'unsubmit_product').with_args( release_id).and_return( ows_product_review_unsubmit_product_response).once()) (flexmock(release_correction_model).should_receive( 'get_last_release_correction').with_args( release_id).and_return( get_last_release_correction_response).once()) submit_correction_data = { **get_last_release_correction_details_update_message, 'last_updated_by': account_id, 'last_updated_type': account_type } release_correction_id = submit_correction_data.pop('release_correction_id') (flexmock(release_correction_model).should_receive( 'update').with_args( release_correction_id, submit_correction_data).and_return( response.Response(message=get_last_release_correction_details_update_message)).once()) submit_data = { 'account_id': account_id, 'account_type': account_type } result = product_submission.unsubmit_digital_product( release_id, submit_data) assert result.status == 200 assert result.message == get_last_release_correction_details_update_message def test_unsubmit_content_review_product_400_failure( release_id, account_id, account_type, delete_last_release_approval_404_response, generic_error_response, ): """Test that model layer get last function is called and 400 response.""" (flexmock(ows_product_review_model).should_receive( 'unsubmit_product').with_args( release_id).and_return( generic_error_response).once()) submit_data = { 'account_id': account_id, 'account_type': account_type } result = product_submission.unsubmit_digital_product( release_id, submit_data) assert result.status == 400 assert result.errors == generic_error_response.errors def test_unsubmit_legacy_product_success( release_id, account_id, account_type, ows_product_review_unsubmit_product_404_response, delete_last_release_approval_response, delete_last_release_approval_message, ): """Test unsubmit endpoint with 200 response.""" (flexmock(ows_product_review_model).should_receive( 'unsubmit_product').with_args( release_id).and_return( ows_product_review_unsubmit_product_404_response).once()) (flexmock(release_approval_queue_model).should_receive( 'delete_latest_release_approval_queue').with_args( release_id, account_id, account_type).and_return( delete_last_release_approval_response).once()) submit_data = { 'account_id': account_id, 'account_type': account_type } result = product_submission.unsubmit_digital_product( release_id, submit_data) assert result.status == 200 assert result.message == delete_last_release_approval_message def test_unsubmit_legacy_product_400_failure( release_id, account_id, account_type, ows_product_review_unsubmit_product_404_response, generic_error_response, ): """Test that model layer get last function is called and 400 response.""" (flexmock(ows_product_review_model).should_receive( 'unsubmit_product').with_args( release_id).and_return( ows_product_review_unsubmit_product_404_response).once()) (flexmock(release_approval_queue_model).should_receive( 'delete_latest_release_approval_queue').with_args( release_id, account_id, account_type).and_return( generic_error_response).once()) submit_data = { 'account_id': account_id, 'account_type': account_type } result = product_submission.unsubmit_digital_product( release_id, submit_data) assert result.status == 400 assert result.errors == generic_error_response.errors def test_unsubmit_legacy_or_content_review_product_404_failure( release_id, account_id, account_type, ows_product_review_unsubmit_product_404_response, delete_last_release_approval_404_response, product_review_404_errors, ): """Test unsubmit endpoint with 404 response.""" (flexmock(ows_product_review_model).should_receive( 'unsubmit_product').with_args( release_id).and_return( ows_product_review_unsubmit_product_404_response).once()) (flexmock(release_approval_queue_model).should_receive( 'delete_latest_release_approval_queue').with_args( release_id, account_id, account_type).and_return( delete_last_release_approval_404_response).once()) submit_data = { 'account_id': account_id, 'account_type': account_type } result = product_submission.unsubmit_digital_product( release_id, submit_data) assert result.status == 404 assert result.errors == product_review_404_errors