The fork takes its own name everywhere a user can see it: binaries (voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus namespace (com.voculinux.Voculinux, no alias for the old name), config/data/cache dirs, single-instance lock, IBus engine identity, tray icons, resource prefixes, VOCULINUX_* environment names, and the update-checker user agent. The internal Python module stays vocalinux and the distribution metadata keeps the upstream URLs as provenance. On first run a previous Vocalinux install's config.json, custom dictionary, and portal restore token are copied once into the new locations (new config always wins, no merge, no write-back); models re-resolve through the pinned-checksum download path. An offline naming-sweep test proves no old-name strings remain on user-visible surfaces outside the allowlist. Refs #18
191 lines
8.2 KiB
Python
191 lines
8.2 KiB
Python
"""
|
|
Additional coverage tests for autostart_manager.py module.
|
|
|
|
Tests for uncovered error cases and edge cases in autostart enable/disable.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
|
|
# Autouse fixture to prevent sys.modules pollution
|
|
@pytest.fixture(autouse=True)
|
|
def _restore_sys_modules():
|
|
saved = dict(sys.modules)
|
|
yield
|
|
added = set(sys.modules.keys()) - set(saved.keys())
|
|
for k in added:
|
|
del sys.modules[k]
|
|
for k, v in saved.items():
|
|
if k not in sys.modules or sys.modules[k] is not v:
|
|
sys.modules[k] = v
|
|
|
|
|
|
class TestAutostartManagerExtra:
|
|
"""Additional tests for autostart_manager edge cases."""
|
|
|
|
def test_is_autostart_enabled_file_exists(self):
|
|
"""Test is_autostart_enabled returns True when file exists."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
autostart_file = Path(tmp_dir) / "voculinux.desktop"
|
|
autostart_file.write_text("[Desktop Entry]\nName=Voculinux")
|
|
|
|
with patch.object(autostart_manager, "get_autostart_file", return_value=autostart_file):
|
|
assert autostart_manager.is_autostart_enabled() is True
|
|
|
|
def test_is_autostart_enabled_file_not_exists(self):
|
|
"""Test is_autostart_enabled returns False when file does not exist."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
autostart_file = Path(tmp_dir) / "voculinux.desktop"
|
|
|
|
with patch.object(autostart_manager, "get_autostart_file", return_value=autostart_file):
|
|
assert autostart_manager.is_autostart_enabled() is False
|
|
|
|
def test_enable_autostart_permission_error(self):
|
|
"""Test enable_autostart handles permission errors gracefully."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
# Create a read-only directory
|
|
readonly_dir = Path(tmp_dir) / "readonly"
|
|
readonly_dir.mkdir()
|
|
|
|
autostart_file = readonly_dir / "voculinux.desktop"
|
|
readonly_dir.chmod(0o444) # Remove write permission
|
|
|
|
try:
|
|
with patch.object(
|
|
autostart_manager, "get_autostart_dir", return_value=readonly_dir
|
|
):
|
|
with patch.object(
|
|
autostart_manager, "get_autostart_file", return_value=autostart_file
|
|
):
|
|
with patch.object(
|
|
autostart_manager,
|
|
"get_exec_command",
|
|
return_value="voculinux --start-minimized",
|
|
):
|
|
result = autostart_manager.enable_autostart()
|
|
assert result is False
|
|
finally:
|
|
# Restore permissions for cleanup
|
|
readonly_dir.chmod(0o755)
|
|
|
|
def test_enable_autostart_creates_parent_directories(self):
|
|
"""Test enable_autostart creates parent directories if they don't exist."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
with patch.dict(os.environ, {"XDG_CONFIG_HOME": tmp_dir}, clear=False):
|
|
with patch(
|
|
"vocalinux.ui.autostart_manager.shutil.which", return_value="/usr/bin/voculinux"
|
|
):
|
|
result = autostart_manager.enable_autostart()
|
|
assert result is True
|
|
|
|
autostart_file = Path(tmp_dir) / "autostart" / "voculinux.desktop"
|
|
assert autostart_file.exists()
|
|
content = autostart_file.read_text(encoding="utf-8")
|
|
assert "[Desktop Entry]" in content
|
|
assert "voculinux" in content
|
|
|
|
def test_disable_autostart_file_not_found(self):
|
|
"""Test disable_autostart succeeds even if file doesn't exist."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
autostart_file = Path(tmp_dir) / "voculinux.desktop"
|
|
|
|
with patch.object(autostart_manager, "get_autostart_file", return_value=autostart_file):
|
|
result = autostart_manager.disable_autostart()
|
|
assert result is True
|
|
|
|
def test_disable_autostart_permission_error(self):
|
|
"""Test disable_autostart handles permission errors gracefully."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
autostart_file = Path(tmp_dir) / "voculinux.desktop"
|
|
autostart_file.write_text("[Desktop Entry]\nName=Voculinux")
|
|
|
|
# Create a mock that will raise a permission error on unlink()
|
|
mock_file = MagicMock()
|
|
mock_file.exists.return_value = True
|
|
mock_file.unlink.side_effect = PermissionError("Permission denied")
|
|
|
|
with patch.object(autostart_manager, "get_autostart_file", return_value=mock_file):
|
|
result = autostart_manager.disable_autostart()
|
|
assert result is False
|
|
|
|
def test_set_autostart_enabled_true(self):
|
|
"""Test set_autostart with enabled=True calls enable_autostart."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
with patch.dict(os.environ, {"XDG_CONFIG_HOME": tmp_dir}, clear=False):
|
|
with patch(
|
|
"vocalinux.ui.autostart_manager.shutil.which", return_value="/usr/bin/voculinux"
|
|
):
|
|
result = autostart_manager.set_autostart(True)
|
|
assert result is True
|
|
|
|
autostart_file = Path(tmp_dir) / "autostart" / "voculinux.desktop"
|
|
assert autostart_file.exists()
|
|
|
|
def test_set_autostart_enabled_false(self):
|
|
"""Test set_autostart with enabled=False calls disable_autostart."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
# First create the file
|
|
autostart_dir = Path(tmp_dir) / "autostart"
|
|
autostart_dir.mkdir(parents=True)
|
|
autostart_file = autostart_dir / "voculinux.desktop"
|
|
autostart_file.write_text("[Desktop Entry]\nName=Voculinux")
|
|
|
|
with patch.dict(os.environ, {"XDG_CONFIG_HOME": tmp_dir}, clear=False):
|
|
result = autostart_manager.set_autostart(False)
|
|
assert result is True
|
|
assert not autostart_file.exists()
|
|
|
|
def test_get_exec_command_frozen_executable(self):
|
|
"""Test get_exec_command when sys.frozen is True."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with patch("vocalinux.ui.autostart_manager.shutil.which", return_value=None):
|
|
with patch("vocalinux.ui.autostart_manager.sys.frozen", True, create=True):
|
|
with patch(
|
|
"vocalinux.ui.autostart_manager.sys.executable", "/usr/local/bin/voculinux-bin"
|
|
):
|
|
command = autostart_manager.get_exec_command()
|
|
assert "/usr/local/bin/voculinux-bin --start-minimized" in command
|
|
|
|
def test_get_autostart_dir_without_xdg_config_home(self):
|
|
"""Test get_autostart_dir uses default location when XDG_CONFIG_HOME is not set."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
# Clear XDG_CONFIG_HOME if it exists
|
|
with patch.dict(os.environ, {}, clear=True):
|
|
autostart_dir = autostart_manager.get_autostart_dir()
|
|
expected = Path.home() / ".config" / "autostart"
|
|
assert autostart_dir == expected
|
|
|
|
def test_get_autostart_file(self):
|
|
"""Test get_autostart_file returns correct path."""
|
|
from vocalinux.ui import autostart_manager
|
|
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
with patch.dict(os.environ, {"XDG_CONFIG_HOME": tmp_dir}, clear=False):
|
|
autostart_file = autostart_manager.get_autostart_file()
|
|
expected = Path(tmp_dir) / "autostart" / "voculinux.desktop"
|
|
assert autostart_file == expected
|