"""Functional tests for creating marketing highlight_projections. Test endpoint: POST /marketing//projections """ import json from oto import error as oto_error from product_digital_marketing.constants import error from product_digital_marketing.constants import header from product_digital_marketing.constants import services from tests.unit.factories import highlight_factory from tests.unit.factories import highlight_projection_factory from tests.unit.factories import territory_factory from tests.unit.test_utils import db PRODUCT_ID = 42 @db.test_schema def test_create_highlight_projections_schema_fails( client, grass_headers, request_engine): """Endpoint responds with 400 when sending invalid data.""" request_engine[services.OWS_PRODUCT].add_spec( 'HEAD', '/vendor/1234/product/{}'.format(PRODUCT_ID)) body = { 'something_bad': 'Going hog wild on the requests over here', } response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers, data=json.dumps(body)) assert response.status_code == 400 data = json.loads(response.data.decode()) assert data['code'] == error.VALIDATION_ERROR_CODE assert data['message']['items']['0']['highlight'] == [ 'Missing data for required field.'] @db.test_schema def test_create_highlight_projection_length_items_schema_fails( client, grass_headers, request_engine): """Endpoint responds with 400 when items array is empty.""" request_engine[services.OWS_PRODUCT].add_spec( 'HEAD', '/vendor/1234/product/{}'.format(PRODUCT_ID)) body = { 'items': [] } response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers, data=json.dumps(body)) assert response.status_code == 400 data = json.loads(response.data.decode()) assert data['code'] == error.VALIDATION_ERROR_CODE assert data['message']['items'] == ['Field may not be an empty list'] @db.test_schema def test_create_highlight_projection_item_schema_fails( client, grass_headers, request_engine): """Endpoint responds with 400 when an item is invalid.""" request_engine[services.OWS_PRODUCT].add_spec( 'HEAD', '/vendor/1234/product/{}'.format(PRODUCT_ID)) body = { 'items': [ { 'highlight': 'For kids', 'apple_projection': 300, 'spotify_projection': None, 'downloads_projection': 100500, } ], } response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers, data=json.dumps(body)) assert response.status_code == 400 data = json.loads(response.data.decode()) assert data['code'] == error.VALIDATION_ERROR_CODE assert data['message']['items']['0']['territory_id'] == [ 'Missing data for required field.'] @db.test_schema def test_create_highlight_projections_without_highlight_fails( client, grass_headers, request_engine): """Endpoint responds with 404 when the highlight doesn't exist.""" request_engine[services.OWS_PRODUCT].add_spec( 'HEAD', '/vendor/1234/product/{}'.format(PRODUCT_ID)) body = { 'items': [ { 'territory_id': 10, 'highlight': 'For kids', 'apple_projection': 300, 'spotify_projection': None, 'downloads_projection': 100500 } ], } response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers, data=json.dumps(body)) assert response.status_code == 404 data = json.loads(response.data.decode()) assert data['code'] == oto_error.ERROR_CODE_NOT_FOUND assert data['message'] == 'No highlight found for product_id {}'.format( PRODUCT_ID) @db.test_schema def test_create_highlight_projections_success( client, grass_headers, request_engine): """Endpoint returns 201 when creating highlight projections.""" highlight = highlight_factory.HighlightFactory( product_id=PRODUCT_ID, global_highlight='Some general drivers', spotify_highlight='awesome spotify drivers', apple_highlight='crazy apple drivers', spotify_total=None, apple_total=300, downloads_total=100500 ) territory = territory_factory.TerritoryFactory( name='Lego Island', category='continent' ) projection = \ highlight_projection_factory.HighlightProjectionFactory( product_id=PRODUCT_ID, territory_id=10, spotify_projection=1, apple_projection=9000, downloads_projection=9001, highlight='Cool highlight 1', priority='A' ) db.seed_models([highlight, territory, projection]) request_engine[services.OWS_PRODUCT].add_spec( 'HEAD', '/vendor/1234/product/{}'.format(PRODUCT_ID)) body = { 'items': [ { 'territory_id': 1, 'highlight': 'For kids', 'apple_projection': 25.5, 'spotify_projection': None, 'downloads_projection': 90.0 }, { 'territory_id': 10, 'highlight': 'For parents', 'apple_projection': 45, 'spotify_projection': 32.5, 'downloads_projection': 80.7, 'priority': 'A' } ], } response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers, data=json.dumps(body)) assert response.status_code == 201 data = json.loads(response.data.decode()) assert data == { 'items': [ { 'id': 2, 'product_id': PRODUCT_ID, 'territory_id': 1, 'spotify_projection': None, 'apple_projection': 25.5, 'downloads_projection': 90.0, 'highlight': 'For kids', 'priority': None }, { 'id': 1, 'product_id': PRODUCT_ID, 'territory_id': 10, 'apple_projection': 45.0, 'spotify_projection': 32.5, 'downloads_projection': 80.7, 'highlight': 'For parents', 'priority': 'A' }, ] } def test_create_highlight_projections_ownership_fails( client, grass_headers, request_engine): """Endpoint is not accessible for wrong user.""" request_engine[services.OWS_PRODUCT].add_spec( 'HEAD', '/vendor/1234/product/{}'.format(PRODUCT_ID), status=403) response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers) assert response.status_code == 403 data = json.loads(response.data.decode()) assert data['message'] == 'Product is not owned by account' def test_create_highlight_projections_invalid_headers(client, grass_headers): """Endpoint is not with wrong GRASS headers.""" del grass_headers[header.GRASS_ACCOUNT_ID] response = client.post( '/marketing/{}/projections'.format(PRODUCT_ID), headers=grass_headers) assert response.status_code == 400 data = json.loads(response.data.decode()) assert data['message'] == 'Incomplete Grass Headers'