"""Functional tests around submit product.""" import json from flexmock import flexmock from oto import response import pytest from product_workflow.models import ows_product_review from product_workflow.models import release_approval_queue from tests.factories import release_approval_queue \ as release_approval_queue_factory from tests.factories import release_correction as release_correction_factory from tests.testutils import db @pytest.fixture def submit_payload(): """Valid payload for product submit.""" return { 'error_correction_flag': True, 'account_type': 'vendor', 'account_id': '25257', } @pytest.fixture def ows_product_response(): """Response from ows-product/product/.""" product_dict = { 'product_id': 1, 'project_id': 1111, 'distribution_format_id': 2, 'product_type_id': 1, 'upc': 100075236325, 'vendor_id': 7123, 'subaccount_id': 0, 'context_type': 'digital', 'release_date': '2016-10-15', 'status': 'label_processing', 'product_name': 'Charlie Dance' } result = response.Response(message=product_dict) return result @db.test_schema def test_submit_product_success( mocker, ows_product_response, client, submit_payload, valid_headers, product_id): """Test result when submitting product.""" mocker.patch( 'product_workflow.models.ows_product.get_product_by_id', return_value=ows_product_response) mocker.patch.object( ows_product_review, 'get_review_queue_eligibility', return_value=response.Response(message='ineligible'), ) result = client.post( '/product/{}/submission'.format(product_id), headers=valid_headers, data=json.dumps(submit_payload)) response_json = json.loads(result.data.decode('utf-8')) expected_body = { 'latest_correction': None, 'release_approval': { 'release_approval_id': 1, 'release_correction_id': None, 'status': 'checked_in', 'release_id': product_id, 'checked_out_by': None} } assert result.status_code == 200 assert response_json == expected_body def test_submit_product_validation( mocker, ows_product_response, client, submit_payload, valid_headers, product_id): """Check validation works.""" mocker.patch( 'product_workflow.models.ows_product.get_product_by_id', return_value=ows_product_response) del submit_payload['account_id'] result = client.post( '/product/{}/submission'.format(product_id), headers=valid_headers, data=json.dumps(submit_payload)) assert result.status_code == 400 test_submit_product_error_correction_update_expected_body = { 'release_approval': { 'release_approval_id': 1, 'release_correction_id': None, 'status': 'checked_in', 'release_id': 123, 'checked_out_by': None } } @pytest.mark.parametrize(( 'correction_flag', 'review_queue_eligibility', 'expected_body', ), [ ( True, 'ineligible', { **test_submit_product_error_correction_update_expected_body, 'latest_correction': { 'items': [], 'release_correction_id': 42, 'release_id': 123, 'status': 'submitted' }, 'release_approval': { **test_submit_product_error_correction_update_expected_body['release_approval'], 'release_correction_id': 42, } }, ), ( True, 'eligible', {'release_approval': {'status': 'checked_in'}}, ), ( False, None, test_submit_product_error_correction_update_expected_body, ), ]) @db.test_schema def test_submit_product_error_correction_update( mocker, ows_product_response, client, submit_payload, valid_headers, product_id, correction_flag, expected_body, review_queue_eligibility): """Check that release correction updated.""" mocker.patch( 'product_workflow.models.ows_product.get_product_by_id', return_value=ows_product_response) mocker.patch.object( ows_product_review, 'get_review_queue_eligibility', return_value=response.Response(message=review_queue_eligibility), ) submit_payload['error_correction_flag'] = correction_flag correction = release_correction_factory.ReleaseCorrectionFactory \ .build_batch(1, release_id=product_id, release_correction_id=42) db.seed_models(correction) result = client.post( '/product/{}/submission'.format(product_id), headers=valid_headers, data=json.dumps(submit_payload)) response_json = None try: response_json = json.loads(result.data.decode('utf-8')) except Exception: pass assert result.status_code == 200 assert response_json == expected_body @db.test_schema def test_submit_product_get_approval_fails( mocker, ows_product_response, client, submit_payload, valid_headers, product_id): """Check response code when get approval fails.""" mocker.patch( 'product_workflow.models.ows_product.get_product_by_id', return_value=ows_product_response) flexmock(release_approval_queue).should_receive( 'get_last_approval').and_return(response.Response(status=418)).once() result = client.post( '/product/{}/submission'.format(product_id), headers=valid_headers, data=json.dumps(submit_payload)) assert result.status_code == 418 @db.test_schema def test_submit_product_already_checked_out( mocker, ows_product_response, client, submit_payload, valid_headers, product_id): """Check response code when product already checked out.""" mocker.patch( 'product_workflow.models.ows_product.get_product_by_id', return_value=ows_product_response) release_approval_queues = \ release_approval_queue_factory.ReleaseApprovalQueueFactory.build_batch( 2, release_id=product_id, status='checked_out') db.seed_models(release_approval_queues) result = client.post( '/product/{}/submission'.format(product_id), headers=valid_headers, data=json.dumps(submit_payload)) assert result.status_code == 400 response_json = json.loads(result.data.decode('utf-8')) assert response_json['message'] == 'Product is already checked out' @pytest.mark.parametrize('correction_flag', [True, False]) @db.test_schema def test_submit_product_for_missing_error_correction( mocker, ows_product_response, client, submit_payload, valid_headers, product_id, correction_flag): """Check when release correction is empty and release is in_content.""" ows_product_response.message['status'] = 'in_content' mocker.patch( 'product_workflow.models.ows_product.get_product_by_id', return_value=ows_product_response) mocker.patch.object( ows_product_review, 'get_review_queue_eligibility', return_value=response.Response(message='eligible'), ) correction = '' db.seed_models(correction) result = client.post( '/product/{}/submission'.format(product_id), headers=valid_headers, data=json.dumps(submit_payload)) response_json = json.loads(result.data.decode('utf-8')) assert result.status_code == 400 assert response_json['message'] == 'Product has missing release correction'