match filter unit test
This commit is contained in:
parent
b8dd8bea5f
commit
6881b7ecf5
9 changed files with 148 additions and 49 deletions
|
|
@ -1,5 +1,6 @@
|
|||
from typing import List, Set
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
from ytdl_sub.config.plugin.plugin import Plugin
|
||||
|
|
@ -35,9 +36,11 @@ class DateRangeOptions(ToggleableOptionsDictValidator):
|
|||
date_range:
|
||||
before: "now"
|
||||
after: "today-2weeks"
|
||||
breaks: True
|
||||
type: "upload_date"
|
||||
"""
|
||||
|
||||
_optional_keys = {"enable", "before", "after", "breaks"}
|
||||
_optional_keys = {"enable", "before", "after", "breaks", "type"}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
|
|
@ -81,7 +84,8 @@ class DateRangeOptions(ToggleableOptionsDictValidator):
|
|||
"""
|
||||
:expected type: Optional[OverridesFormatter]
|
||||
:description:
|
||||
Which type of date to use. Must be either ``upload_date`` or ``release_date``
|
||||
Which type of date to use. Must be either ``upload_date`` or ``release_date``.
|
||||
Defaults to ``upload_date``.
|
||||
"""
|
||||
return self._type
|
||||
|
||||
|
|
|
|||
|
|
@ -349,12 +349,16 @@ class SubscriptionDownload(BaseSubscription, ABC):
|
|||
|
||||
return self.download_archive.get_file_handler_transaction_log()
|
||||
|
||||
def get_ytdl_options(self, plugins: Optional[List[Plugin]], dry_run: bool) -> SubscriptionYTDLOptions:
|
||||
def get_ytdl_options(
|
||||
self, plugins: Optional[List[Plugin]], dry_run: bool
|
||||
) -> SubscriptionYTDLOptions:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
plugins
|
||||
Optional. If not provided, will reinitialize them
|
||||
dry_run
|
||||
Whether its dry run or not
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
@ -392,10 +396,7 @@ class SubscriptionDownload(BaseSubscription, ABC):
|
|||
logging.info("Skipping %s", self.name)
|
||||
return FileHandlerTransactionLog()
|
||||
|
||||
subscription_ytdl_options = self.get_ytdl_options(
|
||||
plugins=plugins,
|
||||
dry_run=dry_run
|
||||
)
|
||||
subscription_ytdl_options = self.get_ytdl_options(plugins=plugins, dry_run=dry_run)
|
||||
|
||||
downloader = MultiUrlDownloader(
|
||||
options=self.downloader_options,
|
||||
|
|
@ -440,10 +441,7 @@ class SubscriptionDownload(BaseSubscription, ABC):
|
|||
self.download_archive.reinitialize(dry_run=dry_run)
|
||||
|
||||
plugins = self._initialize_plugins()
|
||||
subscription_ytdl_options = self.get_ytdl_options(
|
||||
plugins=plugins,
|
||||
dry_run=dry_run
|
||||
)
|
||||
subscription_ytdl_options = self.get_ytdl_options(plugins=plugins, dry_run=dry_run)
|
||||
|
||||
# Re-add the original downloader class' plugins
|
||||
plugins.extend(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class OverridesStringSelectValidator(OverridesStringFormatterValidator):
|
|||
def post_process(self, resolved: str) -> str:
|
||||
if resolved not in self._select_values:
|
||||
raise self._validation_exception(
|
||||
f"Must be one of the following values: {', '.join(self._select_values)}"
|
||||
f"Must be one of the following values: {', '.join(sorted(self._select_values))}"
|
||||
)
|
||||
|
||||
return resolved
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from typing import Callable
|
|||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import Optional
|
||||
from typing import Tuple
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
|
@ -272,3 +273,27 @@ 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()
|
||||
|
||||
|
||||
def get_match_filters(
|
||||
subscription: Subscription, dry_run: bool, download_filters: bool
|
||||
) -> Tuple[List[str], List[str]]:
|
||||
"""
|
||||
Util function to get match filters from a subscription.
|
||||
|
||||
Returns
|
||||
-------
|
||||
match_filters, breaking_match_filters
|
||||
"""
|
||||
options = subscription.get_ytdl_options(plugins=None, dry_run=dry_run)
|
||||
options_dict = (
|
||||
options.download_builder().to_dict()
|
||||
if download_filters
|
||||
else options.metadata_builder().to_dict()
|
||||
)
|
||||
if "match_filter" not in options_dict:
|
||||
return [], []
|
||||
|
||||
match_filter_str = repr(options_dict["match_filter"])
|
||||
out = eval(match_filter_str.split("(", maxsplit=1)[-1].split(")")[0])
|
||||
return out
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
from typing import Dict
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.exceptions import ValidationException
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def single_song_video_dict(output_directory):
|
||||
return {
|
||||
"download": "https://your.name.here",
|
||||
"output_options": {"output_directory": output_directory, "file_name": "will_error.mp4"},
|
||||
# test multi-tags compile
|
||||
"music_tags": {"genres": ["multi_tag_1", "multi_tag_2"]},
|
||||
}
|
||||
|
||||
|
||||
class TestDateRange:
|
||||
def test_date_range(
|
||||
self,
|
||||
config,
|
||||
single_song_video_dict,
|
||||
output_directory,
|
||||
subscription_name,
|
||||
mock_download_collection_entries,
|
||||
):
|
||||
ytdl_options = Subscription.from_dict(
|
||||
config=config,
|
||||
preset_name=subscription_name,
|
||||
preset_dict=single_song_video_dict,
|
||||
).get_ytdl_options(plugins=None, dry_run=False)
|
||||
|
||||
assert ytdl_options.download_builder().to_dict() is False
|
||||
|
|
@ -4,7 +4,6 @@ import pytest
|
|||
from expected_download import assert_expected_downloads
|
||||
from expected_transaction_log import assert_transaction_log_matches
|
||||
|
||||
from ytdl_sub.entries.entry import ytdl_sub_chapters_from_comments
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
|
||||
|
||||
|
|
|
|||
0
tests/unit/plugins/__init__.py
Normal file
0
tests/unit/plugins/__init__.py
Normal file
108
tests/unit/plugins/test_date_range.py
Normal file
108
tests/unit/plugins/test_date_range.py
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
import re
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
|
||||
import pytest
|
||||
from conftest import get_match_filters
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.subscriptions.subscription import Subscription
|
||||
from ytdl_sub.utils.exceptions import ValidationException
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def preset_dict(output_directory) -> Dict[str, Any]:
|
||||
return {
|
||||
"download": "https://your.name.here",
|
||||
"output_options": {"output_directory": output_directory, "file_name": "will_error.mp4"},
|
||||
}
|
||||
|
||||
|
||||
class TestDateRange:
|
||||
@pytest.mark.parametrize("date_range_type", ["upload_date", "release_date"])
|
||||
def test_date_range_type(
|
||||
self,
|
||||
default_config: ConfigFile,
|
||||
preset_dict: Dict[str, Any],
|
||||
output_directory: str,
|
||||
date_range_type: str,
|
||||
):
|
||||
preset_dict["date_range"] = {
|
||||
"before": "20250530",
|
||||
"after": "20250510",
|
||||
"type": date_range_type,
|
||||
}
|
||||
sub = Subscription.from_dict(
|
||||
config=default_config,
|
||||
preset_name="test_date_range",
|
||||
preset_dict=preset_dict,
|
||||
)
|
||||
|
||||
metadata_filter, metadata_breaking_filter = get_match_filters(
|
||||
subscription=sub, dry_run=False, download_filters=False
|
||||
)
|
||||
assert metadata_filter == [
|
||||
f"!is_live & !is_upcoming & !post_live & {date_range_type} < 20250530"
|
||||
]
|
||||
assert metadata_breaking_filter == [f"{date_range_type} >= 20250510"]
|
||||
|
||||
download_filter, download_breaking_filter = get_match_filters(
|
||||
subscription=sub, dry_run=False, download_filters=True
|
||||
)
|
||||
assert not download_filter
|
||||
assert not download_breaking_filter
|
||||
|
||||
def test_date_range_breaks_false(
|
||||
self,
|
||||
default_config: ConfigFile,
|
||||
preset_dict: Dict[str, Any],
|
||||
output_directory: str,
|
||||
):
|
||||
preset_dict["date_range"] = {
|
||||
"before": "20250530",
|
||||
"after": "20250510",
|
||||
"breaks": False,
|
||||
}
|
||||
sub = Subscription.from_dict(
|
||||
config=default_config,
|
||||
preset_name="test_date_range",
|
||||
preset_dict=preset_dict,
|
||||
)
|
||||
|
||||
metadata_filter, metadata_breaking_filter = get_match_filters(
|
||||
subscription=sub, dry_run=False, download_filters=False
|
||||
)
|
||||
assert metadata_filter == [
|
||||
f"!is_live & !is_upcoming & !post_live & upload_date < 20250530 & upload_date >= 20250510"
|
||||
]
|
||||
assert not metadata_breaking_filter
|
||||
|
||||
download_filter, download_breaking_filter = get_match_filters(
|
||||
subscription=sub, dry_run=False, download_filters=True
|
||||
)
|
||||
assert not download_filter
|
||||
assert not download_breaking_filter
|
||||
|
||||
def test_date_range_invalid_type(
|
||||
self,
|
||||
default_config: ConfigFile,
|
||||
preset_dict: Dict[str, Any],
|
||||
output_directory: str,
|
||||
):
|
||||
preset_dict["date_range"] = {
|
||||
"before": "20250530",
|
||||
"after": "20250510",
|
||||
"type": "no",
|
||||
}
|
||||
|
||||
error_msg = (
|
||||
"Validation error in test_date_range.date_range.type: "
|
||||
"Must be one of the following values: release_date, upload_date"
|
||||
)
|
||||
|
||||
with pytest.raises(ValidationException, match=re.escape(error_msg)):
|
||||
Subscription.from_dict(
|
||||
config=default_config,
|
||||
preset_name="test_date_range",
|
||||
preset_dict=preset_dict,
|
||||
).download(dry_run=False)
|
||||
Loading…
Reference in a new issue