From bcf45f7f7e4e1cdfa46f6ce61486753841af78c9 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Wed, 10 Aug 2022 12:16:38 -0700 Subject: [PATCH] [REFACTOR] Use JSON files instead of hard-coded classes for expected downloads (#165) * Expected download summaries WIP * jesse/fix-tests * working * tests passing * remove fixture usage * fix ignore md5 logic --- .../downloaders/youtube/split_video.py | 15 +- tests/e2e/expected_download.py | 114 ++++++++-- tests/e2e/plugins/test_nfo_tags.py | 1 - .../test_soundcloud_discography.json | 19 ++ .../youtube/test_channel_full.json | 42 ++++ .../test_channel_no_additional_downloads.json | 6 + .../youtube/test_channel_recent.json | 12 + .../youtube/test_channel_rolling_recent.json | 9 + .../youtube/test_merge_playlist.json | 5 + .../youtube/test_playlist.json | 12 + .../youtube/test_split_video.json | 20 ++ .../youtube/test_video.json | 5 + .../test_video_with_chapter_timestamps.json | 5 + .../plugins/test_kodi_safe_xml.txt | 6 +- .../youtube/test_channel_full.txt | 54 ++--- .../youtube/test_channel_recent.txt | 12 +- .../youtube/test_channel_rolling_recent.txt | 6 +- .../youtube/test_video.txt | 6 +- .../test_video_with_chapter_timestamps.txt | 6 +- .../soundcloud/test_soundcloud_discography.py | 49 +--- tests/e2e/youtube/test_channel.py | 211 ++++-------------- tests/e2e/youtube/test_merge_playlist.py | 40 ++-- tests/e2e/youtube/test_playlist.py | 71 +++--- tests/e2e/youtube/test_split_video.py | 49 +--- tests/e2e/youtube/test_video.py | 63 ++---- 25 files changed, 397 insertions(+), 441 deletions(-) create mode 100644 tests/e2e/resources/expected_downloads_summaries/soundcloud/test_soundcloud_discography.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json create mode 100644 tests/e2e/resources/expected_downloads_summaries/youtube/test_video_with_chapter_timestamps.json diff --git a/src/ytdl_sub/downloaders/youtube/split_video.py b/src/ytdl_sub/downloaders/youtube/split_video.py index 5a2e545d..c113af63 100644 --- a/src/ytdl_sub/downloaders/youtube/split_video.py +++ b/src/ytdl_sub/downloaders/youtube/split_video.py @@ -161,7 +161,8 @@ class YoutubeSplitVideoDownloader( entry = YoutubeVideo(entry_dict=entry_dict, working_directory=self.working_directory) # convert the entry thumbnail early so we do not have to guess the thumbnail extension # when copying it - convert_download_thumbnail(entry=entry) + if not self.is_dry_run: + convert_download_thumbnail(entry=entry) for idx, title in enumerate(chapters.titles): new_uid = _split_video_uid(source_uid=entry.uid, idx=idx) @@ -181,12 +182,12 @@ class YoutubeSplitVideoDownloader( ) ) - # Copy the original vid thumbnail to the working directory with the new uid. This so - # downstream logic thinks this split video has its own thumbnail - FileHandler.copy( - src_file_path=entry.get_download_thumbnail_path(), - dst_file_path=Path(self.working_directory) / f"{new_uid}.{entry.thumbnail_ext}", - ) + # Copy the original vid thumbnail to the working directory with the new uid. This so + # downstream logic thinks this split video has its own thumbnail + FileHandler.copy( + src_file_path=entry.get_download_thumbnail_path(), + dst_file_path=Path(self.working_directory) / f"{new_uid}.{entry.thumbnail_ext}", + ) # Format the split video as a YoutubePlaylistVideo split_videos_and_metadata.append( diff --git a/tests/e2e/expected_download.py b/tests/e2e/expected_download.py index d327444c..657422c5 100644 --- a/tests/e2e/expected_download.py +++ b/tests/e2e/expected_download.py @@ -1,19 +1,33 @@ import hashlib +import json import os.path from dataclasses import dataclass from pathlib import Path from typing import List from typing import Optional -from typing import Union -from ytdl_sub.utils.file_handler import FileMetadata +_EXPECTED_DOWNLOADS_SUMMARY_PATH = Path("tests/e2e/resources/expected_downloads_summaries") + + +def _get_files_in_directory(relative_directory: Path | str) -> List[Path]: + relative_file_paths: List[Path] = [] + for path in Path(relative_directory).rglob("*"): + if path.is_file(): + relative_path = Path(*path.parts[3:]) + relative_file_paths.append(relative_path) + + return relative_file_paths + + +def _get_file_md5_hash(full_file_path: Path | str) -> str: + with open(full_file_path, "rb") as file: + return hashlib.md5(file.read()).hexdigest() @dataclass class ExpectedDownloadFile: path: Path - md5: Optional[Union[str, List[str]]] = None - metadata: Optional[FileMetadata] = None + md5: str class ExpectedDownloads: @@ -35,21 +49,21 @@ class ExpectedDownloads: def contains(self, relative_path: Path) -> bool: return sum(relative_path == download.path for download in self.expected_downloads) == 1 - def assert_files_exist(self, relative_directory: Path): + def assert_files_exist( + self, relative_directory: str | Path, ignore_md5_hashes_for: Optional[List[str]] = None + ): """ Assert each expected file exists and that its respective md5 hash matches. """ - num_files = 0 - for path in Path(relative_directory).rglob("*"): - if path.is_file(): - num_files += 1 + if ignore_md5_hashes_for is None: + ignore_md5_hashes_for = [] - relative_path = Path(*path.parts[3:]) - assert self.contains( - relative_path - ), f"File {relative_path} was created but not expected" + relative_file_paths = _get_files_in_directory(relative_directory=relative_directory) - assert num_files == self.file_count, "Mismatch in number of created files" + for file_path in relative_file_paths: + assert self.contains(file_path), f"File {file_path} was created but not expected" + + assert len(relative_file_paths) == self.file_count, "Mismatch in number of created files" for expected_download in self.expected_downloads: full_path = Path(relative_directory) / expected_download.path @@ -57,17 +71,69 @@ class ExpectedDownloads: full_path ), f"Expected {str(expected_download.path)} to be a file but it is not" - if expected_download.md5 is None: + if str(expected_download.path) in ignore_md5_hashes_for: continue - with open(full_path, "rb") as file: - md5_hash = hashlib.md5(file.read()).hexdigest() - - expected_md5_hash = expected_download.md5 - if isinstance(expected_download.md5, str): - expected_md5_hash = [expected_download.md5] - - assert md5_hash in expected_md5_hash, ( + md5_hash = _get_file_md5_hash(full_file_path=full_path) + assert md5_hash in expected_download.md5, ( f"MD5 hash for {str(expected_download.path)} does not match: " - f"{md5_hash} != {expected_md5_hash}" + f"{md5_hash} != {expected_download.md5}" ) + + @classmethod + def from_dict(cls, expected_downloads_dict) -> "ExpectedDownloads": + expected_downloads: List[ExpectedDownloadFile] = [] + for file_path, md5_hash in expected_downloads_dict.items(): + expected_downloads.append(ExpectedDownloadFile(path=Path(file_path), md5=md5_hash)) + + return cls(expected_downloads=expected_downloads) + + @classmethod + def from_file(cls, file_path: str | Path) -> "ExpectedDownloads": + with open(file_path, mode="r", encoding="utf-8") as file: + expected_downloads_dict = json.load(file) + return cls.from_dict(expected_downloads_dict) + + @classmethod + def from_directory(cls, directory_path: str | Path) -> "ExpectedDownloads": + relative_file_paths = _get_files_in_directory(relative_directory=directory_path) + expected_downloads_dict = { + str(file_path): _get_file_md5_hash(full_file_path=Path(directory_path) / file_path) + for file_path in relative_file_paths + } + return cls.from_dict(expected_downloads_dict) + + def to_summary_file(self, summary_file_path: Path | str) -> None: + expected_downloads_dict = { + str(exp_dl.path): exp_dl.md5 for exp_dl in self.expected_downloads + } + + with open(summary_file_path, mode="w", encoding="utf-8") as file: + json.dump( + obj=expected_downloads_dict, fp=file, sort_keys=True, ensure_ascii=False, indent=2 + ) + + +def assert_expected_downloads( + output_directory: str | Path, + dry_run: bool, + expected_download_summary_file_name: str, + ignore_md5_hashes_for: Optional[List[str]] = None, + regenerate_expected_download_summary: bool = False, +): + if dry_run: + output_directory_contents = list(Path(output_directory).rglob("*")) + assert ( + len(output_directory_contents) == 0 + ), f"Expected output directory to be empty after a dry-run, but found {output_directory_contents}" + return + + summary_full_path = _EXPECTED_DOWNLOADS_SUMMARY_PATH / expected_download_summary_file_name + if regenerate_expected_download_summary: + ExpectedDownloads.from_directory(directory_path=output_directory).to_summary_file( + summary_file_path=summary_full_path + ) + + ExpectedDownloads.from_file(summary_full_path).assert_files_exist( + relative_directory=output_directory, ignore_md5_hashes_for=ignore_md5_hashes_for + ) diff --git a/tests/e2e/plugins/test_nfo_tags.py b/tests/e2e/plugins/test_nfo_tags.py index a8c6ba29..d8261bb1 100644 --- a/tests/e2e/plugins/test_nfo_tags.py +++ b/tests/e2e/plugins/test_nfo_tags.py @@ -44,5 +44,4 @@ class TestNfoTagsPlugins: output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="plugins/test_kodi_safe_xml.txt", - regenerate_transaction_log=True, ) diff --git a/tests/e2e/resources/expected_downloads_summaries/soundcloud/test_soundcloud_discography.json b/tests/e2e/resources/expected_downloads_summaries/soundcloud/test_soundcloud_discography.json new file mode 100644 index 00000000..f3ce14cd --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/soundcloud/test_soundcloud_discography.json @@ -0,0 +1,19 @@ +{ + ".ytdl-sub-jb-download-archive.json": "1a99156e9ece62539fb2608416a07200", + "j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3": "bffbd558e12c6a9e029dc136a88342c4", + "j_b/[2021] Baby Santana's Dorian Groove/folder.jpg": "967892be44b8c47e1be73f055a7c6f08", + "j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3": "038db58aebe2ba875b733932b42a94d6", + "j_b/[2021] Purple Clouds/folder.jpg": "967892be44b8c47e1be73f055a7c6f08", + "j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3": "e145f0a2f6012768280c38655ca58065", + "j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3": "60c8b8817a197a13e4bb90903af612c5", + "j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3": "8265b7e4f79878af877bc6ecd9757efe", + "j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3": "accf46b76891d2954b893d0f91d82816", + "j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3": "e1f584f523336160d5c1104a61de77f3", + "j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3": "f6885b25901177f0357649afe97328cc", + "j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3": "fa057f221cbe4cf2442cd2fdb960743e", + "j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3": "7794ae812c64580e2ac8fc457d5cc85f", + "j_b/[2022] Acoustic Treats/09 - Finding Home.mp3": "adbf02eddb2090c008eb497d13ff84b9", + "j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3": "65bb10c84366c71498161734f953e93d", + "j_b/[2022] Acoustic Treats/11 - Untold History.mp3": "6904b2918e5dc38d9a9f72d967eb74bf", + "j_b/[2022] Acoustic Treats/folder.jpg": "967892be44b8c47e1be73f055a7c6f08" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json new file mode 100644 index 00000000..8e2db637 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_full.json @@ -0,0 +1,42 @@ +{ + ".ytdl-sub-pz-download-archive.json": "ce0ef71efbe27d9f67d80b5fbc57fc84", + "Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.mp4": "931a705864c57d21d6fedebed4af6bbc", + "Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.nfo": "67d8d71d048039080acbba3bce4febaa", + "Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2-thumb.jpg": "8b32ee9c037fa669e444a0ac181525a1", + "Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.mp4": "d3469b4dca7139cb3dbc38712b6796bf", + "Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.nfo": "d81f49cedbd7edaee987521e89b37904", + "Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg": "b232d253df621aa770b780c1301d364d", + "Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].mp4": "e66287b9832277b6a4d1554e29d9fdcc", + "Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo": "f7c0de89038f8c491bded8a3968720a2", + "Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg": "d17c379ea8b362f5b97c6b213b0342cb", + "Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].mp4": "04ab5cb3cc12325d0c96a7cd04a8b91d", + "Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo": "ee1eda78fa0980bc703e602b5012dd1f", + "Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530", + "Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "025de6099a5c98e6397153c7a62d517d", + "Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "61eb6369430da0ab6134d78829a7621b", + "Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net)-thumb.jpg": "c956192a379b3661595c9920972d4819", + "Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).mp4": "3d9c19835b03355d6fd5d00cd59dbe5b", + "Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).nfo": "60f72b99f5c69f9e03a071a12160928f", + "Season 2011/s2011.e0630 - Project Zombie |Fin|-thumb.jpg": "00ed383591779ffe98291de60f198fe9", + "Season 2011/s2011.e0630 - Project Zombie |Fin|.mp4": "4971cb2d4fa29460361031f3fa8e1ea9", + "Season 2011/s2011.e0630 - Project Zombie |Fin|.nfo": "a7b5d9e57d20852f5daf360a1373bb7a", + "Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC]-thumb.jpg": "1718599d5189c65f7d8cf6acfa5ea851", + "Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].mp4": "55e9b0add08c48c9c66105da0def2426", + "Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].nfo": "fe60e2b6b564f9316b6c7c183e1cf300", + "Season 2012/s2012.e0123 - Project Zombie |Map Trailer|-thumb.jpg": "54ebe9df801b278fdd17b21afa8373a6", + "Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.mp4": "65e4ce53ed5ec4139995469f99477a50", + "Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.nfo": "c8900adcca83c473c79a4afbc7ad2de1", + "Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|-thumb.jpg": "e29d49433175de8a761af35c5307791f", + "Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.mp4": "18620a8257a686beda65e54add4d4cd1", + "Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.nfo": "1c993c41d4308a6049333154d0adee16", + "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg": "6f8f5e1e031ec2a04b0a4906c04a19ee", + "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4": "82f6ee7253e1dbb83ae7215af08ffacc", + "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo": "cc7886aae3af6b7b0facd82f95390242", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "49cc64b25314155c1b8ab0361ac0c34f", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "e733b4cc385b953b08c8eb0f47e03c1e", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "2b3ccb3f1ef81ee49fe1afb88f275a09", + "fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3", + "poster.jpg": "e92872ff94c96ad49e9579501c791578", + "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json new file mode 100644 index 00000000..c6756721 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_no_additional_downloads.json @@ -0,0 +1,6 @@ +{ + ".ytdl-sub-pz-download-archive.json": "99914b932bd37a50b983c5e7c90ae93b", + "fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3", + "poster.jpg": "e92872ff94c96ad49e9579501c791578", + "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json new file mode 100644 index 00000000..7acf32f8 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_recent.json @@ -0,0 +1,12 @@ +{ + ".ytdl-sub-pz-download-archive.json": "523518e883758d9d89b656f9e9966efa", + "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg": "6f8f5e1e031ec2a04b0a4906c04a19ee", + "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4": "82f6ee7253e1dbb83ae7215af08ffacc", + "Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo": "cc7886aae3af6b7b0facd82f95390242", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "49cc64b25314155c1b8ab0361ac0c34f", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "e733b4cc385b953b08c8eb0f47e03c1e", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "2b3ccb3f1ef81ee49fe1afb88f275a09", + "fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3", + "poster.jpg": "e92872ff94c96ad49e9579501c791578", + "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json new file mode 100644 index 00000000..faf8fab2 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_channel_rolling_recent.json @@ -0,0 +1,9 @@ +{ + ".ytdl-sub-pz-download-archive.json": "9639fffe58c44d084124c8398b46ef32", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg": "49cc64b25314155c1b8ab0361ac0c34f", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4": "e733b4cc385b953b08c8eb0f47e03c1e", + "Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo": "2b3ccb3f1ef81ee49fe1afb88f275a09", + "fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3", + "poster.jpg": "e92872ff94c96ad49e9579501c791578", + "tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json new file mode 100644 index 00000000..c77548fe --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_merge_playlist.json @@ -0,0 +1,5 @@ +{ + "JMC - Jesse's Minecraft Server-thumb.jpg": "a3f1910f9c51f6442f845a528e190829", + "JMC - Jesse's Minecraft Server.mkv": "f523ac968dd9dfbd1954cbca72ad4108", + "JMC - Jesse's Minecraft Server.nfo": "10df5dcdb65ab18ecf21b3503c77e48b" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json new file mode 100644 index 00000000..f1021c06 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_playlist.json @@ -0,0 +1,12 @@ +{ + ".ytdl-sub-music_video_playlist_test-download-archive.json": "9f785c29194a6ecfba6a6b4018763ddc", + "JMC - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg": "b232d253df621aa770b780c1301d364d", + "JMC - Jesse's Minecraft Server [Trailer - Feb.1].mp4": "e66287b9832277b6a4d1554e29d9fdcc", + "JMC - Jesse's Minecraft Server [Trailer - Feb.1].nfo": "3d272fe58487b6011ad049b6000b046f", + "JMC - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg": "d17c379ea8b362f5b97c6b213b0342cb", + "JMC - Jesse's Minecraft Server [Trailer - Feb.27].mp4": "04ab5cb3cc12325d0c96a7cd04a8b91d", + "JMC - Jesse's Minecraft Server [Trailer - Feb.27].nfo": "6f99af10bef67276a507d1d9770c5e92", + "JMC - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg": "e7830aa8a64b0cde65ba3f7e5fc56530", + "JMC - Jesse's Minecraft Server [Trailer - Mar.21].mp4": "025de6099a5c98e6397153c7a62d517d", + "JMC - Jesse's Minecraft Server [Trailer - Mar.21].nfo": "beec3c1326654bd8c858cecf4e40977a" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json new file mode 100644 index 00000000..4bd8de28 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_split_video.json @@ -0,0 +1,20 @@ +{ + "Project Zombie - 1-6.Intro.mp4": "eaec6f50f364b13ef1a201e736ec9c05", + "Project Zombie - 2-6.Part 1.mp4": "5850b19acb250cc13db36f80fa1bba5a", + "Project Zombie - 3-6.Part 2.mp4": "445d95eba437db6df284df7e1ab633e8", + "Project Zombie - 4-6.Part 3.mp4": "2b6e7532d515c9e64ed2a33d850cf199", + "Project Zombie - 5-6.Part 4.mp4": "842bf3c4d1fcc4c5ab110635935dac66", + "Project Zombie - 6-6.Part 5.mp4": "238de99f00f829ab72f042b79da9a33a", + "Project Zombie - Intro-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Project Zombie - Intro.nfo": "ded59ac906f579312cc3cf98a57e7ea3", + "Project Zombie - Part 1-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Project Zombie - Part 1.nfo": "70ff5cd0092b8bc22dc4db93a824789b", + "Project Zombie - Part 2-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Project Zombie - Part 2.nfo": "54450c18a2cbb9d6d2ee5d0a1fb3f279", + "Project Zombie - Part 3-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Project Zombie - Part 3.nfo": "0effb13fc4039363a95969d1048dde57", + "Project Zombie - Part 4-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Project Zombie - Part 4.nfo": "74bd0d7c12105469838768a0cc323a8c", + "Project Zombie - Part 5-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "Project Zombie - Part 5.nfo": "a8cf2e77721335ea7c18e22734e7996c" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json new file mode 100644 index 00000000..8fe87f3f --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_video.json @@ -0,0 +1,5 @@ +{ + "JMC - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "JMC - Oblivion Mod "Falcor" p.1.mp4": "931a705864c57d21d6fedebed4af6bbc", + "JMC - Oblivion Mod "Falcor" p.1.nfo": "89f509a8a3d9003e22a9091abeeae5dc" +} \ No newline at end of file diff --git a/tests/e2e/resources/expected_downloads_summaries/youtube/test_video_with_chapter_timestamps.json b/tests/e2e/resources/expected_downloads_summaries/youtube/test_video_with_chapter_timestamps.json new file mode 100644 index 00000000..609ffa44 --- /dev/null +++ b/tests/e2e/resources/expected_downloads_summaries/youtube/test_video_with_chapter_timestamps.json @@ -0,0 +1,5 @@ +{ + "JMC - Oblivion Mod "Falcor" p.1-thumb.jpg": "fb95b510681676e81c321171fc23143e", + "JMC - Oblivion Mod "Falcor" p.1.mp4": "76b8a7dd428e67e5072d003983bb7e33", + "JMC - Oblivion Mod "Falcor" p.1.nfo": "89f509a8a3d9003e22a9091abeeae5dc" +} \ No newline at end of file diff --git a/tests/e2e/resources/transaction_log_summaries/plugins/test_kodi_safe_xml.txt b/tests/e2e/resources/transaction_log_summaries/plugins/test_kodi_safe_xml.txt index 9353f88a..de613a19 100644 --- a/tests/e2e/resources/transaction_log_summaries/plugins/test_kodi_safe_xml.txt +++ b/tests/e2e/resources/transaction_log_summaries/plugins/test_kodi_safe_xml.txt @@ -1,8 +1,8 @@ Files created in '{output_directory}' ---------------------------------------- -Rick Beato - Can you hear the difference 🎸🔥 #shorts-thumb.jpg -Rick Beato - Can you hear the difference 🎸🔥 #shorts.3gp -Rick Beato - Can you hear the difference 🎸🔥 #shorts.nfo +Rick Beato - Can you hear the difference? 🎸🔥 #shorts-thumb.jpg +Rick Beato - Can you hear the difference? 🎸🔥 #shorts.3gp +Rick Beato - Can you hear the difference? 🎸🔥 #shorts.nfo NFO tags: musicvideo: album: Music Videos diff --git a/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_full.txt b/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_full.txt index 303e8874..ea6008fd 100644 --- a/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_full.txt +++ b/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_full.txt @@ -1,9 +1,9 @@ Files created in '{output_directory}' ---------------------------------------- .ytdl-sub-pz-download-archive.json -Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1-thumb.jpg -Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4 -Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo +Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1-thumb.jpg +Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.mp4 +Season 2010/s2010.e0813 - Oblivion Mod "Falcor" p.1.nfo NFO tags: episodedetails: aired: 2010-08-13 @@ -18,9 +18,9 @@ Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo season: 2010 title: Oblivion Mod "Falcor" p.1 year: 2010 -Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2-thumb.jpg -Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.mp4 -Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo +Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2-thumb.jpg +Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.mp4 +Season 2010/s2010.e1202 - Oblivion Mod "Falcor" p.2.nfo NFO tags: episodedetails: aired: 2010-12-02 @@ -127,9 +127,9 @@ Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo season: 2011 title: Jesse's Minecraft Server [Trailer - Mar.21] year: 2011 -Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net)-thumb.jpg -Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).mp4 -Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).nfo +Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net)-thumb.jpg +Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).mp4 +Season 2011/s2011.e0529 - Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net).nfo NFO tags: episodedetails: aired: 2011-05-29 @@ -154,9 +154,9 @@ Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzomb season: 2011 title: Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net) year: 2011 -Season 2011/s2011.e0630 - Project Zombie _Fin-thumb.jpg -Season 2011/s2011.e0630 - Project Zombie _Fin.mp4 -Season 2011/s2011.e0630 - Project Zombie _Fin.nfo +Season 2011/s2011.e0630 - Project Zombie |Fin|-thumb.jpg +Season 2011/s2011.e0630 - Project Zombie |Fin|.mp4 +Season 2011/s2011.e0630 - Project Zombie |Fin|.nfo NFO tags: episodedetails: aired: 2011-06-30 @@ -167,9 +167,9 @@ Season 2011/s2011.e0630 - Project Zombie _Fin.nfo season: 2011 title: Project Zombie |Fin| year: 2011 -Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC]-thumb.jpg -Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4 -Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo +Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC]-thumb.jpg +Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].mp4 +Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [PC].nfo NFO tags: episodedetails: aired: 2011-11-21 @@ -187,9 +187,9 @@ Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo season: 2011 title: Skyrim 'Ultra HD w/Mods' [PC] year: 2011 -Season 2012/s2012.e0123 - Project Zombie _Map Trailer-thumb.jpg -Season 2012/s2012.e0123 - Project Zombie _Map Trailer.mp4 -Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo +Season 2012/s2012.e0123 - Project Zombie |Map Trailer|-thumb.jpg +Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.mp4 +Season 2012/s2012.e0123 - Project Zombie |Map Trailer|.nfo NFO tags: episodedetails: aired: 2012-01-23 @@ -207,9 +207,9 @@ Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo season: 2012 title: Project Zombie |Map Trailer| year: 2012 -Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer-thumb.jpg -Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.mp4 -Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo +Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|-thumb.jpg +Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.mp4 +Season 2013/s2013.e0719 - Project Zombie Rewind |Trailer|.nfo NFO tags: episodedetails: aired: 2013-07-19 @@ -222,9 +222,9 @@ Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo season: 2013 title: Project Zombie Rewind |Trailer| year: 2013 -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4 -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4 +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo NFO tags: episodedetails: aired: 2018-10-29 @@ -242,9 +242,9 @@ Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo season: 2018 title: Jesse's Minecraft Server | Teaser Trailer year: 2018 -Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg -Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4 -Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo +Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg +Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4 +Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo NFO tags: episodedetails: aired: 2018-11-02 diff --git a/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_recent.txt b/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_recent.txt index f8a4f79c..dd1f46e3 100644 --- a/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_recent.txt +++ b/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_recent.txt @@ -1,9 +1,9 @@ Files created in '{output_directory}' ---------------------------------------- .ytdl-sub-pz-download-archive.json -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4 -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4 +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo NFO tags: episodedetails: aired: 2018-10-29 @@ -21,9 +21,9 @@ Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo season: 2018 title: Jesse's Minecraft Server | Teaser Trailer year: 2018 -Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg -Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4 -Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo +Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id-thumb.jpg +Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.mp4 +Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo NFO tags: episodedetails: aired: 2018-11-02 diff --git a/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_rolling_recent.txt b/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_rolling_recent.txt index 2e4d09e9..fefdde78 100644 --- a/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_rolling_recent.txt +++ b/tests/e2e/resources/transaction_log_summaries/youtube/test_channel_rolling_recent.txt @@ -10,6 +10,6 @@ tvshow.nfo Files removed from '{output_directory}' ---------------------------------------- -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4 -Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo \ No newline at end of file +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer-thumb.jpg +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.mp4 +Season 2018/s2018.e1029 - Jesse's Minecraft Server | Teaser Trailer.nfo \ No newline at end of file diff --git a/tests/e2e/resources/transaction_log_summaries/youtube/test_video.txt b/tests/e2e/resources/transaction_log_summaries/youtube/test_video.txt index 0db01fd8..bbeae952 100644 --- a/tests/e2e/resources/transaction_log_summaries/youtube/test_video.txt +++ b/tests/e2e/resources/transaction_log_summaries/youtube/test_video.txt @@ -1,8 +1,8 @@ Files created in '{output_directory}' ---------------------------------------- -JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg -JMC - Oblivion Mod 'Falcor' p.1.mp4 -JMC - Oblivion Mod 'Falcor' p.1.nfo +JMC - Oblivion Mod "Falcor" p.1-thumb.jpg +JMC - Oblivion Mod "Falcor" p.1.mp4 +JMC - Oblivion Mod "Falcor" p.1.nfo NFO tags: musicvideo: album: Music Videos diff --git a/tests/e2e/resources/transaction_log_summaries/youtube/test_video_with_chapter_timestamps.txt b/tests/e2e/resources/transaction_log_summaries/youtube/test_video_with_chapter_timestamps.txt index 71f09d6b..d329bbb9 100644 --- a/tests/e2e/resources/transaction_log_summaries/youtube/test_video_with_chapter_timestamps.txt +++ b/tests/e2e/resources/transaction_log_summaries/youtube/test_video_with_chapter_timestamps.txt @@ -1,7 +1,7 @@ Files created in '{output_directory}' ---------------------------------------- -JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg -JMC - Oblivion Mod 'Falcor' p.1.mp4 +JMC - Oblivion Mod "Falcor" p.1-thumb.jpg +JMC - Oblivion Mod "Falcor" p.1.mp4 Chapters embedded into the video: 0:00: Intro 0:10: Part 1 @@ -9,7 +9,7 @@ JMC - Oblivion Mod 'Falcor' p.1.mp4 0:30: Part 3 0:40: Part 4 1:01: Part 5 -JMC - Oblivion Mod 'Falcor' p.1.nfo +JMC - Oblivion Mod "Falcor" p.1.nfo NFO tags: musicvideo: album: Music Videos diff --git a/tests/e2e/soundcloud/test_soundcloud_discography.py b/tests/e2e/soundcloud/test_soundcloud_discography.py index d1674e8d..0907441c 100644 --- a/tests/e2e/soundcloud/test_soundcloud_discography.py +++ b/tests/e2e/soundcloud/test_soundcloud_discography.py @@ -1,12 +1,7 @@ -from pathlib import Path - import pytest -from e2e.expected_download import ExpectedDownloadFile -from e2e.expected_download import ExpectedDownloads +from e2e.expected_download import assert_expected_downloads from e2e.expected_transaction_log import assert_transaction_log_matches -from ytdl_sub.config.config_file import ConfigFile -from ytdl_sub.config.preset import Preset from ytdl_sub.subscriptions.subscription import Subscription @@ -25,40 +20,6 @@ def subscription_dict(output_directory): } -@pytest.fixture -def expected_discography_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - # Download mapping - ExpectedDownloadFile(path=Path(".ytdl-sub-jb-download-archive.json"), md5="1a99156e9ece62539fb2608416a07200"), - - # Entry files (singles) - ExpectedDownloadFile(path=Path("j_b/[2021] Baby Santana's Dorian Groove/01 - Baby Santana's Dorian Groove.mp3"), md5="bffbd558e12c6a9e029dc136a88342c4"), - ExpectedDownloadFile(path=Path("j_b/[2021] Baby Santana's Dorian Groove/folder.jpg"), md5="967892be44b8c47e1be73f055a7c6f08"), - - ExpectedDownloadFile(path=Path("j_b/[2021] Purple Clouds/01 - Purple Clouds.mp3"), md5="038db58aebe2ba875b733932b42a94d6"), - ExpectedDownloadFile(path=Path("j_b/[2021] Purple Clouds/folder.jpg"), md5="967892be44b8c47e1be73f055a7c6f08"), - - # Entry files (albums) - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/01 - 20160426 184214.mp3"), md5="e145f0a2f6012768280c38655ca58065"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/02 - 20160502 123150.mp3"), md5="60c8b8817a197a13e4bb90903af612c5"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/03 - 20160504 143832.mp3"), md5="8265b7e4f79878af877bc6ecd9757efe"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/04 - 20160601 221234.mp3"), md5="accf46b76891d2954b893d0f91d82816"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/05 - 20160601 222440.mp3"), md5="e1f584f523336160d5c1104a61de77f3"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/06 - 20170604 190236.mp3"), md5="f6885b25901177f0357649afe97328cc"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/07 - 20170612 193646.mp3"), md5="fa057f221cbe4cf2442cd2fdb960743e"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/08 - 20170628 215206.mp3"), md5="7794ae812c64580e2ac8fc457d5cc85f"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/09 - Finding Home.mp3"), md5="adbf02eddb2090c008eb497d13ff84b9"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/10 - Shallow Water WIP.mp3"), md5="65bb10c84366c71498161734f953e93d"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/11 - Untold History.mp3"), md5="6904b2918e5dc38d9a9f72d967eb74bf"), - ExpectedDownloadFile(path=Path("j_b/[2022] Acoustic Treats/folder.jpg"), md5="967892be44b8c47e1be73f055a7c6f08"), - ] - ) - # fmt: on - - class TestSoundcloudDiscography: """ Downloads my (bad) SC recordings I made. Ensure the above files exist and have the @@ -70,7 +31,6 @@ class TestSoundcloudDiscography: self, subscription_dict, soundcloud_discography_config, - expected_discography_download, output_directory, dry_run, ): @@ -85,5 +45,8 @@ class TestSoundcloudDiscography: transaction_log=transaction_log, transaction_log_summary_file_name="soundcloud/test_soundcloud_discography.txt", ) - if not dry_run: - expected_discography_download.assert_files_exist(relative_directory=output_directory) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="soundcloud/test_soundcloud_discography.json", + ) diff --git a/tests/e2e/youtube/test_channel.py b/tests/e2e/youtube/test_channel.py index f689a94d..f9addb76 100644 --- a/tests/e2e/youtube/test_channel.py +++ b/tests/e2e/youtube/test_channel.py @@ -1,12 +1,10 @@ import copy -from pathlib import Path from typing import Dict import mergedeep import pytest from conftest import assert_debug_log -from e2e.expected_download import ExpectedDownloadFile -from e2e.expected_download import ExpectedDownloads +from e2e.expected_download import assert_expected_downloads from e2e.expected_transaction_log import assert_transaction_log_matches import ytdl_sub.downloaders.downloader @@ -45,77 +43,6 @@ def channel_subscription_generator(channel_as_tv_show_config, subscription_name) return _channel_subscription_generator -#################################################################################################### -# FULL CHANNEL FIXTURES - - -@pytest.fixture -def expected_full_channel_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - # Download mapping - ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="dd3c6236a107a665b884f701b8d14d4d"), - - # Output directory files - ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"), - ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"), - ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"), - - # Entry files - ExpectedDownloadFile(path=Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1-thumb.jpg"), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4"), md5="931a705864c57d21d6fedebed4af6bbc"), - ExpectedDownloadFile(path=Path("Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo"), md5="67d8d71d048039080acbba3bce4febaa"), - - ExpectedDownloadFile(path=Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2-thumb.jpg"), md5="8b32ee9c037fa669e444a0ac181525a1"), - ExpectedDownloadFile(path=Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.mp4"), md5="d3469b4dca7139cb3dbc38712b6796bf"), - ExpectedDownloadFile(path=Path("Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo"), md5="d81f49cedbd7edaee987521e89b37904"), - - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg"), md5="b232d253df621aa770b780c1301d364d"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].mp4"), md5="e66287b9832277b6a4d1554e29d9fdcc"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0201 - Jesse's Minecraft Server [Trailer - Feb.1].nfo"), md5="f7c0de89038f8c491bded8a3968720a2"), - - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg"), md5="d17c379ea8b362f5b97c6b213b0342cb"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].mp4"), md5="04ab5cb3cc12325d0c96a7cd04a8b91d"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0227 - Jesse's Minecraft Server [Trailer - Feb.27].nfo"), md5="ee1eda78fa0980bc703e602b5012dd1f"), - - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg"), md5="e7830aa8a64b0cde65ba3f7e5fc56530"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].mp4"), md5="025de6099a5c98e6397153c7a62d517d"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo"), md5="61eb6369430da0ab6134d78829a7621b"), - - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net)-thumb.jpg"), md5="c956192a379b3661595c9920972d4819"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).mp4"), md5="3d9c19835b03355d6fd5d00cd59dbe5b"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzombie.beastnode.net).nfo"), md5="60f72b99f5c69f9e03a071a12160928f"), - - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0630 - Project Zombie _Fin-thumb.jpg"), md5="00ed383591779ffe98291de60f198fe9"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0630 - Project Zombie _Fin.mp4"), md5="4971cb2d4fa29460361031f3fa8e1ea9"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e0630 - Project Zombie _Fin.nfo"), md5="a7b5d9e57d20852f5daf360a1373bb7a"), - - ExpectedDownloadFile(path=Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC]-thumb.jpg"), md5="1718599d5189c65f7d8cf6acfa5ea851"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4"), md5="55e9b0add08c48c9c66105da0def2426"), - ExpectedDownloadFile(path=Path("Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo"), md5="fe60e2b6b564f9316b6c7c183e1cf300"), - - ExpectedDownloadFile(path=Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer-thumb.jpg"), md5="54ebe9df801b278fdd17b21afa8373a6"), - ExpectedDownloadFile(path=Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.mp4"), md5="65e4ce53ed5ec4139995469f99477a50"), - ExpectedDownloadFile(path=Path("Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo"), md5="c8900adcca83c473c79a4afbc7ad2de1"), - - ExpectedDownloadFile(path=Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer-thumb.jpg"), md5="e29d49433175de8a761af35c5307791f"), - ExpectedDownloadFile(path=Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.mp4"), md5="18620a8257a686beda65e54add4d4cd1"), - ExpectedDownloadFile(path=Path("Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo"), md5="1c993c41d4308a6049333154d0adee16"), - - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg"), md5="6f8f5e1e031ec2a04b0a4906c04a19ee"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"), md5="82f6ee7253e1dbb83ae7215af08ffacc"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"), md5="cc7886aae3af6b7b0facd82f95390242"), - - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg"), md5="49cc64b25314155c1b8ab0361ac0c34f"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"), - ] - ) - # fmt: on - - #################################################################################################### # RECENT CHANNEL FIXTURES @pytest.fixture @@ -132,55 +59,6 @@ def recent_channel_preset_dict(channel_preset_dict): ) -@pytest.fixture -def expected_recent_channel_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - # Download mapping - ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="91534d1c5921d121aa35d7a197ba1940"), - - # Output directory files - ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"), - ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"), - ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"), - - # Recent Entry files - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg"), md5="6f8f5e1e031ec2a04b0a4906c04a19ee"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4"), md5="82f6ee7253e1dbb83ae7215af08ffacc"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo"), md5="cc7886aae3af6b7b0facd82f95390242"), - - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg"), md5="49cc64b25314155c1b8ab0361ac0c34f"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"), - ] - ) - # fmt: on - - -#################################################################################################### -# RECENT CHANNEL FIXTURES -- NO VIDS IN RANGE - - -@pytest.fixture -def expected_recent_channel_no_vids_in_range_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - # Download mapping - ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="99914b932bd37a50b983c5e7c90ae93b"), - - # Output directory files - ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"), - ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"), - ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"), - ] - ) - # fmt: on - - #################################################################################################### # ROLLING RECENT CHANNEL FIXTURES @pytest.fixture @@ -195,29 +73,6 @@ def rolling_recent_channel_preset_dict(recent_channel_preset_dict): ) -@pytest.fixture -def expected_rolling_recent_channel_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - # Download mapping - ExpectedDownloadFile(path=Path(".ytdl-sub-pz-download-archive.json"), md5="97ff47a7c5d89a426a653493ad1a3f06"), - - # Output directory files - ExpectedDownloadFile(path=Path("fanart.jpg"), md5="c16b8b88a82cbd47d217ee80f6a8b5f3"), - ExpectedDownloadFile(path=Path("poster.jpg"), md5="e92872ff94c96ad49e9579501c791578"), - ExpectedDownloadFile(path=Path("tvshow.nfo"), md5="83c7db96081ac5bdf289fcf396bec157"), - - # Rolling Recent Entry files - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id-thumb.jpg"), md5="49cc64b25314155c1b8ab0361ac0c34f"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"), - ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"), - ] - ) - # fmt: on - - class TestChannelAsKodiTvShow: """ Downloads my old minecraft youtube channel. Ensure the above files exist and have the @@ -229,7 +84,6 @@ class TestChannelAsKodiTvShow: self, channel_subscription_generator, channel_preset_dict, - expected_full_channel_download, output_directory, dry_run, ): @@ -240,15 +94,17 @@ class TestChannelAsKodiTvShow: transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_channel_full.txt", ) - if not dry_run: - expected_full_channel_download.assert_files_exist(relative_directory=output_directory) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_channel_full.json", + ) @pytest.mark.parametrize("dry_run", [True, False]) def test_recent_channel_download( self, channel_subscription_generator, recent_channel_preset_dict, - expected_recent_channel_download, output_directory, dry_run, ): @@ -262,9 +118,12 @@ class TestChannelAsKodiTvShow: transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_channel_recent.txt", ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_channel_recent.json", + ) if not dry_run: - expected_recent_channel_download.assert_files_exist(relative_directory=output_directory) - # try downloading again, ensure nothing more was downloaded with assert_debug_log( logger=ytdl_sub.downloaders.downloader.download_logger, @@ -278,8 +137,10 @@ class TestChannelAsKodiTvShow: "youtube/test_channel_no_additional_downloads.txt" ), ) - expected_recent_channel_download.assert_files_exist( - relative_directory=output_directory + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_channel_recent.json", ) @pytest.mark.parametrize("dry_run", [True, False]) @@ -287,7 +148,6 @@ class TestChannelAsKodiTvShow: self, channel_subscription_generator, recent_channel_preset_dict, - expected_recent_channel_no_vids_in_range_download, output_directory, dry_run, ): @@ -304,10 +164,11 @@ class TestChannelAsKodiTvShow: transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt", ) - if not dry_run: - expected_recent_channel_no_vids_in_range_download.assert_files_exist( - relative_directory=output_directory - ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_channel_no_additional_downloads.json", + ) @pytest.mark.parametrize("dry_run", [True, False]) def test_rolling_recent_channel_download( @@ -315,8 +176,6 @@ class TestChannelAsKodiTvShow: channel_subscription_generator, recent_channel_preset_dict, rolling_recent_channel_preset_dict, - expected_recent_channel_download, - expected_rolling_recent_channel_download, output_directory, dry_run, ): @@ -333,14 +192,18 @@ class TestChannelAsKodiTvShow: logger=ytdl_sub.downloaders.downloader.download_logger, expected_message="RejectedVideoReached, stopping additional downloads", ): - transaction_log = recent_channel_subscription.download() + transaction_log = recent_channel_subscription.download(dry_run=False) - expected_recent_channel_download.assert_files_exist(relative_directory=output_directory) assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_channel_recent.txt", ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=False, + expected_download_summary_file_name="youtube/test_channel_recent.json", + ) # Then, download the rolling recent vids subscription. This should remove one of the # two videos @@ -350,16 +213,22 @@ class TestChannelAsKodiTvShow: ): transaction_log = rolling_recent_channel_subscription.download(dry_run=dry_run) + expected_downloads_summary = ( + "youtube/test_channel_recent.json" + if dry_run + else "youtube/test_channel_rolling_recent.json" + ) + assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_channel_rolling_recent.txt", - regenerate_transaction_log=True, ) - if not dry_run: - expected_rolling_recent_channel_download.assert_files_exist( - relative_directory=output_directory - ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=False, + expected_download_summary_file_name=expected_downloads_summary, + ) # Invoke the rolling download again, ensure downloading stopped early from it already # existing @@ -375,6 +244,8 @@ class TestChannelAsKodiTvShow: transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt", ) - expected_rolling_recent_channel_download.assert_files_exist( - relative_directory=output_directory + assert_expected_downloads( + output_directory=output_directory, + dry_run=False, + expected_download_summary_file_name=expected_downloads_summary, ) diff --git a/tests/e2e/youtube/test_merge_playlist.py b/tests/e2e/youtube/test_merge_playlist.py index 0792855e..6d88533f 100644 --- a/tests/e2e/youtube/test_merge_playlist.py +++ b/tests/e2e/youtube/test_merge_playlist.py @@ -1,8 +1,5 @@ -from pathlib import Path - import pytest -from e2e.expected_download import ExpectedDownloadFile -from e2e.expected_download import ExpectedDownloads +from e2e.expected_download import assert_expected_downloads from e2e.expected_transaction_log import assert_transaction_log_matches from ytdl_sub.config.config_file import ConfigFile @@ -63,17 +60,17 @@ def playlist_subscription(config, subscription_name, subscription_dict): ) -@pytest.fixture -def expected_playlist_download(): - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server-thumb.jpg"), md5="a3f1910f9c51f6442f845a528e190829"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.mkv")), # not bitexact TODO: check size - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.nfo"), md5="10df5dcdb65ab18ecf21b3503c77e48b"), - ] - ) - # fmt: on +# @pytest.fixture +# def expected_playlist_download(): +# # fmt: off +# return ExpectedDownloads( +# expected_downloads=[ +# ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server-thumb.jpg"), md5="a3f1910f9c51f6442f845a528e190829"), +# ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.mkv")), # not bitexact TODO: check size +# ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.nfo"), md5="10df5dcdb65ab18ecf21b3503c77e48b"), +# ] +# ) +# # fmt: on class TestYoutubeMergePlaylist: @@ -83,15 +80,16 @@ class TestYoutubeMergePlaylist: """ @pytest.mark.parametrize("dry_run", [True, False]) - def test_merge_playlist_download( - self, playlist_subscription, expected_playlist_download, output_directory, dry_run - ): + def test_merge_playlist_download(self, playlist_subscription, output_directory, dry_run): transaction_log = playlist_subscription.download(dry_run=dry_run) assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_merge_playlist.txt", ) - - if not dry_run: - expected_playlist_download.assert_files_exist(relative_directory=output_directory) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + ignore_md5_hashes_for=["JMC - Jesse's Minecraft Server.mkv"], # TODO, better test here + expected_download_summary_file_name="youtube/test_merge_playlist.json", + ) diff --git a/tests/e2e/youtube/test_playlist.py b/tests/e2e/youtube/test_playlist.py index e3e27b7a..77c020a8 100644 --- a/tests/e2e/youtube/test_playlist.py +++ b/tests/e2e/youtube/test_playlist.py @@ -1,10 +1,7 @@ -from pathlib import Path - import pytest from conftest import assert_debug_log from e2e.conftest import mock_run_from_cli -from e2e.expected_download import ExpectedDownloadFile -from e2e.expected_download import ExpectedDownloads +from e2e.expected_download import assert_expected_downloads from e2e.expected_transaction_log import assert_transaction_log_matches import ytdl_sub.downloaders.downloader @@ -26,32 +23,6 @@ def playlist_preset_dict(output_directory): } -@pytest.fixture -def expected_playlist_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - # Download mapping - ExpectedDownloadFile(path=Path(".ytdl-sub-music_video_playlist_test-download-archive.json"), md5="9f785c29194a6ecfba6a6b4018763ddc"), - - # Entry files - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.1]-thumb.jpg"), md5="b232d253df621aa770b780c1301d364d"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.1].mp4"), md5="e66287b9832277b6a4d1554e29d9fdcc"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.1].nfo"), md5="3d272fe58487b6011ad049b6000b046f"), - - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.27]-thumb.jpg"), md5="d17c379ea8b362f5b97c6b213b0342cb"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.27].mp4"), md5="04ab5cb3cc12325d0c96a7cd04a8b91d"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Feb.27].nfo"), md5="6f99af10bef67276a507d1d9770c5e92"), - - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Mar.21]-thumb.jpg"), md5="e7830aa8a64b0cde65ba3f7e5fc56530"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Mar.21].mp4"), md5="025de6099a5c98e6397153c7a62d517d"), - ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server [Trailer - Mar.21].nfo"), md5="beec3c1326654bd8c858cecf4e40977a"), - ] - ) - # fmt: on - - class TestPlaylistAsKodiMusicVideo: """ Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above @@ -63,7 +34,6 @@ class TestPlaylistAsKodiMusicVideo: self, music_video_config, playlist_preset_dict, - expected_playlist_download, output_directory, dry_run, ): @@ -73,24 +43,32 @@ class TestPlaylistAsKodiMusicVideo: preset_dict=playlist_preset_dict, ) - transaction_log = playlist_subscription.download() + transaction_log = playlist_subscription.download(dry_run=dry_run) assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_playlist.txt", ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_playlist.json", + ) + # Ensure another invocation will hit ExistingVideoReached if not dry_run: - expected_playlist_download.assert_files_exist(relative_directory=output_directory) - - # Ensure another invocation will hit ExistingVideoReached with assert_debug_log( logger=ytdl_sub.downloaders.downloader.download_logger, expected_message="ExistingVideoReached, stopping additional downloads", ): transaction_log = playlist_subscription.download() - expected_playlist_download.assert_files_exist(relative_directory=output_directory) - assert transaction_log.is_empty + + assert transaction_log.is_empty + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_playlist.json", + ) @pytest.mark.parametrize("dry_run", [True, False]) def test_playlist_download_from_cli_sub( @@ -98,7 +76,6 @@ class TestPlaylistAsKodiMusicVideo: preset_dict_to_subscription_yaml_generator, music_video_config_path, playlist_preset_dict, - expected_playlist_download, output_directory, dry_run, ): @@ -118,17 +95,23 @@ class TestPlaylistAsKodiMusicVideo: transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_playlist.txt", ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_playlist.json", + ) if not dry_run: - expected_playlist_download.assert_files_exist(relative_directory=output_directory) - # Ensure another invocation will hit ExistingVideoReached with assert_debug_log( logger=ytdl_sub.downloaders.downloader.download_logger, expected_message="ExistingVideoReached, stopping additional downloads", ): transaction_log = mock_run_from_cli(args=args)[0][1] - expected_playlist_download.assert_files_exist( - relative_directory=output_directory - ) - assert transaction_log.is_empty + + assert transaction_log.is_empty + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_playlist.json", + ) diff --git a/tests/e2e/youtube/test_split_video.py b/tests/e2e/youtube/test_split_video.py index 86255cb1..6d1f75d8 100644 --- a/tests/e2e/youtube/test_split_video.py +++ b/tests/e2e/youtube/test_split_video.py @@ -1,9 +1,5 @@ -from pathlib import Path -from tempfile import NamedTemporaryFile - import pytest -from e2e.expected_download import ExpectedDownloadFile -from e2e.expected_download import ExpectedDownloads +from e2e.expected_download import assert_expected_downloads from e2e.expected_transaction_log import assert_transaction_log_matches from ytdl_sub.config.preset import Preset @@ -50,35 +46,6 @@ def single_video_subscription(music_video_config, subscription_dict): ) -@pytest.fixture -def expected_single_video_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - ExpectedDownloadFile(path=Path('Project Zombie - 1-6.Intro.mp4'), md5="eaec6f50f364b13ef1a201e736ec9c05"), - ExpectedDownloadFile(path=Path('Project Zombie - 2-6.Part 1.mp4'), md5="5850b19acb250cc13db36f80fa1bba5a"), - ExpectedDownloadFile(path=Path('Project Zombie - 3-6.Part 2.mp4'), md5="445d95eba437db6df284df7e1ab633e8"), - ExpectedDownloadFile(path=Path('Project Zombie - 4-6.Part 3.mp4'), md5="2b6e7532d515c9e64ed2a33d850cf199"), - ExpectedDownloadFile(path=Path('Project Zombie - 5-6.Part 4.mp4'), md5="842bf3c4d1fcc4c5ab110635935dac66"), - ExpectedDownloadFile(path=Path('Project Zombie - 6-6.Part 5.mp4'), md5="238de99f00f829ab72f042b79da9a33a"), - ExpectedDownloadFile(path=Path('Project Zombie - Intro-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path('Project Zombie - Intro.nfo'), md5="ded59ac906f579312cc3cf98a57e7ea3"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 1-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 1.nfo'), md5="70ff5cd0092b8bc22dc4db93a824789b"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 2-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 2.nfo'), md5="54450c18a2cbb9d6d2ee5d0a1fb3f279"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 3-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 3.nfo'), md5="0effb13fc4039363a95969d1048dde57"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 4-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 4.nfo'), md5="74bd0d7c12105469838768a0cc323a8c"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 5-thumb.jpg'), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path('Project Zombie - Part 5.nfo'), md5="a8cf2e77721335ea7c18e22734e7996c"), - ] - ) - # fmt: on - - class TestPlaylistAsKodiMusicVideo: """ Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above @@ -86,15 +53,15 @@ class TestPlaylistAsKodiMusicVideo: """ @pytest.mark.parametrize("dry_run", [True, False]) - def test_split_video_download( - self, single_video_subscription, expected_single_video_download, output_directory, dry_run - ): - transaction_log = single_video_subscription.download() + def test_split_video_download(self, single_video_subscription, output_directory, dry_run): + transaction_log = single_video_subscription.download(dry_run=dry_run) assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_split_video.txt", ) - - if not dry_run: - expected_single_video_download.assert_files_exist(relative_directory=output_directory) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_split_video.json", + ) diff --git a/tests/e2e/youtube/test_video.py b/tests/e2e/youtube/test_video.py index a569827d..7c044c67 100644 --- a/tests/e2e/youtube/test_video.py +++ b/tests/e2e/youtube/test_video.py @@ -1,10 +1,7 @@ -from pathlib import Path - import pytest from conftest import preset_dict_to_dl_args from e2e.conftest import mock_run_from_cli -from e2e.expected_download import ExpectedDownloadFile -from e2e.expected_download import ExpectedDownloads +from e2e.expected_download import assert_expected_downloads from e2e.expected_transaction_log import assert_transaction_log_matches from ytdl_sub.subscriptions.subscription import Subscription @@ -30,41 +27,12 @@ def single_video_preset_dict_dl_args(single_video_preset_dict): return preset_dict_to_dl_args(single_video_preset_dict) -@pytest.fixture -def expected_single_video_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg"), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.mp4"), md5="931a705864c57d21d6fedebed4af6bbc"), - ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.nfo"), md5="89f509a8a3d9003e22a9091abeeae5dc"), - ] - ) - # fmt: on - - -@pytest.fixture -def expected_single_video_with_chapter_timestamps_download(): - # turn off black formatter here for readability - # fmt: off - return ExpectedDownloads( - expected_downloads=[ - ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg"), md5="fb95b510681676e81c321171fc23143e"), - ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.mp4"), md5="76b8a7dd428e67e5072d003983bb7e33"), - ExpectedDownloadFile(path=Path("JMC - Oblivion Mod 'Falcor' p.1.nfo"), md5="89f509a8a3d9003e22a9091abeeae5dc"), - ] - ) - # fmt: on - - class TestYoutubeVideo: @pytest.mark.parametrize("dry_run", [True, False]) def test_single_video_download( self, music_video_config, single_video_preset_dict, - expected_single_video_download, output_directory, dry_run, ): @@ -74,21 +42,23 @@ class TestYoutubeVideo: preset_dict=single_video_preset_dict, ) - transaction_log = single_video_subscription.download() + transaction_log = single_video_subscription.download(dry_run=dry_run) assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_video.txt", ) - if not dry_run: - expected_single_video_download.assert_files_exist(relative_directory=output_directory) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_video.json", + ) @pytest.mark.parametrize("dry_run", [True, False]) def test_single_video_download_from_cli_dl( self, music_video_config_path, single_video_preset_dict_dl_args, - expected_single_video_download, output_directory, dry_run, ): @@ -105,8 +75,11 @@ class TestYoutubeVideo: transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_video.txt", ) - if not dry_run: - expected_single_video_download.assert_files_exist(relative_directory=output_directory) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_video.json", + ) @pytest.mark.parametrize("dry_run", [True, False]) def test_single_video_with_timestamp_chapters_download( @@ -114,7 +87,6 @@ class TestYoutubeVideo: timestamps_file_path, music_video_config, single_video_preset_dict, - expected_single_video_with_chapter_timestamps_download, output_directory, dry_run, ): @@ -125,13 +97,14 @@ class TestYoutubeVideo: preset_dict=single_video_preset_dict, ) - transaction_log = single_video_subscription.download() + transaction_log = single_video_subscription.download(dry_run=dry_run) assert_transaction_log_matches( output_directory=output_directory, transaction_log=transaction_log, transaction_log_summary_file_name="youtube/test_video_with_chapter_timestamps.txt", ) - if not dry_run: - expected_single_video_with_chapter_timestamps_download.assert_files_exist( - relative_directory=output_directory - ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="youtube/test_video_with_chapter_timestamps.json", + )