def test_invalid_constructor_parameters(self):
     """
     Tests using invalid parameter types with the constructor
     :return: None
     """
     source = Id({IdType.MYANIMELIST: 1})
     dest = Id({IdType.MYANIMELIST: 2})
     for parameters in [
         (None, MediaType.ANIME, dest, MediaType.ANIME,
          RelationType.SEQUEL),
         (source, MediaType.ANIME, None, MediaType.ANIME,
          RelationType.SEQUEL),
         (source, MediaType.ANIME, dest, MediaType.ANIME, None),
         (1, MediaType.ANIME, 2, MediaType.ANIME, RelationType.SEQUEL),
         (True, MediaType.ANIME, False, MediaType.ANIME,
          RelationType.SEQUEL),
         (source, MediaType.ANIME, dest, MediaType.ANIME, "SEQUEL"),
         (source, "ANIME", dest, MediaType.ANIME, RelationType.SEQUEL),
         (source, MediaType.ANIME, dest, "MANGA", RelationType.SEQUEL)
     ]:
         try:
             Relation(*parameters)
             self.fail()
         except TypeError:
             pass
    def test_equality(self):
        """
        Tests that the equality of the objects is handled correctly
        :return: None
        """
        id_one = Id({IdType.MYANIMELIST: 1})
        id_two = Id({IdType.MYANIMELIST: 2})
        id_three = Id({IdType.MYANIMELIST: 3})

        one = Relation(id_one, MediaType.ANIME, id_two, MediaType.ANIME,
                       RelationType.SEQUEL)
        two = Relation(id_one, MediaType.ANIME, id_two, MediaType.ANIME,
                       RelationType.SEQUEL)
        three = Relation(id_one, MediaType.ANIME, id_three, MediaType.ANIME,
                         RelationType.SEQUEL)
        four = Relation(id_one, MediaType.ANIME, id_two, MediaType.ANIME,
                        RelationType.ADAPTATION)
        five = Relation(id_one, MediaType.ANIME, id_two, MediaType.MANGA,
                        RelationType.SEQUEL)

        self.assertNotEqual(one, "Test")
        self.assertEqual(one, two)
        self.assertNotEqual(two, three)
        self.assertNotEqual(two, four)
        self.assertNotEqual(three, four)
        self.assertNotEqual(one, five)
Beispiel #3
0
    def __resolve_query_id(self, media_type: MediaType, _id: Id,
                           allow_mal: bool) -> Optional[Tuple[int, IdType]]:
        """
        Calculates the ID value to use in a query
        :param media_type: The media type of the ID
        :param _id: The ID
        :param allow_mal: If True, may return a Myanimelist ID.
                          This will be signified by the second return value
                          being IdType.MYANIMELIST
        :return: A tuple consisting of the ID and the IDs type
        """
        mal_id = _id.get(IdType.MYANIMELIST)
        anilist_id = _id.get(IdType.ANILIST)

        id_type = IdType.ANILIST
        if anilist_id is None:
            query_id = mal_id

            if allow_mal:
                id_type = IdType.MYANIMELIST
            else:
                query_id = self.get_anilist_id_from_mal_id(
                    media_type, query_id)

        else:
            query_id = anilist_id

        if query_id is None:
            return None
        else:
            return query_id, id_type
Beispiel #4
0
 def test_retrieving_non_existant_list_entry(self):
     """
     Tests retrieving entries that are not in a user's list
     Uses very badly rated entries to make sure that they never get added
     to the list, breaking the test
     :return: None
     """
     for media_type, _id in {
         MediaType.ANIME: Id({
             IdType.KITSU: 378,  # Mars of Destruction
             IdType.MYANIMELIST: 413,
             IdType.ANILIST: 413
         }),
         MediaType.MANGA: Id({
             IdType.KITSU: 45257,  # Treasure Hunter Kukai
             IdType.MYANIMELIST: 539,
             IdType.ANILIST: 75257
         }),
     }.items():
         self.assertIsNone(self.api.get_list_entry(
             media_type, _id, self.username
         ))
         self.assertIsNone(self.api.get_user_data(
             media_type, _id, self.username
         ))
 def test_generating_anime_media_list_entry(self):
     """
     Tests generating an anime media list entry object
     :return: None
     """
     data = self.generate_sample_anime_entry()
     self.assertEqual(data.id, Id({IdType.MYANIMELIST: 1}))
     self.assertEqual(data.title, Title({TitleType.ROMAJI: "Test"}))
     self.assertEqual(data.relations, [
         Relation(Id({IdType.MYANIMELIST: 1}), MediaType.ANIME,
                  Id({IdType.MYANIMELIST: 2}), MediaType.MANGA,
                  RelationType.SEQUEL)
     ])
     self.assertEqual(data.releasing_status, ReleasingStatus.FINISHED)
     self.assertEqual(data.releasing_start, Date(2018, 1, 1))
     self.assertEqual(data.releasing_end, Date(2018, 4, 4))
     self.assertEqual(data.episode_count, 12)
     self.assertEqual(data.episode_duration, 25)
     self.assertEqual(data.cover_url, "https://example.com/image.png")
     self.assertEqual(data.username, "namboy94")
     self.assertEqual(data.score, Score(55, ScoreType.PERCENTAGE))
     self.assertEqual(data.consuming_status, ConsumingStatus.COMPLETED)
     self.assertEqual(data.episode_progress, 12)
     self.assertEqual(data.consuming_start, Date(2018, 1, 1))
     self.assertEqual(data.consuming_end, Date(2018, 4, 4))
     self.assertEqual(data.media_type, MediaType.ANIME)
Beispiel #6
0
    def test_serialization(self):
        """
        Tests serializing an ID object
        :return: None
        """
        ob = Id({IdType.MYANIMELIST: 1, IdType.ANILIST: 2})
        data = ob.serialize()

        self.assertEqual(data, {"MYANIMELIST": 1, "ANILIST": 2, "KITSU": None})
Beispiel #7
0
 def test_string_representation(self):
     """
     Tests that the string representation is correct
     :return: None
     """
     _id = Id({IdType.MYANIMELIST: 1, IdType.ANILIST: 2})
     representation = str(_id)
     serialised = json.loads(representation)
     self.assertEqual(_id, Id.deserialize(serialised))
Beispiel #8
0
 def test_unfilled_entries(self):
     """
     Tests that unfilled ID entries lead to Null values for the respective
     IDs
     :return: None
     """
     _id = Id({IdType.MYANIMELIST: 1})
     self.assertEqual(1, _id.get(IdType.MYANIMELIST))
     self.assertEqual(None, _id.get(IdType.ANILIST))
     self.assertEqual(None, _id.get(IdType.KITSU))
Beispiel #9
0
 def test_fetching_different_id_types(self):
     """
     Tests generating an ID using the constructor and fetching the
     different IDs
     :return: None
     """
     _id = Id({IdType.MYANIMELIST: 1, IdType.ANILIST: 2, IdType.KITSU: 3})
     self.assertEqual(1, _id.get(IdType.MYANIMELIST))
     self.assertEqual(2, _id.get(IdType.ANILIST))
     self.assertEqual(3, _id.get(IdType.KITSU))
 def test_string_representation(self):
     """
     Tests that the string representation is correct
     :return: None
     """
     source = Id({IdType.MYANIMELIST: 1})
     dest = Id({IdType.MYANIMELIST: 2})
     relation = Relation(source, MediaType.ANIME, dest, MediaType.ANIME,
                         RelationType.SEQUEL)
     representation = str(relation)
     serialised = json.loads(representation)
     self.assertEqual(relation, Relation.deserialize(serialised))
 def generate_sample_manga_data() -> MangaData:
     """
     Generates a generic MangaData object
     :return: The generated manga data object
     """
     return MangaData(Id(
         {IdType.MYANIMELIST: 1}), Title({TitleType.ROMAJI: "Test"}), [
             Relation(Id({IdType.MYANIMELIST: 1}), MediaType.MANGA,
                      Id({IdType.MYANIMELIST: 2}), MediaType.MANGA,
                      RelationType.SEQUEL)
         ], ReleasingStatus.FINISHED, Date(2018, 1, 1), Date(2018, 4, 4),
                      "https://example.com/image.png", 100, 10)
Beispiel #12
0
 def test_deserialization(self):
     """
     Tests deserializing an ID object
     :return: None
     """
     self.assertEqual(Id.deserialize({
         "MYANIMELIST": 1,
         "ANILIST": 2
     }), Id({
         IdType.MYANIMELIST: 1,
         IdType.ANILIST: 2
     }))
Beispiel #13
0
    def test_equality(self):
        """
        Tests that the equality of the objects is handled correctly
        :return: None
        """
        one = Id({IdType.MYANIMELIST: 1, IdType.ANILIST: 2})
        two = Id({IdType.MYANIMELIST: 1, IdType.ANILIST: 2})
        three = Id({IdType.MYANIMELIST: 1})

        self.assertEqual(one, two)
        self.assertNotEqual(two, three)

        self.assertNotEqual(one, "Test")
Beispiel #14
0
    def test_caching_anime(self):
        """
        Tests that the caching works correctly for media data
        :return: None
        """
        self.api.cache = Cache(self.cache.cache_location)
        for media_type, english, _id in [
            (MediaType.ANIME, "Steins;Gate",
             Id({
                 IdType.KITSU: 5646,
                 IdType.MYANIMELIST: 9253,
                 IdType.ANILIST: 9253
             })),
            (MediaType.MANGA, "Spice & Wolf",
             Id({
                 IdType.MYANIMELIST: 9115,
                 IdType.KITSU: 18471,
                 IdType.ANILIST: 39115
             }))
        ]:
            fetched_entry = self.api.get_list_entry(
                media_type, _id, self.username
            )
            fetched_data = self.api.get_data(media_type, _id)
            cached_entry = self.api.cache.get_media_list_entry(
                self.api.id_type, media_type, _id, self.username
            )
            cached_data = self.api.cache.get_media_data(
                self.api.id_type, media_type, _id
            )
            self.assertEqual(
                fetched_data.title.get(TitleType.ENGLISH), english
            )
            self.assertEqual(
                fetched_entry.title.get(TitleType.ENGLISH), english
            )
            self.assertEqual(fetched_data, cached_data)
            self.assertEqual(fetched_entry, cached_entry)

            def raise_value_error():
                raise ValueError()

            # Makes sure that cached value is used from now on
            with mock.patch("requests.post", new=raise_value_error):
                with mock.patch("requests.get", new=raise_value_error):
                    new_fetched_data = self.api.get_data(media_type, _id)
                    new_fetched_entry = self.api.get_list_entry(
                        media_type, _id, self.username
                    )
                    self.assertEqual(new_fetched_data, cached_data)
                    self.assertEqual(new_fetched_entry, cached_entry)
Beispiel #15
0
    def test_setting_invalid_ids(self):
        """
        Tests setting ids that are invalid types
        :return: None
        """
        _id = Id({IdType.MYANIMELIST: 1})

        for value in [None, "100", 100.0, True]:
            try:
                # noinspection PyTypeChecker
                _id.set(value, IdType.ANILIST)
                self.fail()
            except TypeError:
                pass
    def test_equality(self):
        """
        Tests that the equality of the objects is handled correctly
        :return: None
        """
        one = self.generate_sample_anime_entry()
        two = self.generate_sample_anime_entry()

        self.assertEqual(one, two)

        two.id = Id({IdType.KITSU: 1})
        self.assertNotEqual(one, two)
        two = self.generate_sample_anime_entry()

        two.releasing_start = None
        self.assertNotEqual(one, two)
        two = self.generate_sample_anime_entry()

        two.username = "******"
        self.assertNotEqual(one, two)
        two = self.generate_sample_anime_entry()

        two.consuming_end = None
        self.assertNotEqual(one, two)

        self.assertNotEqual(one, self.generate_sample_manga_entry())
Beispiel #17
0
    def _get_common_deserialized_components(
            cls,
            data: Dict[str, Optional[str or int or float or bool or
                                     Dict or List or Tuple or Set]]) \
            -> Dict[str, Optional[str or int or float or bool or
                                  Dict or List or Tuple or Set]]:
        """
        Deserializes the common child components of the data dictionary
        :param data: The data to deserialize
        :return: The deserialized dictionary
        """
        deserialized = {
            "media_type":
            MediaType[data["media_type"]],
            "id":
            Id.deserialize(data["id"]),
            "title":
            Title.deserialize(data["title"]),
            "relations":
            list(map(lambda x: Relation.deserialize(x), data["relations"])),
            "releasing_status":
            ReleasingStatus[data["releasing_status"]],
            "cover_url":
            data["cover_url"]
        }

        for date in ["releasing_start", "releasing_end"]:
            date_data = data[date]
            if date_data is not None:
                deserialized[date] = Date.deserialize(date_data)
            else:
                deserialized[date] = None

        return deserialized
    def _get_common_deserialized_components(
            cls,
            data: Dict[str, Optional[str or int or float or bool or
                                     Dict or List or Tuple or Set]]) \
            -> Dict[str, Optional[str or int or float or bool or
                                  Dict or List or Tuple or Set]]:
        """
        Deserializes the common child components of the data dictionary
        :param data: The data to deserialize
        :return: The deserialized dictionary
        """
        deserialized = {
            "media_id": Id.deserialize(data["media_id"]),
            "media_type": MediaType[data["media_type"]],
            "username": data["username"],
            "score": Score.deserialize(data["score"]),
            "consuming_status": ConsumingStatus[data["consuming_status"]]
        }

        for date in ["consuming_start", "consuming_end"]:
            if data[date] is not None:
                deserialized[date] = Date.deserialize(data[date])
            else:
                deserialized[date] = None

        return deserialized
    def test_invalid_deserialization(self):
        """
        Tests that invalid serialized data raises ValueErrors when deserialized
        :return: None
        """
        def attempt_deserialize(media_cls: type(MediaType), data: dict):
            try:
                media_cls.deserialize(data)
                self.fail()
            except (ValueError, TypeError):
                pass

        for media_class, sample in [
            (AnimeData, self.generate_sample_serialized_anime_data()),
            (MangaData, self.generate_sample_serialized_manga_data())
        ]:
            for key, value in sample.items():

                for faux_value in [2000, "Hello", Id({IdType.KITSU: 1})]:
                    if type(faux_value) != type(value):
                        copy = deepcopy(sample)
                        copy[key] = faux_value
                        attempt_deserialize(media_class, copy)

                copy = deepcopy(sample)
                copy.pop(key)
                attempt_deserialize(media_class, copy)
Beispiel #20
0
    def test_loading_and_retrieving_cache(self):
        """
        Tests writing some data into the cache and then reloading it
        in a different Cache object
        :return: None
        """
        entry = TestMediaListEntry.generate_sample_anime_entry()
        one = entry.id
        two = Id({IdType.MYANIMELIST: 2})
        user = entry.username

        self.cache.add(IdType.MYANIMELIST, entry.get_media_data())
        self.cache.add(IdType.MYANIMELIST, entry.get_user_data())

        entry.id = two
        self.cache.add(IdType.MYANIMELIST, entry)

        self.cache.write()
        new_cache = Cache("testdir/.cache")

        for cache in [self.cache, new_cache]:
            for _id in [one, two]:
                entry.id = _id
                self.assertEqual(
                    cache.get_media_data(IdType.MYANIMELIST, MediaType.ANIME,
                                         _id), entry.get_media_data())
                self.assertEqual(
                    cache.get_media_user_data(IdType.MYANIMELIST,
                                              MediaType.ANIME, _id, user),
                    entry.get_user_data())
                self.assertEqual(
                    cache.get_media_list_entry(IdType.MYANIMELIST,
                                               MediaType.ANIME, _id, user),
                    entry)
 def generate_sample_manga_user_data() -> MangaUserData:
     """
     Generates a sample MangaUserData object
     :return: The generated MangaUserData object
     """
     return MangaUserData(Id({IdType.MYANIMELIST: 1}), "namboy94",
                          Score(55, ScoreType.PERCENTAGE),
                          ConsumingStatus.COMPLETED, Date(2018, 1, 1),
                          Date(2018, 4, 4), 100, 10)
Beispiel #22
0
 def __generate_id_obj(self, _id: int or Id) -> Id:
     """
     Generates an Id object if the given ID is an integer
     :param _id: The ID to make sure is an Id object
     :return: The generated Id object
     """
     if isinstance(_id, int):
         _id = Id({self.id_type: _id})
     return _id
Beispiel #23
0
 def test_invalid_deserialization(self):
     """
     Tests that invalid serialized data raises ValueErrors when deserialized
     :return: None
     """
     for data in [{
             "A": 1
     }, {}, {
             "ANILIST": "1"
     }, {
             "Anilist": 1
     }, {
             "ANILIST": None
     }, []]:
         try:
             Id.deserialize(data)
             self.fail()
         except (TypeError, ValueError):
             pass
Beispiel #24
0
 def _deserialize(cls, data: Dict[
     str,
     Optional[str
              or int or float or bool or Dict or List or Tuple or Set]]):
     """
     Deserializes a dictionary into an object of this type
     :param data: The data to deserialize
     :return: The deserialized object
     :raises TypeError: If a type error occurred
     :raises ValueError: If the data could not be deserialized
     """
     source = Id.deserialize(data["source"])
     source_type = MediaType[data["source_type"]]
     dest = Id.deserialize(data["dest"])
     dest_type = MediaType[data["dest_type"]]
     relation_type = RelationType[data["type"]]
     generated = cls(source, source_type, dest, dest_type,
                     relation_type)  # type: Relation
     return generated
Beispiel #25
0
    def test_retrieving_data(self):
        """
        Tests retrieving a data, user data and list entries for both anime
        and manga
        :return: None
        """
        for media_type, english, _id in [
            (MediaType.ANIME, "Steins;Gate",
             Id({
                 IdType.KITSU: 5646,
                 IdType.MYANIMELIST: 9253,
                 IdType.ANILIST: 9253
             })),
            (MediaType.MANGA, "Spice & Wolf",
             Id({
                 IdType.MYANIMELIST: 9115,
                 IdType.KITSU: 18471,
                 IdType.ANILIST: 39115
             }))
        ]:
            media_data = self.api.get_data(media_type, _id)
            user_data = self.api.get_user_data(media_type, _id, self.username)
            entry = self.api.get_list_entry(media_type, _id, self.username)

            self.assertEqual(
                media_data.id.get(self.api.id_type),
                _id.get(self.api.id_type)
            )
            self.assertEqual(
                user_data.id.get(self.api.id_type),
                _id.get(self.api.id_type)
            )
            self.assertEqual(
                entry.id.get(self.api.id_type),
                _id.get(self.api.id_type)
            )

            self.assertEqual(media_data.title.get(TitleType.ENGLISH), english)
            self.assertEqual(entry.title.get(TitleType.ENGLISH), english)

            self.assertEqual(media_data, entry.get_media_data())
            self.assertEqual(user_data, entry.get_user_data())
 def test_generating_manga_data(self):
     """
     Tests generating a manga data object
     :return: None
     """
     data = self.generate_sample_manga_data()
     self.assertEqual(data.id, Id({IdType.MYANIMELIST: 1}))
     self.assertEqual(data.title, Title({TitleType.ROMAJI: "Test"}))
     self.assertEqual(data.relations, [
         Relation(Id({IdType.MYANIMELIST: 1}), MediaType.MANGA,
                  Id({IdType.MYANIMELIST: 2}), MediaType.MANGA,
                  RelationType.SEQUEL)
     ])
     self.assertEqual(data.releasing_status, ReleasingStatus.FINISHED)
     self.assertEqual(data.releasing_start, Date(2018, 1, 1))
     self.assertEqual(data.releasing_end, Date(2018, 4, 4))
     self.assertEqual(data.chapter_count, 100)
     self.assertEqual(data.volume_count, 10)
     self.assertEqual(data.cover_url, "https://example.com/image.png")
     self.assertEqual(data.media_type, MediaType.MANGA)
Beispiel #27
0
 def test_invalid_constructor_parameters(self):
     """
     Tests using invalid parameter types with the constructor
     :return: None
     """
     for parameters in [([], ), (100, )]:
         try:
             Id(*parameters)
             self.fail()
         except TypeError:
             pass
Beispiel #28
0
 def test_no_entries(self):
     """
     Tests that the constructor raises a ValueError when no ID at all is
     provided
     :return: None
     """
     try:
         Id({})
         self.fail()
     except ValueError:
         pass
Beispiel #29
0
 def test_no_valid_entries(self):
     """
     Tests that providing None values as the only IDs still result in
     a ValueError
     :return: None
     """
     try:
         # noinspection PyTypeChecker
         Id({IdType.MYANIMELIST: None})
         self.fail()
     except ValueError:
         pass
Beispiel #30
0
    def test_getting_fresh_data(self):
        """
        Tests retrieving fresh data
        :return: None
        """
        self.api.cache.expiration = 6000
        _id = Id({
             IdType.KITSU: 5646,
             IdType.MYANIMELIST: 9253,
             IdType.ANILIST: 9253
         })

        media_data = self.api.get_anime_data(_id)
        user_data = self.api.get_anime_user_data(_id, self.username)
        original_media = deepcopy(media_data)
        original_user = deepcopy(user_data)

        self.assertEqual(
            self.api.cache.get_media_data(
                self.api.id_type, MediaType.ANIME, _id
            ),
            media_data
        )
        self.assertEqual(
            self.api.cache.get_media_user_data(
                self.api.id_type, MediaType.ANIME, _id, self.username
            ),
            user_data
        )

        media_data.title.set("Test", TitleType.ENGLISH)
        user_data.score = Score(0, ScoreType.PERCENTAGE)
        self.api.cache.add(self.api.id_type, media_data)
        self.api.cache.add(self.api.id_type, user_data)

        self.assertNotEqual(original_media, media_data)
        self.assertNotEqual(original_user, user_data)

        self.assertEqual(media_data, self.api.get_anime_data(_id))
        self.assertEqual(
            user_data, self.api.get_anime_user_data(_id, self.username)
        )

        fresh_media = self.api.get_anime_data(_id, True)
        fresh_user = self.api.get_anime_user_data(_id, self.username, True)

        self.assertNotEqual(fresh_media, media_data)
        self.assertEqual(fresh_media, original_media)
        self.assertNotEqual(fresh_user, user_data)
        self.assertEqual(fresh_user, original_user)