from datetime import date from unittest.mock import patch, MagicMock from typing import List import pytest from models.performance_breakdown_option import BreakdownOptions from tests.performance.utils import metrics_details_result, MetricsDetailsQueryResult from tests.test_utils import FixtureLoader from models import models from tests import BaseTestCase, mock_for_user from tests.performance.fixtures.performance_metrics_fixture import fixture user1Mock = mock_for_user(1, "dev-marketing-user-1@example.com", "sme-dna|5cf0091d6c91d310fe6fcdc6") user2Mock = mock_for_user(2, "dev-marketing-user-2@example.com", "sme-dna|3po0091d6c91ty670fe6ftryf") def stub_snowflake(fetcher, stub_result: List[MetricsDetailsQueryResult]): fetcher_mock = MagicMock() fetcher_mock.fetch_project_details_by_platforms.return_value = stub_result fetcher_mock.fetch_project_details_by_campaigns.return_value = stub_result fetcher_mock.fetch_project_details_by_categories.return_value = stub_result fetcher_mock.fetch_project_details_by_objective.return_value = stub_result fetcher_mock.fetch_project_details_by_goal.return_value = stub_result fetcher_mock.fetch_project_details_by_type.return_value = stub_result fetcher_mock.fetch_project_details_by_country.return_value = stub_result fetcher_mock.fetch_project_details_by_day.return_value = stub_result fetcher_mock.fetch_project_details_by_week.return_value = stub_result fetcher_mock.fetch_project_details_by_month.return_value = stub_result fetcher_mock.fetch_project_details_by_chartweek.return_value = stub_result fetcher_mock.fetch_project_details_by_genders.return_value = stub_result fetcher_mock.fetch_project_details_by_age.return_value = stub_result fetcher_mock.fetch_project_details_by_ad_sets.return_value = stub_result fetcher_mock.fetch_project_details_by_providers.return_value = stub_result fetcher_mock.fetch_artist_details_by_projects.return_value = stub_result fetcher_mock.fetch_artist_details_by_campaigns.return_value = stub_result fetcher_mock.fetch_artist_details_by_ad_sets.return_value = stub_result fetcher_mock.fetch_artist_details_by_platforms.return_value = stub_result fetcher_mock.fetch_artist_details_by_category.return_value = stub_result fetcher_mock.fetch_artist_details_by_objective.return_value = stub_result fetcher_mock.fetch_artist_details_by_goal.return_value = stub_result fetcher_mock.fetch_artist_details_by_type.return_value = stub_result fetcher_mock.fetch_artist_details_by_country.return_value = stub_result fetcher_mock.fetch_artist_details_by_day.return_value = stub_result fetcher_mock.fetch_artist_details_by_month.return_value = stub_result fetcher_mock.fetch_artist_details_by_week.return_value = stub_result fetcher_mock.fetch_artist_details_by_chartweek.return_value = stub_result fetcher_mock.fetch_artist_details_by_genders.return_value = stub_result fetcher_mock.fetch_artist_details_by_provider.return_value = stub_result fetcher_mock.fetch_artist_details_by_age.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_country.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_age.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_gender.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_platform.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_provider.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_category.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_objective.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_goal.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_campaign_type.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_ad_set.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_day.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_week.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_chartweek.return_value = stub_result fetcher_mock.fetch_campaigns_details_by_month.return_value = stub_result fetcher.return_value = fetcher_mock class TestPerformanceMetricsDetails(BaseTestCase): stub_data = [ metrics_details_result(name="name1", entity_id=10, spend=1100), metrics_details_result(name="name2", entity_id=10, video_views=300, start_date=date(2020, 10, 11)), metrics_details_result( name="name3", entity_id=10, spend=12, start_date=date(2020, 10, 13), end_date=date(2020, 11, 14) ), ] breakdown_options = [option.value for option in BreakdownOptions] def do_request(self, url, breakdown_option, additional_params=None): if additional_params is None: additional_params = {} return self.execute_get( url, headers=self.headers, query_string={ "startDate": "2020-10-05", "endDate": "2020-10-10", "labels": [4, 5], "provider": 1, "objective": 4, "fields": [16, 26, 39, 40, 63], "breakdown": breakdown_option, **additional_params, }, ) def verify_response(self, response): self.assertEqual(200, response.status_code) items = response.json["items"] self.assertIs(list, type(items)) self.assertEqual(len(self.stub_data), len(items)) for index, stub in enumerate(self.stub_data): self.soft_assert_equal( items[index], { "entityId": str(stub.entity_id), "fields": { "16": stub.spend, "26": stub.video_views, "39": stub.video_50_watched, "40": stub.impressions, "63": stub.video_25_watched, }, "name": stub.name, "metadata": None, }, ) self.assert_all() @staticmethod def get_url(group, entity_id): return "/performance/metrics/{}/{}/details".format(group, entity_id) def setUp(self): super().setUp() FixtureLoader(models=models).import_as_sql(fixture) def get_breakdown_options(self, excluded_options: List[int]): return list(set(self.breakdown_options) - set(excluded_options)) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1Mock.jwt_decode) @pytest.mark.skip(reason="Add tests after release") def test_get_artists_metrics_details(self, map_countries_helper, fetcher): stub_snowflake(fetcher, self.stub_data) # Stub countries helper to prevent replacing of names and elastic calls map_countries_helper.return_value = self.stub_data url = self.get_url("artists", 10) excluded_options = [ BreakdownOptions.ARTISTS.value, BreakdownOptions.AGE_AND_GENDERS.value, BreakdownOptions.GOALS.value, ] breakdown_options = self.get_breakdown_options(excluded_options) for breakdown_option in breakdown_options: response = self.do_request(url, breakdown_option) self.verify_response(response) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1Mock.jwt_decode) @pytest.mark.skip(reason="Add tests after release") def test_get_projects_metrics_details(self, map_countries_helper, fetcher): stub_snowflake(fetcher, self.stub_data) # Stub countries helper to prevent replacing of names and elastic calls map_countries_helper.return_value = self.stub_data url = self.get_url("projects", 10) excluded_options = [ BreakdownOptions.ARTISTS.value, BreakdownOptions.PROJECTS.value, BreakdownOptions.AGE_AND_GENDERS.value, BreakdownOptions.GOALS.value, ] breakdown_options = self.get_breakdown_options(excluded_options) for breakdown_option in breakdown_options: response = self.do_request(url, breakdown_option) self.verify_response(response) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1Mock.jwt_decode) @pytest.mark.skip(reason="Add tests after release") def test_get_campaigns_metrics_details(self, map_countries_helper, fetcher): stub_snowflake(fetcher, self.stub_data) # Stub countries helper to prevent replacing of names and elastic calls map_countries_helper.return_value = self.stub_data url = self.get_url("campaigns", 10) excluded_options = [ BreakdownOptions.ARTISTS.value, BreakdownOptions.PROJECTS.value, BreakdownOptions.CAMPAIGNS.value, BreakdownOptions.AGE_AND_GENDERS.value, BreakdownOptions.GOALS.value, BreakdownOptions.CATEGORIES.value, BreakdownOptions.OBJECTIVES.value, BreakdownOptions.CAMPAIGN_TYPES.value, ] breakdown_options = self.get_breakdown_options(excluded_options) for breakdown_option in breakdown_options: response = self.do_request(url, breakdown_option) self.verify_response(response) @patch("auth.atlas.atlas_token_decoder.jwt.decode", user1Mock.jwt_decode) def test_get_campaigns_metrics_wrong_daterange_should_return_422(self): url = self.get_url("campaigns", 10) breakdown_options = self.get_breakdown_options([]) custom_params = {"startDate": "2017-10-05", "endDate": "2021-09-10"} for breakdown_option in breakdown_options: response = self.do_request(url, breakdown_option, custom_params) self.assertEqual(response.status_code, 422)