import copy from http import HTTPStatus from typing import List import pytest from apollo_utils.core.constants.dsp import DSP from apollo_utils.core.utils.multikeysort import multikeysort from apollo_utils.core.utils.singleton import SingleValue from server.cache.base import get_cache from server.client.clients.dsp_api import DspApiClient from tests.api.playlists.v1.responses.constants import SpecificItem from tests.api.playlists.v1.responses.generate_delphi_response import get_delphi_playlists_api_response from tests.api.playlists.v1.responses.get_expected_response import get_v3_playlists_dsp_by_track_expected_response response_copy = SingleValue() params_copy = SingleValue() def set_response_copy_variable_global(f): async def wrapped(*args, **kwargs): global response_copy global params_copy result = await f(*args, **kwargs) response_copy = copy.deepcopy(result) params_copy = kwargs["params"] return result return wrapped @pytest.mark.parametrize( "dsp,params,status_code,specify", ( ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.PERSONALISED] ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["gb"]}, HTTPStatus.OK, [SpecificItem.PERSONALISED] ), ), ) async def test_get_v3_playlists_dsp_by_track_personalised_item( mocker, client, auth, dsp: DSP, params: dict, status_code: HTTPStatus, specify: List[SpecificItem] ): # Personalised playlist expected fields to be: expected_item_response_field_value = { "personalized": True, "trend": None, "position_change_date": None, "is_new": False } @set_response_copy_variable_global async def async_dsp_mock(url, *args, **kwargs): return get_delphi_playlists_api_response(url=url, specify=specify, **kwargs) mocker.patch.object(DspApiClient, "send_request", side_effect=async_dsp_mock) response = await client.get(f"/api/v3/playlists/{dsp.value}/by-track/", params=params, headers=auth) assert response.status == status_code await get_cache().clear() json_response = await response.json() item = json_response["items"][0] for key, value in expected_item_response_field_value.items(): assert {key: item[key]} == {key: value} @pytest.mark.parametrize( "dsp,params,status_code,specify", ( ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.IS_NOT_TOP_TRACK_FOR_ISRC, SpecificItem.NOT_PERSONALISED] ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["db"]}, HTTPStatus.OK, [SpecificItem.IS_NOT_TOP_TRACK_FOR_ISRC, SpecificItem.NOT_PERSONALISED] ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.IS_NOT_TOP_TRACK_FOR_ISRC, SpecificItem.PERSONALISED] ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["gb"]}, HTTPStatus.OK, [SpecificItem.IS_NOT_TOP_TRACK_FOR_ISRC, SpecificItem.PERSONALISED] ), ), ) async def test_get_v3_playlists_dsp_by_track_is_not_top_track_for_isrc_item( mocker, client, auth, dsp: DSP, params: dict, status_code: HTTPStatus, specify: List[SpecificItem] ): expected_item_response_field_value = { "personalized": True if SpecificItem.PERSONALISED in specify else False, "is_new": False } @set_response_copy_variable_global async def async_dsp_mock(url, *args, **kwargs): return get_delphi_playlists_api_response(url=url, specify=specify, **kwargs) mocker.patch.object(DspApiClient, "send_request", side_effect=async_dsp_mock) response = await client.get(f"/api/v3/playlists/{dsp.value}/by-track/", params=params, headers=auth) assert response.status == status_code await get_cache().clear() json_response = await response.json() item = json_response["items"][0] for key, value in expected_item_response_field_value.items(): assert {key: item[key]} == {key: value} @pytest.mark.parametrize( "dsp,params,status_code,specify", ( ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.BlUE_DOT] ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["gb"]}, HTTPStatus.OK, [SpecificItem.NOT_BLUE_DOT] ), ), ) async def test_get_v3_playlists_dsp_by_track_blue_dot_item( mocker, client, auth, dsp: DSP, params: dict, status_code: HTTPStatus, specify: List[SpecificItem] ): expected_item_response_field_value = { "is_new": True if SpecificItem.BlUE_DOT in specify else False } @set_response_copy_variable_global async def async_dsp_mock(url, *args, **kwargs): return get_delphi_playlists_api_response(url=url, specify=specify, **kwargs) mocker.patch.object(DspApiClient, "send_request", side_effect=async_dsp_mock) response = await client.get(f"/api/v3/playlists/{dsp.value}/by-track/", params=params, headers=auth) assert response.status == status_code await get_cache().clear() json_response = await response.json() item = json_response["items"][0] for key, value in expected_item_response_field_value.items(): assert {key: item[key]} == {key: value} @pytest.mark.parametrize( "dsp,params,status_code,specify", ( ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.BlUE_DOT] ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["gb"]}, HTTPStatus.OK, [SpecificItem.NOT_BLUE_DOT] ), ( DSP.APPLE, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.BlUE_DOT] ), ( DSP.APPLE, {"isrc": "USSM12200609", "market": ["gb"]}, HTTPStatus.OK, [SpecificItem.NOT_BLUE_DOT] ), ), ) async def test_get_v3_playlists_dsp_by_track_blue_dot_item( mocker, client, auth, dsp: DSP, params: dict, status_code: HTTPStatus, specify: List[SpecificItem] ): expected_item_response_field_value = { "is_new": True if SpecificItem.BlUE_DOT in specify else False } @set_response_copy_variable_global async def async_dsp_mock(url, *args, **kwargs): return get_delphi_playlists_api_response(url=url, specify=specify, **kwargs) mocker.patch.object(DspApiClient, "send_request", side_effect=async_dsp_mock) response = await client.get(f"/api/v3/playlists/{dsp.value}/by-track/", params=params, headers=auth) assert response.status == status_code await get_cache().clear() json_response = await response.json() item = json_response["items"][0] for key, value in expected_item_response_field_value.items(): assert {key: item[key]} == {key: value} @pytest.mark.parametrize( "dsp,params,status_code,specify", ( ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.UNIX_EPOCH_DATE] ), ( DSP.APPLE, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK, [SpecificItem.NOT_UNIX_EPOCH_DATE] ), ), ) async def test_get_v3_playlists_dsp_by_track_unix_epoch_added_date_item( mocker, client, auth, dsp: DSP, params: dict, status_code: HTTPStatus, specify: List[SpecificItem] ): expected_item_response_field_value = { "added_date": None if SpecificItem.UNIX_EPOCH_DATE in specify else "1970-01-02" } @set_response_copy_variable_global async def async_dsp_mock(url, *args, **kwargs): return get_delphi_playlists_api_response(url=url, specify=specify, **kwargs) mocker.patch.object(DspApiClient, "send_request", side_effect=async_dsp_mock) response = await client.get(f"/api/v3/playlists/{dsp.value}/by-track/", params=params, headers=auth) assert response.status == status_code await get_cache().clear() json_response = await response.json() item = json_response["items"][0] for key, value in expected_item_response_field_value.items(): assert {key: item[key]} == {key: value} @pytest.mark.parametrize( "dsp,params,status_code", ( ( DSP.SPOTIFY, {}, HTTPStatus.BAD_REQUEST ), ( DSP.SPOTIFY, {"country_code": "us"}, HTTPStatus.BAD_REQUEST ), ( DSP.APPLE, {}, HTTPStatus.BAD_REQUEST ), ( DSP.APPLE, {"country_code": "us"}, HTTPStatus.BAD_REQUEST ), ( DSP.SPOTIFY, {"isrc": "USSM12200609", "market": ["us"]}, HTTPStatus.OK ), ( DSP.APPLE, {"isrc": "USSM12200609"}, HTTPStatus.OK ), ), ) async def test_get_v3_playlists_dsp_by_track( mocker, client, auth, dsp: DSP, params: dict, status_code: HTTPStatus ): await get_cache().clear() @set_response_copy_variable_global async def async_dsp_mock(url, *args, **kwargs): return get_delphi_playlists_api_response(url=url, items_count=10, **kwargs) mocker.patch.object(DspApiClient, "send_request", side_effect=async_dsp_mock) response = await client.get(f"/api/v3/playlists/{dsp.value}/by-track/", params=params, headers=auth) response_status = response.status assert response_status == status_code if response_status == HTTPStatus.OK: sort_by = ["added_date"] expected_response = get_v3_playlists_dsp_by_track_expected_response( dsp=dsp, items=response_copy["items"], isrc=params["isrc"], sort_by=sort_by) response_json = await response.json() response_json["items"] = multikeysort(response_json["items"], sort_by) assert expected_response == response_json