import json import unittest.mock from typing import Any from unittest import mock import pytest import slz_downloader.dsp.spotify import slz_downloader.entities from slz_downloader.dsp.entities import S3Path from slz_downloader.dsp.spotify import base from slz_downloader.entities import Job @pytest.fixture def mocked_secrets(): with unittest.mock.patch('slz_downloader.dsp.spotify.enhanced.get_secret') as mock: yield mock @pytest.fixture def set_secrets(mocked_secrets): def wrapper(secrets): mocked_secrets.return_value = json.dumps(secrets) return wrapper @unittest.mock.patch('slz_downloader.dsp.spotify.enhanced.get_copier') @unittest.mock.patch('requests.get') @unittest.mock.patch('requests.post') def test_downloading(requests_post, requests_get, get_copier, params, set_secrets): ACCESS_TOKEN = 'id' CLIENT_ID = 'client-id' CLIENT_SECRET = 'client-secret' uow_dict = { 'uow_id': 'spotify-20191117-sme-users-v1', 'dsp': 'spotify', 'report_type': 'users', 'version': 'v1', 'report_date': '2019-11-17', 'licensor': 'sme', 'extension': 'gz', 'context': 'en', } # Mock AWS Secrets set_secrets({ 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, }) # Mock response from Spotify auth service requests_post.return_value.json.return_value = { 'access_token': ACCESS_TOKEN, } # Mock response from Spotify stream requests_get.return_value.ok = True logger = unittest.mock.Mock() client = slz_downloader.dsp.spotify.SpotifyClient(logger=logger) client.configure(params) client.download(slz_downloader.entities.Job.from_dict(uow_dict)) # Auth service called with correct params requests_post.assert_called_with( url='https://accounts.spotify.com/api/token', auth=(CLIENT_ID, CLIENT_SECRET), data={'grant_type': 'client_credentials'}, ) # Spotify API called with correct request requests_get.assert_called_with( url= 'https://provider-api.spotify.com/v1/analytics/sonybmgmusicentertainment/enhanced/users/2019/11/17/en', headers={ 'Authorization': 'Bearer ' + ACCESS_TOKEN, }, stream=True, params={}, timeout=10, ) assert get_copier.called class SpotifyTestCase(unittest.TestCase): def setUp(self) -> None: self.dsp_client = slz_downloader.dsp.spotify.SpotifyClient(logger=mock.Mock()) self.job = slz_downloader.entities.Job.empty() def test_get_request_params(self): self.job.version = "v1" params = self.dsp_client._get_request_params(self.job) self.assertEqual(params, {}) self.job.version = "v4" params = self.dsp_client._get_request_params(self.job) self.assertEqual(params, {"version": "4"}) class DummyBaseClient(): def __init__(self, logger: Any): ... class DummyClient(base.SpotifyFilepathMixin, DummyBaseClient): def configure(self, params: Any, **kwargs): self._buckets = params.s3 @pytest.mark.parametrize( 'job,expected_archive_path,expected_decompressed_path,expected_corrupted_path', [ ( { 'uow_id': 'spotify-20191117-sme-users-v1', 'dsp': 'spotify', 'report_type': 'users', 'version': 'v1', 'report_date': '2019-11-17', 'licensor': 'sme', 'extension': 'json', 'context': 'en', 'job_id': 'test_job_id', }, 's3://bucket-archive/spotify/users/v1/report_date=2019-11-17/report_licensor=sme/users_20191117_en.gz', 's3://bucket-decompressed/spotify/users/v1/report_date=2019-11-17/report_licensor=sme/users_20191117_en.json', 's3://bucket-corrupted/spotify/users/v1/report_date=2019-11-17/report_licensor=sme/users_20191117_en.gz', ) ] ) def test_spotify_filepath_mixin( job, expected_archive_path, expected_decompressed_path, expected_corrupted_path, params ): logger = mock.Mock() client = DummyClient(logger) job = Job.from_dict(job) client.configure(params) archive_path, decompressed_path, corrupted_path = client.get_s3_paths(job) assert archive_path.url == expected_archive_path assert decompressed_path.url == expected_decompressed_path assert corrupted_path.url == expected_corrupted_path