"""Unit tests for Spotify Statistics Workflow.""" import datetime from unittest import mock import config import spotify_with_spotipy as spotify from tests.conftest import artist_last_stats, artist_statistics_from_table class TestSpotifyTracker: """Test Spotify Tracker related methods.""" def test_get_id_from_link(self, processed_links): """Test get_username_from_link method with reverse parameter also.""" config.SPOTIFY_LINK = 'https://open.spotify.com' username = spotify.get_id_from_link(processed_links['spotify']) assert username == '060CEbkq3Bubu0AvJu4NKf' def test_create_tables_for_the_first_time( self, mock_delete_from_staging_raw, mock_create_staging_raw_spotify_statistics, mock_create_spotify_statistics, mock_create_artist_link_table, mock_select_artists_links, mock_executor, processed_links, get_artists_links, mock_set_webdriver, mock_spotify): """Test create_tables working correctly during the very first run.""" mock_select_artists_links.return_value = get_artists_links tracker = spotify.SpotifyTracker() tracker.create_tables() assert not mock_create_artist_link_table.called assert mock_select_artists_links.called assert mock_create_spotify_statistics.called assert mock_delete_from_staging_raw.called assert mock_create_staging_raw_spotify_statistics.called assert tracker.__first_time__ assert 'cijikin' in tracker.get_profiles().keys() @mock.patch('spotify_with_spotipy.SpotifyStatsSFExecutor.' 'select_artists_stats', artist_statistics_from_table) def test_create_tables_not_for_the_first_time( self, mock_delete_from_staging_raw, mock_create_staging_raw_spotify_statistics, mock_create_spotify_statistics, mock_create_artist_link_table, mock_select_artists_links, mock_executor, processed_links, get_artists_links, mock_set_webdriver, mock_spotify): """Test create_tables working correctly if the run is not first.""" mock_select_artists_links.return_value = get_artists_links mock_create_artist_link_table.\ return_value, mock_create_staging_raw_spotify_statistics.\ return_value, mock_create_spotify_statistics.\ return_value = [['already exists']] * 3 tracker = spotify.SpotifyTracker() tracker.create_tables() assert not mock_create_artist_link_table.called assert mock_select_artists_links.called assert mock_create_spotify_statistics.called assert mock_delete_from_staging_raw.called assert mock_create_staging_raw_spotify_statistics.called assert not tracker.__first_time__ assert 'cijikin' in tracker.get_profiles() @mock.patch('spotify_with_spotipy.SpotifyStatsSFExecutor.' 'select_weekly_change') def test_compare_current_and_last_week_stats_for_weekly_statistics( self, mock_select_weekly_change, mock_executor, processed_links, mock_set_webdriver, mock_spotify): """Test correctness of comparing method calculations.""" def weekly_side_effect(*args, **kwargs): if -6 in list(kwargs.values()): return {'followers': 7, 'monthly_listeners': 17} else: return {'followers': 19, 'monthly_listeners': 30} mock_select_weekly_change.side_effect = weekly_side_effect current_followers = 578 tracker = spotify.SpotifyTracker() calculations = tracker.compare_current_and_last_week_stats( current_followers, 'followers', artist_last_stats(), 'cijikin') artist_lasts = artist_last_stats()['cijikin'] assert calculations == { 'current_followers': current_followers, 'last_week_followers': artist_lasts['last_week_followers'], 'daily_change_in_followers': current_followers - artist_lasts[ 'current_followers'], 'current_weekly_change_in_followers': current_followers - artist_lasts['current_followers'] + weekly_side_effect('cijikin')['followers'], 'weekly_change_in_followers': weekly_side_effect(first_day_of_period=-6)['followers'], 'percentage_change_in_followers': artist_lasts[ 'percentage_change_in_followers'], 'acceleration_followers': (current_followers - artist_lasts[ 'current_followers'] + weekly_side_effect('cijikin')['followers'] - weekly_side_effect(first_day_of_period=-6)['followers']) / weekly_side_effect(first_day_of_period=-6)['followers'], 'last_processing_date': datetime.date.today(), 'last_week_processing_date': artist_lasts['last_week_processing_date']} @mock.patch('spotify_with_spotipy.SpotifyStatsSFExecutor.' 'select_weekly_change') def test_compare_current_and_last_week_stats_for_week_period_statistics( self, mock_select_weekly_change, mock_executor, processed_links, mock_set_webdriver, mock_spotify): """Test correctness of comparing method calculations for posts.""" tracker = spotify.SpotifyTracker() current_monthly_listeners = 25000 def weekly_side_effect(*args, **kwargs): if -6 in list(kwargs.values()): return {'followers': 7, 'monthly_listeners': 17} else: return {'followers': 19, 'monthly_listeners': 30} mock_select_weekly_change.side_effect = weekly_side_effect calculations = tracker.compare_current_and_last_week_stats( current_monthly_listeners, 'monthly_listeners', artist_last_stats( last_week_processing_date=datetime.date.today( ) - datetime.timedelta(days=7)), 'cijikin') artist_lasts = artist_last_stats( last_week_processing_date=datetime.date.today( ) - datetime.timedelta(days=7))['cijikin'] # checking the calculation when week period ends assert mock_select_weekly_change.called assert calculations == { 'current_monthly_listeners': current_monthly_listeners, 'last_week_monthly_listeners': artist_lasts['last_week_monthly_listeners'], 'daily_change_in_monthly_listeners': current_monthly_listeners - artist_lasts ['current_monthly_listeners'], 'current_weekly_change_in_monthly_listeners': current_monthly_listeners - artist_lasts[ 'current_monthly_listeners'] + weekly_side_effect('cijikin')['monthly_listeners'], 'weekly_change_in_monthly_listeners': weekly_side_effect(first_day_of_period=-6)[ 'monthly_listeners'], 'percentage_change_in_monthly_listeners': 0, 'acceleration_monthly_listeners': (current_monthly_listeners - artist_lasts[ 'current_monthly_listeners'] + weekly_side_effect('cijikin')['monthly_listeners'] - weekly_side_effect( first_day_of_period=-6)['monthly_listeners']) / weekly_side_effect( first_day_of_period=-6)['monthly_listeners'], 'last_processing_date': datetime.date.today(), 'last_week_processing_date': datetime.date.today()} @mock.patch('spotify_with_spotipy.SpotifyTracker.' 'get_profiles', artist_last_stats) def test_get_artist_info( self, mock_abbreviated_value_to_int, mock_executor, mock_executor_context, mock_set_webdriver, mock_load_profile, mock_compare_current_and_last_week_stats, mock_spotify): """Test get_artist_info method.""" tracker = spotify.SpotifyTracker() for artist in artist_last_stats(): tracker.get_common_stats(artist) assert mock_set_webdriver.called assert mock_load_profile.called assert mock_compare_current_and_last_week_stats.called assert mock_compare_current_and_last_week_stats.call_count == 2 @mock.patch('spotify_with_spotipy.SpotifyTracker.get_profiles', artist_last_stats) def test_get_monthly_listeners( self, mock_abbreviated_value_to_int, mock_get_dom_of_artist_page, mock_executor, mock_executor_context, mock_set_webdriver, mock_select_weekly_change, mock_spotify, mock_compare_current_and_last_week_stats): """Test get_monthly_listeners method.""" tracker = spotify.SpotifyTracker() for artist in artist_last_stats(): tracker.get_monthly_listeners(artist) assert mock_set_webdriver.called assert mock_get_dom_of_artist_page.called assert mock_compare_current_and_last_week_stats.called @mock.patch('spotify_with_spotipy.SpotifyTracker.get_profiles', artist_last_stats) def test_get_and_update_stats( self, mock_update_new_artists_stats, mock_get_monthly_listeners, mock_get_common_stats, mock_get_playlists_stats, mock_executor, mock_executor_context, mock_set_webdriver, mock_spotify): """Test get_and_update_stats method.""" tracker = spotify.SpotifyTracker() tracker.get_all_stats_and_update() assert mock_get_monthly_listeners.called assert mock_get_common_stats.called assert mock_get_playlists_stats.called assert mock_update_new_artists_stats.called def test_perform_tracking( self, mock_update_staging_raw_table, mock_create_tables, mock_get_all_stats_and_update, mock_executor, mock_executor_context, mock_set_webdriver, mock_spotify): """Test perform_tracking method.""" tracker = spotify.SpotifyTracker() tracker.perform_tracking() assert mock_create_tables.called assert mock_set_webdriver.called assert mock_get_all_stats_and_update.called assert not mock_update_staging_raw_table.called