ytdl-sub/tests/unit/validators/test_file_path_validators.py
Jesse Bannon e92b1cd12a
[BACKEND][HUGE] Function Support in variable syntax (#838)
A complete gutting of the internals of ytdl-sub to support functions in our variable syntax, in addition to being able to access a yt-dlp entry's .info.json fields using functions. Functionally, ytdl-sub should still look and behave the same from a user-perspective.

With so many lines of code changed (+8927, -2708), no doubt there will be new issues. Please make a GH issue or reach out on Discord if your config/subscriptions break in any way/shape/form.

Details on how to use function support will come soon in the form of proper documentation in our readthedocs.
2023-12-18 16:08:15 -08:00

111 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import tempfile
from pathlib import Path
import pytest
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.config.defaults import MAX_FILE_NAME_BYTES
from ytdl_sub.script.script import Script
from ytdl_sub.utils.file_path import FilePathTruncater
from ytdl_sub.utils.subtitles import SUBTITLE_EXTENSIONS
from ytdl_sub.validators.file_path_validators import StringFormatterFileNameValidator
@pytest.mark.usefixtures("register_custom_functions")
class TestStringFormatterFilePathValidator:
@pytest.mark.parametrize(
"ext",
["mp4", "info.json", "-thumb.jpg"] + [f"en-US.{ext}" for ext in SUBTITLE_EXTENSIONS],
)
@pytest.mark.parametrize("file_name_char", ["a", "𒃀"])
@pytest.mark.parametrize("file_name_len", [10, 10000])
def test_truncates_file_name_successfully(
self, ext: str, file_name_char: str, file_name_len: int
):
if "thumb" not in ext: # do not put . in front of -thumb
ext = f".{ext}" # pytest args with . in the beginning act weird
with tempfile.TemporaryDirectory() as temp_dir:
file_name = (file_name_char * file_name_len) + ext
file_path = str(Path(temp_dir) / file_name)
formatter = StringFormatterFileNameValidator(name="test", value=str(file_path))
truncated_file_path = formatter.post_process(
Script({"file_name": formatter.format_string}).resolve().get_str("file_name")
)
assert truncated_file_path.count(".") == ext.count(".")
assert str(Path(temp_dir)) in truncated_file_path
assert ext in truncated_file_path
# Ensure it can actually open the file
with open(truncated_file_path, "w", encoding="utf-8"):
# Make sure the file is actually in the directory
dir_paths = list(Path(temp_dir).rglob("*"))
assert len(dir_paths) == 1
assert Path(truncated_file_path) == dir_paths[0]
@pytest.mark.parametrize(
"ext",
["mp4", "info.json", "-thumb.jpg"] + [f"en-US.{ext}" for ext in SUBTITLE_EXTENSIONS],
)
def test_truncates_file_names_successfully(self, ext: str):
if "thumb" not in ext: # do not put . in front of -thumb
ext = f".{ext}" # pytest args with . in the beginning act weird
base_file_name = "s2023.e031701 - 𝗪𝗔𝗥𝗡𝗜𝗡𝗚 LG Secretly Overhaul This OLED Feature on C & G… Should You Buy C Instead"
with tempfile.TemporaryDirectory() as temp_dir:
file_path = str(Path(temp_dir) / f"{base_file_name}{ext}")
formatter = StringFormatterFileNameValidator(name="test", value=str(file_path))
truncated_file_path = formatter.post_process(
Script({"file_name": formatter.format_string}).resolve().get_str("file_name")
)
assert truncated_file_path == str(
Path(temp_dir)
/ f"s2023.e031701 - 𝗪𝗔𝗥𝗡𝗜𝗡𝗚 LG Secretly Overhaul This OLED Feature on C & G… Should You Buy C Instead{ext}"
)
# Ensure it can actually open the file
with open(truncated_file_path, "w", encoding="utf-8"):
# Make sure the file is actually in the directory
dir_paths = list(Path(temp_dir).rglob("*"))
assert len(dir_paths) == 1
assert Path(truncated_file_path) == dir_paths[0]
@pytest.mark.parametrize(
"file_name_max_bytes, expected_max",
[
(50, 50 - FilePathTruncater._EXTENSION_BYTES),
(0, 16),
(10000, MAX_FILE_NAME_BYTES - FilePathTruncater._EXTENSION_BYTES),
],
)
def test_config_changes_max_file_name_bytes(self, file_name_max_bytes: int, expected_max: int):
# Ensure the default is set
assert (
FilePathTruncater._MAX_BASE_FILE_NAME_BYTES
== FilePathTruncater._DEFAULT_MAX_BASE_FILE_NAME_BYTES
)
try:
# Initializes the config values, setting the max to 10 bytes
_ = ConfigFile.from_dict(
{
"configuration": {
"working_directory": ".",
"file_name_max_bytes": file_name_max_bytes,
},
"presets": {},
}
)
assert FilePathTruncater._MAX_BASE_FILE_NAME_BYTES == expected_max
finally:
FilePathTruncater._MAX_BASE_FILE_NAME_BYTES = (
FilePathTruncater._DEFAULT_MAX_BASE_FILE_NAME_BYTES
)