예제 #1
0
    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)
예제 #2
0
    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_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_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
예제 #5
0
 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)
예제 #6
0
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)
예제 #7
0
 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)
예제 #8
0
    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))
예제 #9
0
 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"],
             )
예제 #10
0
    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))