import datetime import json from collections import namedtuple from apollo_push_client import PushClient import pytest from sme_logger import get_logger from apollo_main_db.push_notifications.models import PushMessage, TopicEnum, VendorEnum from spotify_charts_notifications import utils from spotify_charts_notifications.config import Config from spotify_charts_notifications.constants import SPOTIFY_TRACK_PREFIX, SPOTIFY_URL_PREFIX from spotify_charts_notifications.handler import process_added_tracks, process_dropped_tracks, \ process_major_moves_of_tracks from tests import factories Track = namedtuple('Track', ['name', 'url', 'artist_name', 'uri', 'isrc']) def get_formatted_today_yesterday(): today = datetime.date.today() yesterday = today - datetime.timedelta(days=1) return today.strftime("%Y-%m-%d"), yesterday.strftime("%Y-%m-%d") def test_get_chart_last_dates(db_session): today, yesterday = get_formatted_today_yesterday() market = 'us' factories.SpotifyChartsFactory.create(date=today, market=market) factories.SpotifyChartsFactory.create(date=yesterday, market=market) factories.SpotifyChartsFactory.create_batch(size=10, market=market) latest_dates = utils.get_chart_last_dates('us') assert latest_dates == [today, yesterday] @pytest.mark.parametrize( 'track_position,count', ( ((1, 3, 6, 10), 1), ((1, 3, 10, 15), 2), ) ) def test_get_major_moves_of_tracks(db_session, track_position, count): today, yesterday = get_formatted_today_yesterday() market = 'us' tracks = [] for i in range(2): track = Track( name=f'track_{i}', url=f'{SPOTIFY_URL_PREFIX}_{i}', uri=f'{SPOTIFY_TRACK_PREFIX}_{i}', artist_name=f'artist{i}', isrc='USRC11901901' ) tracks.append(track) factories.SpotifyTrack2Factory.create(id=track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track.isrc) positions = { today: { tracks[0].url: track_position[0], tracks[1].url: track_position[1] }, yesterday: { tracks[0].url: track_position[2], tracks[1].url: track_position[3] } } # create charts entities for track in tracks: for current_date in (today, yesterday): factories.SpotifyChartsFactory.create( position=positions[current_date][track.url], track_url=track.url, artist_name=track.artist_name, track_name=track.name, market=market, date=current_date, isrc=track.isrc ) major_moves = utils.get_major_moves(db_session, market, start_date=today, end_date=yesterday).all() assert len(major_moves) == count for mm in major_moves: track = next(t for t in tracks if t.url == mm.track_url) assert mm.track_name == track.name assert mm.artist_name == track.artist_name assert mm.isrc == track.isrc assert mm.position == positions[today][mm.track_url] assert mm.moves == mm.position - min(positions[yesterday].values()) def test_get_added_tracks(db_session): today, yesterday = get_formatted_today_yesterday() market = 'us' track_1 = Track( name='track 1', url=f'{SPOTIFY_URL_PREFIX}1', uri=f'{SPOTIFY_TRACK_PREFIX}1', artist_name='artist 1', isrc='USRC11901901' ) track_2 = Track( name='track 2', url=f'{SPOTIFY_URL_PREFIX}2', uri=f'{SPOTIFY_TRACK_PREFIX}2', artist_name='artist 2', isrc='USRC11901902' ) factories.SpotifyTrack2Factory.create(id=track_1.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track_1.isrc) factories.SpotifyTrack2Factory.create(id=track_2.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track_2.isrc) # create charts entities factories.SpotifyChartsFactory.create( position=6, track_url=track_1.url, artist_name=track_1.artist_name, track_name=track_1.name, market=market, date=yesterday, isrc=track_1.isrc ) for i, track in enumerate([track_1, track_2], start=1): factories.SpotifyChartsFactory.create( position=i, track_url=track.url, artist_name=track.artist_name, track_name=track.name, market=market, date=today, isrc=track.isrc ) added_tracks = utils.get_diff_tracks_by_dates(db_session, market, start_date=today, end_date=yesterday).all() assert len(added_tracks) == 1 assert added_tracks[0].track_url == track_2.url assert added_tracks[0].position == 2 assert added_tracks[0].isrc == track_2.isrc def test_get_only_starred_tracks(db_session): track = Track( name='track 1', url=f'{SPOTIFY_URL_PREFIX}1', uri=f'{SPOTIFY_TRACK_PREFIX}1', artist_name='artist 1', isrc='USRC11901901' ) starred_track = Track( name='track 2', url=f'{SPOTIFY_URL_PREFIX}2', uri=f'{SPOTIFY_TRACK_PREFIX}2', artist_name='artist 2', isrc='USRC11901902' ) factories.SpotifyTrack2Factory.create(id=track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track.isrc) factories.SpotifyTrack2Factory.create( id=starred_track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=starred_track.isrc) market = factories.MarketFactory.create(market_name='us') today, _ = get_formatted_today_yesterday() factories.SpotifyChartsFactory.create( position=1, track_url=track.url, artist_name=track.artist_name, track_name=track.name, market=market.market_name, date=today, isrc=track.isrc ) factories.SpotifyChartsFactory.create( position=2, track_url=starred_track.url, artist_name=starred_track.artist_name, track_name=starred_track.name, market=market.market_name, date=today, isrc=starred_track.isrc ) # mark track as starred user_id = 'user_id' factories.UserMarketFactory.create(user_id=user_id, market_id=market.market_id) factories.StarredContentFactory.create(user_id=user_id, uri=starred_track.uri, isrc=starred_track.isrc) tracks_query = utils.get_base_query(db_session, market.market_name, date=today).subquery() factories.UserDeviceFactory.create_batch( size=2, user_id=user_id, is_active=False) factories.UserDeviceFactory.create_batch( size=3, user_id=user_id, is_active=True) starred_tracks = utils.get_only_starred_tracks_with_device_tokens( db_session, tracks_query, market.market_name).all() assert len(starred_tracks) == 1 assert starred_tracks[0].user_id == user_id assert starred_tracks[0].track_url == starred_track.url assert starred_tracks[0].position == 2 assert starred_tracks[0].isrc == starred_track.isrc assert len(starred_tracks[0].device_tokens.split(',')) == 3 def test_process_major_moves(db_session, mocked_sqs, redis_client): user_id = 'user_id' market = factories.MarketFactory.create(market_name='us') factories.UserMarketFactory.create( user_id=user_id, market_id=market.market_id) factories.UserDeviceFactory.create_batch( size=3, user_id=user_id, is_active=True) today, yesterday = get_formatted_today_yesterday() # set up un starred track track1 = Track( name='track 1', url=f'{SPOTIFY_URL_PREFIX}1', uri=f'{SPOTIFY_TRACK_PREFIX}1', artist_name='artist 1', isrc='USRC11901901' ) track2 = Track( name='track 2', url=f'{SPOTIFY_URL_PREFIX}2', uri=f'{SPOTIFY_TRACK_PREFIX}2', artist_name='artist 2', isrc='USRC11901901' ) factories.SpotifyTrack2Factory.create(id=track1.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track1.isrc) factories.SpotifyTrack2Factory.create(id=track2.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track2.isrc) factories.StarredContentFactory.create(user_id=user_id, isrc=track1.isrc) factories.SpotifyChartsFactory.create( position=20, track_url=track1.url, artist_name=track1.artist_name, track_name=track1.name, market=market.market_name, date=yesterday, isrc=track1.isrc ) factories.SpotifyChartsFactory.create( position=100, track_url=track2.url, artist_name=track2.artist_name, track_name=track2.name, market=market.market_name, date=yesterday, isrc=track2.isrc ) factories.SpotifyChartsFactory.create( position=10, track_url=track1.url, artist_name=track1.artist_name, track_name=track1.name, market=market.market_name, date=today, isrc=track1.isrc ) factories.SpotifyChartsFactory.create( position=90, track_url=track2.url, artist_name=track2.artist_name, track_name=track2.name, market=market.market_name, date=today, isrc=track2.isrc ) config = Config() logger = get_logger('test') push_client = PushClient( logger_client=logger, sqs_client=mocked_sqs, db_session=db_session, config=config ) process_major_moves_of_tracks(market.market_name, today, yesterday, push_client, redis_client, db_session) push_messages = db_session.query(PushMessage).all() assert len(push_messages) == 1 for push in push_messages: assert push.track_id == track1.url.replace(SPOTIFY_URL_PREFIX, '') assert push.topic == TopicEnum.CHART_MAJOR_MOVES assert push.vendor == VendorEnum.SPOTIFY push_data = json.loads(push.data) assert push_data['change'] == -10 assert push_data['isrc'] == track1.isrc def test_process_added_tracks(db_session, mocked_sqs, redis_client): user_id = 'user_id' market = factories.MarketFactory.create(market_name='us') factories.UserMarketFactory.create(user_id=user_id, market_id=market.market_id) factories.UserDeviceFactory.create_batch(size=3, user_id=user_id, is_active=True) today, yesterday = get_formatted_today_yesterday() # set up un starred track starred_track = Track( name='track 1', url=f'{SPOTIFY_URL_PREFIX}1', uri=f'{SPOTIFY_TRACK_PREFIX}1', artist_name='artist 1', isrc='USRC11901901' ) factories.StarredContentFactory.create(user_id=user_id, isrc=starred_track.isrc) track = Track( name='track 2', url=f'{SPOTIFY_URL_PREFIX}2', uri=f'{SPOTIFY_TRACK_PREFIX}2', artist_name='artist 2', isrc='USRC11901902' ) factories.SpotifyTrack2Factory.create(id=track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track.isrc) factories.SpotifyTrack2Factory.create( id=starred_track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=starred_track.isrc) for i, t in enumerate([starred_track, track], start=1): factories.SpotifyChartsFactory.create( position=i, track_url=t.url, artist_name=t.artist_name, track_name=t.name, market=market.market_name, date=today, isrc=track.isrc ) config = Config() logger = get_logger('test') push_client = PushClient( logger_client=logger, sqs_client=mocked_sqs, db_session=db_session, config=config ) process_added_tracks(market.market_name, today, yesterday, push_client, redis_client, db_session) push_messages = db_session.query(PushMessage).all() assert len(push_messages) == 1 push = push_messages[0] assert push.track_id == starred_track.url.replace(SPOTIFY_URL_PREFIX, '') assert push.topic == TopicEnum.CHART_ADDITIONS assert push.vendor == VendorEnum.SPOTIFY push_data = json.loads(push.data) assert push_data['position'] == 1 assert push_data['isrc'] == starred_track.isrc def test_process_dropped_tracks(db_session, mocked_sqs, redis_client): user_id = 'user_id' market = factories.MarketFactory.create(market_name='us') factories.UserMarketFactory.create( user_id=user_id, market_id=market.market_id) factories.UserDeviceFactory.create_batch( size=3, user_id=user_id, is_active=True) today, yesterday = get_formatted_today_yesterday() # set up un starred track starred_track = Track( name='track 1', url=f'{SPOTIFY_URL_PREFIX}1', uri=f'{SPOTIFY_TRACK_PREFIX}1', artist_name='artist 1', isrc='USRC11901901' ) factories.StarredContentFactory.create(user_id=user_id, isrc=starred_track.isrc) track = Track( name='track 2', url=f'{SPOTIFY_URL_PREFIX}2', uri=f'{SPOTIFY_TRACK_PREFIX}2', artist_name='artist 2', isrc='USRC11901902' ) factories.SpotifyTrack2Factory.create(id=track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=track.isrc) factories.SpotifyTrack2Factory.create( id=starred_track.uri.replace(SPOTIFY_TRACK_PREFIX, ''), isrc=starred_track.isrc) for i, t in enumerate([starred_track, track], start=1): factories.SpotifyChartsFactory.create( position=i, track_url=t.url, artist_name=t.artist_name, track_name=t.name, market=market.market_name, date=yesterday, isrc=track.isrc ) config = Config() logger = get_logger('test') push_client = PushClient( logger_client=logger, sqs_client=mocked_sqs, db_session=db_session, config=config ) process_dropped_tracks(market.market_name, today, yesterday, push_client, redis_client, db_session) push_messages = db_session.query(PushMessage).all() assert len(push_messages) == 1 push = push_messages[0] assert push.track_id == starred_track.url.replace(SPOTIFY_URL_PREFIX, '') assert push.topic == TopicEnum.CHART_REMOVALS assert push.vendor == VendorEnum.SPOTIFY push_data = json.loads(push.data) assert push_data['position'] == 1 assert push_data['isrc'] == starred_track.isrc