refactored, tests passing
This commit is contained in:
parent
056b111be6
commit
f2d60b3ade
4 changed files with 242 additions and 90 deletions
|
|
@ -13,12 +13,12 @@ TV Show Full Archive:
|
|||
"Opeth": "https://www.youtube.com/channel/UCmQSJTFZaXN85gYk6W3XbdQ"
|
||||
|
||||
# Sets "Kids" for genre, "TV-Y" for content rating
|
||||
= Kids | TV-Y:
|
||||
= Kids | = TV-Y:
|
||||
"Jake Trains": "https://www.youtube.com/@JakeTrains"
|
||||
"Kids Toys Play": "https://www.youtube.com/@KidsToysPlayChannel"
|
||||
|
||||
|
||||
# All subscriptions under this will use the `TV Show Only Recent` preset
|
||||
TV Show Only Recent:
|
||||
= News | TV-14:
|
||||
= News | = TV-14:
|
||||
"BBC": "https://www.youtube.com/@BBCNews"
|
||||
|
|
|
|||
|
|
@ -120,45 +120,9 @@ class YTDLOptions(LiteralDictValidator):
|
|||
"""
|
||||
|
||||
|
||||
class OverridesVariables(DictFormatterValidator):
|
||||
"""
|
||||
Override variables that are automatically added to every subscription.
|
||||
"""
|
||||
|
||||
def _add_override_variable(self, key_name: str, format_string: str, sanitize: bool = False):
|
||||
if sanitize:
|
||||
key_name = f"{key_name}_sanitized"
|
||||
format_string = sanitize_filename(format_string)
|
||||
|
||||
self._value[key_name] = StringFormatterValidator(
|
||||
name="__should_never_fail__",
|
||||
value=format_string,
|
||||
)
|
||||
|
||||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
|
||||
# Add sanitized and non-sanitized override variables
|
||||
for sanitize in [True, False]:
|
||||
self._add_override_variable(
|
||||
key_name="subscription_name",
|
||||
format_string=self.subscription_name,
|
||||
sanitize=sanitize,
|
||||
)
|
||||
|
||||
@property
|
||||
def subscription_name(self) -> str:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
Name of the subscription
|
||||
"""
|
||||
return self._root_name
|
||||
|
||||
|
||||
# Disable for proper docstring formatting
|
||||
# pylint: disable=line-too-long
|
||||
class Overrides(OverridesVariables):
|
||||
class Overrides(DictFormatterValidator):
|
||||
"""
|
||||
Optional. This section allows you to define variables that can be used in any string formatter.
|
||||
For example, if you want your file and thumbnail files to match without copy-pasting a large
|
||||
|
|
@ -188,6 +152,16 @@ class Overrides(OverridesVariables):
|
|||
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
def _add_override_variable(self, key_name: str, format_string: str, sanitize: bool = False):
|
||||
if sanitize:
|
||||
key_name = f"{key_name}_sanitized"
|
||||
format_string = sanitize_filename(format_string)
|
||||
|
||||
self._value[key_name] = StringFormatterValidator(
|
||||
name="__should_never_fail__",
|
||||
value=format_string,
|
||||
)
|
||||
|
||||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
import copy
|
||||
import dataclasses
|
||||
from abc import ABC
|
||||
from abc import abstractmethod
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import final
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.config.preset_options import Overrides
|
||||
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
||||
from ytdl_sub.validators.validators import DictValidator
|
||||
from ytdl_sub.validators.validators import StringListValidator
|
||||
from ytdl_sub.validators.validators import StringValidator
|
||||
|
|
@ -36,18 +39,6 @@ def subscription_value_variable_name() -> str:
|
|||
return "subscription_value"
|
||||
|
||||
|
||||
def maybe_indent_override_values(value: str) -> List[str]:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
Value if it is an overide [Value]. None otherwise.
|
||||
"""
|
||||
if value.startswith("="):
|
||||
# Drop the =, split on |, and strip each indent_value (both left + right)
|
||||
return [indent_value.strip() for indent_value in value[1:].split("|")]
|
||||
return []
|
||||
|
||||
|
||||
class SubscriptionOutput(Validator, ABC):
|
||||
def __init__(self, name, value, presets: List[str], indent_overrides: List[str]):
|
||||
super().__init__(name, value)
|
||||
|
|
@ -75,6 +66,15 @@ class SubscriptionOutput(Validator, ABC):
|
|||
Subscriptions in the form of ``{ subscription_name: preset_dict }``
|
||||
"""
|
||||
|
||||
@property
|
||||
def subscription_name(self) -> str:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
The name of the subscription
|
||||
"""
|
||||
return self._leaf_name
|
||||
|
||||
|
||||
class SubscriptionPresetDictValidator(SubscriptionOutput, DictValidator):
|
||||
def __init__(self, name, value, presets: List[str], indent_overrides: List[str]):
|
||||
|
|
@ -93,12 +93,46 @@ class SubscriptionPresetDictValidator(SubscriptionOutput, DictValidator):
|
|||
|
||||
output_dict["preset"] = parent_presets + self._presets + global_presets_to_apply
|
||||
output_dict["overrides"] = dict(
|
||||
output_dict.get("overrides", {}), **self._indent_overrides_dict()
|
||||
output_dict.get("overrides", {}),
|
||||
**self._indent_overrides_dict(),
|
||||
**{"subscription_name": self.subscription_name},
|
||||
)
|
||||
return {self._leaf_name: output_dict}
|
||||
return {self.subscription_name: output_dict}
|
||||
|
||||
|
||||
class SubscriptionValueValidator(SubscriptionOutput, StringValidator):
|
||||
class SubscriptionLeafValidator(SubscriptionOutput, ABC):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
value,
|
||||
config: ConfigFile,
|
||||
presets: List[str],
|
||||
indent_overrides: List[str],
|
||||
):
|
||||
super().__init__(name=name, value=value, presets=presets, indent_overrides=indent_overrides)
|
||||
|
||||
if self.subscription_name in config.presets.keys:
|
||||
raise self._validation_exception(
|
||||
f"{self.subscription_name} conflicts with an existing preset name and cannot be "
|
||||
f"used as a subscription name"
|
||||
)
|
||||
|
||||
self._overrides_to_add: Dict[str, str] = {"subscription_name": self.subscription_name}
|
||||
|
||||
@final
|
||||
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
||||
return {
|
||||
self.subscription_name: {
|
||||
"preset": self._presets + global_presets_to_apply,
|
||||
"overrides": dict(
|
||||
self._indent_overrides_dict(),
|
||||
**self._overrides_to_add,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SubscriptionValueValidator(SubscriptionLeafValidator, StringValidator):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
|
|
@ -108,30 +142,72 @@ class SubscriptionValueValidator(SubscriptionOutput, StringValidator):
|
|||
indent_overrides: List[str],
|
||||
subscription_value: Optional[str],
|
||||
):
|
||||
super().__init__(name=name, value=value, presets=presets, indent_overrides=indent_overrides)
|
||||
super().__init__(
|
||||
name=name,
|
||||
value=value,
|
||||
config=config,
|
||||
presets=presets,
|
||||
indent_overrides=indent_overrides,
|
||||
)
|
||||
|
||||
if self._leaf_name in config.presets.keys:
|
||||
raise self._validation_exception(
|
||||
f"{self._leaf_name} conflicts with an existing preset name and cannot be "
|
||||
f"used as a subscription name"
|
||||
)
|
||||
self._subscription_value: Optional[str] = subscription_value
|
||||
|
||||
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
||||
subscription_value_dict: Dict[str, str] = {"subscription_value": self.value}
|
||||
# TODO: Eventually delete in favor of {subscription_value}
|
||||
if self._subscription_value:
|
||||
subscription_value_dict[self._subscription_value] = self.value
|
||||
if subscription_value:
|
||||
self._overrides_to_add[subscription_value] = self.value
|
||||
self._overrides_to_add["subscription_value"] = self.value
|
||||
|
||||
return {
|
||||
self._leaf_name: {
|
||||
"preset": self._presets + global_presets_to_apply,
|
||||
"overrides": dict(
|
||||
subscription_value_dict,
|
||||
**self._indent_overrides_dict(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
class SubscriptionListValuesValidator(SubscriptionLeafValidator, StringListValidator):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
value,
|
||||
config: ConfigFile,
|
||||
presets: List[str],
|
||||
indent_overrides: List[str],
|
||||
):
|
||||
super().__init__(
|
||||
name=name,
|
||||
value=value,
|
||||
config=config,
|
||||
presets=presets,
|
||||
indent_overrides=indent_overrides,
|
||||
)
|
||||
|
||||
for idx, list_value in enumerate(self.list):
|
||||
# Write the first list value into subscription_value as well
|
||||
if idx == 0:
|
||||
self._overrides_to_add["subscription_value"] = list_value.value
|
||||
self._overrides_to_add[f"subscription_value_{idx + 1}"] = list_value.value
|
||||
|
||||
|
||||
class SubscriptionWithOverridesValidator(SubscriptionLeafValidator, DictFormatterValidator):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
value,
|
||||
config: ConfigFile,
|
||||
presets: List[str],
|
||||
indent_overrides: List[str],
|
||||
):
|
||||
super().__init__(
|
||||
name=name,
|
||||
value=value,
|
||||
config=config,
|
||||
presets=presets,
|
||||
indent_overrides=indent_overrides,
|
||||
)
|
||||
|
||||
self._overrides_to_add = dict(self.dict_with_format_strings, **self._overrides_to_add)
|
||||
|
||||
@property
|
||||
def subscription_name(self) -> str:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
Name of the subscription
|
||||
"""
|
||||
# drop the ~ in "~Subscription Name":
|
||||
return super().subscription_name[1:]
|
||||
|
||||
|
||||
class SubscriptionValidator(SubscriptionOutput):
|
||||
|
|
@ -139,6 +215,35 @@ class SubscriptionValidator(SubscriptionOutput):
|
|||
Top-level subscription validator
|
||||
"""
|
||||
|
||||
@dataclasses.dataclass
|
||||
class PresetIndentKey:
|
||||
presets: List[str] = dataclasses.field(default_factory=list)
|
||||
indent_overrides: List[str] = dataclasses.field(default_factory=list)
|
||||
|
||||
def _preset_indent_key(self, key: str, config: ConfigFile) -> Optional[PresetIndentKey]:
|
||||
presets: List[str] = []
|
||||
indent_overrides: List[str] = []
|
||||
|
||||
stripped_split_keys = [sub_key.strip() for sub_key in key.split("|")]
|
||||
for sub_key in stripped_split_keys:
|
||||
if sub_key.startswith("="):
|
||||
indent_overrides.append(sub_key[1:].strip())
|
||||
elif sub_key in config.presets.keys:
|
||||
presets.append(sub_key)
|
||||
else:
|
||||
if presets or indent_overrides:
|
||||
raise self._validation_exception(
|
||||
f"'{sub_key.strip()}' in '{key.strip()}' is not a preset name. "
|
||||
f"To use as a subscription indent value, define it as '= {sub_key.strip()}'"
|
||||
)
|
||||
|
||||
if not presets and not indent_overrides:
|
||||
return None
|
||||
|
||||
return SubscriptionValidator.PresetIndentKey(
|
||||
presets=presets, indent_overrides=indent_overrides
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
|
|
@ -154,6 +259,8 @@ class SubscriptionValidator(SubscriptionOutput):
|
|||
for key, obj in value.items():
|
||||
obj_name = f"{name}.{key}" if name else key
|
||||
|
||||
# Subscription defined as
|
||||
# "Sub Name": "value"
|
||||
if isinstance(obj, str):
|
||||
self._children.append(
|
||||
SubscriptionValueValidator(
|
||||
|
|
@ -165,26 +272,45 @@ class SubscriptionValidator(SubscriptionOutput):
|
|||
subscription_value=subscription_value,
|
||||
)
|
||||
)
|
||||
elif isinstance(value, dict):
|
||||
if key in config.presets.keys:
|
||||
self._children.append(
|
||||
SubscriptionValidator(
|
||||
name=obj_name,
|
||||
value=obj,
|
||||
config=config,
|
||||
presets=presets + [key],
|
||||
indent_overrides=indent_overrides,
|
||||
subscription_value=subscription_value,
|
||||
)
|
||||
# Subscription defined as
|
||||
# "Sub Name":
|
||||
# - "value1"
|
||||
# - "value2"
|
||||
elif isinstance(obj, list):
|
||||
self._children.append(
|
||||
SubscriptionListValuesValidator(
|
||||
name=obj_name,
|
||||
value=obj,
|
||||
config=config,
|
||||
presets=presets,
|
||||
indent_overrides=indent_overrides,
|
||||
)
|
||||
elif override_values := maybe_indent_override_values(key):
|
||||
)
|
||||
elif isinstance(obj, dict):
|
||||
# Subscription defined as
|
||||
# "~Sub Name":
|
||||
# override_1: "abc"
|
||||
# override_2: "123"
|
||||
if key.startswith("~"):
|
||||
self._children.append(
|
||||
SubscriptionValidator(
|
||||
SubscriptionWithOverridesValidator(
|
||||
name=obj_name,
|
||||
value=obj,
|
||||
config=config,
|
||||
presets=presets,
|
||||
indent_overrides=indent_overrides + override_values,
|
||||
indent_overrides=indent_overrides,
|
||||
)
|
||||
)
|
||||
elif (
|
||||
preset_indent_key := self._preset_indent_key(key=key, config=config)
|
||||
) is not None:
|
||||
self._children.append(
|
||||
SubscriptionValidator(
|
||||
name=obj_name,
|
||||
value=obj,
|
||||
config=config,
|
||||
presets=presets + preset_indent_key.presets,
|
||||
indent_overrides=indent_overrides + preset_indent_key.indent_overrides,
|
||||
subscription_value=subscription_value,
|
||||
)
|
||||
)
|
||||
|
|
@ -197,6 +323,10 @@ class SubscriptionValidator(SubscriptionOutput):
|
|||
indent_overrides=indent_overrides,
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise self._validation_exception(
|
||||
"Subscription value should either be a string, list, or object"
|
||||
)
|
||||
|
||||
def subscription_dicts(self, global_presets_to_apply: List[str]) -> Dict[str, Dict]:
|
||||
subscription_dicts: Dict[str, Dict] = {}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,25 @@ def preset_with_subscription_value_nested_presets_and_indent_variables(
|
|||
@pytest.fixture
|
||||
def preset_with_subscription_value_nested_presets_and_indent_variables_same_line(
|
||||
preset_with_subscription_value: Dict,
|
||||
):
|
||||
return dict(
|
||||
preset_with_subscription_value,
|
||||
**{
|
||||
"parent_preset_2": {
|
||||
"=INDENT_1": {
|
||||
"parent_preset_1": {"test_2_1": "is_2_1_overwritten"},
|
||||
"= INDENT_2 | = INDENT_3 ": {
|
||||
"test_1": "is_1_overwritten",
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def preset_with_subscription_value_nested_presets_and_indent_variables_same_line_old_format_errors(
|
||||
preset_with_subscription_value: Dict,
|
||||
):
|
||||
return dict(
|
||||
preset_with_subscription_value,
|
||||
|
|
@ -191,6 +210,7 @@ def test_subscription_file_value_applies_sub_file_takes_precedence(
|
|||
assert value_sub.get("test_file_subscription_value") == "is_overwritten"
|
||||
assert value_sub.get("test_config_subscription_value") == "original"
|
||||
assert value_sub.get("subscription_name") == "test_value"
|
||||
assert value_sub.get("subscription_name_sanitized") == "test_value"
|
||||
assert value_sub.get("subscription_value") == "is_overwritten"
|
||||
assert value_sub.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||
|
||||
|
|
@ -209,6 +229,7 @@ def test_subscription_file_value_applies_from_config(
|
|||
assert value_sub.get("test_file_subscription_value") == "original"
|
||||
assert value_sub.get("test_config_subscription_value") == "is_overwritten"
|
||||
assert value_sub.get("subscription_name") == "test_value"
|
||||
assert value_sub.get("subscription_name_sanitized") == "test_value"
|
||||
assert value_sub.get("subscription_value") == "is_overwritten"
|
||||
assert value_sub.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||
|
||||
|
|
@ -229,11 +250,13 @@ def test_subscription_file_value_applies_from_config_and_nested(
|
|||
|
||||
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
||||
assert sub_1.get("subscription_name") == "test_1"
|
||||
assert sub_1.get("subscription_name_sanitized") == "test_1"
|
||||
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
||||
assert sub_1.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||
|
||||
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
||||
assert sub_2_1.get("subscription_name") == "test_2_1"
|
||||
assert sub_2_1.get("subscription_name_sanitized") == "test_2_1"
|
||||
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
||||
assert sub_2_1.get("current_override") == "__preset__" # ensure __preset__ takes precedence
|
||||
|
||||
|
|
@ -262,6 +285,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
|||
|
||||
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
||||
assert sub_1.get("subscription_name") == "test_1"
|
||||
assert sub_1.get("subscription_name_sanitized") == "test_1"
|
||||
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
||||
assert sub_1.get("subscription_indent_1") == "INDENT_1"
|
||||
assert sub_1.get("subscription_indent_2") == "INDENT_2"
|
||||
|
|
@ -269,6 +293,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
|||
|
||||
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
||||
assert sub_2_1.get("subscription_name") == "test_2_1"
|
||||
assert sub_2_1.get("subscription_name_sanitized") == "test_2_1"
|
||||
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
||||
assert sub_2_1.get("subscription_indent_1") == "INDENT_1"
|
||||
assert sub_2_1.get("subscription_indent_2") == "original_2"
|
||||
|
|
@ -299,6 +324,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
|||
|
||||
assert sub_1.get("test_config_subscription_value") == "is_1_overwritten"
|
||||
assert sub_1.get("subscription_name") == "test_1"
|
||||
assert sub_1.get("subscription_name_sanitized") == "test_1"
|
||||
assert sub_1.get("subscription_value") == "is_1_overwritten"
|
||||
assert sub_1.get("subscription_indent_1") == "INDENT_1"
|
||||
assert sub_1.get("subscription_indent_2") == "INDENT_2"
|
||||
|
|
@ -307,6 +333,7 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
|||
|
||||
assert sub_2_1.get("test_config_subscription_value") == "is_2_1_overwritten"
|
||||
assert sub_2_1.get("subscription_name") == "test_2_1"
|
||||
assert sub_2_1.get("subscription_name_sanitized") == "test_2_1"
|
||||
assert sub_2_1.get("subscription_value") == "is_2_1_overwritten"
|
||||
assert sub_2_1.get("subscription_indent_1") == "INDENT_1"
|
||||
assert sub_2_1.get("subscription_indent_2") == "original_2"
|
||||
|
|
@ -314,6 +341,24 @@ def test_subscription_file_value_applies_from_config_and_nested_and_indent_varia
|
|||
assert "subscription_indent_3" not in sub_2_1
|
||||
|
||||
|
||||
def test_subscription_file_value_applies_from_config_and_nested_and_indent_variables_same_line_old_format_errors(
|
||||
config_file_with_subscription_value: ConfigFile,
|
||||
preset_with_subscription_value_nested_presets_and_indent_variables_same_line_old_format_errors: Dict,
|
||||
):
|
||||
with mock_load_yaml(
|
||||
preset_dict=preset_with_subscription_value_nested_presets_and_indent_variables_same_line_old_format_errors
|
||||
), pytest.raises(
|
||||
ValidationException,
|
||||
match=re.escape(
|
||||
"Validation error in parent_preset_2.=INDENT_1: 'INDENT_3' in '= INDENT_2 | INDENT_3' is not a preset name. "
|
||||
"To use as a subscription indent value, define it as '= INDENT_3'"
|
||||
),
|
||||
):
|
||||
Subscription.from_file_path(
|
||||
config=config_file_with_subscription_value, subscription_path="mocked"
|
||||
)
|
||||
|
||||
|
||||
def test_subscription_file_bad_value(config_file: ConfigFile):
|
||||
with mock_load_yaml(preset_dict={"__value__": {"should be": "string"}}), pytest.raises(
|
||||
ValidationException,
|
||||
|
|
@ -346,7 +391,7 @@ def test_subscription_file_using_conflicting_preset_name(config_file: ConfigFile
|
|||
def test_subscription_file_invalid_form(config_file: ConfigFile):
|
||||
with mock_load_yaml(preset_dict={"sub_name": 4332}), pytest.raises(
|
||||
ValidationException,
|
||||
match=re.escape(f"Validation error in sub_name: should be of type object."),
|
||||
match=re.escape(f"Subscription value should either be a string, list, or object"),
|
||||
):
|
||||
_ = Subscription.from_file_path(config=config_file, subscription_path="mocked")
|
||||
|
||||
|
|
@ -363,6 +408,7 @@ def test_tv_show_subscriptions(
|
|||
jake_train_overrides = subs[2].overrides.dict_with_format_strings
|
||||
|
||||
assert jake_train_overrides["subscription_name"] == "Jake Trains"
|
||||
assert jake_train_overrides["subscription_name_sanitized"] == "Jake Trains"
|
||||
assert jake_train_overrides["subscription_value"] == "https://www.youtube.com/@JakeTrains"
|
||||
assert jake_train_overrides["subscription_indent_1"] == "Kids"
|
||||
assert jake_train_overrides["subscription_indent_2"] == "TV-Y"
|
||||
|
|
@ -378,6 +424,7 @@ def test_music_subscriptions(default_config: ConfigFile, music_subscriptions_pat
|
|||
monk = subs[2].overrides.dict_with_format_strings
|
||||
|
||||
assert monk["subscription_name"] == "Stan Getz"
|
||||
assert monk["subscription_name_sanitized"] == "Stan Getz"
|
||||
assert monk["subscription_value"] == "https://www.youtube.com/@stangetzofficial/releases"
|
||||
assert monk["subscription_indent_1"] == "Jazz"
|
||||
|
||||
|
|
@ -392,6 +439,7 @@ def test_music_video_subscriptions(default_config: ConfigFile, music_video_subsc
|
|||
monk = subs[1].overrides.dict_with_format_strings
|
||||
|
||||
assert monk["subscription_name"] == "Michael Jackson"
|
||||
assert monk["subscription_name_sanitized"] == "Michael Jackson"
|
||||
assert (
|
||||
monk["subscription_value"]
|
||||
== "https://www.youtube.com/playlist?list=OLAK5uy_mnY03zP6abNWH929q2XhGzWD_2uKJ_n8E"
|
||||
|
|
|
|||
Loading…
Reference in a new issue