Esempio n. 1
0
def test_insert_retrieve_discussion(test_database):
    user = User(1, name="test")
    beatmapset = Beatmapset(1, creator=user, allow_api=False)
    discussion = Discussion(1,
                            beatmapset=beatmapset,
                            user=user,
                            content="testing",
                            tab="tab",
                            difficulty="diff")
    test_database.insert_discussion(discussion)

    retrieved_discussion = test_database.retrieve_discussion(
        where="id=%s", where_values=(1, ))
    assert retrieved_discussion.id == discussion.id
    assert retrieved_discussion.beatmapset == discussion.beatmapset
    assert retrieved_discussion.user == discussion.user
    assert retrieved_discussion.content == discussion.content
    assert retrieved_discussion.tab == discussion.tab
    assert retrieved_discussion.difficulty == discussion.difficulty
    assert retrieved_discussion == discussion
Esempio n. 2
0
def test_insert_retrieve_newspost(test_database):
    author = User(1, name="test")
    newspost = NewsPost(_id=3,
                        title="title",
                        preview="preview",
                        author=author,
                        slug="slug",
                        image_url="image_url")
    test_database.insert_newspost(newspost)

    retrieved_newspost = test_database.retrieve_newspost(where="id=%s",
                                                         where_values=(3, ))
    assert retrieved_newspost.id == newspost.id
    assert retrieved_newspost.title == newspost.title
    assert retrieved_newspost.preview == newspost.preview
    assert retrieved_newspost.author.id == newspost.author.id
    assert retrieved_newspost.author.name == newspost.author.name
    assert retrieved_newspost.slug == newspost.slug
    assert retrieved_newspost.image_url == newspost.image_url
    assert retrieved_newspost == newspost
Esempio n. 3
0
async def test_insert_retrieve_event_with_newspost(test_database):
    time = datetime.utcnow()

    author = User(1, name="test")
    newspost = NewsPost(_id=3,
                        title="title",
                        preview="preview",
                        author=author,
                        slug="slug",
                        image_url="image_url")
    event = Event(_type="news", time=time, newspost=newspost, user=author)

    test_database.insert_event(event)

    retrieved_event = await test_database.retrieve_event("type=%s", ("news", ))
    assert retrieved_event.type == event.type
    assert retrieved_event.time == event.time
    assert retrieved_event.newspost == event.newspost
    assert retrieved_event.user == event.user
    assert retrieved_event.content == event.content
    assert retrieved_event == event
Esempio n. 4
0
def test_insert_retrieve_beatmapset(test_database):
    user = User(1, name="test")
    beatmapset = Beatmapset(1,
                            artist="123",
                            title="456",
                            creator=user,
                            modes=["osu", "taiko"],
                            genre="genre",
                            language="language")
    test_database.insert_beatmapset(beatmapset)

    retrieved_beatmapset = test_database.retrieve_beatmapset(
        where="id=%s", where_values=(1, ))
    assert retrieved_beatmapset.id == beatmapset.id
    assert retrieved_beatmapset.artist == beatmapset.artist
    assert retrieved_beatmapset.title == beatmapset.title
    assert retrieved_beatmapset.creator == beatmapset.creator
    assert retrieved_beatmapset.modes == beatmapset.modes
    assert retrieved_beatmapset.genre == beatmapset.genre
    assert retrieved_beatmapset.language == beatmapset.language
    assert retrieved_beatmapset == beatmapset
Esempio n. 5
0
def test_insert_retrieve_multiple_beatmapsets(test_database):
    user = User(1, name="test")
    beatmapset1 = Beatmapset(1,
                             artist="123",
                             title="456",
                             creator=user,
                             modes=["osu", "taiko"],
                             allow_api=False)
    beatmapset2 = Beatmapset(2,
                             artist="456",
                             title="789",
                             creator=user,
                             modes=["osu"],
                             allow_api=False)

    test_database.insert_beatmapset(beatmapset1)
    test_database.insert_beatmapset(beatmapset2)

    retrieved_beatmapsets = test_database.retrieve_beatmapsets(
        where="creator_id=%s", where_values=(user.id, ))
    assert next(retrieved_beatmapsets, None) == beatmapset1
    assert next(retrieved_beatmapsets, None) == beatmapset2
Esempio n. 6
0
def test_insert_retrieve_multiple_newsposts(test_database):
    author = User(_id=1, name="test")
    newspost1 = NewsPost(_id=1,
                         title="title",
                         preview="preview",
                         author=author,
                         slug="slug",
                         image_url="image_url")
    newspost2 = NewsPost(_id=2,
                         title="title2",
                         preview="preview2",
                         author=author,
                         slug="slug2",
                         image_url="image_url2")

    test_database.insert_newspost(newspost1)
    test_database.insert_newspost(newspost2)

    retrieved_newsposts = test_database.retrieve_newsposts(
        where="author_id=%s", where_values=(author.id, ))
    assert next(retrieved_newsposts, None) == newspost1
    assert next(retrieved_newsposts, None) == newspost2
Esempio n. 7
0
 def retrieve_newsposts(
         self,
         where: str,
         where_values: tuple = None) -> Generator[NewsPost, None, None]:
     """Returns a generator of all newsposts from the database matching the given WHERE clause."""
     fetched_rows = self.retrieve_table_data(
         table="newsposts",
         where=where,
         where_values=where_values,
         selection=
         "id, title, preview, author_id, author_name, slug, image_url")
     for row in (fetched_rows or []):
         _id = row[0]
         title = row[1]
         preview = row[2]
         author = self.retrieve_user("id=%s", (row[3], ))
         author_name = row[4]
         if not author:
             author = User(_id=None, name=author_name)
         slug = row[5]
         image_url = row[6]
         yield NewsPost(_id, title, preview, author, slug, image_url)
Esempio n. 8
0
def test_insert_retrieve_multiple_discussions(test_database):
    user = User(1, name="test")
    beatmapset = Beatmapset(1, creator=user, allow_api=False)
    discussion1 = Discussion(1,
                             beatmapset=beatmapset,
                             user=user,
                             content="testing",
                             tab="tab",
                             difficulty="diff")
    discussion2 = Discussion(2,
                             beatmapset=beatmapset,
                             user=user,
                             content="real testing",
                             tab="tab",
                             difficulty="diff")

    test_database.insert_discussion(discussion1)
    test_database.insert_discussion(discussion2)

    retrieved_discussions = test_database.retrieve_discussions(
        where="beatmapset_id=%s", where_values=(beatmapset.id, ))
    assert next(retrieved_discussions, None) == discussion1
    assert next(retrieved_discussions, None) == discussion2
Esempio n. 9
0
async def test_insert_retrieve_event_cached(cached_database):
    time = datetime.utcnow()

    user = User(1, name="test")
    beatmapset = Beatmapset(1, creator=user, allow_api=False)
    discussion = Discussion(1,
                            beatmapset=beatmapset,
                            user=user,
                            content="testing",
                            tab="tab",
                            difficulty="diff")

    for i in range(100):
        event = Event(_type=f"{i}",
                      time=time,
                      beatmapset=beatmapset,
                      discussion=discussion,
                      user=user)
        cached_database.insert_event(event)

    start_time = datetime.utcnow()
    retrieved_events_uncached = cached_database.retrieve_events(
        where="beatmapset_id=%s", where_values=(beatmapset.id, ))
    async for event in retrieved_events_uncached:
        assert event.beatmapset == beatmapset
    delta_time_uncached = datetime.utcnow() - start_time

    start_time = datetime.utcnow()
    retrieved_events_cached = cached_database.retrieve_events(
        where="beatmapset_id=%s", where_values=(beatmapset.id, ))
    async for event in retrieved_events_cached:
        assert event.beatmapset == beatmapset
    delta_time_cached = datetime.utcnow() - start_time

    assert await anext(retrieved_events_uncached,
                       None) == await anext(retrieved_events_cached, None)
    assert delta_time_uncached > delta_time_cached
Esempio n. 10
0
def test_user_get_name_restricted():
    user = User(1)

    assert user.id == 1
    assert user.name is None
    assert str(user) == "1"
Esempio n. 11
0
def test_user_get_id_restricted():
    user = User(name="a")
    
    assert user.id is None
    assert user.name == "a"
Esempio n. 12
0
def test_user_get_id_from_api():
    user = User(name="peppy")

    assert user.id == 2
    assert user.name == "peppy"
Esempio n. 13
0
def test_user_no_args():
    with pytest.raises(ValueError) as err:
        User()
    assert "neither id nor name provided" in str(err)
Esempio n. 14
0
def test_newspost_hash():
    newspost = NewsPost(_id="1", title="title", preview="hello there", author=User(1, "someone"), slug="newspost-1", image_url="/image")
    assert hash(newspost)
Esempio n. 15
0
def test_user_get_name_from_api():
    user = User(2)
    
    assert user.id == 2
    assert user.name == "peppy"
Esempio n. 16
0
def test_newspost_eq_different_types():
    newspost = NewsPost(_id="1", title="title", preview="hello there", author=User(1, "someone"), slug="newspost-1", image_url="/image")
    assert newspost != "string"
Esempio n. 17
0
def test_user_without_api():
    user = User(14, allow_api=False)

    assert user.id == 14
    assert user.name is not None
Esempio n. 18
0
def test_beatmapset_int_artist_title():
    beatmapset = Beatmapset(41823, 5, 6, User(2, 222), ["osu"], genre="g", language="l")

    assert beatmapset.artist == "5"
    assert beatmapset.title == "6"
Esempio n. 19
0
def test_user_int_name():
    user = User(3, 487)
    assert user.name == "487"
Esempio n. 20
0
def test_user_get_id_from_api_name_case():
    user = User(name="PEPPY")

    assert user.id == 2
    assert user.name == "peppy"
Esempio n. 21
0
def test_user_str_id():
    user = User("101", "someone")
    assert user.id == 101
Esempio n. 22
0
    def parse_event_json(self,
                         event_json: object,
                         user_jsons: object = None) -> Event:
        """Returns a BeatmapsetEvent reflecting the given event json object.
        Ignores any event with an incomplete context (e.g. deleted beatmaps).

        Requests user names from the api unless supplied with the json-users."""
        if not event_json:
            # Seems to occur when the respective beatmapset has been deleted.
            log_err(
                "WARNING | An event is missing; the beatmapset was probably deleted."
            )
            return None

        try:
            # Scrape object data
            _type = event_json["type"]
            time = timestamp.from_string(event_json["created_at"])

            if "beatmapset" not in event_json or not event_json["beatmapset"]:
                raise DeletedContextError(
                    "No beatmapset was found in this event. It was likely deleted."
                )

            beatmapset_id = event_json["beatmapset"]["id"]
            discussion_id = event_json["discussion"][
                "id"] if "discussion" in event_json and event_json[
                    "discussion"] else None

            user_id = event_json["user_id"] if "user_id" in event_json else None
            user_json = self.__lookup_user_json(user_id, user_jsons)
            user_name = user_json["username"] if user_json else None

            content = None
            if _type in [types.LANGUAGE_EDIT, types.GENRE_EDIT]:
                # Language/genre edits always have "old" and "new" fields, which no other type has.
                old = event_json["comment"]["old"]
                new = event_json["comment"]["new"]
                content = f"{old} -> {new}"

            if _type in [types.UNLOVE]:
                # E.g. "Mapper has asked for it to be removed from Loved".
                content = event_json["comment"]["reason"]

            # Reconstruct objects
            beatmapset = Beatmapset(beatmapset_id)
            user = User(user_id, user_name) if user_id is not None else None
            discussion = Discussion(
                discussion_id,
                beatmapset) if discussion_id is not None else None
        except DeletedContextError as err:
            log_err(err)
        else:
            return Event(_type=_type,
                         time=time,
                         beatmapset=beatmapset,
                         discussion=discussion,
                         user=user,
                         content=content)

        return None
Esempio n. 23
0
def test_user():
    user = User(101, "Generic Name")

    assert user.id == 101
    assert user.name == "Generic Name"
    assert str(user) == "Generic Name"
Esempio n. 24
0
    def parse_event_json(self,
                         event_json: object,
                         user_jsons: object = None,
                         discussion_jsons_for_replies: object = None) -> Event:
        """Returns a BeatmapsetEvent reflecting the given event json object.
        Ignores any event with an incomplete context (e.g. deleted beatmaps).

        Requests user names from the api unless supplied with the corresponding user json from the discussion page."""
        if not event_json:
            # Seems to occur when the respective beatmapset has been deleted. However, it's there when
            # viewing the page source manually for some reason, regardless of login status.
            log_err(
                "WARNING | An event is missing; the beatmapset was probably deleted."
            )
            return None

        try:
            # Scrape object data
            _type = event_json[
                "message_type"] if "message_type" in event_json else types.REPLY
            time = timestamp.from_string(event_json["created_at"])

            # This part only matters in case `event_json` is a post, as we would then be missing some context.
            respective_discussion_json = None
            if discussion_jsons_for_replies:
                for discussion_json in discussion_jsons_for_replies:
                    if discussion_json["id"] == event_json[
                            "beatmapset_discussion_id"]:
                        respective_discussion_json = discussion_json
                        break

                if respective_discussion_json is None:
                    log_err(
                        "WARNING | The parent discussion for a reply is missing; it was probably deleted."
                    )
                    return None

            beatmapset_id = event_json[
                "beatmapset_id"] if "beatmapset_id" in event_json else respective_discussion_json[
                    "beatmapset_id"]
            if discussion_jsons_for_replies:
                discussion_id = event_json["beatmapset_discussion_id"]
            else:
                discussion_id = event_json["starting_post"][
                    "beatmapset_discussion_id"] if "starting_post" in event_json else None

            user_id = event_json["user_id"]
            # The user name is either provided by a user json from the discussion page, or queried through the api.
            user_json = self.__lookup_user_json(user_id, user_jsons)
            user_name = user_json["username"] if user_json else None

            if discussion_jsons_for_replies:
                content = event_json["message"]
            else:
                content = event_json["starting_post"][
                    "message"] if discussion_id else None

            difficulty = event_json["beatmap"][
                "version"] if "beatmap" in event_json and "version" in event_json[
                    "beatmap"] else None
            tab = None
            if "timestamp" in event_json:
                if event_json["timestamp"] is not None: tab = "timeline"
                elif difficulty: tab = "general"
                else: tab = "generalAll"

            # Reconstruct objects
            beatmapset = Beatmapset(beatmapset_id)
            user = User(user_id, user_name) if user_id is not None else None
            # TODO: This portion is missing handling for replies, see the other method.
            # Still unclear which message_type replies use; will need to find out if/when replies get json formats.
            discussion = Discussion(
                discussion_id, beatmapset, user, content, tab,
                difficulty) if discussion_id is not None else None
        except DeletedContextError as err:
            log_err(err)
        else:
            return Event(_type=_type,
                         time=time,
                         beatmapset=beatmapset,
                         discussion=discussion,
                         user=user,
                         content=content)

        return None