"""Integration API tests for OWS product digital marketing.""" import copy import json from os import getenv from random import randint, uniform import time from auth.auth import GrassAuth, UserType import pytest from product_digital_marketing.schemas.territories_schema \ import TerritoriesGetSchema from tests.testutils.api_client import APIClient from tests.testutils.mysql_client import MySQLClient @pytest.fixture(scope='session') def workstation_session_token(): """Initialize Workstation grass auth token at start of test session.""" return GrassAuth(UserType.WORKSTATION, 7123).grass_token @pytest.fixture(scope='session') def oa_session_token(): """Initialize OA grass auth token at start of test session.""" return GrassAuth(UserType.OA).grass_token @pytest.fixture def workstation_api_client(): """Create APIClient object with QA URL and Workstation session token.""" return APIClient(getenv('BASE_QA_URL'), workstation_session_token()) @pytest.fixture def oa_api_client(): """Create APIClient object with QA URL and OA session token.""" return APIClient(getenv('BASE_QA_URL'), oa_session_token()) @pytest.fixture def internal_api_client(): """Create APIClient object with internal QA URL and no session token.""" return APIClient(getenv('INTERNAL_QA_URL'), None) @pytest.fixture def marketing_product(): """Product ID of QA product fixture.""" return 2323517 @pytest.fixture def product_receive_copy(): """Product ID of QA product fixture to receive copy data.""" return 2323520 @pytest.fixture def timestamped_marketing_highlights(): """Return JSON formatted marketing highlights with timestamps.""" timestamp = time.time() random_number = randint(10000, 99999) return { 'global_highlight': 'Global Highlight {}'.format(timestamp), 'apple_highlight': 'Apple Highlight {}'.format(timestamp), 'spotify_highlight': 'Spotify Highlight {}'.format(timestamp), 'apple_total': random_number, 'spotify_total': random_number, 'downloads_total': random_number } @pytest.fixture def timestamped_projections(): """Return JSON formatted projections with timestamps.""" timestamp = time.time() random_number = round(uniform(10000.0, 99999.0), 1) return {'items': [{ 'territory_id': 1, 'spotify_projection': random_number, 'apple_projection': random_number, 'downloads_projection': random_number, 'highlight': 'A Highlight {}'.format(timestamp), 'priority': 'A' }]} def delete_all_marketing_data(product_id): """Delete marketing data for a given product.""" mysql_client = MySQLClient() delete_highlight_projections = \ 'DELETE FROM marketing_highlight_projection WHERE product_id=%s' mysql_client.execute_query(delete_highlight_projections, product_id) delete_highlight = 'DELETE FROM marketing_highlight WHERE product_id=%s' mysql_client.execute_query(delete_highlight, product_id) def copy_and_null_out_projections(data_to_copy): """Take a dictionary, copy it and remove projection data.""" dict_copy = copy.deepcopy(data_to_copy) dict_copy['apple_total'] = None dict_copy['downloads_total'] = None dict_copy['spotify_total'] = None for projection in dict_copy['projections']: projection['apple_projection'] = None projection['downloads_projection'] = None projection['spotify_projection'] = None return dict_copy @pytest.mark.parametrize( 'api_client', [workstation_api_client(), oa_api_client()]) def test_get_territories(api_client): """Test territories endpoint.""" response = api_client.get_territories() assert response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format(response.status_code) result = TerritoriesGetSchema().load( json.loads(response.content), partial=False) assert not result.errors, 'Expected no errors, got {}'.format( result.errors) @pytest.mark.parametrize( 'api_client', [workstation_api_client(), oa_api_client()]) def test_get_public_territories(api_client): """Test public territories endpoint.""" response = api_client.get_public_territories() assert response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format(response.status_code) result = TerritoriesGetSchema().load( json.loads(response.content), partial=False) assert not result.errors, 'Expected no errors, got {}'.format( result.errors) @pytest.mark.parametrize( 'api_client', [workstation_api_client(), oa_api_client()]) def test_post_drivers( api_client, timestamped_marketing_highlights, marketing_product): """Test POST against marketing endpoint.""" post_response = api_client.post_marketing( marketing_product, timestamped_marketing_highlights) assert post_response.status_code == 201, \ 'Result of POST was {}, expected 201.'.format( post_response.status_code) json_post_response = json.loads(post_response.content) del json_post_response['projections'] assert json_post_response == timestamped_marketing_highlights get_response = api_client.get_marketing(marketing_product) assert get_response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format( get_response.status_code) json_get_response = json.loads(get_response.content) del json_get_response['projections'] assert json_get_response == timestamped_marketing_highlights @pytest.mark.parametrize( 'api_client', [workstation_api_client(), oa_api_client()]) def test_post_projections( api_client, timestamped_projections, marketing_product): """Test POST against marketing/projections endpoint.""" post_response = api_client.post_projections( marketing_product, timestamped_projections) assert post_response.status_code == 201, \ 'Result of POST was {}, expected 201.'.format( post_response.status_code) json_post_response = json.loads(post_response.content) del json_post_response['items'][0]['id'] del json_post_response['items'][0]['product_id'] assert json_post_response == timestamped_projections get_response = api_client.get_marketing(marketing_product) assert get_response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format( get_response.status_code) json_get_response_projections = json.loads( get_response.content)['projections'][0] del json_get_response_projections['id'] del json_get_response_projections['product_id'] assert json_get_response_projections == timestamped_projections['items'][0] @pytest.mark.parametrize( 'api_client', [workstation_api_client(), oa_api_client()]) def test_delete_projection( api_client, timestamped_projections, marketing_product): """Test DELETE against marketing/projection.""" post_response = api_client.post_projections( marketing_product, timestamped_projections) assert post_response.status_code == 201, \ 'Result of POST was {}, expected 201.'.format( post_response.status_code) projection_id = json.loads(post_response.content)['items'][0]['id'] delete_response = api_client.delete_projection( marketing_product, projection_id) assert delete_response.status_code == 200, \ 'Result of DELETE was {}, expected 200.'.format( delete_response.status_code) get_response = api_client.get_marketing(marketing_product) assert get_response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format( get_response.status_code) assert not json.loads(get_response.content)['projections'] def test_copy_projections( workstation_api_client, internal_api_client, timestamped_projections, marketing_product, product_receive_copy): """Test copy against marketing/projections endpoint.""" delete_all_marketing_data(product_receive_copy) post_response = workstation_api_client.post_projections( marketing_product, timestamped_projections) assert post_response.status_code == 201, \ 'Result of POST was {}, expected 201.'.format( post_response.status_code) get_source_response = workstation_api_client.get_marketing( marketing_product) assert get_source_response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format( get_source_response.status_code) json_get_source_response = json.loads(get_source_response.content) del json_get_source_response['projections'][0]['id'] del json_get_source_response['projections'][0]['product_id'] copy_response = internal_api_client.post_copy( marketing_product, product_receive_copy) assert copy_response.status_code == 201, \ 'Result of POST was {}, expected 201.'.format( copy_response.status_code) json_copy_response = json.loads(copy_response.content) del json_copy_response['projections'][0]['id'] del json_copy_response['projections'][0]['product_id'] comparison_data = copy_and_null_out_projections(json_get_source_response) assert json_copy_response == comparison_data get_response = workstation_api_client.get_marketing(product_receive_copy) assert get_response.status_code == 200, \ 'Result of GET was {}, expected 200.'.format( get_response.status_code) json_get_response = json.loads(get_response.content) del json_get_response['projections'][0]['id'] del json_get_response['projections'][0]['product_id'] assert json_get_response == comparison_data