def test_delete__episodes_in_another_podcast__ok( self, client, episode_data, user, mocked_s3, dbs ): dbs = dbs podcast_1 = await_(Podcast.async_create(dbs, **get_podcast_data(created_by_id=user.id))) episode_data["status"] = Episode.Status.PUBLISHED episode_data["podcast_id"] = podcast_1.id episode_1 = await_(Episode.async_create(dbs, **episode_data)) episode_1_1 = await_(Episode.async_create(dbs, **get_episode_data(podcast_1, "published"))) podcast_2 = await_(Podcast.async_create(dbs, **get_podcast_data())) episode_data["status"] = Episode.Status.PUBLISHED episode_data["podcast_id"] = podcast_2.id # creating episode with same `source_id` in another podcast episode_2 = await_(Episode.async_create(dbs, **episode_data)) await_(dbs.commit()) client.login(user) url = self.url.format(id=podcast_1.id) response = client.delete(url) assert response.status_code == 200 assert await_(Podcast.async_get(dbs, id=podcast_1.id)) is None assert await_(Episode.async_get(dbs, id=episode_1.id)) is None assert await_(Podcast.async_get(dbs, id=podcast_2.id)) is not None assert await_(Episode.async_get(dbs, id=episode_2.id)) is not None mocked_s3.delete_files_async.assert_called_with([episode_1_1.file_name])
def test_generate__several_podcasts__ok(self, user, mocked_s3, dbs): podcast_1 = await_(Podcast.async_create(dbs, **get_podcast_data())) podcast_2 = await_(Podcast.async_create(dbs, **get_podcast_data())) await_(dbs.commit()) generate_rss_task = tasks.GenerateRSSTask(db_session=dbs) result_code = await_(generate_rss_task.run(podcast_1.id, podcast_2.id)) assert result_code == FinishCode.OK for podcast in [podcast_1, podcast_2]: expected_file_path = mocked_s3.tmp_upload_dir / f"{podcast.publish_id}.xml" assert os.path.exists( expected_file_path ), f"File {expected_file_path} didn't uploaded"
def test_filter_by_status__ok(self, client, user, episode_data, mocked_redis, dbs): podcast_1 = await_( Podcast.async_create(dbs, **get_podcast_data(created_by_id=user.id))) podcast_2 = await_( Podcast.async_create(dbs, **get_podcast_data(created_by_id=user.id))) episode_data["created_by_id"] = user.id p1_episode_new = create_episode(dbs, episode_data, podcast_1, STATUS.NEW, MB_1) p1_episode_down = create_episode(dbs, episode_data, podcast_1, STATUS.DOWNLOADING, MB_2) p2_episode_down = create_episode(dbs, episode_data, podcast_2, STATUS.DOWNLOADING, MB_4) # p2_episode_new create_episode(dbs, episode_data, podcast_2, STATUS.NEW, MB_1) mocked_redis.async_get_many.return_value = mocked_redis.async_return({ p1_episode_new.file_name.partition(".")[0]: { "status": EpisodeStatus.DL_PENDING, "processed_bytes": 0, "total_bytes": MB_1, }, p1_episode_down.file_name.partition(".")[0]: { "status": EpisodeStatus.DL_EPISODE_DOWNLOADING, "processed_bytes": MB_1, "total_bytes": MB_2, }, p2_episode_down.file_name.partition(".")[0]: { "status": EpisodeStatus.DL_EPISODE_DOWNLOADING, "processed_bytes": MB_1, "total_bytes": MB_4, }, }) client.login(user) response = client.get(self.url) response_data = self.assert_ok_response(response) assert response_data == [ _progress(podcast_2, p2_episode_down, current_size=MB_1, completed=25.0), _progress(podcast_1, p1_episode_down, current_size=MB_1, completed=50.0), ]
def test_delete__same_episode_exists__ok( self, client, podcast, episode_data, mocked_s3, same_episode_status, delete_called, dbs, ): source_id = get_video_id() user_1 = create_user(dbs) user_2 = create_user(dbs) podcast_1 = await_( Podcast.async_create(dbs, db_commit=True, **get_podcast_data(created_by_id=user_1.id))) podcast_2 = await_( Podcast.async_create(dbs, db_commit=True, **get_podcast_data(created_by_id=user_2.id))) episode_data["created_by_id"] = user_1.id _ = create_episode(dbs, episode_data, podcast_1, status=same_episode_status, source_id=source_id) episode_data["created_by_id"] = user_2.id episode_2 = create_episode(dbs, episode_data, podcast_2, status=Episode.Status.NEW, source_id=source_id) url = self.url.format(id=episode_2.id) client.login(user_2) response = client.delete(url) assert response.status_code == 204, f"Delete API is not available: {response.text}" assert await_(Episode.async_get(dbs, id=episode_2.id)) is None if delete_called: mocked_s3.delete_files_async.assert_called_with( [episode_2.file_name]) else: assert not mocked_s3.delete_files_async.called
def test_create__same_episode_in_other_podcast__ok( self, podcast, episode, user, mocked_youtube, dbs ): mocked_youtube.extract_info.return_value = { "id": episode.source_id, "title": "Updated title", "description": "Updated description", "webpage_url": "https://new.watch.site/updated/", "thumbnail": "https://link.to.image/updated/", "uploader": "Updated author", "duration": 123, } new_podcast = await_(Podcast.async_create(dbs, db_commit=True, **get_podcast_data())) episode_creator = EpisodeCreator( dbs, podcast_id=new_podcast.id, source_url=episode.watch_url, user_id=user.id, ) new_episode: Episode = await_(episode_creator.create()) assert episode is not None assert new_episode.id != episode.id assert new_episode.source_id == episode.source_id assert new_episode.watch_url == "https://new.watch.site/updated/" assert new_episode.title == "Updated title" assert new_episode.description == "Updated description" assert new_episode.image_url == "https://link.to.image/updated/" assert new_episode.author == "Updated author" assert new_episode.length == 123
def test_get_list__filter_by_created_by__ok(self, client, dbs): user_1 = create_user(dbs) user_2 = create_user(dbs) podcast_data = get_podcast_data() podcast_data["created_by_id"] = user_1.id await_(Podcast.async_create(dbs, db_commit=True, **podcast_data)) podcast_data = get_podcast_data() podcast_data["created_by_id"] = user_2.id podcast_2 = await_(Podcast.async_create(dbs, db_commit=True, **podcast_data)) client.login(user_2) response = client.get(self.url) response_data = self.assert_ok_response(response) assert response_data == [_podcast(podcast_2)]
def test_get_list__check_episodes_count__ok(self, client, user, loop, dbs): dbs = dbs podcast_1 = await_(Podcast.async_create(dbs, **get_podcast_data(created_by_id=user.id))) create_episode(dbs, get_episode_data(), podcast_1) create_episode(dbs, get_episode_data(), podcast_1) podcast_2 = await_(Podcast.async_create(dbs, **get_podcast_data(created_by_id=user.id))) create_episode(dbs, get_episode_data(), podcast_2) client.login(user) response = client.get(self.url) response_data = self.assert_ok_response(response) expected_episodes_counts = {podcast_1.id: 2, podcast_2.id: 1} actual_episodes_counts = { podcast["id"]: podcast["episodes_count"] for podcast in response_data } assert expected_episodes_counts == actual_episodes_counts
def test_generate__single_podcast__ok(self, user, mocked_s3, dbs): podcast_1: Podcast = await_( Podcast.async_create(dbs, **get_podcast_data())) podcast_2: Podcast = await_( Podcast.async_create(dbs, **get_podcast_data())) episode_data = get_episode_data(podcast_1, creator=user) episode_data["status"] = Episode.Status.NEW episode_new = await_(Episode.async_create(dbs, **episode_data)) episode_data = get_episode_data(podcast_1, creator=user) episode_data["status"] = Episode.Status.DOWNLOADING episode_downloading = await_(Episode.async_create(dbs, **episode_data)) episode_data = get_episode_data(podcast_1, creator=user) episode_data["status"] = Episode.Status.PUBLISHED episode_data["published_at"] = datetime.now() episode_published = await_(Episode.async_create(dbs, **episode_data)) episode_data = get_episode_data(podcast_2, creator=user) episode_data["status"] = Episode.Status.PUBLISHED episode_podcast_2 = await_(Episode.async_create(dbs, **episode_data)) await_(dbs.commit()) expected_file_path = mocked_s3.tmp_upload_dir / f"{podcast_1.publish_id}.xml" generate_rss_task = tasks.GenerateRSSTask(db_session=dbs) result_code = await_(generate_rss_task.run(podcast_1.id)) assert result_code == FinishCode.OK assert os.path.exists( expected_file_path), f"File {expected_file_path} didn't uploaded" with open(expected_file_path) as file: generated_rss_content = file.read() assert episode_published.title in generated_rss_content assert episode_published.description in generated_rss_content assert episode_published.file_name in generated_rss_content for episode in [episode_new, episode_downloading, episode_podcast_2]: assert episode.source_id not in generated_rss_content, f"{episode} in RSS {podcast_1}" podcast_1 = await_(Podcast.async_get(dbs, id=podcast_1.id)) assert podcast_1.rss_link == str(expected_file_path)
def test_filter_by_user__ok(self, client, episode_data, mocked_redis, dbs): user_1 = create_user(dbs) user_2 = create_user(dbs) podcast_1 = await_( Podcast.async_create(dbs, **get_podcast_data(created_by_id=user_1.id))) podcast_2 = await_( Podcast.async_create(dbs, **get_podcast_data(created_by_id=user_2.id))) ep_data_1 = get_episode_data(creator=user_1) ep_data_2 = get_episode_data(creator=user_2) p1_episode_down = create_episode(dbs, ep_data_1, podcast_1, STATUS.DOWNLOADING, MB_2) p2_episode_down = create_episode(dbs, ep_data_2, podcast_2, STATUS.DOWNLOADING, MB_4) await_(dbs.commit()) mocked_redis.async_get_many.return_value = mocked_redis.async_return({ p1_episode_down.file_name.partition(".")[0]: { "status": EpisodeStatus.DL_EPISODE_DOWNLOADING, "processed_bytes": MB_1, "total_bytes": MB_2, }, p2_episode_down.file_name.partition(".")[0]: { "status": EpisodeStatus.DL_EPISODE_DOWNLOADING, "processed_bytes": MB_1, "total_bytes": MB_4, }, }) client.login(user_1) response = client.get(self.url) response_data = self.assert_ok_response(response) assert response_data == [ _progress(podcast_1, p1_episode_down, current_size=MB_1, completed=50.0), ]
def test_download_episode__file_correct__ignore( self, episode_data, podcast_data, mocked_youtube, mocked_ffmpeg, mocked_s3, mocked_generate_rss_task, dbs, ): podcast_1 = await_(Podcast.async_create(dbs, **get_podcast_data())) podcast_2 = await_(Podcast.async_create(dbs, **get_podcast_data())) episode_data.update({ "status": "published", "source_id": mocked_youtube.video_id, "watch_url": mocked_youtube.watch_url, "file_size": 1024, "podcast_id": podcast_1.id, }) await_(Episode.async_create(dbs, **episode_data)) episode_data["status"] = "new" episode_data["podcast_id"] = podcast_2.id episode_2 = await_(Episode.async_create(dbs, **episode_data)) await_(dbs.commit()) mocked_s3.get_file_size.return_value = episode_2.file_size result = await_(DownloadEpisodeTask(db_session=dbs).run(episode_2.id)) await_(dbs.refresh(episode_2)) mocked_generate_rss_task.run.assert_called_with( podcast_1.id, podcast_2.id) assert result == FinishCode.SKIP assert not mocked_youtube.download.called assert not mocked_ffmpeg.called assert episode_2.status == Episode.Status.PUBLISHED assert episode_2.published_at == episode_2.created_at
def test_create__same_episode__extract_failed__ok( self, podcast, episode, user, mocked_youtube, dbs ): mocked_youtube.extract_info.side_effect = ExtractorError("Something went wrong here") new_podcast = await_(Podcast.async_create(dbs, **get_podcast_data())) episode_creator = EpisodeCreator( dbs, podcast_id=new_podcast.id, source_url=episode.watch_url, user_id=user.id, ) new_episode: Episode = await_(episode_creator.create()) assert episode is not None assert new_episode.id != episode.id assert new_episode.source_id == episode.source_id assert new_episode.watch_url == episode.watch_url
def podcast(podcast_data, user, loop, dbs): podcast_data["created_by_id"] = user.id podcast = loop.run_until_complete(Podcast.async_create( dbs, **podcast_data)) loop.run_until_complete(dbs.commit()) return podcast