Files
cthulhu/tests/test_sound_preferences_regressions.py
2026-04-05 21:32:06 -04:00

176 lines
7.4 KiB
Python

import sys
import tempfile
import unittest
import xml.etree.ElementTree as ET
from pathlib import Path
from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
from cthulhu import cthulhu
from cthulhu import settings
from cthulhu import cthulhu_gui_prefs
from cthulhu import settings_manager
class SoundSettingsPersistenceTests(unittest.TestCase):
def test_progress_bar_beep_interval_is_user_customizable(self):
self.assertIn("progressBarBeepInterval", settings.userCustomizableSettings)
def test_activate_writes_progress_bar_beep_interval_default(self):
with tempfile.TemporaryDirectory() as tempDir:
manager = settings_manager.SettingsManager(mock.Mock())
manager.activate(prefsDir=tempDir)
settingsText = Path(tempDir, "user-settings.toml").read_text(encoding="utf-8")
self.assertIn("progressBarBeepInterval = 0", settingsText)
class SoundPreferencesBuilderTests(unittest.TestCase):
def test_ui_definition_exposes_sounds_tab_controls(self):
uiPath = Path(__file__).resolve().parents[1] / "src" / "cthulhu" / "cthulhu-setup.ui"
root = ET.fromstring(uiPath.read_text(encoding="utf-8"))
objectIds = {
element.attrib["id"]
for element in root.iter()
if element.tag == "object" and "id" in element.attrib
}
self.assertIn("soundsGrid", objectIds)
self.assertIn("soundsTabLabel", objectIds)
self.assertIn("enableSoundCheckButton", objectIds)
self.assertIn("soundVolumeScale", objectIds)
self.assertIn("progressBarBeepIntervalSpinButton", objectIds)
def test_notebook_tab_positions_keep_sounds_page_and_label_aligned(self):
uiPath = Path(__file__).resolve().parents[1] / "src" / "cthulhu" / "cthulhu-setup.ui"
root = ET.fromstring(uiPath.read_text(encoding="utf-8"))
notebook = next(
element for element in root.iter()
if element.tag == "object" and element.attrib.get("id") == "notebook"
)
positions = {}
for child in notebook.findall("child"):
obj = child.find("object")
if obj is None or "id" not in obj.attrib:
continue
position = None
packing = child.find("packing")
if packing is not None:
for prop in packing.findall("property"):
if prop.attrib.get("name") == "position":
position = int(prop.text)
break
positions[obj.attrib["id"]] = position
self.assertEqual(positions["generalGrid"], 0)
self.assertEqual(positions["generalTabLabel"], 0)
self.assertEqual(positions["soundsGrid"], 1)
self.assertEqual(positions["soundsTabLabel"], 1)
self.assertEqual(positions["voiceGrid"], 2)
self.assertEqual(positions["voiceLabel"], 2)
self.assertEqual(positions["textAttributesGrid"], 8)
self.assertEqual(positions["textAttributesTabLabel"], 8)
class SoundPreferencesControllerTests(unittest.TestCase):
def test_init_sound_state_loads_sound_volume_and_beep_interval(self):
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI)
gui.prefsDict = {
"enableSound": False,
"soundSink": settings.SOUND_SINK_PULSE,
"soundTheme": "default",
"roleSoundPresentation": settings.ROLE_SOUND_PRESENTATION_SOUND_ONLY,
"soundVolume": 0.65,
"progressBarBeepInterval": 0,
"beepProgressBarUpdates": True,
"playSoundForRole": True,
"playSoundForState": True,
"playSoundForPositionInSet": False,
"playSoundForValue": False,
}
widgets = {
"soundSinkCombo": mock.Mock(),
"soundThemeCombo": mock.Mock(),
"roleSoundPresentationCombo": mock.Mock(),
"soundVolumeScale": mock.Mock(),
"progressBarBeepIntervalSpinButton": mock.Mock(),
"enableSoundCheckButton": mock.Mock(),
"playSoundForRoleCheckButton": mock.Mock(),
"playSoundForStateCheckButton": mock.Mock(),
"playSoundForPositionInSetCheckButton": mock.Mock(),
"playSoundForValueCheckButton": mock.Mock(),
"beepProgressBarUpdatesCheckButton": mock.Mock(),
}
gui.get_widget = widgets.__getitem__
fakeThemeManager = mock.Mock()
fakeThemeManager.getAvailableThemes.return_value = ["default"]
fakeSettingsManager = mock.Mock()
fakeSettingsManager.getSetting.return_value = settings.SOUND_SINK_AUTO
fakeApp = mock.Mock(settingsManager=fakeSettingsManager)
with (
mock.patch.object(cthulhu_gui_prefs.cthulhu, "cthulhuApp", fakeApp),
mock.patch.object(
cthulhu_gui_prefs.sound_theme_manager,
"getManager",
return_value=fakeThemeManager,
),
):
gui._initSoundThemeState()
widgets["enableSoundCheckButton"].set_active.assert_called_once_with(False)
widgets["soundVolumeScale"].set_value.assert_called_once_with(0.65)
widgets["playSoundForRoleCheckButton"].set_active.assert_called_once_with(True)
widgets["playSoundForStateCheckButton"].set_active.assert_called_once_with(True)
widgets["playSoundForPositionInSetCheckButton"].set_active.assert_called_once_with(False)
widgets["playSoundForValueCheckButton"].set_active.assert_called_once_with(False)
widgets["beepProgressBarUpdatesCheckButton"].set_active.assert_called_once_with(True)
widgets["progressBarBeepIntervalSpinButton"].set_value.assert_called_once_with(0)
def test_sound_value_handlers_store_current_values(self):
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI)
gui.prefsDict = {}
volumeWidget = mock.Mock()
volumeWidget.get_value.return_value = 0.7
beepWidget = mock.Mock()
beepWidget.get_value_as_int.return_value = 0
gui.soundVolumeValueChanged(volumeWidget)
gui.progressBarBeepIntervalValueChanged(beepWidget)
self.assertEqual(gui.prefsDict["soundVolume"], 0.7)
self.assertEqual(gui.prefsDict["progressBarBeepInterval"], 0)
def test_load_profile_reinitializes_sound_state(self):
gui = cthulhu_gui_prefs.CthulhuSetupGUI.__new__(cthulhu_gui_prefs.CthulhuSetupGUI)
gui.saveBasicSettings = mock.Mock()
gui._initGUIState = mock.Mock()
gui._initSoundThemeState = mock.Mock()
gui._initSpeechState = mock.Mock()
gui._initEchoSpeechState = mock.Mock()
gui._populateKeyBindings = mock.Mock()
gui._CthulhuSetupGUI__initProfileCombo = mock.Mock()
gui.prefsDict = {}
fakeSettingsManager = mock.Mock()
fakeSettingsManager.getGeneralSettings.return_value = {"soundVolume": 0.5}
fakeApp = mock.Mock(settingsManager=fakeSettingsManager)
with (
mock.patch.object(cthulhu_gui_prefs.cthulhu, "cthulhuApp", fakeApp),
mock.patch.object(cthulhu_gui_prefs.cthulhu, "loadUserSettings"),
mock.patch.object(cthulhu_gui_prefs.braille, "checkBrailleSetting"),
):
gui.loadProfile(["Default", "default"])
gui._initSoundThemeState.assert_called_once_with()
if __name__ == "__main__":
unittest.main()