179 lines
6.8 KiB
Python
179 lines
6.8 KiB
Python
import shlex
|
|
from typing import Callable, Dict, List, Optional
|
|
|
|
import pytest
|
|
|
|
from ytdl_sub.cli.parsers.dl import DownloadArgsParser
|
|
from ytdl_sub.cli.parsers.main import MainArguments, parser
|
|
from ytdl_sub.config.config_validator import ConfigOptions
|
|
from ytdl_sub.utils.exceptions import InvalidDlArguments
|
|
|
|
|
|
@pytest.fixture
|
|
def config_options_generator() -> Callable:
|
|
def _config_options_generator(dl_aliases: Optional[Dict[str, str]] = None):
|
|
config_options_dict = {
|
|
"working_directory": ".",
|
|
}
|
|
if dl_aliases:
|
|
config_options_dict["dl_aliases"] = dl_aliases
|
|
|
|
return ConfigOptions(name="config_options_unit_test", value=config_options_dict)
|
|
|
|
return _config_options_generator
|
|
|
|
|
|
@pytest.fixture
|
|
def argument_error_msg() -> str:
|
|
return "dl arguments must be in the form of --subscription.option.name 'value'"
|
|
|
|
|
|
def _get_extra_arguments(cmd_string: str) -> List[str]:
|
|
sys_argv = shlex.split(cmd_string)
|
|
_, extra_args = parser.parse_known_args(args=sys_argv)
|
|
|
|
return extra_args
|
|
|
|
|
|
class TestDownloadArgsParser:
|
|
@pytest.mark.parametrize(
|
|
"aliases, cmd, expected_sub_dict",
|
|
[
|
|
(
|
|
{"mv": "--preset 'Jellyfin Music Videos'", "v": "--download.url"},
|
|
"dl --mv --v 123abc",
|
|
{"preset": "Jellyfin Music Videos", "download": {"url": "123abc"}},
|
|
),
|
|
(
|
|
{
|
|
"ch": "--preset yt_channel",
|
|
"c": "--youtube.channel_url",
|
|
"name": "--overrides.tv_name",
|
|
"concert": "--overrides.genre 'Some Genre Name'",
|
|
},
|
|
"dl --ch --c https://youtube.com/channel/123abc --name 'Sweet TV Show' --concert",
|
|
{
|
|
"preset": "yt_channel",
|
|
"youtube": {"channel_url": "https://youtube.com/channel/123abc"},
|
|
"overrides": {"tv_name": "Sweet TV Show", "genre": "Some Genre Name"},
|
|
},
|
|
),
|
|
(
|
|
None,
|
|
"dl --youtube.playlist_url https://youtube.com/playlist?list=123abc",
|
|
{"youtube": {"playlist_url": "https://youtube.com/playlist?list=123abc"}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --parameter.using.list[1] 'v1'",
|
|
{"parameter": {"using": {"list": ["v1"]}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --parameter.using.list[1] 'v1' --parameter.using.list[2] 'v2'",
|
|
{"parameter": {"using": {"list": ["v1", "v2"]}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --parameter.using.list[2] 'v2' --parameter.using.list[1] 'v1'",
|
|
{"parameter": {"using": {"list": ["v1", "v2"]}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --parameter.using.list[2] 'v3' --parameter.using.list[1] 'v1' --parameter.using.list[2] 'v2'",
|
|
{"parameter": {"using": {"list": ["v1", "v2"]}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --parameter.using.list[3] 'v3' --parameter.using.list[1] 'v1'",
|
|
{"parameter": {"using": {"list": ["v1"]}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --parameter.not.using.list[0] 'v0'",
|
|
{"parameter": {"not": {"using": {"list[0]": "v0"}}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --a.float.parameter 1.3",
|
|
{"a": {"float": {"parameter": 1.3}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --a.int.parameter 6",
|
|
{"a": {"int": {"parameter": 6}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --a.true.parameter True",
|
|
{"a": {"true": {"parameter": True}}},
|
|
),
|
|
(
|
|
None,
|
|
"dl --a.false.parameter False",
|
|
{"a": {"false": {"parameter": False}}},
|
|
),
|
|
],
|
|
)
|
|
def test_successful_args(self, config_options_generator, aliases, cmd, expected_sub_dict):
|
|
config_options = config_options_generator(dl_aliases=aliases)
|
|
extra_args = _get_extra_arguments(cmd_string=cmd)
|
|
|
|
output_sub_dict = DownloadArgsParser(
|
|
extra_arguments=extra_args, config_options=config_options
|
|
).to_subscription_dict()
|
|
|
|
assert output_sub_dict == expected_sub_dict
|
|
|
|
def test_error_uneven_args(self, config_options_generator, argument_error_msg):
|
|
config_options = config_options_generator()
|
|
extra_args = _get_extra_arguments(cmd_string="dl --preset")
|
|
|
|
with pytest.raises(InvalidDlArguments, match=argument_error_msg):
|
|
DownloadArgsParser(
|
|
extra_arguments=extra_args, config_options=config_options
|
|
).to_subscription_dict()
|
|
|
|
def test_error_adjacent_values(self, config_options_generator, argument_error_msg):
|
|
config_options = config_options_generator()
|
|
extra_args = _get_extra_arguments(cmd_string="dl --preset buttered toast --test")
|
|
|
|
with pytest.raises(InvalidDlArguments, match=argument_error_msg):
|
|
DownloadArgsParser(
|
|
extra_arguments=extra_args, config_options=config_options
|
|
).to_subscription_dict()
|
|
|
|
def test_error_incomplete_list(self, config_options_generator):
|
|
config_options = config_options_generator()
|
|
extra_args = _get_extra_arguments(cmd_string="dl --parameter.using.list[3] 'v3'")
|
|
|
|
with pytest.raises(InvalidDlArguments, match="Incomplete list"):
|
|
DownloadArgsParser(
|
|
extra_arguments=extra_args, config_options=config_options
|
|
).to_subscription_dict()
|
|
|
|
def test_error_two_different_types(self, config_options_generator):
|
|
config_options = config_options_generator()
|
|
extra_args = _get_extra_arguments(
|
|
cmd_string="dl --parameter.using.list 'v2' --parameter.using.list[1] 'v1'"
|
|
)
|
|
|
|
with pytest.raises(
|
|
InvalidDlArguments,
|
|
match="Invalid dl argument --parameter.using.list: "
|
|
"Cannot specify an argument to be two different types",
|
|
):
|
|
DownloadArgsParser(
|
|
extra_arguments=extra_args, config_options=config_options
|
|
).to_subscription_dict()
|
|
|
|
@pytest.mark.parametrize("main_argument", MainArguments.all_arguments())
|
|
def test_error_uses_main_args(self, main_argument, config_options_generator):
|
|
config_options = config_options_generator()
|
|
extra_args = _get_extra_arguments(cmd_string=f"dl {main_argument}")
|
|
|
|
with pytest.raises(
|
|
InvalidDlArguments,
|
|
match=f"'{main_argument}' is a ytdl-sub argument and must placed behind 'dl'",
|
|
):
|
|
DownloadArgsParser(extra_arguments=extra_args, config_options=config_options)
|