shared fixtures for all tests
This commit is contained in:
parent
6c745236d4
commit
e7b91e107e
4 changed files with 113 additions and 87 deletions
|
|
@ -2,6 +2,7 @@ import contextlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
@ -11,10 +12,14 @@ from typing import List
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from expected_download import _get_files_in_directory
|
||||||
|
|
||||||
|
from ytdl_sub.config.config_file import ConfigFile
|
||||||
|
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
|
||||||
from ytdl_sub.utils.file_handler import FileHandler
|
from ytdl_sub.utils.file_handler import FileHandler
|
||||||
from ytdl_sub.utils.logger import Logger
|
from ytdl_sub.utils.logger import Logger
|
||||||
from ytdl_sub.utils.logger import LoggerLevels
|
from ytdl_sub.utils.logger import LoggerLevels
|
||||||
|
from ytdl_sub.utils.yaml import load_yaml
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
|
|
@ -28,9 +33,31 @@ def cleanup_debug_file():
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def working_directory() -> Path:
|
def working_directory() -> str:
|
||||||
|
"""
|
||||||
|
Any time the working directory is used, ensure no files remain on cleaning it up
|
||||||
|
"""
|
||||||
|
logger = Logger.get("test")
|
||||||
|
|
||||||
with tempfile.TemporaryDirectory() as temp_dir:
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
yield temp_dir
|
|
||||||
|
def _assert_working_directory_empty(self, is_error: bool = False):
|
||||||
|
files = [str(file_path) for file_path in _get_files_in_directory(temp_dir)]
|
||||||
|
num_files = len(files)
|
||||||
|
if os.path.isdir(temp_dir):
|
||||||
|
shutil.rmtree(temp_dir)
|
||||||
|
|
||||||
|
if not is_error:
|
||||||
|
if num_files > 0:
|
||||||
|
logger.error("left-over files in working dir:\n%s", "\n".join(files))
|
||||||
|
assert num_files == 0
|
||||||
|
|
||||||
|
with patch.object(
|
||||||
|
SubscriptionDownload,
|
||||||
|
"_delete_working_directory",
|
||||||
|
new=_assert_working_directory_empty,
|
||||||
|
):
|
||||||
|
yield temp_dir
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
|
@ -106,3 +133,38 @@ def preset_dict_to_subscription_yaml_generator() -> Callable:
|
||||||
FileHandler.delete(tmp_file.name)
|
FileHandler.delete(tmp_file.name)
|
||||||
|
|
||||||
return _preset_dict_to_subscription_yaml_generator
|
return _preset_dict_to_subscription_yaml_generator
|
||||||
|
|
||||||
|
|
||||||
|
###################################################################################################
|
||||||
|
# Example config fixtures
|
||||||
|
|
||||||
|
|
||||||
|
def _load_config(config_path: Path, working_directory: Path) -> ConfigFile:
|
||||||
|
config_dict = load_yaml(file_path=config_path)
|
||||||
|
config_dict["configuration"]["working_directory"] = working_directory
|
||||||
|
|
||||||
|
return ConfigFile.from_dict(config_dict)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def music_video_config_path() -> Path:
|
||||||
|
return Path("examples/music_videos_config.yaml")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def music_video_config(music_video_config_path, working_directory) -> ConfigFile:
|
||||||
|
return _load_config(music_video_config_path, working_directory)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def channel_as_tv_show_config(working_directory) -> ConfigFile:
|
||||||
|
return _load_config(
|
||||||
|
config_path=Path("examples/tv_show_config.yaml"), working_directory=working_directory
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def music_audio_config(working_directory) -> ConfigFile:
|
||||||
|
return _load_config(
|
||||||
|
config_path=Path("examples/music_audio_config.yaml"), working_directory=working_directory
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,16 @@
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from expected_download import _get_files_in_directory
|
|
||||||
|
|
||||||
from ytdl_sub.cli.main import main
|
from ytdl_sub.cli.main import main
|
||||||
from ytdl_sub.config.config_file import ConfigFile
|
|
||||||
from ytdl_sub.subscriptions.subscription import Subscription
|
from ytdl_sub.subscriptions.subscription import Subscription
|
||||||
from ytdl_sub.subscriptions.subscription_download import SubscriptionDownload
|
|
||||||
from ytdl_sub.utils.file_handler import FileHandler
|
from ytdl_sub.utils.file_handler import FileHandler
|
||||||
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
|
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
|
||||||
from ytdl_sub.utils.logger import Logger
|
|
||||||
from ytdl_sub.utils.yaml import load_yaml
|
|
||||||
|
|
||||||
logger = Logger.get("test")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def working_directory() -> str:
|
|
||||||
"""
|
|
||||||
Any time the working directory is used, ensure no files remain on cleaning it up
|
|
||||||
"""
|
|
||||||
with tempfile.TemporaryDirectory() as temp_dir:
|
|
||||||
|
|
||||||
def _assert_working_directory_empty(self, is_error: bool = False):
|
|
||||||
files = [str(file_path) for file_path in _get_files_in_directory(temp_dir)]
|
|
||||||
num_files = len(files)
|
|
||||||
if os.path.isdir(temp_dir):
|
|
||||||
shutil.rmtree(temp_dir)
|
|
||||||
|
|
||||||
if not is_error:
|
|
||||||
if num_files > 0:
|
|
||||||
logger.error("left-over files in working dir:\n%s", "\n".join(files))
|
|
||||||
assert num_files == 0
|
|
||||||
|
|
||||||
with patch.object(
|
|
||||||
SubscriptionDownload,
|
|
||||||
"_delete_working_directory",
|
|
||||||
new=_assert_working_directory_empty,
|
|
||||||
):
|
|
||||||
yield temp_dir
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def music_video_config_path() -> Path:
|
|
||||||
return Path("examples/music_videos_config.yaml")
|
|
||||||
|
|
||||||
|
|
||||||
def _load_config(config_path: Path, working_directory: Path) -> ConfigFile:
|
|
||||||
config_dict = load_yaml(file_path=config_path)
|
|
||||||
config_dict["configuration"]["working_directory"] = working_directory
|
|
||||||
|
|
||||||
return ConfigFile.from_dict(config_dict)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def music_video_config(music_video_config_path, working_directory) -> ConfigFile:
|
|
||||||
return _load_config(music_video_config_path, working_directory)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
|
@ -77,20 +24,6 @@ def music_video_config_for_cli(music_video_config) -> str:
|
||||||
FileHandler.delete(tmp_file.name)
|
FileHandler.delete(tmp_file.name)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def channel_as_tv_show_config(working_directory) -> ConfigFile:
|
|
||||||
return _load_config(
|
|
||||||
config_path=Path("examples/tv_show_config.yaml"), working_directory=working_directory
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
|
||||||
def music_audio_config(working_directory) -> ConfigFile:
|
|
||||||
return _load_config(
|
|
||||||
config_path=Path("examples/music_audio_config.yaml"), working_directory=working_directory
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def timestamps_file_path():
|
def timestamps_file_path():
|
||||||
timestamps = [
|
timestamps = [
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from ytdl_sub.cli.main import main
|
from ytdl_sub.cli.main import main
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,3 +19,30 @@ def test_args_after_sub_work():
|
||||||
assert mock_sub.call_args.kwargs["args"].config == "examples/tv_show_config.yaml"
|
assert mock_sub.call_args.kwargs["args"].config == "examples/tv_show_config.yaml"
|
||||||
assert mock_sub.call_args.kwargs["args"].subscription_paths == ["subscriptions.yaml"]
|
assert mock_sub.call_args.kwargs["args"].subscription_paths == ["subscriptions.yaml"]
|
||||||
assert mock_sub.call_args.kwargs["args"].ytdl_sub_log_level == "debug"
|
assert mock_sub.call_args.kwargs["args"].ytdl_sub_log_level == "debug"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def persist_logs_directory():
|
||||||
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
|
yield temp_dir
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def persist_logs_config():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestPersistLogs:
|
||||||
|
@pytest.mark.parametrize("mock_success_output", [True, False])
|
||||||
|
@pytest.mark.parametrize("keep_successful_logs", [True, False])
|
||||||
|
def test_subscription_logs_write_to_file(
|
||||||
|
self, persist_logs_directory: str, mock_success_output: bool, keep_successful_logs: bool
|
||||||
|
):
|
||||||
|
|
||||||
|
config_dict = {
|
||||||
|
"working_directory": ".",
|
||||||
|
"persist_logs": {
|
||||||
|
"logs_directory": persist_logs_directory,
|
||||||
|
"keep_successful_logs": keep_successful_logs,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
|
||||||
playlist_index: int = 1,
|
playlist_index: int = 1,
|
||||||
playlist_count: int = 1,
|
playlist_count: int = 1,
|
||||||
is_youtube_channel: bool = False,
|
is_youtube_channel: bool = False,
|
||||||
|
mock_download_to_working_dir: bool = True,
|
||||||
) -> Dict:
|
) -> Dict:
|
||||||
entry_dict = {
|
entry_dict = {
|
||||||
UID: uid,
|
UID: uid,
|
||||||
|
|
@ -84,12 +85,14 @@ def mock_entry_dict_factory(mock_downloaded_file_path) -> Callable:
|
||||||
]
|
]
|
||||||
|
|
||||||
# Create mock video file
|
# Create mock video file
|
||||||
copy_file_fixture(
|
if mock_download_to_working_dir:
|
||||||
fixture_name="sample_vid.mp4", output_file_path=mock_downloaded_file_path(f"{uid}.mp4")
|
copy_file_fixture(
|
||||||
)
|
fixture_name="sample_vid.mp4",
|
||||||
copy_file_fixture(
|
output_file_path=mock_downloaded_file_path(f"{uid}.mp4"),
|
||||||
fixture_name="thumb.jpg", output_file_path=mock_downloaded_file_path(f"{uid}.jpg")
|
)
|
||||||
)
|
copy_file_fixture(
|
||||||
|
fixture_name="thumb.jpg", output_file_path=mock_downloaded_file_path(f"{uid}.jpg")
|
||||||
|
)
|
||||||
return entry_dict
|
return entry_dict
|
||||||
|
|
||||||
return _mock_entry_dict_factory
|
return _mock_entry_dict_factory
|
||||||
|
|
@ -124,36 +127,33 @@ def mock_download_collection_entries(
|
||||||
):
|
):
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def _mock_download_collection_entries_factory(is_youtube_channel: bool):
|
def _mock_download_collection_entries_factory(is_youtube_channel: bool):
|
||||||
def _(**kwargs):
|
|
||||||
return mock_entry_dict_factory(**kwargs)
|
|
||||||
|
|
||||||
def _write_entries_to_working_dir(*args, **kwargs) -> List[Dict]:
|
def _write_entries_to_working_dir(*args, **kwargs) -> List[Dict]:
|
||||||
if (len(args[0].collection.urls.list) == 1) or (
|
if (len(args[0].collection.urls.list) == 1) or (
|
||||||
"season.2" in kwargs["url"] and len(args[0].download_options.urls.list) > 1
|
"season.2" in kwargs["url"] and len(args[0].download_options.urls.list) > 1
|
||||||
):
|
):
|
||||||
return [
|
return [
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="21-1",
|
uid="21-1",
|
||||||
upload_date="20210808",
|
upload_date="20210808",
|
||||||
playlist_index=1,
|
playlist_index=1,
|
||||||
playlist_count=4,
|
playlist_count=4,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
), # 1
|
), # 1
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-1",
|
uid="20-1",
|
||||||
upload_date="20200808",
|
upload_date="20200808",
|
||||||
playlist_index=2,
|
playlist_index=2,
|
||||||
playlist_count=4,
|
playlist_count=4,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
), # 2 98
|
), # 2 98
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-2",
|
uid="20-2",
|
||||||
upload_date="20200808",
|
upload_date="20200808",
|
||||||
playlist_index=3,
|
playlist_index=3,
|
||||||
playlist_count=4,
|
playlist_count=4,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
), # 1 99
|
), # 1 99
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-3",
|
uid="20-3",
|
||||||
upload_date="20200807",
|
upload_date="20200807",
|
||||||
playlist_index=4,
|
playlist_index=4,
|
||||||
|
|
@ -163,35 +163,36 @@ def mock_download_collection_entries(
|
||||||
]
|
]
|
||||||
return [
|
return [
|
||||||
# 20-3 should resolve to collection 1 (which is season 2)
|
# 20-3 should resolve to collection 1 (which is season 2)
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-3",
|
uid="20-3",
|
||||||
upload_date="20200807",
|
upload_date="20200807",
|
||||||
playlist_index=1,
|
playlist_index=1,
|
||||||
playlist_count=5,
|
playlist_count=5,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
|
mock_download_to_working_dir=False,
|
||||||
),
|
),
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-4",
|
uid="20-4",
|
||||||
upload_date="20200806",
|
upload_date="20200806",
|
||||||
playlist_index=2,
|
playlist_index=2,
|
||||||
playlist_count=5,
|
playlist_count=5,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
),
|
),
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-5",
|
uid="20-5",
|
||||||
upload_date="20200706",
|
upload_date="20200706",
|
||||||
playlist_index=3,
|
playlist_index=3,
|
||||||
playlist_count=5,
|
playlist_count=5,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
),
|
),
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-6",
|
uid="20-6",
|
||||||
upload_date="20200706",
|
upload_date="20200706",
|
||||||
playlist_index=4,
|
playlist_index=4,
|
||||||
playlist_count=5,
|
playlist_count=5,
|
||||||
is_youtube_channel=is_youtube_channel,
|
is_youtube_channel=is_youtube_channel,
|
||||||
),
|
),
|
||||||
_(
|
mock_entry_dict_factory(
|
||||||
uid="20-7",
|
uid="20-7",
|
||||||
upload_date="20200606",
|
upload_date="20200606",
|
||||||
playlist_index=5,
|
playlist_index=5,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue