Expected download summaries WIP
This commit is contained in:
parent
3e60f7d1da
commit
127ba0b184
12 changed files with 148 additions and 106 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
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
|
||||||
|
|
@ -6,14 +7,25 @@ from typing import List
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Union
|
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: Optional[Union[str, List[str]]] = None
|
||||||
metadata: Optional[FileMetadata] = None
|
|
||||||
|
|
||||||
|
|
||||||
class ExpectedDownloads:
|
class ExpectedDownloads:
|
||||||
|
|
@ -35,21 +47,16 @@ 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):
|
||||||
"""
|
"""
|
||||||
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
|
relative_file_paths = _get_files_in_directory(relative_directory=relative_directory)
|
||||||
for path in Path(relative_directory).rglob("*"):
|
|
||||||
if path.is_file():
|
|
||||||
num_files += 1
|
|
||||||
|
|
||||||
relative_path = Path(*path.parts[3:])
|
for file_path in relative_file_paths:
|
||||||
assert self.contains(
|
assert self.contains(file_path), f"File {file_path} was created but not expected"
|
||||||
relative_path
|
|
||||||
), f"File {relative_path} was created but not expected"
|
|
||||||
|
|
||||||
assert num_files == self.file_count, "Mismatch in number of created files"
|
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
|
||||||
|
|
@ -60,9 +67,7 @@ class ExpectedDownloads:
|
||||||
if expected_download.md5 is None:
|
if expected_download.md5 is None:
|
||||||
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()
|
|
||||||
|
|
||||||
expected_md5_hash = expected_download.md5
|
expected_md5_hash = expected_download.md5
|
||||||
if isinstance(expected_download.md5, str):
|
if isinstance(expected_download.md5, str):
|
||||||
expected_md5_hash = [expected_download.md5]
|
expected_md5_hash = [expected_download.md5]
|
||||||
|
|
@ -71,3 +76,57 @@ class ExpectedDownloads:
|
||||||
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_md5_hash}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@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,
|
||||||
|
regenerate_expected_download_summary: bool = True,
|
||||||
|
):
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ def assert_transaction_log_matches(
|
||||||
output_directory: str,
|
output_directory: str,
|
||||||
transaction_log: FileHandlerTransactionLog,
|
transaction_log: FileHandlerTransactionLog,
|
||||||
transaction_log_summary_file_name: str,
|
transaction_log_summary_file_name: str,
|
||||||
regenerate_transaction_log: bool = False,
|
regenerate_transaction_log: bool = True,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Parameters
|
Parameters
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 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].mp4
|
||||||
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w_Mods' [PC].nfo
|
Season 2011/s2011.e1121 - Skyrim 'Ultra HD w⧸Mods' [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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,9 @@ def expected_full_channel_download():
|
||||||
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.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.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-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.mp4"), md5="e733b4cc385b953b08c8eb0f47e03c1e"),
|
||||||
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server _ IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"),
|
ExpectedDownloadFile(path=Path("Season 2018/s2018.e1102 - Jesse's Minecraft Server | IP mc.jesse.id.nfo"), md5="2b3ccb3f1ef81ee49fe1afb88f275a09"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
|
||||||
|
|
@ -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,14 +42,17 @@ 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(
|
||||||
|
|
@ -105,8 +76,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 +88,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 +98,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"
|
||||||
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue