"""Test update project.""" from datetime import datetime import json from unittest.mock import MagicMock from oto import response from owsrequest import request from owsrequest import test_utils import pytest from project_manager.constant import error_const from project_manager.constant import header_const from project_manager.constant import marketing_const from project_manager.models import ows_product from tests.common_assert import assert_header from tests.conftest import header_user_helper, header_user_oa_helper expected_updated_project = { 'project_id': 1, 'project_code': 'ABC', 'vendor_id': 7123, 'subaccount_id': 1, 'project_name': 'updated project name', 'artist_id': 12346, 'artist_name': 'Solange Knowles', 'created_date_utc': '2016-01-01 00:00:00.000000', 'updated_date_utc': '2016-01-01 00:00:00.000000', 'product_count': 4, 'project_highlights': 'Kissed Madonna on stage at the VMAs', 'description': None, 'vendor_name': 'Awesome Vendor', 'subaccount_name': 'subaccount_test_value', 'deletions': 'N' } expected_updated_project_description = { 'project_id': 1, 'project_code': 'ABC', 'vendor_id': 7123, 'subaccount_id': 1, 'project_name': 'new project', 'artist_id': 123, 'artist_name': 'Solange Knowles', 'created_date_utc': '2016-01-01 00:00:00.000000', 'updated_date_utc': '2016-01-01 00:00:00.000000', 'product_count': 4, 'project_highlights': 'Kissed Madonna on stage at the VMAs', 'description': 'an updated description', 'vendor_name': 'Awesome Vendor', 'subaccount_name': 'subaccount_test_value', 'deletions': 'N' } expected_updated_project_project_code = { 'project_id': 3, 'project_code': 'knowles-knows', 'vendor_id': 7123, 'subaccount_id': 1, 'project_name': 'new project', 'artist_id': 123, 'artist_name': 'Solange Knowles', 'created_date_utc': '2016-01-01 00:00:00.000000', 'updated_date_utc': '2016-01-01 00:00:00.000000', 'product_count': 0, 'project_highlights': 'Kissed Madonna on stage at the VMAs', 'description': None, 'deletions': 'N'} update_request_data = { 'project_name': 'updated project name', 'artist_id': 12346} update_request_data_description = { 'description': 'an updated description', 'artist_id': 123} update_request_project_code = { 'project_code': 'knowles-knows', 'artist_id': 123} def test_update_empty_response( db_fixture, project, client, header): """Assert empty response from PUT /project. It checks to see if an empty json is returned for updating non existing project. It tests for correlation-id and content-type to be in the response header. """ res = client.put( '/project/0', data=json.dumps(update_request_data), headers=header) res_json = json.loads(res.data.decode()) assert 'Unable to find project_id 0' == res_json[error_const.ERROR_DETAIL] assert error_const.ERROR_CODE_NOT_FOUND == res_json[error_const.ERROR_CODE] assert 404 == res.status_code assert_header(header, res.headers) @pytest.mark.parametrize('header', [(header_user_helper('alw:123')), (header_user_oa_helper('oa:123'))], ids=['header', 'oa_header']) def test_update_valid_response( header, db_fixture, project_highlight_ok, monkeypatch, project, client, get_artist_info_ok, get_content_review_data_all, get_company_brand_ows_response, test_request_context): """Assert valid response from PUT /project. It checks to see updated json is returned for updating project. It tests for correlation-id and content-type to be in the response header. """ updated_project_fetch = { 'service': 'ows-artist', 'path': '/artist/12346', 'status': 200, 'json': { 'id': 12346, 'name': 'Solange Knowles', 'artist_type': 'artist'}} monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests([ project_highlight_ok, get_artist_info_ok, updated_project_fetch, get_company_brand_ows_response, { 'service': 'ows-account', 'path': '/subaccount/1', 'status': 200, 'json': {'vendor_id': 7123} }, *get_content_review_data_all ])) monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) res = client.put( '/project/1', data=json.dumps(update_request_data), headers=header) actual = json.loads(res.data.decode()) assert res.status_code == 200 for key, value in actual.items(): if key != 'updated_date_utc': assert expected_updated_project[key] == value else: actual_date = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') expected_date = datetime.strptime( expected_updated_project['updated_date_utc'], '%Y-%m-%d %H:%M:%S.%f') assert actual_date > expected_date assert_header(header, res.headers) def test_update_valid_response_with_project_code( db_fixture, project_highlight_ok_no_products, monkeypatch, projects, client, header, get_artist_info_ok, get_company_brand_ows_response): """Assert valid response from PUT /project when updating project code. It checks to see updated json is returned for updating a project code for a project that does not have any products. """ header[header_const.ORCHARD_USER_ID] = 'alw:123' monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests( [ project_highlight_ok_no_products, get_artist_info_ok, get_company_brand_ows_response, { 'service': 'ows-account', 'path': '/subaccount/1', 'status': 200, 'json': {'vendor_id': 7123} } ])) monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) res = client.put( '/project/3', data=json.dumps(update_request_project_code), headers=header) actual = json.loads(res.data.decode()) assert res.status_code == 200 assert actual['project_code'] ==\ update_request_project_code['project_code'] assert_header(header, res.headers) def test_update_valid_response_with_description( db_fixture, project_highlight_ok, monkeypatch, project, client, header, get_artist_info_ok, get_company_brand_ows_response): """Assert valid response from PUT /project. It checks to see updated json is returned for updating project. It tests for correlation-id and content-type to be in the response header. """ header[header_const.ORCHARD_USER_ID] = 'alw:123' monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests( [ project_highlight_ok, get_artist_info_ok, get_company_brand_ows_response, { 'service': 'ows-account', 'path': '/subaccount/1', 'status': 200, 'json': {'vendor_id': 7123} } ])) monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) res = client.put( '/project/1', data=json.dumps(update_request_data_description), headers=header) actual = json.loads(res.data.decode()) assert res.status_code == 200 for key, value in actual.items(): if key != 'updated_date_utc': assert expected_updated_project_description[key] == value else: actual_date = datetime.strptime(value, '%Y-%m-%dT%H:%M:%S.%f') expected_date = datetime.strptime( expected_updated_project['updated_date_utc'], '%Y-%m-%d %H:%M:%S.%f') assert actual_date > expected_date assert_header(header, res.headers) def test_update_valid_project_with_project_highlights( monkeypatch, db_fixture, project, client, header, get_artist_info_ok, get_content_review_data_all, get_company_brand_ows_response): """Valid project also updates project_highlights. Call is made to marketing service to update highlight associated with the project. """ highlight_id = 12377 project_id = 1 updated_project_highlights_description = 'Some highlight about something.' update_request_data_with_highlights = { 'project_name': 'updated project name', 'artist_id': 12346, 'project_highlights': updated_project_highlights_description} get_project_highlights_json = { 'items': [{ 'attachment': 'N', 'client': 'alw', 'highlight_id': highlight_id, 'entity': 'project', 'mkt_program_id': 20, 'scope': 'public', 'description': 'Old description', 'entity_id': 1, 'subject': 'Project Highlights'}], 'pagination': { 'total_records': 2, 'limit': 50, 'type': 'standard', 'offset': 0}} get_specs = [ { 'service': 'ows-marketing', 'path': '/highlights/project/{}?mkt_program_id={}'.format( project_id, marketing_const.PROGRAM_MARKETING_HIGHLIGHTS), 'status': 200, 'json': get_project_highlights_json }, get_company_brand_ows_response, { 'service': 'ows-account', 'path': '/subaccount/1', 'status': 200, 'json': {'vendor_id': 7123} }, get_artist_info_ok, *get_content_review_data_all ] put_project_highlights_json = { 'attachment': 'N', 'client': 'alw', 'highlight_id': highlight_id, 'entity': 'project', 'mkt_program_id': 20, 'scope': 'public', 'description': updated_project_highlights_description, 'entity_id': 1, 'subject': 'Project Highlights'} put_specs = [{ 'service': 'ows-marketing', 'path': '/highlights/{}'.format(highlight_id), 'status': 200, 'json': put_project_highlights_json}] header[header_const.ORCHARD_USER_ID] = 'alw:123' monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(get_specs)) monkeypatch.setattr( request, 'put', test_utils.mock_ows_requests(put_specs)) monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) project_response = client.put( '/project/1', data=json.dumps( update_request_data_with_highlights), headers=header) response_json = json.loads(project_response.data.decode()) assert project_response.status_code == 200 assert_header(header, project_response.headers) assert response_json.get('project_id') == 1 assert response_json.get( 'project_highlights') == updated_project_highlights_description def test_update_valid_project_with_project_highlights_when_none( db_fixture, monkeypatch, project, client, header, get_content_review_data_all, get_company_brand_ows_response): """Valid project creates project_highlights when none. Call is made to marketing service to create highlight associated with the project. """ project_id = 1 artist_spec_get = { 'service': 'ows-artist', 'path': '/artist/123', 'status': 200, 'json': { 'id': 123, 'name': 'Solange Knowles', 'artist_type': 'artist'}} get_specs = [ { 'service': 'ows-marketing', 'path': '/highlights/project/{}?mkt_program_id={}'.format( project_id, marketing_const.PROGRAM_MARKETING_HIGHLIGHTS), 'status': 404, 'json': {} }, artist_spec_get, get_company_brand_ows_response, { 'service': 'ows-account', 'path': '/subaccount/1', 'status': 200, 'json': {'vendor_id': 7123} }, *get_content_review_data_all ] updated_project_highlights_description = 'Some highlight about something.' update_request_data_with_highlights = { 'project_name': 'updated project name', 'artist_id': 12346, 'project_highlights': updated_project_highlights_description} post_project_highlights_json = { 'attachment': 'N', 'client': 'alw', 'highlight_id': 12377, 'entity': 'project', 'mkt_program_id': 20, 'scope': 'public', 'description': updated_project_highlights_description, 'entity_id': 1, 'subject': 'Project Highlights'} post_specs = [{ 'service': 'ows-marketing', 'path': '/highlights', 'status': 201, 'json': post_project_highlights_json}] header[header_const.ORCHARD_USER_ID] = 'alw:123' monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(get_specs)) monkeypatch.setattr( request, 'post', test_utils.mock_ows_requests(post_specs)) monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) project_response = client.put( '/project/{}'.format(project_id), data=json.dumps( update_request_data_with_highlights), headers=header) response_json = json.loads(project_response.data.decode()) assert_header(header, project_response.headers) assert project_response.status_code == 200 assert response_json.get('project_id') == project_id assert response_json.get( 'project_highlights') == updated_project_highlights_description def test_update_valid_project_with_project_highlights_blank( monkeypatch, db_fixture, project, client, header, get_artist_info_ok, get_content_review_data_all, get_company_brand_ows_response): """Valid project also updates project_highlights. Call is made to marketing service to update highlight associated with the project. """ project_id = 1 highlight_id = 12377 update_request_data_with_null_highlights = { 'project_name': 'updated project name', 'artist_id': 12346, 'project_highlights': ''} get_project_highlights_json = { 'items': [{ 'attachment': 'N', 'client': 'alw', 'highlight_id': highlight_id, 'entity': 'project', 'mkt_program_id': 20, 'scope': 'public', 'description': 'Old description', 'entity_id': project_id, 'subject': 'Project Highlights'}], 'pagination': { 'total_records': 2, 'limit': 50, 'type': 'standard', 'offset': 0}} get_specs = [ { 'service': 'ows-marketing', 'path': '/highlights/project/{}?mkt_program_id={}'.format( project_id, marketing_const.PROGRAM_MARKETING_HIGHLIGHTS), 'status': 200, 'json': get_project_highlights_json }, get_company_brand_ows_response, { 'service': 'ows-account', 'path': '/subaccount/1', 'status': 200, 'json': {'vendor_id': 7123} }, get_artist_info_ok, *get_content_review_data_all] monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests(get_specs)) put_project_highlights_json = { 'attachment': 'N', 'client': 'alw', 'highlight_id': highlight_id, 'entity': 'project', 'mkt_program_id': 20, 'scope': 'public', 'description': '', 'entity_id': 1, 'subject': 'Project Highlights'} put_specs = [{ 'service': 'ows-marketing', 'path': '/highlights/{}'.format(highlight_id), 'status': 200, 'json': put_project_highlights_json}] header[header_const.ORCHARD_USER_ID] = 'alw:123' monkeypatch.setattr( request, 'put', test_utils.mock_ows_requests(put_specs)) monkeypatch.setattr( ows_product, 'update_products_by_pool', MagicMock(return_value=response.Response( status=200, message={'message': 'ok', 'status': 200}))) project_response = client.put( '/project/{}'.format(project_id), data=json.dumps( update_request_data_with_null_highlights), headers=header) response_json = json.loads(project_response.data.decode()) assert_header(header, project_response.headers) assert project_response.status_code == 200 assert response_json.get('project_id') == project_id assert response_json.get( 'project_highlights') == '' def test_bad_json(db_fixture, project, client, header): """Assert invalid response given bad JSON.""" res = client.put('/project/0', data='{{}', headers=header) assert res.status_code == 400 def test_get_not_auth( db_fixture, project, client, header, get_artist_info_ok, monkeypatch): """Assert that updating project not owned will give 403.""" monkeypatch.setattr( request, 'get', test_utils.mock_ows_requests([get_artist_info_ok])) header[header_const.GRASS_ACCOUNT_ID] = 7555 res = client.put( '/project/1', data=json.dumps(update_request_data), headers=header) data = json.loads(res.data.decode()) assert 403 == res.status_code assert error_const.AUTHORIZATION_ERROR == data[error_const.ERROR_CODE] assert_header(header, res.headers)