def test_it_returns_follow_events(self):
        # 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')

        # 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)

        # should contain 3 events, the main user followed 2 people and then we created a new follow event
        self.assertEqual(3, r.json['payload']['count'])

        # the first event should be the latest one
        self.assertEqual('follow',
                         r.json['payload']['events'][0]['event_type'])
        self.assertEqual('following_1',
                         r.json['payload']['events'][0]['user_name'])
        self.assertEqual(
            'following_1',
            r.json['payload']['events'][0]['metadata']['user_name_0'])
        self.assertEqual(
            'new_user_1',
            r.json['payload']['events'][0]['metadata']['user_name_1'])
        self.assertEqual(
            'follow',
            r.json['payload']['events'][0]['metadata']['relationship_type'])

        # now, check the main user's own following events
        self.assertEqual('follow',
                         r.json['payload']['events'][1]['event_type'])
        self.assertEqual(self.main_user['musicbrainz_id'],
                         r.json['payload']['events'][1]['user_name'])
        self.assertEqual(
            self.main_user['musicbrainz_id'],
            r.json['payload']['events'][1]['metadata']['user_name_0'])
        self.assertEqual(
            self.following_user_2['musicbrainz_id'],
            r.json['payload']['events'][1]['metadata']['user_name_1'])
        self.assertEqual(
            'follow',
            r.json['payload']['events'][1]['metadata']['relationship_type'])

        self.assertEqual('follow',
                         r.json['payload']['events'][2]['event_type'])
        self.assertEqual(self.main_user['musicbrainz_id'],
                         r.json['payload']['events'][2]['user_name'])
        self.assertEqual(
            self.main_user['musicbrainz_id'],
            r.json['payload']['events'][2]['metadata']['user_name_0'])
        self.assertEqual(
            self.following_user_1['musicbrainz_id'],
            r.json['payload']['events'][2]['metadata']['user_name_1'])
        self.assertEqual(
            'follow',
            r.json['payload']['events'][2]['metadata']['relationship_type'])
Example #2
0
    def test_get_following_for_user_returns_correct_data(self):

        # no relationships yet, should return an empty list
        following = db_user_relationship.get_following_for_user(
            self.main_user['id'])
        self.assertListEqual(following, [])

        # make the main_user follow followed_user_1
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_1['id'], 'follow')

        # the list of users main_user is following should have 1 element now
        following = db_user_relationship.get_following_for_user(
            self.main_user['id'])
        self.assertEqual(1, len(following))

        # make it so that the main user follows two users, followed_user_1 and followed_user_2
        self.followed_user_2 = db_user.get_or_create(3, 'followed_user_2')
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_2['id'], 'follow')

        # the list of users main_user is following should have 2 elements now
        following = db_user_relationship.get_following_for_user(
            self.main_user['id'])
        self.assertEqual(2, len(following))
Example #3
0
    def test_get_pins_for_user_following(self):
        """Test that valid response is received with 200 code"""
        # user follows followed_user_1 and followed_user_2
        db_user_relationship.insert(self.user["id"], self.followed_user_1["id"], "follow")
        db_user_relationship.insert(self.user["id"], self.followed_user_2["id"], "follow")

        pin1 = self.pin_single_sample(self.followed_user_1["id"], 0)  # pin recording for followed_user_1
        pin2 = self.pin_single_sample(self.followed_user_2["id"], 1)  # pin recording for followed_user_2

        response = self.client.get(
            url_for("pinned_rec_api_bp_v1.get_pins_for_user_following", user_name=self.user["musicbrainz_id"])
        )
        self.assert200(response)
        data = json.loads(response.data)

        pins = data["pinned_recordings"]

        self.assertEqual(data["offset"], 0)
        self.assertEqual(data["count"], 2)
        self.assertEqual(data["user_name"], self.user["musicbrainz_id"])

        # check that data is sorted in descending order of created date
        self.assertEqual(pins[0]["recording_msid"], pin2.recording_msid)  # pin2 was pinned most recently
        self.assertEqual(pins[0]["recording_mbid"], pin2.recording_mbid)
        self.assertEqual(pins[0]["blurb_content"], pin2.blurb_content)
        self.assertEqual(pins[0]["user_name"], self.followed_user_2["musicbrainz_id"])

        self.assertEqual(pins[1]["recording_msid"], pin1.recording_msid)  # pin2 was pinned before pin1
        self.assertEqual(pins[1]["recording_mbid"], pin1.recording_mbid)
        self.assertEqual(pins[1]["blurb_content"], pin1.blurb_content)
        self.assertEqual(pins[1]["user_name"], self.followed_user_1["musicbrainz_id"])
def follow_user(user_name: str):
    """
    Follow the user ``user_name``. A user token (found on  https://listenbrainz.org/profile/ ) must
    be provided in the Authorization header!

    :reqheader Authorization: Token <user token>
    :reqheader Content-Type: *application/json*
    :statuscode 200: Successfully followed the user ``user_name``.
    :statuscode 400:
                    - Already following the user ``user_name``.
                    - Trying to follow yourself.
    :statuscode 401: invalid authorization. See error message for details.
    :resheader Content-Type: *application/json*
    """
    current_user = validate_auth_header()
    user = db_user.get_by_mb_id(user_name)

    if not user:
        raise APINotFound("User %s not found" % user_name)

    if user["musicbrainz_id"] == current_user["musicbrainz_id"]:
        raise APIBadRequest("Whoops, cannot follow yourself.")

    if db_user_relationship.is_following_user(current_user["id"], user["id"]):
        raise APIBadRequest("%s is already following user %s" % (current_user["musicbrainz_id"], user["musicbrainz_id"]))

    try:
        db_user_relationship.insert(current_user["id"], user["id"], "follow")
    except Exception as e:
        current_app.logger.error("Error while trying to insert a relationship: %s", str(e))
        raise APIInternalServerError("Something went wrong, please try again later")

    return jsonify({"status": "ok"})
Example #5
0
 def test_is_following_user(self):
     self.assertFalse(
         db_user_relationship.is_following_user(self.main_user['id'],
                                                self.followed_user_1['id']))
     db_user_relationship.insert(self.main_user['id'],
                                 self.followed_user_1['id'], 'follow')
     self.assertTrue(
         db_user_relationship.is_following_user(self.main_user['id'],
                                                self.followed_user_1['id']))
    def test_get_pins_for_user_following(self):
        # user follows followed_user_1
        db_user_relationship.insert(self.user["id"],
                                    self.followed_user_1["id"], "follow")
        self.assertTrue(
            db_user_relationship.is_following_user(self.user["id"],
                                                   self.followed_user_1["id"]))

        # test that followed_pins contains followed_user_1's pinned recording
        self.pin_single_sample(self.followed_user_1["id"], 0)
        followed_pins = db_pinned_rec.get_pins_for_user_following(user_id=1,
                                                                  count=50,
                                                                  offset=0)
        self.assertEqual(len(followed_pins), 1)
        self.assertEqual(followed_pins[0].user_name, "followed_user_1")

        # test that pins from users that the user is not following are not included
        self.pin_single_sample(self.followed_user_2["id"], 0)
        self.assertEqual(len(followed_pins), 1)

        # test that followed_user_2's pin is included after user follows
        db_user_relationship.insert(self.user["id"],
                                    self.followed_user_2["id"], "follow")
        followed_pins = db_pinned_rec.get_pins_for_user_following(user_id=1,
                                                                  count=50,
                                                                  offset=0)
        self.assertEqual(len(followed_pins), 2)
        self.assertEqual(followed_pins[0].user_name, "followed_user_2")

        # test that list is returned in descending order of creation date
        self.assertGreater(followed_pins[0].created, followed_pins[1].created)
        self.assertEqual(followed_pins[1].user_name, "followed_user_1")

        # test the limit argument
        limit = 1
        limited_following_pins = db_pinned_rec.get_pins_for_user_following(
            user_id=self.user["id"], count=limit, offset=0)
        self.assertEqual(len(limited_following_pins), limit)

        limit = 999
        limited_following_pins = db_pinned_rec.get_pins_for_user_following(
            user_id=self.user["id"], count=limit, offset=0)
        self.assertEqual(len(limited_following_pins), 2)

        # test the offset argument
        offset = 1
        offset_following_pins = db_pinned_rec.get_pins_for_user_following(
            user_id=self.user["id"], count=50, offset=offset)
        self.assertEqual(len(offset_following_pins), 2 - offset)

        offset = 999
        offset_following_pins = db_pinned_rec.get_pin_history_for_user(
            user_id=self.user["id"], count=50, offset=offset)
        self.assertFalse(offset_following_pins)
    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
Example #8
0
def follow_user(user_name: str):
    user = _get_user(user_name)

    if user.musicbrainz_id == current_user.musicbrainz_id:
        raise APIBadRequest("Whoops, cannot follow yourself.")

    if db_user_relationship.is_following_user(current_user.id, user.id):
        raise APIBadRequest(f"{current_user.musicbrainz_id} is already following user {user.musicbrainz_id}")

    try:
        db_user_relationship.insert(current_user.id, user.id, 'follow')
    except Exception:
        current_app.logger.critical("Error while trying to insert a relationship", exc_info=True)
        raise APIInternalServerError("Something went wrong, please try again later")

    return jsonify({"status": 200, "message": "Success!"})
Example #9
0
    def test_get_followers_of_user_returns_correct_data(self):
        # no relationships yet, should return an empty list
        followers = db_user_relationship.get_followers_of_user(
            self.followed_user_1['id'])
        self.assertListEqual(followers, [])

        # add two relationships
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_1['id'], 'follow')
        self.following_user_1 = db_user.get_or_create(3, 'following_user_1')
        db_user_relationship.insert(self.following_user_1['id'],
                                    self.followed_user_1['id'], 'follow')

        # At this point, the main_user and following_user_1 follow followed_user_1
        # So, if we get the followers of followed_user_1, we'll get back two users
        followers = db_user_relationship.get_followers_of_user(
            self.followed_user_1['id'])
        self.assertEqual(2, len(followers))
Example #10
0
    def test_get_follow_events_honors_timestamp_parameters(self):
        ts = int(time.time())

        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_1['id'], 'follow')
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_2['id'], 'follow')

        time.sleep(3)
        new_user = db_user.get_or_create(4, 'new_user')
        db_user_relationship.insert(self.followed_user_1['id'], new_user['id'],
                                    'follow')

        # max_ts is too low, won't return anything
        events = db_user_relationship.get_follow_events(
            user_ids=(self.main_user['id'], self.followed_user_1['id']),
            min_ts=0,
            max_ts=ts,
            count=50)
        self.assertListEqual([], events)

        # check that it honors min_ts as well
        events = db_user_relationship.get_follow_events(
            user_ids=(self.main_user['id'], self.followed_user_1['id']),
            min_ts=ts + 1,
            max_ts=ts + 10,
            count=50)
        self.assertEqual(1, len(events))
Example #11
0
    def test_get_pins_for_user_following_offset_param(self):
        """Tests that valid response is received honoring offset parameter"""
        # user follows followed_user_1 and followed_user_2
        db_user_relationship.insert(self.user["id"], self.followed_user_1["id"], "follow")
        db_user_relationship.insert(self.user["id"], self.followed_user_2["id"], "follow")

        included_pin = self.pin_single_sample(self.followed_user_1["id"], 0)  # pin recording for followed_user_1
        self.pin_single_sample(self.followed_user_2["id"], 1)  # pin recording for followed_user_2

        offset = 1
        response = self.client.get(
            url_for("pinned_rec_api_bp_v1.get_pins_for_user_following", user_name=self.user["musicbrainz_id"], offset=offset)
        )
        data = json.loads(response.data)
        pins = data["pinned_recordings"]

        self.assertEqual(data["offset"], offset)
        self.assertEqual(data["count"], 2 - offset)

        # check that only the older pin was included in returned JSON
        self.assertEqual(pins[0]["recording_msid"], included_pin.recording_msid)  # included_pin was pinned most recently
        self.assertEqual(pins[0]["recording_mbid"], included_pin.recording_mbid)
        self.assertEqual(pins[0]["blurb_content"], included_pin.blurb_content)
        self.assertEqual(pins[0]["user_name"], self.followed_user_1["musicbrainz_id"])
Example #12
0
    def test_get_follow_events_honors_count_parameter(self):
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_1['id'], 'follow')
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_2['id'], 'follow')

        new_user = db_user.get_or_create(4, 'new_user')
        db_user_relationship.insert(self.followed_user_1['id'], new_user['id'],
                                    'follow')

        events = db_user_relationship.get_follow_events(
            user_ids=(self.main_user['id'], self.followed_user_1['id']),
            min_ts=0,
            max_ts=int(time.time()) + 10,
            count=2,
        )

        # 3 events exist, but should only return 2
        self.assertEqual(2, len(events))
Example #13
0
    def test_get_follow_events_returns_correct_events(self):
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_1['id'], 'follow')
        db_user_relationship.insert(self.main_user['id'],
                                    self.followed_user_2['id'], 'follow')

        new_user = db_user.get_or_create(4, 'new_user')
        db_user_relationship.insert(self.followed_user_1['id'], new_user['id'],
                                    'follow')

        events = db_user_relationship.get_follow_events(
            user_ids=(self.main_user['id'], self.followed_user_1['id']),
            min_ts=0,
            max_ts=int(time.time()) + 10,
            count=50)
        self.assertEqual(3, len(events))
        self.assertEqual('followed_user_1', events[0]['user_name_0'])
        self.assertEqual('new_user', events[0]['user_name_1'])

        self.assertEqual('iliekcomputers', events[1]['user_name_0'])
        self.assertEqual('followed_user_2', events[1]['user_name_1'])

        self.assertEqual('iliekcomputers', events[2]['user_name_0'])
        self.assertEqual('followed_user_1', events[2]['user_name_1'])
Example #14
0
 def create_and_follow_user(self, user: int, mb_row_id: int, name: str) -> dict:
     following_user = db_user.get_or_create(mb_row_id, name)
     db_user_relationship.insert(user, following_user['id'], 'follow')
     return following_user
Example #15
0
 def test_insert_raises_value_error_for_invalid_relationship(self):
     with self.assertRaises(ValueError):
         db_user_relationship.insert(self.main_user['id'],
                                     self.followed_user_1['id'],
                                     'idkwhatrelationshipthisis')