You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RedditVideoMakerBot/tests/test_gui_utils.py

132 lines
5.2 KiB

import json
import os
import pytest
from unittest.mock import patch, MagicMock
from pathlib import Path
from utils import gui_utils
@pytest.fixture
def mock_background_json(tmp_path):
bg_file = tmp_path / "background_videos.json"
initial_data = {
"__comment": "test",
"minecraft": ["https://www.youtube.com/watch?v=n_Dv4JMiwK8", "parkour.mp4", "bbswitzer", "center"]
}
bg_file.write_text(json.dumps(initial_data))
return bg_file
@pytest.fixture
def mock_template_toml(tmp_path):
template_file = tmp_path / ".config.template.toml"
template_content = """
[settings.background]
background_video = { optional = true, default = "minecraft", options = ["minecraft"] }
"""
template_file.write_text(template_content)
return template_file
@patch("utils.gui_utils.flash")
def test_delete_background(mock_flash, mock_background_json, mock_template_toml):
# We need to patch the paths used in gui_utils
with patch("utils.gui_utils.open", MagicMock(side_effect=lambda path, *args, **kwargs: open(mock_background_json if "background_videos.json" in str(path) else path, *args, **kwargs))), \
patch("utils.gui_utils.Path", MagicMock(side_effect=lambda path: Path(mock_template_toml) if ".config.template.toml" in str(path) else Path(path))):
gui_utils.delete_background("minecraft")
# Verify background_videos.json
with open(mock_background_json, "r") as f:
data = json.load(f)
assert "minecraft" not in data
# Verify .config.template.toml
import tomlkit
template_data = tomlkit.loads(mock_template_toml.read_text())
assert "minecraft" not in template_data["settings"]["background"]["background_video"]["options"]
mock_flash.assert_called_with('Successfully removed "minecraft" background!')
@patch("utils.gui_utils.flash")
def test_add_background(mock_flash, mock_background_json, mock_template_toml):
with patch("utils.gui_utils.open", MagicMock(side_effect=lambda path, *args, **kwargs: open(mock_background_json if "background_videos.json" in str(path) else path, *args, **kwargs))), \
patch("utils.gui_utils.Path", MagicMock(side_effect=lambda path: Path(mock_template_toml) if ".config.template.toml" in str(path) else Path(path))):
# Test adding a new background
gui_utils.add_background(
youtube_uri="https://www.youtube.com/watch?v=dQw4w9WgXcQ",
filename="test_new",
citation="Rick",
position="center"
)
# Verify background_videos.json
with open(mock_background_json, "r") as f:
data = json.load(f)
assert "test_new" in data
assert data["test_new"][0] == "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# Verify .config.template.toml
import tomlkit
template_data = tomlkit.loads(mock_template_toml.read_text())
assert "test_new" in template_data["settings"]["background"]["background_video"]["options"]
mock_flash.assert_called_with('Added "Rick-test_new.mp4" as a new background video!')
@patch("utils.gui_utils.flash")
def test_modify_settings_preserves_masked_secrets(mock_flash):
config_load = {
"reddit": {
"creds": {
"client_secret": "real-secret",
"password": "real-password",
}
}
}
checks = {
"reddit.creds.client_secret": {"optional": False, "type": "str"},
"reddit.creds.password": {"optional": False, "type": "str"},
}
result = gui_utils.modify_settings(
{
"reddit.creds.client_secret": "********",
"reddit.creds.password": "changed-password",
},
config_load,
checks,
)
assert config_load["reddit"]["creds"]["client_secret"] == "real-secret"
assert config_load["reddit"]["creds"]["password"] == "changed-password"
assert result["reddit.creds.client_secret"] == "real-secret"
@patch("utils.gui_utils.flash")
def test_modify_settings_does_not_materialize_missing_default_values(mock_flash, tmp_path):
config_load = {"settings": {"channel_name": "My Channel"}}
checks = {
"settings.channel_name": {"optional": True, "type": "str"},
"settings.tts.voice_choice": {"optional": False, "type": "str", "default": "Supertonic"},
"settings.tts.supertonic_voice": {"optional": True, "type": "str", "default": "M1"},
"threads.creds.username": {"optional": True, "type": "str"},
}
config_path = tmp_path / "config.toml"
with patch("utils.gui_utils.Path", MagicMock(return_value=config_path)):
result = gui_utils.modify_settings(
{
"settings.channel_name": "Updated Channel",
"settings.tts.voice_choice": "Supertonic",
"settings.tts.supertonic_voice": "M1",
"threads.creds.username": "",
},
config_load,
checks,
)
assert config_load["settings"]["channel_name"] == "Updated Channel"
assert "tts" not in config_load["settings"]
assert "threads" not in config_load
assert "settings.tts.voice_choice" not in result
assert "threads.creds.username" not in result