From a16f4c9c4b2027e1d0a47453d33c112ff8a62f47 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Tue, 25 Oct 2022 23:21:18 -0700 Subject: [PATCH] preset test --- src/ytdl_sub/config/preset.py | 36 ++++++++++++++++++----- src/ytdl_sub/prebuilt_presets/__init__.py | 6 ++++ tests/unit/config/test_config_file.py | 24 +++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/ytdl_sub/config/preset.py b/src/ytdl_sub/config/preset.py index b190ace0..84974d35 100644 --- a/src/ytdl_sub/config/preset.py +++ b/src/ytdl_sub/config/preset.py @@ -22,6 +22,9 @@ from ytdl_sub.downloaders.downloader import DownloaderValidator from ytdl_sub.entries.entry import Entry from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import PluginOptions +from ytdl_sub.prebuilt_presets import PREBUILT_PRESET_NAMES +from ytdl_sub.prebuilt_presets import PUBLISHED_PRESET_NAMES +from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.yaml import dump_yaml from ytdl_sub.validators.strict_dict_validator import StrictDictValidator from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator @@ -45,6 +48,19 @@ PRESET_KEYS = { } +def _parent_preset_error_message( + current_preset_name: str, parent_preset_name: str, presets: List[str] +) -> ValidationException: + user_defined_presets = set(presets) - PREBUILT_PRESET_NAMES - {current_preset_name} + + return validation_exception( + name=current_preset_name, + error_message=f"preset '{parent_preset_name}' does not exist in the provided config.\n" + f"Available prebuilt presets: {', '.join(sorted(PUBLISHED_PRESET_NAMES))}\n" + f"Your presets: {', '.join(sorted(user_defined_presets))}", + ) + + class PresetPlugins: _TPluginOptions = TypeVar("_TPluginOptions", bound=PluginOptions) @@ -180,6 +196,11 @@ class Preset(_PresetShell): Preset name value Preset value + + Raises + ------ + ValidationException + If validation fails """ # Ensure value is a dict _ = _PresetShell(name=name, value=value) @@ -201,10 +222,10 @@ class Preset(_PresetShell): parent_presets = StringListValidator(name=f"{name}.preset", value=value.get("preset", [])) for parent_preset_name in parent_presets.list: if parent_preset_name.value not in config.presets.keys: - raise validation_exception( - name=f"{name}.preset", - error_message=f"preset '{parent_preset_name.value}' does not exist in the " - f"provided config. Available presets: {', '.join(config.presets.keys)}", + raise _parent_preset_error_message( + current_preset_name=name, + parent_preset_name=parent_preset_name.value, + presets=config.presets.keys, ) @property @@ -373,9 +394,10 @@ class Preset(_PresetShell): # Make sure the parent preset actually exists if parent_preset not in config.presets.keys: - raise self._validation_exception( - f"preset '{parent_preset}' does not exist in the provided config. " - f"Available presets: {', '.join(config.presets.keys)}" + raise _parent_preset_error_message( + current_preset_name=self._name, + parent_preset_name=parent_preset, + presets=config.presets.keys, ) parent_preset_dict = copy.deepcopy(config.presets.dict[parent_preset]) diff --git a/src/ytdl_sub/prebuilt_presets/__init__.py b/src/ytdl_sub/prebuilt_presets/__init__.py index 96701605..43ae2433 100644 --- a/src/ytdl_sub/prebuilt_presets/__init__.py +++ b/src/ytdl_sub/prebuilt_presets/__init__.py @@ -1,6 +1,7 @@ import pathlib from typing import Any from typing import Dict +from typing import Set import mergedeep @@ -21,3 +22,8 @@ def _merge_presets() -> Dict[str, Any]: PREBUILT_PRESETS: Dict[str, Any] = _merge_presets() + +PREBUILT_PRESET_NAMES: Set[str] = set(PREBUILT_PRESETS.keys()) +PUBLISHED_PRESET_NAMES: Set[str] = { + name for name in PREBUILT_PRESET_NAMES if not name.startswith("_") +} diff --git a/tests/unit/config/test_config_file.py b/tests/unit/config/test_config_file.py index 733d5f2f..7e465705 100644 --- a/tests/unit/config/test_config_file.py +++ b/tests/unit/config/test_config_file.py @@ -6,6 +6,7 @@ import pytest from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.config.preset import PRESET_KEYS +from ytdl_sub.config.preset_class_mappings import DownloadStrategyMapping from ytdl_sub.config.preset_class_mappings import PluginMapping from ytdl_sub.utils.exceptions import ValidationException @@ -44,10 +45,19 @@ class TestConfigFilePartiallyValidatesPresets: def test_success(self, preset_dict: Dict): self._partial_validate(preset_dict) + @pytest.mark.parametrize("key", ["output_options", "overrides", "ytdl_options"]) + def test_success__empty_preset_keys(self, key): + self._partial_validate({key: {}}) + @pytest.mark.parametrize("plugin", PluginMapping.plugins()) def test_success__empty_plugins(self, plugin: str): self._partial_validate({plugin: {}}) + @pytest.mark.parametrize("source", DownloadStrategyMapping.sources()) + def test_success__empty_sources(self, source: str): + for download_strategy in DownloadStrategyMapping.source_download_strategies(source): + self._partial_validate({source: {"download_strategy": download_strategy}}) + def test_error__bad_preset_section(self): self._partial_validate( preset_dict={"does_not_exist": "lol"}, @@ -129,3 +139,17 @@ class TestConfigFilePartiallyValidatesPresets: preset_dict=preset_dict, expected_error_message="Validation error in partial_preset.ytdl_options", ) + + @pytest.mark.parametrize( + "preset_dict", + [ + {"preset": "DNE"}, + {"preset": ["DNE"]}, + ], + ) + def test_error__non_existent_preset(self, preset_dict): + self._partial_validate( + preset_dict=preset_dict, + expected_error_message="Validation error in partial_preset: " + "preset 'DNE' does not exist in the provided config.", + )