[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
This commit is contained in:
Jesse Bannon 2022-08-10 12:16:38 -07:00 committed by GitHub
parent 3e60f7d1da
commit bcf45f7f7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 397 additions and 441 deletions

View file

@ -161,7 +161,8 @@ class YoutubeSplitVideoDownloader(
entry = YoutubeVideo(entry_dict=entry_dict, working_directory=self.working_directory) 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 # convert the entry thumbnail early so we do not have to guess the thumbnail extension
# when copying it # 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): for idx, title in enumerate(chapters.titles):
new_uid = _split_video_uid(source_uid=entry.uid, idx=idx) 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 # 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 # downstream logic thinks this split video has its own thumbnail
FileHandler.copy( FileHandler.copy(
src_file_path=entry.get_download_thumbnail_path(), src_file_path=entry.get_download_thumbnail_path(),
dst_file_path=Path(self.working_directory) / f"{new_uid}.{entry.thumbnail_ext}", dst_file_path=Path(self.working_directory) / f"{new_uid}.{entry.thumbnail_ext}",
) )
# Format the split video as a YoutubePlaylistVideo # Format the split video as a YoutubePlaylistVideo
split_videos_and_metadata.append( split_videos_and_metadata.append(

View file

@ -1,19 +1,33 @@
import hashlib import hashlib
import json
import os.path import os.path
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path
from typing import List from typing import List
from typing import Optional 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 @dataclass
class ExpectedDownloadFile: class ExpectedDownloadFile:
path: Path path: Path
md5: Optional[Union[str, List[str]]] = None md5: str
metadata: Optional[FileMetadata] = None
class ExpectedDownloads: class ExpectedDownloads:
@ -35,21 +49,21 @@ class ExpectedDownloads:
def contains(self, relative_path: Path) -> bool: def contains(self, relative_path: Path) -> bool:
return sum(relative_path == download.path for download in self.expected_downloads) == 1 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. Assert each expected file exists and that its respective md5 hash matches.
""" """
num_files = 0 if ignore_md5_hashes_for is None:
for path in Path(relative_directory).rglob("*"): ignore_md5_hashes_for = []
if path.is_file():
num_files += 1
relative_path = Path(*path.parts[3:]) relative_file_paths = _get_files_in_directory(relative_directory=relative_directory)
assert self.contains(
relative_path
), f"File {relative_path} was created but not expected"
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: for expected_download in self.expected_downloads:
full_path = Path(relative_directory) / expected_download.path full_path = Path(relative_directory) / expected_download.path
@ -57,17 +71,69 @@ class ExpectedDownloads:
full_path full_path
), f"Expected {str(expected_download.path)} to be a file but it is not" ), 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 continue
with open(full_path, "rb") as file: md5_hash = _get_file_md5_hash(full_file_path=full_path)
md5_hash = hashlib.md5(file.read()).hexdigest() assert md5_hash in expected_download.md5, (
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, (
f"MD5 hash for {str(expected_download.path)} does not match: " 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
)

View file

@ -44,5 +44,4 @@ class TestNfoTagsPlugins:
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="plugins/test_kodi_safe_xml.txt", transaction_log_summary_file_name="plugins/test_kodi_safe_xml.txt",
regenerate_transaction_log=True,
) )

View file

@ -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"
}

View file

@ -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 wMods' [PC]-thumb.jpg": "1718599d5189c65f7d8cf6acfa5ea851",
"Season 2011/s2011.e1121 - Skyrim 'Ultra HD wMods' [PC].mp4": "55e9b0add08c48c9c66105da0def2426",
"Season 2011/s2011.e1121 - Skyrim 'Ultra HD wMods' [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"
}

View file

@ -0,0 +1,6 @@
{
".ytdl-sub-pz-download-archive.json": "99914b932bd37a50b983c5e7c90ae93b",
"fanart.jpg": "c16b8b88a82cbd47d217ee80f6a8b5f3",
"poster.jpg": "e92872ff94c96ad49e9579501c791578",
"tvshow.nfo": "83c7db96081ac5bdf289fcf396bec157"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -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"
}

View file

@ -1,8 +1,8 @@
Files created in '{output_directory}' Files created in '{output_directory}'
---------------------------------------- ----------------------------------------
Rick Beato - Can you hear the difference 🎸🔥 #shorts-thumb.jpg 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.3gp
Rick Beato - Can you hear the difference 🎸🔥 #shorts.nfo Rick Beato - Can you hear the difference 🎸🔥 #shorts.nfo
NFO tags: NFO tags:
musicvideo: musicvideo:
album: Music Videos album: Music Videos

View file

@ -1,9 +1,9 @@
Files created in '{output_directory}' Files created in '{output_directory}'
---------------------------------------- ----------------------------------------
.ytdl-sub-pz-download-archive.json .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-thumb.jpg
Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.mp4 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.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2010-08-13 aired: 2010-08-13
@ -18,9 +18,9 @@ Season 2010/s2010.e0813 - Oblivion Mod 'Falcor' p.1.nfo
season: 2010 season: 2010
title: Oblivion Mod "Falcor" p.1 title: Oblivion Mod "Falcor" p.1
year: 2010 year: 2010
Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2-thumb.jpg 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.mp4
Season 2010/s2010.e1202 - Oblivion Mod 'Falcor' p.2.nfo Season 2010/s2010.e1202 - Oblivion Mod Falcor p.2.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2010-12-02 aired: 2010-12-02
@ -127,9 +127,9 @@ Season 2011/s2011.e0321 - Jesse's Minecraft Server [Trailer - Mar.21].nfo
season: 2011 season: 2011
title: Jesse's Minecraft Server [Trailer - Mar.21] title: Jesse's Minecraft Server [Trailer - Mar.21]
year: 2011 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)-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).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).nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2011-05-29 aired: 2011-05-29
@ -154,9 +154,9 @@ Season 2011/s2011.e0529 - Project Zombie _Official Trailer_ (IP - mc.projectzomb
season: 2011 season: 2011
title: Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net) title: Project Zombie |Official Trailer| (IP: mc.projectzombie.beastnode.net)
year: 2011 year: 2011
Season 2011/s2011.e0630 - Project Zombie _Fin-thumb.jpg Season 2011/s2011.e0630 - Project Zombie Fin-thumb.jpg
Season 2011/s2011.e0630 - Project Zombie _Fin.mp4 Season 2011/s2011.e0630 - Project Zombie Fin.mp4
Season 2011/s2011.e0630 - Project Zombie _Fin.nfo Season 2011/s2011.e0630 - Project Zombie Fin.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2011-06-30 aired: 2011-06-30
@ -167,9 +167,9 @@ Season 2011/s2011.e0630 - Project Zombie _Fin.nfo
season: 2011 season: 2011
title: Project Zombie |Fin| title: Project Zombie |Fin|
year: 2011 year: 2011
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC]-thumb.jpg Season 2011/s2011.e1121 - Skyrim 'Ultra HD wMods' [PC]-thumb.jpg
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].mp4 Season 2011/s2011.e1121 - Skyrim 'Ultra HD wMods' [PC].mp4
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo Season 2011/s2011.e1121 - Skyrim 'Ultra HD wMods' [PC].nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2011-11-21 aired: 2011-11-21
@ -187,9 +187,9 @@ Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo
season: 2011 season: 2011
title: Skyrim 'Ultra HD w/Mods' [PC] title: Skyrim 'Ultra HD w/Mods' [PC]
year: 2011 year: 2011
Season 2012/s2012.e0123 - Project Zombie _Map Trailer-thumb.jpg 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.mp4
Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo Season 2012/s2012.e0123 - Project Zombie Map Trailer.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2012-01-23 aired: 2012-01-23
@ -207,9 +207,9 @@ Season 2012/s2012.e0123 - Project Zombie _Map Trailer.nfo
season: 2012 season: 2012
title: Project Zombie |Map Trailer| title: Project Zombie |Map Trailer|
year: 2012 year: 2012
Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer-thumb.jpg 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.mp4
Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo Season 2013/s2013.e0719 - Project Zombie Rewind Trailer.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2013-07-19 aired: 2013-07-19
@ -222,9 +222,9 @@ Season 2013/s2013.e0719 - Project Zombie Rewind _Trailer.nfo
season: 2013 season: 2013
title: Project Zombie Rewind |Trailer| title: Project Zombie Rewind |Trailer|
year: 2013 year: 2013
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer-thumb.jpg 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.mp4
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo Season 2018/s2018.e1029 - Jesse's Minecraft Server Teaser Trailer.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2018-10-29 aired: 2018-10-29
@ -242,9 +242,9 @@ Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
season: 2018 season: 2018
title: Jesse's Minecraft Server | Teaser Trailer title: Jesse's Minecraft Server | Teaser Trailer
year: 2018 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-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.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.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2018-11-02 aired: 2018-11-02

View file

@ -1,9 +1,9 @@
Files created in '{output_directory}' Files created in '{output_directory}'
---------------------------------------- ----------------------------------------
.ytdl-sub-pz-download-archive.json .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-thumb.jpg
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4 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.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2018-10-29 aired: 2018-10-29
@ -21,9 +21,9 @@ Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.nfo
season: 2018 season: 2018
title: Jesse's Minecraft Server | Teaser Trailer title: Jesse's Minecraft Server | Teaser Trailer
year: 2018 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-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.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.nfo
NFO tags: NFO tags:
episodedetails: episodedetails:
aired: 2018-11-02 aired: 2018-11-02

View file

@ -10,6 +10,6 @@ tvshow.nfo
Files removed from '{output_directory}' 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-thumb.jpg
Season 2018/s2018.e1029 - Jesse's Minecraft Server _ Teaser Trailer.mp4 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.nfo

View file

@ -1,8 +1,8 @@
Files created in '{output_directory}' Files created in '{output_directory}'
---------------------------------------- ----------------------------------------
JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg JMC - Oblivion Mod Falcor p.1-thumb.jpg
JMC - Oblivion Mod 'Falcor' p.1.mp4 JMC - Oblivion Mod Falcor p.1.mp4
JMC - Oblivion Mod 'Falcor' p.1.nfo JMC - Oblivion Mod Falcor p.1.nfo
NFO tags: NFO tags:
musicvideo: musicvideo:
album: Music Videos album: Music Videos

View file

@ -1,7 +1,7 @@
Files created in '{output_directory}' Files created in '{output_directory}'
---------------------------------------- ----------------------------------------
JMC - Oblivion Mod 'Falcor' p.1-thumb.jpg JMC - Oblivion Mod Falcor p.1-thumb.jpg
JMC - Oblivion Mod 'Falcor' p.1.mp4 JMC - Oblivion Mod Falcor p.1.mp4
Chapters embedded into the video: Chapters embedded into the video:
0:00: Intro 0:00: Intro
0:10: Part 1 0:10: Part 1
@ -9,7 +9,7 @@ JMC - Oblivion Mod 'Falcor' p.1.mp4
0:30: Part 3 0:30: Part 3
0:40: Part 4 0:40: Part 4
1:01: Part 5 1:01: Part 5
JMC - Oblivion Mod 'Falcor' p.1.nfo JMC - Oblivion Mod Falcor p.1.nfo
NFO tags: NFO tags:
musicvideo: musicvideo:
album: Music Videos album: Music Videos

View file

@ -1,12 +1,7 @@
from pathlib import Path
import pytest import pytest
from e2e.expected_download import ExpectedDownloadFile from e2e.expected_download import assert_expected_downloads
from e2e.expected_download import ExpectedDownloads
from e2e.expected_transaction_log import assert_transaction_log_matches 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 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: class TestSoundcloudDiscography:
""" """
Downloads my (bad) SC recordings I made. Ensure the above files exist and have the Downloads my (bad) SC recordings I made. Ensure the above files exist and have the
@ -70,7 +31,6 @@ class TestSoundcloudDiscography:
self, self,
subscription_dict, subscription_dict,
soundcloud_discography_config, soundcloud_discography_config,
expected_discography_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -85,5 +45,8 @@ class TestSoundcloudDiscography:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="soundcloud/test_soundcloud_discography.txt", transaction_log_summary_file_name="soundcloud/test_soundcloud_discography.txt",
) )
if not dry_run: assert_expected_downloads(
expected_discography_download.assert_files_exist(relative_directory=output_directory) output_directory=output_directory,
dry_run=dry_run,
expected_download_summary_file_name="soundcloud/test_soundcloud_discography.json",
)

View file

@ -1,12 +1,10 @@
import copy import copy
from pathlib import Path
from typing import Dict from typing import Dict
import mergedeep import mergedeep
import pytest import pytest
from conftest import assert_debug_log from conftest import assert_debug_log
from e2e.expected_download import ExpectedDownloadFile from e2e.expected_download import assert_expected_downloads
from e2e.expected_download import ExpectedDownloads
from e2e.expected_transaction_log import assert_transaction_log_matches from e2e.expected_transaction_log import assert_transaction_log_matches
import ytdl_sub.downloaders.downloader import ytdl_sub.downloaders.downloader
@ -45,77 +43,6 @@ def channel_subscription_generator(channel_as_tv_show_config, subscription_name)
return _channel_subscription_generator 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 # RECENT CHANNEL FIXTURES
@pytest.fixture @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 # ROLLING RECENT CHANNEL FIXTURES
@pytest.fixture @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: class TestChannelAsKodiTvShow:
""" """
Downloads my old minecraft youtube channel. Ensure the above files exist and have the Downloads my old minecraft youtube channel. Ensure the above files exist and have the
@ -229,7 +84,6 @@ class TestChannelAsKodiTvShow:
self, self,
channel_subscription_generator, channel_subscription_generator,
channel_preset_dict, channel_preset_dict,
expected_full_channel_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -240,15 +94,17 @@ class TestChannelAsKodiTvShow:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_channel_full.txt", transaction_log_summary_file_name="youtube/test_channel_full.txt",
) )
if not dry_run: assert_expected_downloads(
expected_full_channel_download.assert_files_exist(relative_directory=output_directory) 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]) @pytest.mark.parametrize("dry_run", [True, False])
def test_recent_channel_download( def test_recent_channel_download(
self, self,
channel_subscription_generator, channel_subscription_generator,
recent_channel_preset_dict, recent_channel_preset_dict,
expected_recent_channel_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -262,9 +118,12 @@ class TestChannelAsKodiTvShow:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_channel_recent.txt", 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: if not dry_run:
expected_recent_channel_download.assert_files_exist(relative_directory=output_directory)
# try downloading again, ensure nothing more was downloaded # try downloading again, ensure nothing more was downloaded
with assert_debug_log( with assert_debug_log(
logger=ytdl_sub.downloaders.downloader.download_logger, logger=ytdl_sub.downloaders.downloader.download_logger,
@ -278,8 +137,10 @@ class TestChannelAsKodiTvShow:
"youtube/test_channel_no_additional_downloads.txt" "youtube/test_channel_no_additional_downloads.txt"
), ),
) )
expected_recent_channel_download.assert_files_exist( assert_expected_downloads(
relative_directory=output_directory 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]) @pytest.mark.parametrize("dry_run", [True, False])
@ -287,7 +148,6 @@ class TestChannelAsKodiTvShow:
self, self,
channel_subscription_generator, channel_subscription_generator,
recent_channel_preset_dict, recent_channel_preset_dict,
expected_recent_channel_no_vids_in_range_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -304,10 +164,11 @@ class TestChannelAsKodiTvShow:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt", transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt",
) )
if not dry_run: assert_expected_downloads(
expected_recent_channel_no_vids_in_range_download.assert_files_exist( output_directory=output_directory,
relative_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]) @pytest.mark.parametrize("dry_run", [True, False])
def test_rolling_recent_channel_download( def test_rolling_recent_channel_download(
@ -315,8 +176,6 @@ class TestChannelAsKodiTvShow:
channel_subscription_generator, channel_subscription_generator,
recent_channel_preset_dict, recent_channel_preset_dict,
rolling_recent_channel_preset_dict, rolling_recent_channel_preset_dict,
expected_recent_channel_download,
expected_rolling_recent_channel_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -333,14 +192,18 @@ class TestChannelAsKodiTvShow:
logger=ytdl_sub.downloaders.downloader.download_logger, logger=ytdl_sub.downloaders.downloader.download_logger,
expected_message="RejectedVideoReached, stopping additional downloads", 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( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_channel_recent.txt", 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 # Then, download the rolling recent vids subscription. This should remove one of the
# two videos # two videos
@ -350,16 +213,22 @@ class TestChannelAsKodiTvShow:
): ):
transaction_log = rolling_recent_channel_subscription.download(dry_run=dry_run) 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( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_channel_rolling_recent.txt", transaction_log_summary_file_name="youtube/test_channel_rolling_recent.txt",
regenerate_transaction_log=True,
) )
if not dry_run: assert_expected_downloads(
expected_rolling_recent_channel_download.assert_files_exist( output_directory=output_directory,
relative_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 # Invoke the rolling download again, ensure downloading stopped early from it already
# existing # existing
@ -375,6 +244,8 @@ class TestChannelAsKodiTvShow:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt", transaction_log_summary_file_name="youtube/test_channel_no_additional_downloads.txt",
) )
expected_rolling_recent_channel_download.assert_files_exist( assert_expected_downloads(
relative_directory=output_directory output_directory=output_directory,
dry_run=False,
expected_download_summary_file_name=expected_downloads_summary,
) )

View file

@ -1,8 +1,5 @@
from pathlib import Path
import pytest import pytest
from e2e.expected_download import ExpectedDownloadFile from e2e.expected_download import assert_expected_downloads
from e2e.expected_download import ExpectedDownloads
from e2e.expected_transaction_log import assert_transaction_log_matches from e2e.expected_transaction_log import assert_transaction_log_matches
from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.config.config_file import ConfigFile
@ -63,17 +60,17 @@ def playlist_subscription(config, subscription_name, subscription_dict):
) )
@pytest.fixture # @pytest.fixture
def expected_playlist_download(): # def expected_playlist_download():
# fmt: off # # fmt: off
return ExpectedDownloads( # return ExpectedDownloads(
expected_downloads=[ # expected_downloads=[
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server-thumb.jpg"), md5="a3f1910f9c51f6442f845a528e190829"), # 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.mkv")), # not bitexact TODO: check size
ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.nfo"), md5="10df5dcdb65ab18ecf21b3503c77e48b"), # ExpectedDownloadFile(path=Path("JMC - Jesse's Minecraft Server.nfo"), md5="10df5dcdb65ab18ecf21b3503c77e48b"),
] # ]
) # )
# fmt: on # # fmt: on
class TestYoutubeMergePlaylist: class TestYoutubeMergePlaylist:
@ -83,15 +80,16 @@ class TestYoutubeMergePlaylist:
""" """
@pytest.mark.parametrize("dry_run", [True, False]) @pytest.mark.parametrize("dry_run", [True, False])
def test_merge_playlist_download( def test_merge_playlist_download(self, playlist_subscription, output_directory, dry_run):
self, playlist_subscription, expected_playlist_download, output_directory, dry_run
):
transaction_log = playlist_subscription.download(dry_run=dry_run) transaction_log = playlist_subscription.download(dry_run=dry_run)
assert_transaction_log_matches( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_merge_playlist.txt", transaction_log_summary_file_name="youtube/test_merge_playlist.txt",
) )
assert_expected_downloads(
if not dry_run: output_directory=output_directory,
expected_playlist_download.assert_files_exist(relative_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",
)

View file

@ -1,10 +1,7 @@
from pathlib import Path
import pytest import pytest
from conftest import assert_debug_log from conftest import assert_debug_log
from e2e.conftest import mock_run_from_cli from e2e.conftest import mock_run_from_cli
from e2e.expected_download import ExpectedDownloadFile from e2e.expected_download import assert_expected_downloads
from e2e.expected_download import ExpectedDownloads
from e2e.expected_transaction_log import assert_transaction_log_matches from e2e.expected_transaction_log import assert_transaction_log_matches
import ytdl_sub.downloaders.downloader 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: class TestPlaylistAsKodiMusicVideo:
""" """
Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above
@ -63,7 +34,6 @@ class TestPlaylistAsKodiMusicVideo:
self, self,
music_video_config, music_video_config,
playlist_preset_dict, playlist_preset_dict,
expected_playlist_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -73,24 +43,32 @@ class TestPlaylistAsKodiMusicVideo:
preset_dict=playlist_preset_dict, preset_dict=playlist_preset_dict,
) )
transaction_log = playlist_subscription.download() transaction_log = playlist_subscription.download(dry_run=dry_run)
assert_transaction_log_matches( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_playlist.txt", 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: if not dry_run:
expected_playlist_download.assert_files_exist(relative_directory=output_directory)
# Ensure another invocation will hit ExistingVideoReached
with assert_debug_log( with assert_debug_log(
logger=ytdl_sub.downloaders.downloader.download_logger, logger=ytdl_sub.downloaders.downloader.download_logger,
expected_message="ExistingVideoReached, stopping additional downloads", expected_message="ExistingVideoReached, stopping additional downloads",
): ):
transaction_log = playlist_subscription.download() 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]) @pytest.mark.parametrize("dry_run", [True, False])
def test_playlist_download_from_cli_sub( def test_playlist_download_from_cli_sub(
@ -98,7 +76,6 @@ class TestPlaylistAsKodiMusicVideo:
preset_dict_to_subscription_yaml_generator, preset_dict_to_subscription_yaml_generator,
music_video_config_path, music_video_config_path,
playlist_preset_dict, playlist_preset_dict,
expected_playlist_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -118,17 +95,23 @@ class TestPlaylistAsKodiMusicVideo:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_playlist.txt", 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: if not dry_run:
expected_playlist_download.assert_files_exist(relative_directory=output_directory)
# Ensure another invocation will hit ExistingVideoReached # Ensure another invocation will hit ExistingVideoReached
with assert_debug_log( with assert_debug_log(
logger=ytdl_sub.downloaders.downloader.download_logger, logger=ytdl_sub.downloaders.downloader.download_logger,
expected_message="ExistingVideoReached, stopping additional downloads", expected_message="ExistingVideoReached, stopping additional downloads",
): ):
transaction_log = mock_run_from_cli(args=args)[0][1] 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_expected_downloads(
assert transaction_log.is_empty output_directory=output_directory,
dry_run=dry_run,
expected_download_summary_file_name="youtube/test_playlist.json",
)

View file

@ -1,9 +1,5 @@
from pathlib import Path
from tempfile import NamedTemporaryFile
import pytest import pytest
from e2e.expected_download import ExpectedDownloadFile from e2e.expected_download import assert_expected_downloads
from e2e.expected_download import ExpectedDownloads
from e2e.expected_transaction_log import assert_transaction_log_matches from e2e.expected_transaction_log import assert_transaction_log_matches
from ytdl_sub.config.preset import Preset 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: class TestPlaylistAsKodiMusicVideo:
""" """
Downloads my old minecraft youtube channel, pretends they are music videos. Ensure the above 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]) @pytest.mark.parametrize("dry_run", [True, False])
def test_split_video_download( def test_split_video_download(self, single_video_subscription, output_directory, dry_run):
self, single_video_subscription, expected_single_video_download, output_directory, dry_run transaction_log = single_video_subscription.download(dry_run=dry_run)
):
transaction_log = single_video_subscription.download()
assert_transaction_log_matches( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_split_video.txt", transaction_log_summary_file_name="youtube/test_split_video.txt",
) )
assert_expected_downloads(
if not dry_run: output_directory=output_directory,
expected_single_video_download.assert_files_exist(relative_directory=output_directory) dry_run=dry_run,
expected_download_summary_file_name="youtube/test_split_video.json",
)

View file

@ -1,10 +1,7 @@
from pathlib import Path
import pytest import pytest
from conftest import preset_dict_to_dl_args from conftest import preset_dict_to_dl_args
from e2e.conftest import mock_run_from_cli from e2e.conftest import mock_run_from_cli
from e2e.expected_download import ExpectedDownloadFile from e2e.expected_download import assert_expected_downloads
from e2e.expected_download import ExpectedDownloads
from e2e.expected_transaction_log import assert_transaction_log_matches from e2e.expected_transaction_log import assert_transaction_log_matches
from ytdl_sub.subscriptions.subscription import Subscription 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) 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: class TestYoutubeVideo:
@pytest.mark.parametrize("dry_run", [True, False]) @pytest.mark.parametrize("dry_run", [True, False])
def test_single_video_download( def test_single_video_download(
self, self,
music_video_config, music_video_config,
single_video_preset_dict, single_video_preset_dict,
expected_single_video_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -74,21 +42,23 @@ class TestYoutubeVideo:
preset_dict=single_video_preset_dict, 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( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_video.txt", transaction_log_summary_file_name="youtube/test_video.txt",
) )
if not dry_run: assert_expected_downloads(
expected_single_video_download.assert_files_exist(relative_directory=output_directory) output_directory=output_directory,
dry_run=dry_run,
expected_download_summary_file_name="youtube/test_video.json",
)
@pytest.mark.parametrize("dry_run", [True, False]) @pytest.mark.parametrize("dry_run", [True, False])
def test_single_video_download_from_cli_dl( def test_single_video_download_from_cli_dl(
self, self,
music_video_config_path, music_video_config_path,
single_video_preset_dict_dl_args, single_video_preset_dict_dl_args,
expected_single_video_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -105,8 +75,11 @@ class TestYoutubeVideo:
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_video.txt", transaction_log_summary_file_name="youtube/test_video.txt",
) )
if not dry_run: assert_expected_downloads(
expected_single_video_download.assert_files_exist(relative_directory=output_directory) output_directory=output_directory,
dry_run=dry_run,
expected_download_summary_file_name="youtube/test_video.json",
)
@pytest.mark.parametrize("dry_run", [True, False]) @pytest.mark.parametrize("dry_run", [True, False])
def test_single_video_with_timestamp_chapters_download( def test_single_video_with_timestamp_chapters_download(
@ -114,7 +87,6 @@ class TestYoutubeVideo:
timestamps_file_path, timestamps_file_path,
music_video_config, music_video_config,
single_video_preset_dict, single_video_preset_dict,
expected_single_video_with_chapter_timestamps_download,
output_directory, output_directory,
dry_run, dry_run,
): ):
@ -125,13 +97,14 @@ class TestYoutubeVideo:
preset_dict=single_video_preset_dict, 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( assert_transaction_log_matches(
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name="youtube/test_video_with_chapter_timestamps.txt", transaction_log_summary_file_name="youtube/test_video_with_chapter_timestamps.txt",
) )
if not dry_run: assert_expected_downloads(
expected_single_video_with_chapter_timestamps_download.assert_files_exist( output_directory=output_directory,
relative_directory=output_directory dry_run=dry_run,
) expected_download_summary_file_name="youtube/test_video_with_chapter_timestamps.json",
)