"""Test for persister.""" from collections import namedtuple from unittest.mock import call from unittest.mock import MagicMock from unittest.mock import patch from flask import g from oto import response from owsrequest import request from owsrequest import test_utils import pytest from pythonfeatures import pythonfeatures from project_manager.entity.project_post_request import ProjectPostRequest from project_manager.models import ows_product from project_manager.models import persister from project_manager.util import features as features_util def test_get_artists_when_no_artists( db_fixture, projects, product_with_no_primary_artists): """Assert empty list is returned when no primary artists for a release. Asserts that when there are no primary artists in the db for a release an empty list is returned. """ artists_response = persister.get_artists_for_product(1020) assert artists_response.status == 200 assert artists_response.message == [] def test_get_artists_when_many_artists( db_fixture, projects, multiple_primary_artists): """Assert list of artist names is returned when multiple primary artists. Asserts that when there are multiple primary artists for a relase in the db their names are returned in a list. """ artists_response = persister.get_artists_for_product(1001) assert artists_response.status == 200 assert artists_response.message == ['Mike Jones', 'Billy Bones', 'Jane Dune'] def test_get_artists_when_one_artist(db_fixture, projects): """Assert list of single artist name is returned when one primary artist. Asserts that when there is one primary artist for a release in the db their name is returned in a list. """ artists_response = persister.get_artists_for_product(1001) assert artists_response.status == 200 assert artists_response.message == ['Mike Jones'] def test_get_artists_when_no_release(db_fixture): """Assert empty list is returned when their is no release. Asserts that when there are no releases that match in the db an empty list is returned. """ artists_response = persister.get_artists_for_product(4444) assert artists_response.status == 200 assert artists_response.message == [] def test_get_product_types(db_fixture): """Assert that expected product type options are returned.""" product_types_response = persister.get_product_types() expected_message = [{'name': 'New', 'display_name': 'New Release'}, {'name': 'Catalog', 'display_name': 'Catalog'}] assert product_types_response assert product_types_response.message == expected_message @patch('project_manager.util.features.is_feature_flag_enabled', return_value=False) def test_get_product_genres_ff_off(is_feature_flag_enabled, product_genres_db_fixture): """Assert that expected product genre options are returned.""" product_genres_response = persister.get_product_genres() expected_message = [{ 'id': 6, 'name': 'Alternative' }, { 'id': 2, 'name': 'Electronic' }, { 'id': 5, 'name': 'Folk' }, { 'id': 3, 'name': 'Metal' }, { 'id': 4, 'name': 'Punk' }, { 'id': 1, 'name': 'Rock' }] assert product_genres_response assert product_genres_response.message == expected_message @patch('project_manager.util.features.is_feature_flag_enabled', return_value=True) def test_get_product_genres_ff_on(is_feature_flag_enabled, product_genres_db_fixture): """Assert that expected product genre options are returned.""" product_genres_response = persister.get_product_genres() expected_message = [{ 'id': 2, 'name': 'Electronic' }, { 'id': 5, 'name': 'Folk' }, { 'id': 3, 'name': 'Metal' }, { 'id': 4, 'name': 'Punk' }, { 'id': 1, 'name': 'Rock' }] assert product_genres_response assert product_genres_response.message == expected_message def test_get_product_subgenres(product_subgenres_db_fixture): """Assert that expected product subgenre options are returned.""" product_subgenres_response = persister.get_product_subgenres(2) expected_message = [{ 'id': 996, 'name': 'Electro House', 'composer': True }, { 'id': 355, 'name': 'Trance', 'composer': False }] assert product_subgenres_response assert product_subgenres_response.message == expected_message def test_get_product_subgenres_empty_response(product_subgenres_db_fixture): """Assert that no product subgenre options are returned. Test the case when there are no subgenres for a given genre id. """ product_subgenres_response = persister.get_product_subgenres(12345) expected_message = [] assert product_subgenres_response assert product_subgenres_response.message == expected_message def test_get_products_for_project_model( monkeypatch, db_fixture, projects, test_request_context, get_company_brand_ows_response, get_vendor_ows_response): """Assert that expected products are returned for a project. Asserts that a 200 is returned with a set of products with correct attributes. """ monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests([ get_vendor_ows_response, get_company_brand_ows_response])) products_for_project_response = persister.get_products_for_project(1, 7123) expected_message = [{ 'display_upc': '888831283041', 'upc': 888831283041, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1001, 'release_name': 'Something Strange Here', 'version': 'Deluxe', 'delivered_version': 'Live at Wembley', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Single', 'not_for_distribution': 'N', 'release_approval_status': None, '_is_enabled_rejections_from_cr': False, }, { 'display_upc': '889845667810', 'upc': 889845667810, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1002, 'release_name': 'Something Strange Here', 'version': 'Unremarkable', 'delivered_version': 'Live in New York', 'distribution_format_id': 2, 'distribution_format_name': 'CD', 'context_type': 'physical', 'format': 'EP', 'not_for_distribution': 'N', 'release_approval_status': 'rejected', '_is_enabled_rejections_from_cr': False, }, { 'display_upc': '889845667872', 'upc': 889845667872, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1003, 'release_name': 'Something Strange Here', 'version': 'Target Special Edition', 'delivered_version': 'Live in Berlin', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Full Length', 'not_for_distribution': 'N', 'release_approval_status': 'checked_in', '_is_enabled_rejections_from_cr': False, }, { 'display_upc': '803680422555', 'upc': 803680422555, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1014, 'release_name': 'Herp Derp', 'version': 'Le 4th status', 'delivered_version': 'Remixed by Rem', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Single', 'not_for_distribution': 'N', 'release_approval_status': 'rejected', '_is_enabled_rejections_from_cr': False, }] assert products_for_project_response.status == 200 assert products_for_project_response.message == expected_message def test_get_products_for_project_model_from_contentreview( monkeypatch, db_fixture, projects, test_request_context, mocker): """Assert that expected products are returned for a project when FF is on. Asserts that a 200 is returned with a set of products including the correct attributes. """ mocker.patch.object( features_util, 'get_rejections_from_cr_ff_status', return_value=True, ) product_for_project_response = persister.get_products_for_project(1, 7123) expected_message = [{ 'display_upc': '888831283041', 'upc': 888831283041, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1001, 'release_name': 'Something Strange Here', 'version': 'Deluxe', 'delivered_version': 'Live at Wembley', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Single', 'not_for_distribution': 'N', 'release_approval_status': None, '_is_enabled_rejections_from_cr': True, }, { 'display_upc': '889845667810', 'upc': 889845667810, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1002, 'release_name': 'Something Strange Here', 'version': 'Unremarkable', 'delivered_version': 'Live in New York', 'distribution_format_id': 2, 'distribution_format_name': 'CD', 'context_type': 'physical', 'format': 'EP', 'not_for_distribution': 'N', 'release_approval_status': 'rejected', '_is_enabled_rejections_from_cr': True, }, { 'display_upc': '889845667872', 'upc': 889845667872, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1003, 'release_name': 'Something Strange Here', 'version': 'Target Special Edition', 'delivered_version': 'Live in Berlin', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Full Length', 'not_for_distribution': 'N', 'release_approval_status': 'checked_in', '_is_enabled_rejections_from_cr': True, }, { 'display_upc': '803680422555', 'upc': 803680422555, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1014, 'release_name': 'Herp Derp', 'version': 'Le 4th status', 'delivered_version': 'Remixed by Rem', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Single', 'not_for_distribution': 'N', 'release_approval_status': 'rejected', '_is_enabled_rejections_from_cr': True, }] assert features_util.get_rejections_from_cr_ff_status.mock_calls == [ call( 7123, 1, ), call( 7123, 2, ), ] assert product_for_project_response.status == 200 assert product_for_project_response.message == expected_message def test_get_product_for_project_contentreview( db_fixture, projects, test_request_context, get_company_brand_ows_response, monkeypatch, mocker): """Assert that expected product is returned for a project. Asserts that a 200 is returned with a product including the correct attributes. """ mocker.patch.object( features_util, 'get_rejections_from_cr_ff_status', return_value=True, ) product_for_project_response = persister.get_product_for_project( 1, 1003, 7123) expected_message = { 'display_upc': '889845667872', 'upc': 889845667872, 'product_type': 'Music', 'product_type_id': 1, 'product_id': 1003, 'release_name': 'Something Strange Here', 'version': 'Target Special Edition', 'delivered_version': 'Live in Berlin', 'distribution_format_id': 1, 'distribution_format_name': 'Digital', 'context_type': 'digital', 'format': 'Full Length', 'not_for_distribution': 'N', 'release_approval_status': 'checked_in', '_is_enabled_rejections_from_cr': True, } assert features_util.get_rejections_from_cr_ff_status.mock_calls == [ call( 7123, 1, ), ] assert product_for_project_response.status == 200 assert product_for_project_response.message == expected_message def test_get_product_for_project_with_deletions( db_fixture, test_request_context, mocker, deleted_project): """Assert that expected product is not returned for a deleted project. Asserts that a 404 is returned. """ mocker.spy(g.log, 'warning') product_for_project_response = persister.get_product_for_project( 1, 1003, 7123) expected_error_message = 'Unable to find product_id 1003' response_errors = product_for_project_response.errors assert product_for_project_response.status == 404 assert response_errors.get('message') == expected_error_message assert response_errors.get('code') == 'not_found_error' g.log.warning.assert_called_once_with( 'No product found for product id 1003') def test_get_product_for_project_no_product( db_fixture, test_request_context, mocker): """Assert that expected not found message is returned when no product. Asserts that a 404 is returned with the appropriate message. """ mocker.spy(g.log, 'warning') get_product_response = persister.get_product_for_project(1, 2143, 7123) expected_error_message = 'Unable to find product_id 2143' response_errors = get_product_response.errors assert get_product_response.status == 404 assert response_errors.get('message') == expected_error_message assert response_errors.get('code') == 'not_found_error' g.log.warning.assert_called_once_with( 'No product found for product id 2143') @pytest.mark.parametrize( ('subaccount_id', 'expected_message'), [ (1, [{'id': 'Apple Records', 'name': 'Apple Records'}, {'id': 'Maple Records', 'name': 'Maple Records'}]), (2, [{'id': 'Banana Records', 'name': 'Banana Records'}]), (3, []) ]) def test_get_product_imprints_for_subaccount( product_imprints_db_fixture, subaccount_id, expected_message): """Assert that expected product imprint options are returned. Assert that expected product imprint options are returned for a given subaccount. """ imprints_response = persister.get_product_imprints_for_subaccount( subaccount_id) assert imprints_response assert imprints_response.message == expected_message @pytest.mark.parametrize( ('vendor_id', 'expected_message'), [ (1, [{'id': 'Best Records', 'name': 'Best Records'}, {'id': 'Second Best Records', 'name': 'Second Best Records'}]), (2, [{'id': 'Going Records', 'name': 'Going Records'}]), (3, []) ]) def test_get_product_imprints_for_vendor( product_imprints_db_fixture, vendor_id, expected_message): """Assert that expected product imprint options are returned. Assert that expected product imprint options are returned for a given vendor. """ imprints_response = persister.get_product_imprints_for_vendor( vendor_id) assert imprints_response assert imprints_response.message == expected_message def test_get_release_status_for_error_correction(db_fixture): """Assert error correction releases get that status. Asserts that when the latest entry in error correction for a release exists and has status "active" the release is in error_correction """ status_response = persister.get_release_status_for_product(1001) assert status_response.status == 200 assert status_response.message == { 'correction_status': 'active', 'release_status': 'in_content', 'review_status': None } def test_get_release_status_for_action_required(db_fixture): """Assert error correction releases get that status. Asserts that when the latest entry in release approval for a release exists and has status "rejected" the release is in action_required """ status_response = persister.get_release_status_for_product(1002) assert status_response.status == 200 assert status_response.message == { 'correction_status': None, 'release_status': 'in_content', 'review_status': 'rejected' } def test_get_release_status_for_action_required_error_correction(db_fixture): """Assert error correction releases get that status. Asserts that when the latest entry in release approval for a release exists and has status "rejected" the release is in action_required """ status_response = persister.get_release_status_for_product(1014) assert status_response.status == 200 assert status_response.message == { 'correction_status': 'active', 'release_status': 'in_content', 'review_status': 'rejected' } def test_get_release_status_for_in_content(db_fixture): """Assert in_content releases get that status. Asserts that when a release is in_content and does not meet error correction or action required conditions then it is in_content """ status_response = persister.get_release_status_for_product(1011) assert status_response.status == 200 assert status_response.message == { 'correction_status': None, 'release_status': 'in_content', 'review_status': None } def test_get_release_status_for_transfer_to_content(db_fixture): """Assert transfer_to_content releases get that status. Asserts that when a release is transfer_to_content that status is returned. """ status_response = persister.get_release_status_for_product(1003) assert status_response.status == 200 assert status_response.message == { 'correction_status': None, 'release_status': 'transfer_to_content', 'review_status': 'checked_in' } def test_get_release_status_for_label_processing_when_rejected( db_fixture, release_with_status_label_processing_and_rejected): """Assert label_processing releases that are rejected get action_required. Asserts that when a release is label_processing that the correct status is returned """ status_response = persister.get_release_status_for_product(2034) assert status_response.status == 200 assert status_response.message == { 'correction_status': None, 'release_status': 'label_processing', 'review_status': 'rejected' } def test_get_release_status_for_in_content_when_submitted(db_fixture, release_with_status_in_content_and_correction_submitted): # noqa """In_content releases with submitted correction get transfer_to_content. Asserts that when a release is in_content that the correct status is returned. """ status_response = persister.get_release_status_for_product(1853456) assert status_response.status == 200 assert status_response.message == { 'correction_status': 'submitted', 'release_status': 'in_content', 'review_status': None } def test_get_project_and_artist_info_by_id(product_artist_db_fixture): """Assert get_project_and_artist_info_by_id returns the correct data.""" status_response = persister.get_project_and_artist_info_by_id(1) assert status_response.status == 200 assert status_response.message == { 'project_id': 1, 'project_code': 'code', 'vendor_id': 1, 'subaccount_id': 1, 'project_name': 'Name', 'created_date_utc': 'created', 'updated_date_utc': 'updated', 'correlation_id': '123', 'description': 'description', 'artist_id': 1, 'artist_name': 'Billy Bob', 'artist_description': 'The best honky tonky', 'artist_url': 'http://www.billy.com/', 'subaccount_name': 'subaccount_test_value', 'deletions': 'N' } def test_get_project_and_artist_info_by_id_with_tenant_uuids(db_fixture, product_artist_db_fixture): """Assert get_project_and_artist_info_by_id returns the correct data.""" status_response = persister.get_project_and_artist_info_by_id(1, True) assert status_response.status == 200 assert status_response.message == { 'project_id': 1, 'project_code': 'code', 'vendor_id': 1, 'subaccount_id': 1, 'project_name': 'Name', 'created_date_utc': 'created', 'updated_date_utc': 'updated', 'correlation_id': '123', 'description': 'description', 'artist_id': 1, 'artist_name': 'Billy Bob', 'artist_description': 'The best honky tonky', 'artist_url': 'http://www.billy.com/', 'subaccount_name': 'subaccount_test_value', 'deletions': 'N', 'companyBrandUUID': 'd25a4cd1-e820-45f2-be5c-56edcfeb8298', 'parentCompanyUUID': '955a1bbd-b623-4ea1-ab5f-8d6620c442fb', 'subaccountUUID': 'a6a48264-7882-4ef4-9b7d-2500fb2c3ce4', 'vendorUUID': 'a8d36bb5-bca5-4e3e-80dc-1b292857351c' } def test_get_project_and_artist_info_by_id_with_deletions( product_artist_with_deletions_db_fixture): """Assert get_project_and_artist_info_by_id returns data with deletion.""" status_response = persister.get_project_and_artist_info_by_id(1) assert status_response.status == 200 def test_insert_project_with_artist_and_description( db_fixture, get_artist_info_ok, monkeypatch): """Assert that an artist and description can be inserted with a project.""" monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests([get_artist_info_ok])) project_code = 96741599989 project_name = 'Some Awesome Album' artist_id = 123 subaccount_id = 1234234 grass_account_type = 'vendor' grass_account_id = 213421 correlation_id = 'abc-123' description = 'Such an awesome album.' user = 'alw:123' project_request = ProjectPostRequest( project_code, project_name, artist_id, subaccount_id, grass_account_type, grass_account_id, correlation_id, description, None, user) persister_response = persister.insert_project(project_request) persister_message = persister_response.message new_project = persister.get_project_by_id(persister_message['project_id']) # assertions against model function return value assert persister_response.status == 201 assert persister_message['project_code'] == str(project_code) assert persister_message['artist_id'] == artist_id assert persister_message['description'] == description # assertions against updated values in db assert new_project.message['project_code'] == str(project_code) assert new_project.message['artist_id'] == artist_id assert new_project.message['description'] == description def test_insert_project_with_artist( db_fixture, monkeypatch, get_artist_info_ok): """Assert that an artist can be inserted with a project.""" monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests([get_artist_info_ok])) project_code = 96741599989 project_name = 'Some Awesome Album' artist_id = 123 subaccount_id = 1234234 grass_account_type = 'vendor' grass_account_id = 213421 correlation_id = None user = 'alw:123' project_request = ProjectPostRequest( project_code, project_name, artist_id, subaccount_id, grass_account_type, grass_account_id, correlation_id, None, None, user) persister_response = persister.insert_project(project_request) persister_message = persister_response.message new_project = persister.get_project_by_id(persister_message['project_id']) # assertions against model function return value assert persister_response.status == 201 assert persister_message['project_code'] == str(project_code) assert persister_message['artist_id'] == artist_id # assertions against updated values in db assert new_project.message['project_code'] == str(project_code) assert new_project.message['artist_id'] == artist_id def test_create_project_with_existing_project_code_error(db_fixture): """Assert that project_code uniqueness check is case insensitive.""" def get_project_data(project_code): ProjectData = namedtuple( 'ProjectData', [ 'project_code', 'vendor_id', 'subaccount_id', 'project_name', 'correlation_id', 'artist_id', 'description', 'user']) return ProjectData( project_code=project_code, vendor_id=7123, subaccount_id=0, project_name='Applesauce Applesauce', correlation_id='some-correlation-id', artist_id=123, description="It's good!", user='alw:123') persister_response = persister.insert_project( get_project_data('applesauce')) assert persister_response persister_response = persister.insert_project( get_project_data('appLEsaucE')) assert not persister_response assert persister_response.errors == { 'code': 'validation_error', 'message': { 'project_code': { 'message': "Project code \'appLEsaucE\' already exists", 'validator': 'used', 'validator_value': True, 'deletions': 'N', 'existing_project_id': 1}}} def test_update_project_by_id_with_bogus_param( db_fixture, project, test_request_context, monkeypatch, get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response): """Assert that the project is not updated with invalid params.""" monkeypatch.setattr( pythonfeatures, 'get_single_feature', MagicMock(return_value=response.Response(message='disabled'))) request_specs = [ get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response, { 'service': 'ows-artist', 'path': '/artist/234234', 'status': 200, 'json': { 'id': 234234, 'name': 'Solange Knowles', 'artist_type': 'artist'}}] monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(request_specs)) project_name = 'Something Awesome' artist_id = 234234 project_id = 1 description = 'An even better description' user = 'alw:123' params = { 'project_name': project_name, 'artist_id': artist_id, 'description': description, 'project_highlights': 'Something something horrible'} monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) project_response = persister.update_project_by_id( project_id, params, user) message = project_response.message updated_project = persister.get_project_by_id(message['project_id']) # assertions against model function return value assert project_response.status == 200 assert message['project_name'] == project_name assert message['artist_id'] == artist_id assert message['description'] == description assert 'project_highlight' not in message.keys() # assertions against updated values in db assert updated_project.message['project_name'] == project_name assert updated_project.message['artist_id'] == artist_id assert updated_project.message['description'] == description assert 'project_highlight' not in updated_project.message.keys() def test_update_project_by_id_with_project_code_with_no_products( db_fixture, projects, test_request_context, monkeypatch, get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response): """Assert that project code is updated if the project has no products.""" request_specs = [ get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response, { 'service': 'ows-artist', 'path': '/artist/234234', 'status': 200, 'json': { 'id': 234234, 'name': 'Buyepongo', 'artist_type': 'artist'}}] monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(request_specs)) monkeypatch.setattr( pythonfeatures, 'get_single_feature', MagicMock(return_value=response.Response(message='disabled'))) project_name = 'Todo Mundo' artist_id = 234234 project_id = 3 description = 'Much descriptive' project_code = 'so-coded' user = 'alw:123' params = { 'project_name': project_name, 'artist_id': artist_id, 'description': description, 'project_code': project_code} monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) project_response = persister.update_project_by_id( project_id, params, user) message = project_response.message updated_project = persister.get_project_by_id(message['project_id']) # assertions against model function return value assert project_response.status == 200 assert message['project_name'] == project_name assert message['artist_id'] == artist_id assert message['description'] == description assert message['project_code'] == project_code # assertions against updated values in db assert updated_project.message['project_name'] == project_name assert updated_project.message['artist_id'] == artist_id assert updated_project.message['description'] == description assert updated_project.message['project_code'] == project_code def test_update_project_by_id_with_user( db_fixture, project, test_request_context, monkeypatch, get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response): """Assert that the project is updated.""" monkeypatch.setattr( pythonfeatures, 'get_single_feature', MagicMock(return_value=response.Response(message='disabled'))) request_specs = [ get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response, { 'service': 'ows-artist', 'path': '/artist/234234', 'status': 200, 'json': { 'id': 234234, 'name': 'Solange Knowles', 'artist_type': 'artist' } } ] monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(request_specs)) project_name = 'Something Awesome' artist_id = 234234 project_id = 1 description = 'An even better description' params = { 'project_name': project_name, 'artist_id': artist_id, 'description': description } user = 'alw:123' monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) project_response = persister.update_project_by_id( project_id, params, user) message = project_response.message updated_project = persister.get_project_by_id(message['project_id']) # assertions against model function return value assert project_response.status == 200 assert message['project_name'] == project_name assert message['artist_id'] == artist_id assert message['description'] == description # assertions against updated values in db assert updated_project.message['project_name'] == project_name assert updated_project.message['artist_id'] == artist_id assert updated_project.message['description'] == description def test_update_project_by_id_with_artist_param( db_fixture, project, test_request_context, monkeypatch, get_artist_info_ok, create_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response): """Assert that the project is updated.""" request_specs_get = [ get_artist_info_ok, get_company_brand_ows_response, get_vendor_ows_response, { 'service': 'ows-artist', 'path': '/artist/234234', 'status': 200, 'json': { 'id': 234234, 'name': 'Solange Knowles', 'artist_type': 'artist' } } ] monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(request_specs_get)) monkeypatch.setattr( pythonfeatures, 'get_single_feature', MagicMock(return_value=response.Response(message='disabled'))) request_specs_post = [ create_artist_info_ok, { 'service': 'ows-artist', 'path': '/artist', 'status': 200, 'json': { 'id': 234234, 'name': 'Solange Knowles', 'artist_type': 'artist' } } ] monkeypatch.setattr( request, 'post', test_utils.mock_ows_requests(request_specs_post)) project_name = 'Something Awesome' artist_id = 123 project_id = 1 description = 'An even better description' params = { 'project_name': project_name, 'description': description, 'artist': { 'name': 'test', 'vendor_id': 123, 'subaccount_id': 0 } } user = 'alw:123' result = persister.update_project_by_id(project_id, params, user) message = result.message updated_project = persister.get_project_by_id(message['project_id']) # assertions against model function return value assert result.status == 200 assert message['project_name'] == project_name assert message['artist_id'] == artist_id assert message['description'] == description # assertions against updated values in db assert updated_project.message['project_name'] == project_name assert updated_project.message['artist_id'] == artist_id assert updated_project.message['description'] == description @patch('project_manager.models.ows_account.get_subaccount_for_subaccount_id') def test_get_projects_as_distributor_contains_subaccount_data( mock_get_subaccount, db_fixture, projects): """Multiple projects returned for distributor with subaccount data.""" test_subaccount_obj = { 'subaccount_name': 'Label One', 'description': 'This is my first subaccount.', 'subaccount_id': 1, 'vendor_id': 16055} mock_get_subaccount.return_value = test_subaccount_obj result = persister.get_projects(7123, None, 0, 1000) assert result.status == 200 assert result.message.get('items')[0].get( 'subaccount') == test_subaccount_obj assert result.message.get('items')[1].get( 'subaccount') == test_subaccount_obj @patch('project_manager.models.ows_account.get_subaccount_for_subaccount_id') def test_get_projects_as_distributor_contains_subaccount_data_with_deletions( mock_get_subaccount, db_fixture, deleted_project): """No project returned since deleted.""" test_subaccount_obj = { 'subaccount_name': 'Label One', 'description': 'This is my first subaccount.', 'subaccount_id': 1, 'vendor_id': 16055} mock_get_subaccount.return_value = test_subaccount_obj result = persister.get_projects(7123, None, 0, 1000) assert result.status == 200 assert result.message.get('items') == [] @patch('project_manager.models.ows_account.get_subaccount_for_subaccount_id') def test_get_projects_as_non_distributor_no_subaccount_data( mock_get_subaccount, db_fixture, projects_without_subaccount): """Muitlple Projects returned for non distributor w/o subaccount data.""" test_subaccount_obj = { 'subaccount_name': 'Label One', 'description': 'This is my first subaccount.', 'subaccount_id': 1, 'vendor_id': 16055} mock_get_subaccount.return_value = test_subaccount_obj result = persister.get_projects(7123, None, 0, 1000) mock_get_subaccount.assert_not_called() assert result.status == 200 assert result.message.get('items')[0].get( 'subaccount') is None assert result.message.get('items')[1].get( 'subaccount') is None def test_get_project_artist_name_no_artist_id(monkeypatch, db_fixture): """Test get artist skips request when no artist_id is present.""" project_code = 96741599989 project_name = 'Some Awesome Album' subaccount_id = 1234234 grass_account_type = 'vendor' grass_account_id = 213421 correlation_id = None description = 'Such an awesome album.' user = 'alw:123' project_request = ProjectPostRequest( project_code, project_name, 0, subaccount_id, grass_account_type, grass_account_id, correlation_id, description, None, user) project_request.artist_id = None project_id = persister.insert_project( project_request).message.get('project_id') result = persister.get_project_by_id(project_id) assert result.message.get('artist_name') is None def test_insert_project_with_deletions( monkeypatch, db_fixture, deleted_project): """Test insert fails when deleted project already exist with same code.""" project_code = 'DELETED' project_name = 'Some Awesome Album' subaccount_id = 1 grass_account_type = 'vendor' grass_account_id = 7123 correlation_id = None description = 'Such an awesome album.' user = 'alw:123' project_request = ProjectPostRequest( project_code, project_name, 0, subaccount_id, grass_account_type, grass_account_id, correlation_id, description, None, user) project_request.artist_id = None response = persister.insert_project(project_request) expected_code = 'validation_error' expected_message = "Project code 'DELETED' already exists" assert response.errors['code'] == expected_code assert response.errors['message']['project_code']['message'] \ == expected_message assert response.status == 400 def test_insert_project_with_user_id_and_type( db_fixture, monkeypatch, get_artist_info_ok): """Assert that an user id and user type can be inserted with a project.""" monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests([get_artist_info_ok])) project_code = 96741599989 project_name = 'Some Awesome Album' artist_id = 123 subaccount_id = 1234234 grass_account_type = 'vendor' grass_account_id = 213421 correlation_id = None user = 'alw:123' project_request = ProjectPostRequest( project_code, project_name, artist_id, subaccount_id, grass_account_type, grass_account_id, correlation_id, None, None, user) persister_response = persister.insert_project(project_request) persister_message = persister_response.message new_project = persister.get_project_by_id(persister_message['project_id']) # assertions against model function return value assert persister_response.status == 201 assert persister_message['project_code'] == str(project_code) assert persister_message['artist_id'] == artist_id # assertions against updated values in db assert new_project.message['project_code'] == str(project_code) assert new_project.message['artist_id'] == artist_id @pytest.mark.parametrize('project_code,status_code', [ ('does_not_exist', 404), ('ABC', 200), (None, 404), ]) def test_get_project_by_project_code( db_fixture, test_request_context, project, project_code, status_code): """Test get_project_by_project_code.""" result = persister.get_project_by_project_code(project_code, 7123, 1) assert result.status == status_code @pytest.mark.parametrize('project_codes,subaccount_uuid,message', [ ( ['ABC', 'DEF', 'GHI'], 'a6a48264-7882-4ef4-9b7d-2500fb2c3ce4', [ { 'project_id': 2, 'project_code': 'ABC', 'project_name': 'new project', 'artist_name': 'Test Artist 1', 'deletions': 'N' }, { 'project_id': 3, 'project_code': 'DEF', 'project_name': 'new project 2', 'artist_name': 'Test Artist 2', 'deletions': 'N' }, ] ), ( ['ABC', 'DEF', 'GHI'], '6e420fd1-2268-47a2-b5a9-ccacf4b46a98', [ { 'project_id': 4, 'project_code': 'GHI', 'project_name': 'new project 3', 'artist_name': 'Test Artist 3', 'deletions': 'N' } ] ), ( ['ABC', 'doesnt-exist'], 'a6a48264-7882-4ef4-9b7d-2500fb2c3ce4', [ { 'project_id': 2, 'project_code': 'ABC', 'project_name': 'new project', 'artist_name': 'Test Artist 1', 'deletions': 'N' }, ] ), (['doesnt-exist', 'doesnt-exist-either'], 'a6a48264-7882-4ef4-9b7d-2500fb2c3ce4', []), ]) def test_get_existing_project_codes( available_project_codes_db_fixture, test_request_context, project_codes, subaccount_uuid, message, ): """Test get_project_by_project_code.""" result = persister.get_existing_projects( project_codes, '369a8193-132c-4d8c-9d87-b8e7a61dbc25', subaccount_uuid ) assert result.message == message def test_get_projects_by_ids_empty_returns_empty(): """Empty id list short-circuits to an empty list without a query.""" result = persister.get_projects_by_ids([]) assert result.message == []