diff --git a/src/ytdl_sub/cli/entrypoint.py b/src/ytdl_sub/cli/entrypoint.py index 86a98e57..c19baf33 100644 --- a/src/ytdl_sub/cli/entrypoint.py +++ b/src/ytdl_sub/cli/entrypoint.py @@ -161,7 +161,7 @@ def _download_subscription_from_cli( extra_arguments=extra_args, config_options=config.config_options ) subscription_args_dict = dl_args_parser.to_subscription_dict() - subscription_name = f"cli-dl-{dl_args_parser.get_args_hash()}" + subscription_name = dl_args_parser.get_dl_subscription_name() subscription = Subscription.from_dict( config=config, preset_name=subscription_name, preset_dict=subscription_args_dict diff --git a/src/ytdl_sub/cli/parsers/dl.py b/src/ytdl_sub/cli/parsers/dl.py index d9e1eb1a..790eacbe 100644 --- a/src/ytdl_sub/cli/parsers/dl.py +++ b/src/ytdl_sub/cli/parsers/dl.py @@ -242,12 +242,10 @@ class DownloadArgsParser: return subscription_dict - def get_args_hash(self) -> str: - """ - :return: Hash of the arguments provided - """ - hash_string = str(sorted(self._unknown_arguments)) - return hashlib.sha256(hash_string.encode()).hexdigest()[-8:] + def get_dl_subscription_name(self) -> str: + to_hash = str(sorted(self._unknown_arguments)) + hash = hashlib.sha256(to_hash.encode()).hexdigest()[-8:] + return f"cli-dl-{hash}" @classmethod def from_dl_override(cls, override: str, config: ConfigFile) -> "DownloadArgsParser": diff --git a/tests/conftest.py b/tests/conftest.py index 522ddb3b..28f4e114 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,10 +2,12 @@ import contextlib import json import logging import os +import shlex import shutil +import sys import tempfile from pathlib import Path -from typing import Any +from typing import Any, List from typing import Callable from typing import Dict from typing import List @@ -18,8 +20,10 @@ from resources import copy_file_fixture from resources import file_fixture_path from yt_dlp.utils import sanitize_filename +from ytdl_sub.cli.entrypoint import main from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.entries.script.custom_functions import CustomFunctions +from ytdl_sub.subscriptions.subscription import Subscription from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.logger import Logger @@ -262,3 +266,9 @@ def default_config_path(default_config) -> str: @pytest.fixture() def music_subscriptions_path() -> Path: return Path("examples/music_subscriptions.yaml") + + +def mock_run_from_cli(args: str) -> List[Subscription]: + args_list = ["ytdl-sub"] + shlex.split(args) + with patch.object(sys, "argv", args_list): + return main() diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index d2957a27..aac8a076 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -1,13 +1,7 @@ -import shlex -import sys import tempfile -from typing import List -from unittest.mock import patch import pytest -from ytdl_sub.cli.entrypoint import main -from ytdl_sub.subscriptions.subscription import Subscription from ytdl_sub.utils.file_handler import FileHandler @@ -33,7 +27,3 @@ def timestamps_file_path(): FileHandler.delete(tmp.name) -def mock_run_from_cli(args: str) -> List[Subscription]: - args_list = ["ytdl-sub"] + shlex.split(args) - with patch.object(sys, "argv", args_list): - return main() diff --git a/tests/e2e/plugins/internal/test_view.py b/tests/e2e/plugins/internal/test_view.py index dbfcd13b..88951250 100644 --- a/tests/e2e/plugins/internal/test_view.py +++ b/tests/e2e/plugins/internal/test_view.py @@ -1,7 +1,7 @@ from typing import Optional import pytest -from e2e.conftest import mock_run_from_cli +from conftest import mock_run_from_cli from ytdl_sub.utils.file_handler import FileMetadata diff --git a/tests/e2e/youtube/test_playlist.py b/tests/e2e/youtube/test_playlist.py index e173c568..65193c15 100644 --- a/tests/e2e/youtube/test_playlist.py +++ b/tests/e2e/youtube/test_playlist.py @@ -2,8 +2,7 @@ from pathlib import Path from typing import Dict import pytest -from conftest import assert_logs -from e2e.conftest import mock_run_from_cli +from conftest import assert_logs, mock_run_from_cli from expected_download import assert_expected_downloads from expected_transaction_log import assert_transaction_log_matches from mergedeep import mergedeep diff --git a/tests/e2e/youtube/test_video.py b/tests/e2e/youtube/test_video.py index c07fc944..4bf4f8f8 100644 --- a/tests/e2e/youtube/test_video.py +++ b/tests/e2e/youtube/test_video.py @@ -1,17 +1,8 @@ -from unittest.mock import patch - import pytest from conftest import preset_dict_to_dl_args -from e2e.conftest import mock_run_from_cli from expected_download import assert_expected_downloads from expected_transaction_log import assert_transaction_log_matches - -from ytdl_sub.downloaders.ytdlp import YTDLP -from ytdl_sub.entries.entry import Entry from ytdl_sub.subscriptions.subscription import Subscription -from ytdl_sub.utils.file_handler import FileHandler -from ytdl_sub.utils.system import IS_WINDOWS -from ytdl_sub.utils.thumbnail import try_convert_download_thumbnail @pytest.fixture @@ -69,32 +60,3 @@ class TestYoutubeVideo: dry_run=dry_run, expected_download_summary_file_name="youtube/test_video.json", ) - - @pytest.mark.parametrize("dry_run", [True, False]) - def test_single_video_download_from_cli_dl( - self, - default_config_path, - single_video_preset_dict_dl_args, - output_directory, - dry_run, - ): - # TODO: Fix CLI parsing on windows when dealing with spaces - if IS_WINDOWS: - return - - args = "--dry-run " if dry_run else "" - args += f"--config {default_config_path} " - args += f"dl {single_video_preset_dict_dl_args}" - subscriptions = mock_run_from_cli(args=args) - - assert len(subscriptions) == 1 - assert_transaction_log_matches( - output_directory=output_directory, - transaction_log=subscriptions[0].transaction_log, - transaction_log_summary_file_name="youtube/test_video_cli.txt", - ) - assert_expected_downloads( - output_directory=output_directory, - dry_run=dry_run, - expected_download_summary_file_name="youtube/test_video_cli.json", - ) diff --git a/tests/integration/cli/test_dl.py b/tests/integration/cli/test_dl.py new file mode 100644 index 00000000..a2d58490 --- /dev/null +++ b/tests/integration/cli/test_dl.py @@ -0,0 +1,65 @@ +from typing import Dict +from unittest.mock import patch + +import pytest + +from conftest import preset_dict_to_dl_args, mock_run_from_cli +from expected_download import assert_expected_downloads +from expected_transaction_log import assert_transaction_log_matches +from ytdl_sub.cli.parsers.dl import DownloadArgsParser + +from ytdl_sub.utils.system import IS_WINDOWS + + +@pytest.fixture +def dl_subscription_dict(output_directory) -> Dict: + return { + "preset": "Jellyfin Music Videos", + "overrides": { + "music_video_artist": "JMC", + "music_video_directory": output_directory, + "url": "https://your.name.here", + }, + } + + +class TestCliDl: + @pytest.mark.parametrize("dry_run", [True, False]) + def test_cli_dl_command( + self, + default_config_path: str, + subscription_name: str, + dl_subscription_dict: Dict, + output_directory: str, + mock_download_collection_entries, + dry_run, + ): + # TODO: Fix CLI parsing on windows when dealing with spaces + if IS_WINDOWS: + return + + args = "--dry-run " if dry_run else "" + args += f"--config {default_config_path} " + args += f"dl {preset_dict_to_dl_args(dl_subscription_dict)} " + + with ( + patch.object(DownloadArgsParser, "get_dl_subscription_name") as mock_subscription_name, + mock_download_collection_entries( + is_youtube_channel=False, + num_urls=1, + is_extracted_audio=False, + is_dry_run=dry_run, + )): + mock_subscription_name.return_value = subscription_name + subscriptions = mock_run_from_cli(args=args) + + assert_transaction_log_matches( + output_directory=output_directory, + transaction_log=subscriptions[0].transaction_log, + transaction_log_summary_file_name="dl/test_cli_dl_command.txt", + ) + assert_expected_downloads( + output_directory=output_directory, + dry_run=dry_run, + expected_download_summary_file_name="dl/test_cli_dl_command.json", + ) diff --git a/tests/resources/expected_downloads_summaries/dl/test_cli_dl_command.json b/tests/resources/expected_downloads_summaries/dl/test_cli_dl_command.json new file mode 100644 index 00000000..d2ad4ef9 --- /dev/null +++ b/tests/resources/expected_downloads_summaries/dl/test_cli_dl_command.json @@ -0,0 +1,19 @@ +{ + ".ytdl-sub-subscription_test-download-archive.json": "76e202bd03ceef93daaffffee2cfa193", + "JMC/Mock Entry 20-1.info.json": "INFO_JSON", + "JMC/Mock Entry 20-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "JMC/Mock Entry 20-1.mp4": "dbaeb2a3bfd1de1c7e9615e8bdacb910", + "JMC/Mock Entry 20-1.nfo": "fefcf0b3e4f4ff80ad636584d50dadec", + "JMC/Mock Entry 20-2.info.json": "INFO_JSON", + "JMC/Mock Entry 20-2.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "JMC/Mock Entry 20-2.mp4": "76c2c70572489c684923a51cb1b50687", + "JMC/Mock Entry 20-2.nfo": "025c0b631da5ff5470382b38fce78d2d", + "JMC/Mock Entry 20-3.info.json": "INFO_JSON", + "JMC/Mock Entry 20-3.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "JMC/Mock Entry 20-3.mp4": "7bb4f21d59a6fb91836537b27a24e776", + "JMC/Mock Entry 20-3.nfo": "618b0ff948d9de2e10cf1da8c0dd6615", + "JMC/Mock Entry 21-1.info.json": "INFO_JSON", + "JMC/Mock Entry 21-1.jpg": "e80c508c4818454300133fe1dc1a9cd7", + "JMC/Mock Entry 21-1.mp4": "7b008531ca5660b51fb8adc83c799084", + "JMC/Mock Entry 21-1.nfo": "e5c715749efc1603a6e2f59244d87aba" +} \ No newline at end of file diff --git a/tests/resources/transaction_log_summaries/dl/test_cli_dl_command.txt b/tests/resources/transaction_log_summaries/dl/test_cli_dl_command.txt new file mode 100644 index 00000000..bb74a9cc --- /dev/null +++ b/tests/resources/transaction_log_summaries/dl/test_cli_dl_command.txt @@ -0,0 +1,77 @@ +Files created: +---------------------------------------- +{output_directory} + .ytdl-sub-subscription_test-download-archive.json +{output_directory}/JMC + Mock Entry 20-1.info.json + Mock Entry 20-1.jpg + Mock Entry 20-1.mp4 + Video Tags: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + year: 2020 + Mock Entry 20-1.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-1 + Mock Entry 20-2.info.json + Mock Entry 20-2.jpg + Mock Entry 20-2.mp4 + Video Tags: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + year: 2020 + Mock Entry 20-2.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2020-08-08 + title: Mock Entry 20-2 + Mock Entry 20-3.info.json + Mock Entry 20-3.jpg + Mock Entry 20-3.mp4 + Video Tags: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + year: 2020 + Mock Entry 20-3.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2020-08-07 + title: Mock Entry 20-3 + Mock Entry 21-1.info.json + Mock Entry 21-1.jpg + Mock Entry 21-1.mp4 + Video Tags: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 + year: 2021 + Mock Entry 21-1.nfo + NFO tags: + musicvideo: + album: Music Videos + artist: JMC + genre: ytdl-sub + premiered: 2021-08-08 + title: Mock Entry 21-1 \ No newline at end of file diff --git a/tests/unit/config/test_subscription.py b/tests/unit/config/test_subscription.py index 574da070..88f9dfc6 100644 --- a/tests/unit/config/test_subscription.py +++ b/tests/unit/config/test_subscription.py @@ -186,6 +186,11 @@ def preset_with_subscription_overrides_map( "elem2", "elem3", ], + "custom_map": { + "custom_map_key": [ + "custom_map_list_value" + ] + } } }, }, @@ -290,6 +295,11 @@ def test_subscription_overrides_map( "elem2", "elem3", ], + "custom_map": { + "custom_map_key": [ + "custom_map_list_value" + ] + } }