def test_get_events_for_feed_returns_events(self): db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) new_user = db_user.get_or_create(2, 'superman') db_user_timeline_event.create_user_track_recommendation_event( user_id=new_user['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) events = db_user_timeline_event.get_recording_recommendation_events_for_feed( user_ids=(self.user['id'], new_user['id']), min_ts=0, max_ts=int(time.time()) + 10, count=50, ) self.assertEqual(2, len(events)) self.assertEqual(new_user['id'], events[0].user_id) self.assertEqual(self.user['id'], events[1].user_id)
def test_get_events_for_feed_honors_count_parameter(self): db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Da Funk", artist_name="Daft Punk", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) events = db_user_timeline_event.get_recording_recommendation_events_for_feed( user_ids=(self.user['id'], ), min_ts=0, max_ts=int(time.time()) + 10, count=1, ) # 2 events exist, should return only one, the one that is newer self.assertEqual(1, len(events)) self.assertEqual('Da Funk', events[0].metadata.track_name)
def test_it_returns_recording_recommendation_events(self): # create a recording recommendation ourselves db_user_timeline_event.create_user_track_recommendation_event( user_id=self.main_user['id'], metadata=RecordingRecommendationMetadata( track_name="Lose yourself to dance", artist_name="Daft Punk", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) # create a recording recommendation for a user we follow db_user_timeline_event.create_user_track_recommendation_event( user_id=self.following_user_1['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) # this should show up in the events r = self.client.get( url_for('user_timeline_event_api_bp.user_feed', user_name=self.main_user['musicbrainz_id']), headers={'Authorization': f"Token {self.main_user['auth_token']}"}, query_string={'max_ts': int(time.time()) + 1}) self.assert200(r) # first, let's remove the own follow events, we don't care about those in this test. payload = self.remove_own_follow_events(r.json['payload']) # now, check for both the recording recommendations and their order self.assertEqual(2, payload['count']) self.assertEqual('recording_recommendation', payload['events'][0]['event_type']) self.assertEqual('following_1', payload['events'][0]['user_name']) self.assertEqual( 'Sunflower', payload['events'][0]['metadata']['track_metadata']['track_name']) self.assertEqual( 'Swae Lee & Post Malone', payload['events'][0]['metadata']['track_metadata']['artist_name']) self.assertEqual('recording_recommendation', payload['events'][1]['event_type']) self.assertEqual(self.main_user['musicbrainz_id'], payload['events'][1]['user_name']) self.assertEqual( 'Lose yourself to dance', payload['events'][1]['metadata']['track_metadata']['track_name']) self.assertEqual( 'Daft Punk', payload['events'][1]['metadata']['track_metadata']['artist_name'])
def test_get_events_for_feed_honors_time_parameters(self): ts = int(time.time()) db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Da Funk", artist_name="Daft Punk", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) time.sleep(3) new_user = db_user.get_or_create(4, 'new_user') db_user_timeline_event.create_user_track_recommendation_event( user_id=new_user['id'], metadata=RecordingRecommendationMetadata( track_name="Da Funk", artist_name="Daft Punk", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) # max_ts is too low, won't return anything events = db_user_timeline_event.get_recording_recommendation_events_for_feed( user_ids=(self.user['id'], new_user['id']), min_ts=0, max_ts=ts, count=50, ) self.assertListEqual([], events) # check that it honors min_ts as well events = db_user_timeline_event.get_recording_recommendation_events_for_feed( user_ids=(self.user['id'], new_user['id']), min_ts=ts + 1, max_ts=ts + 10, count=50, ) self.assertEqual(1, len(events))
def test_create_user_track_recommendation_sets_event_type_correctly(self): event = db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), ) ) self.assertEqual(UserTimelineEventType.RECORDING_RECOMMENDATION, event.event_type)
def test_it_raises_database_exceptions_if_something_goes_wrong(self, mock_db_connect): with self.assertRaises(DatabaseException): db_user_timeline_event.create_user_timeline_event( user_id=self.user['id'], event_type=UserTimelineEventType.RECORDING_RECOMMENDATION, metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), ) )
def create_user_recording_recommendation_event(user_name): """ Make the user recommend a recording to their followers. The request should post the following data about the recording being recommended: .. code-block:: json { "metadata": { "artist_name": "<The name of the artist, required>", "track_name": "<The name of the track, required>", "artist_msid": "<The MessyBrainz ID of the artist, required>", "recording_msid": "<The MessyBrainz ID of the recording, required>", "release_name": "<The name of the release, optional>", "recording_mbid": "<The MusicBrainz ID of the recording, optional>" } } :param user_name: The MusicBrainz ID of the user who is recommending the recording. :type user_name: ``str`` :statuscode 200: Successful query, recording has been recommended! :statuscode 400: Bad request, check ``response['error']`` for more details. :statuscode 401: Unauthorized, you do not have permissions to recommend recordings on the behalf of this user :statuscode 404: User not found :resheader Content-Type: *application/json* """ user = validate_auth_header() if user_name != user['musicbrainz_id']: raise APIUnauthorized( "You don't have permissions to post to this user's timeline.") try: data = ujson.loads(request.get_data()) except ValueError as e: raise APIBadRequest(f"Invalid JSON: {str(e)}") try: metadata = RecordingRecommendationMetadata(**data['metadata']) except pydantic.ValidationError as e: raise APIBadRequest(f"Invalid metadata: {str(e)}") try: event = db_user_timeline_event.create_user_track_recommendation_event( user['id'], metadata) except DatabaseException: raise APIInternalServerError("Something went wrong, please try again.") event_data = event.dict() event_data['created'] = event_data['created'].timestamp() event_data['event_type'] = event_data['event_type'].value return jsonify(event_data)
def test_get_events_only_gets_events_for_the_specified_user(self): db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) new_user = db_user.get_or_create(2, 'captain america') db_user_timeline_event.create_user_track_recommendation_event( user_id=new_user['id'], metadata=RecordingRecommendationMetadata( track_name="Fade", artist_name="Kanye West", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) events = db_user_timeline_event.get_user_track_recommendation_events( user_id=new_user['id'], ) self.assertEqual(1, len(events)) self.assertEqual(new_user['id'], events[0].user_id)
def test_delete_feed_events(self): # creating recording recommendation and checking event_rec = db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="All Caps", artist_name="MF DOOM", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) self.assertEqual(UserTimelineEventType.RECORDING_RECOMMENDATION, event_rec.event_type) self.assertEqual(self.user['id'], event_rec.user_id) # creating a new user for notification new_user = db_user.get_or_create(2, 'riksucks') message = 'You have a <a href="https://listenbrainz.org/non-existent-playlist">playlist</a>' event_not = db_user_timeline_event.create_user_notification_event( user_id=new_user['id'], metadata=NotificationMetadata( creator=new_user['musicbrainz_id'], message=message, )) self.assertEqual(new_user['id'], event_not.user_id) self.assertEqual(message, event_not.metadata.message) self.assertEqual(new_user['musicbrainz_id'], event_not.metadata.creator) self.assertEqual(UserTimelineEventType.NOTIFICATION, event_not.event_type) # deleting recording recommendation db_user_timeline_event.delete_user_timeline_event( id=event_rec.id, user_id=self.user["id"], ) event_rec = db_user_timeline_event.get_user_notification_events( user_id=self.user["id"], count=1, ) self.assertEqual(0, len(event_rec)) # deleting notification db_user_timeline_event.delete_user_timeline_event( id=event_not.id, user_id=new_user["id"], ) event_not = db_user_timeline_event.get_user_notification_events( user_id=new_user["id"], count=1, ) self.assertEqual(0, len(event_not))
def test_it_returns_all_types_of_events_sorted_by_time_in_descending_order( self): with open(self.path_to_data_file('valid_single.json'), 'r') as f: payload = json.load(f) # send a listen from the past ts = int(time.time()) payload['payload'][0]['listened_at'] = ts - 10 response = self.send_data(payload, user=self.following_user_1) self.assert200(response) self.assertEqual(response.json['status'], 'ok') # make a user you're following follow a new user new_user_1 = db_user.get_or_create(104, 'new_user_1') db_user_relationship.insert(self.following_user_1['id'], new_user_1['id'], 'follow') time.sleep( 1.5 ) # sleep a bit to avoid ordering conflicts, cannot mock this time as it comes from postgres # create a recording recommendation for a user we follow db_user_timeline_event.create_user_track_recommendation_event( user_id=self.following_user_1['id'], metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) time.sleep(2) r = self.client.get( url_for('user_timeline_event_api_bp.user_feed', user_name=self.main_user['musicbrainz_id']), headers={'Authorization': f"Token {self.main_user['auth_token']}"}, ) self.assert200(r) self.assertEqual( 5, r.json['payload'] ['count']) # 3 events we created + 2 own follow events self.assertEqual('recording_recommendation', r.json['payload']['events'][0]['event_type']) self.assertEqual('follow', r.json['payload']['events'][1]['event_type']) self.assertEqual('listen', r.json['payload']['events'][4] ['event_type']) # last event should be a listen
def test_delete_feed_events_for_something_goes_wrong(self): # creating recording recommendation event_rec = db_user_timeline_event.create_user_track_recommendation_event( user_id=self.user['id'], metadata=RecordingRecommendationMetadata( track_name="All Caps", artist_name="MF DOOM", recording_msid=str(uuid.uuid4()), ) ) with mock.patch("listenbrainz.db.engine.connect", side_effect=Exception): with self.assertRaises(DatabaseException): # checking if DatabaseException is raised or not db_user_timeline_event.delete_user_timeline_event( id=event_rec.id, user_id=self.user["id"], )
def test_it_adds_rows_to_the_database(self): event = db_user_timeline_event.create_user_timeline_event( user_id=self.user['id'], event_type=UserTimelineEventType.RECORDING_RECOMMENDATION, metadata=RecordingRecommendationMetadata( track_name="Sunflower", artist_name="Swae Lee & Post Malone", recording_msid=str(uuid.uuid4()), artist_msid=str(uuid.uuid4()), )) events = db_user_timeline_event.get_user_track_recommendation_events( user_id=self.user['id'], count=1, ) self.assertEqual(1, len(events)) self.assertEqual(event.id, events[0].id) self.assertEqual(event.created, events[0].created) self.assertEqual('Sunflower', events[0].metadata.track_name)