class TestUpdateMedias(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.media_fixture = MediaFixture()
        cls.media_fixture.build_media_directory(MEDIA_DIRECTORY_PATH, SUBDIRECTORIES, MEDIA_PATHS)

    @classmethod
    def tearDownClass(cls):
        cls.media_fixture.delete_media_directory(MEDIA_DIRECTORY_PATH)

    def setUp(self):
        self.media_database = MemoryMediaDatabase()
        self.media_finder = MediaFinder(MEDIA_DIRECTORY_PATH, VALID_EXTENSIONS)
        self.media_repository = MediaRepository(self.media_database, self.media_finder)

    def test_when_calling_get_all_medias_before_updating_then_no_medias_are_returned(self):
        medias = self.media_repository.get_all_medias()

        self.assertEqual(len(medias), 0)

    def test_when_calling_get_all_medias_after_updating_then_some_medias_are_returned(self):
        self.media_repository.update()
        medias = self.media_repository.get_all_medias()

        self.assertEqual(len(medias), len(MEDIA_PATHS))

    def test_when_calling_update_after_removing_a_media_then_one_less_media_is_returned(self):
        a_media_filepath = MEDIA_PATHS[0]

        with TemporarilyRemovedFile(a_media_filepath):
            self.media_repository.update()
            medias = self.media_repository.get_all_medias()

            self.assertEqual(len(medias), len(MEDIA_PATHS) - 1)

    def test_when_calling_update_after_adding_a_media_then_one_more_media_is_returned(self):
        a_media_filepath = ANOTHER_MEDIA_PATH

        with TemporarilyAddedFile(a_media_filepath):
            self.media_repository.update()
            medias = self.media_repository.get_all_medias()

            self.assertEqual(len(medias), len(MEDIA_PATHS) + 1)
class TestMediaRepository(unittest.TestCase):
    def setUp(self):
        self.media_database = MemoryMediaDatabase()
        self.media_finder = self.create_mock_media_finder()
        self.media_repository = MediaRepository(self.media_database, self.media_finder)

    def create_mock_media_finder(self):
        media_finder = Mock()
        media_finder.find_medias.return_value = MEDIA_PATHS

        return media_finder

    def test_when_calling_get_all_medias_before_adding_medias_then_no_medias_are_returned(self):
        medias = self.media_repository.get_all_medias()

        self.assertEqual(len(medias), 0)

    def test_when_calling_get_all_medias_after_adding_a_media_then_one_media_is_returned(self):
        a_media = Media(A_MEDIA_ID, A_MEDIA_URI, A_MEDIA_TITLE)
        self.media_repository.add(a_media)
        medias = self.media_repository.get_all_medias()

        self.assertEqual(len(medias), 1)

    def test_when_adding_a_media_twice_then_mediaalreadyexistserror_is_raised(self):
        a_media = Media(A_MEDIA_ID, A_MEDIA_URI, A_MEDIA_TITLE)
        self.media_repository.add(a_media)

        with self.assertRaises(MediaAlreadyExistsError):
            self.media_repository.add(a_media)

    def test_when_adding_a_media_with_an_id_that_already_exists_then_mediaalreadyexistserror_is_raised(self):
        a_media = Media(A_MEDIA_ID, A_MEDIA_URI, A_MEDIA_TITLE)
        another_media = Media(A_MEDIA_ID, ANOTHER_MEDIA_URI, A_MEDIA_TITLE)
        self.media_repository.add(a_media)

        with self.assertRaises(MediaAlreadyExistsError):
            self.media_repository.add(another_media)

    def test_when_adding_a_media_with_an_uri_that_already_exists_then_mediaalreadyexistserror_is_raised(self):
        a_media = Media(A_MEDIA_ID, A_MEDIA_URI, A_MEDIA_TITLE)
        another_media = Media(ANOTHER_MEDIA_ID, A_MEDIA_URI, A_MEDIA_TITLE)
        self.media_repository.add(a_media)

        with self.assertRaises(MediaAlreadyExistsError):
            self.media_repository.add(another_media)

    def test_given_an_existing_media_when_calling_get_by_id_then_same_media_is_returned(self):
        a_media = Media(A_MEDIA_ID, A_MEDIA_URI, A_MEDIA_TITLE)
        self.media_repository.add(a_media)

        self.assertEqual(self.media_repository.get_by_id(A_MEDIA_ID), a_media)

    def test_given_no_medias_when_calling_get_by_id_then_nomediafounderror_is_raised(self):
        with self.assertRaises(NoMediaFoundError):
            self.media_repository.get_by_id(A_NON_EXISTING_ID)

    def test_given_a_media_finder_with_medias_when_calling_update_then_same_amount_of_medias_are_returned(self):
        self.media_repository.update()
        medias = self.media_repository.get_all_medias()

        self.assertEqual(len(medias), len(MEDIA_PATHS))