"""Unittests for product submit endpoint with submit_product FF.""" import datetime import json from flexmock import flexmock from oto import response import pytest from product_digital import features from product_digital.connectors import mysql from product_digital.constants import features as feature_names from product_digital.constants import services from product_digital.models import release from product_digital.models import release_status from tests.factories.release import ReleaseFactory from tests.factories.release_artist import ReleaseArtistFactory from tests.factories.release_subgenre import ReleaseSubgenreFactory from tests.testutils import db PRODUCT_ID = 12345 @pytest.fixture def ff_disabled(): """Mock out validation calls for complete product.""" ( flexmock(features) .should_receive('is_feature_flag_enabled') .with_args( feature_names.REJECTIONS_FROM_CONTENTREVIEW, use_account_context=True ) .and_return(False) ) def _mock_validation(request_engine, **kwargs): product = ReleaseFactory.build( release_id=PRODUCT_ID, release_date=datetime.datetime.utcnow(), project_id=12345, sale_start_date=datetime.datetime.utcnow(), **kwargs) release_artist = ReleaseArtistFactory(release_id=PRODUCT_ID) subgenre = ReleaseSubgenreFactory(release_id=PRODUCT_ID) db.seed_models([product, release_artist, subgenre]) # @todo: remove v1 artwork validation stub on teardown of artwork_upload_v2 request_engine[services.OWS_ASSETS].add_spec( 'GET', '/validators/product/{}/artwork'.format(PRODUCT_ID)) request_engine[services.OWS_ASSETS].add_spec( 'GET', '/v2/validators/product/{}/artwork'.format(PRODUCT_ID)) request_engine[services.OWS_ASSETS].add_spec( 'GET', '/asset/product/{}'.format(PRODUCT_ID), {'assets': []}) request_engine[services.OWS_TRACK].add_spec( 'GET', '/product/{}/tracks/validate'.format(PRODUCT_ID), { 'errors': [], 'valid': True, 'valid_tracks': 1, 'total_tracks': 1, }) request_engine[services.OWS_PRODUCT_WORKFLOW].add_spec( 'GET', '/product/{}/release-approval'.format(PRODUCT_ID), status=404) return product @pytest.mark.parametrize( 'original_status,expected_status', [ ('label_processing', 'transfer_to_content'), ('in_content', 'in_content') ]) @db.test_schema def test_submit_product_workflow_success( client, ff_disabled, valid_headers_with_orchard_user_id, request_engine, original_status, expected_status, mock_vendor_company_brand, mock_vendor_response, mock_language_model_response): """Check that submit process works with FF.""" product = _mock_validation(request_engine, release_status=original_status) request_engine[services.OWS_PROJECT_MANAGER].add_spec( 'GET', '/project/{}'.format(product.project_id), {'vendor_id': 4242}) request_engine[services.OWS_PRODUCT].add_spec( 'GET', '/product/{}'.format(product.project_id)) request_engine[services.OWS_PRODUCT_WORKFLOW].add_spec( 'POST', '/product/{}/submission'.format(PRODUCT_ID), { 'release_approval': { 'release_approval_id': 1, 'release_correction_id': 42, 'status': 'checked_in', 'release_id': PRODUCT_ID }, 'latest_correction': { 'items': [], 'release_correction_id': 42, 'release_id': 123, 'status': 'submitted', } }) request_engine[services.OWS_PRODUCT_REVIEW].add_spec( 'GET', '/review-queue/product/12345/eligibility-check', 'ineligible') request_engine[services.OWS_PRODUCT_WORKFLOW].add_spec( 'GET', '/product/{}/correction'.format(PRODUCT_ID)) request_engine[services.OWS_ACCOUNT].add_spec( 'GET', '/vendor/brand/4242', mock_vendor_company_brand) request_engine[services.OWS_ACCOUNT].add_spec( 'GET', '/vendor/4242', mock_vendor_response) request_engine[services.OWS_TRACK].add_spec( 'GET', '/product/{}/tracks'.format(PRODUCT_ID), {'items': []}) put_response = client.put( '/product/audio/{}/status'.format(PRODUCT_ID), headers=valid_headers_with_orchard_user_id ) assert put_response.status_code == 200 response_body = json.loads(put_response.data.decode()) assert response_body['release_approval_status'] == 'checked_in' assert response_body['release_status'] == 'transfer_to_content' with mysql.db_session() as session: product = session.query(release.Release).get(PRODUCT_ID) assert product.release_status == expected_status if product.release_status != 'in_content': status = session.query(release_status.ReleaseStatus).filter_by( release_id=PRODUCT_ID).first() assert status.status == 'transfer_to_content' @db.test_schema def test_submit_product_workflow_product_not_found( client, valid_headers_with_orchard_user_id, request_engine, ff_disabled): """Check behavior if product deleted after validation.""" _mock_validation(request_engine) flexmock(release).should_receive('get_release_instance').and_return( response.Response(status=500)) put_response = client.put( '/product/audio/{}/status'.format(PRODUCT_ID), headers=valid_headers_with_orchard_user_id ) assert put_response.status_code == 500 @db.test_schema def test_submit_product_workflow_product_already_submitted( client, valid_headers_with_orchard_user_id, request_engine, ff_disabled, get_project_response_message, mock_vendor_company_brand, mock_vendor_response, mock_language_model_response): """Check behavior if product already submitted.""" _mock_validation(request_engine, release_status='transfer_to_content') request_engine[services.OWS_PRODUCT_WORKFLOW].add_spec( 'GET', '/product/{}/correction'.format(PRODUCT_ID)) request_engine[services.OWS_PROJECT_MANAGER].add_spec( 'GET', '/project/12345', get_project_response_message) request_engine[services.OWS_PRODUCT].add_spec( 'GET', '/product/{}'.format(PRODUCT_ID), {'vendor_id': 123}) request_engine[services.OWS_ACCOUNT].add_spec( 'GET', '/vendor/brand/9999', mock_vendor_company_brand) request_engine[services.OWS_ACCOUNT].add_spec( 'GET', '/vendor/9999', mock_vendor_response) request_engine[services.OWS_TRACK].add_spec( 'GET', '/product/{}/tracks'.format(PRODUCT_ID), {'items': []}) put_response = client.put( '/product/audio/{}/status'.format(PRODUCT_ID), headers=valid_headers_with_orchard_user_id ) assert put_response.status_code == 400 assert put_response.data.decode('utf-8') == 'Product is already submitted.' @db.test_schema def test_submit_product_workflow_project_failed( client, valid_headers_with_orchard_user_id, request_engine, ff_disabled): """Check behavior if project request failed.""" product = _mock_validation(request_engine) request_engine[services.OWS_PROJECT_MANAGER].add_spec( 'GET', '/project/{}'.format(product.project_id), status=404) request_engine[services.OWS_PRODUCT].add_spec( 'GET', '/product/{}'.format(PRODUCT_ID), {'vendor_id': 123}) put_response = client.put( '/product/audio/{}/status'.format(PRODUCT_ID), headers=valid_headers_with_orchard_user_id ) assert put_response.status_code == 400 @db.test_schema def test_submit_product_workflow_failed( client, valid_headers_with_orchard_user_id, request_engine, ff_disabled, mock_vendor_company_brand, mock_vendor_response, mock_language_model_response): """Check behavior if project request failed.""" product = _mock_validation(request_engine) request_engine[services.OWS_PRODUCT_REVIEW].add_spec( 'GET', '/review-queue/product/12345/eligibility-check', 'ineligible') request_engine[services.OWS_PROJECT_MANAGER].add_spec( 'GET', '/project/{}'.format(product.project_id), {'vendor_id': 4242}) request_engine[services.OWS_PRODUCT].add_spec( 'GET', '/product/{}'.format(PRODUCT_ID), {'vendor_id': 123}) request_engine[services.OWS_ACCOUNT].add_spec( 'GET', '/vendor/brand/4242', mock_vendor_company_brand) request_engine[services.OWS_ACCOUNT].add_spec( 'GET', '/vendor/4242', mock_vendor_response) request_engine[services.OWS_PRODUCT_WORKFLOW].add_spec( 'POST', '/product/{}/submission'.format(PRODUCT_ID), status=418) request_engine[services.OWS_TRACK].add_spec( 'GET', '/product/{}/tracks'.format(PRODUCT_ID), {'items': []}) put_response = client.put( '/product/audio/{}/status'.format(PRODUCT_ID), headers=valid_headers_with_orchard_user_id ) assert put_response.status_code == 418