mirror of
https://github.com/chidiwilliams/buzz.git
synced 2026-03-14 14:45:46 +01:00
Co-authored-by: Raivis Dejus <orvils@gmail.com>
This commit is contained in:
parent
47ddc1461c
commit
6e54b5cb02
29 changed files with 2171 additions and 166 deletions
324
tests/widgets/presentation_window_test.py
Normal file
324
tests/widgets/presentation_window_test.py
Normal file
|
|
@ -0,0 +1,324 @@
|
|||
import os
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
from unittest.mock import patch, MagicMock
|
||||
from pytestqt.qtbot import QtBot
|
||||
from PyQt6.QtCore import Qt
|
||||
from PyQt6.QtGui import QKeyEvent
|
||||
|
||||
from buzz.widgets.presentation_window import PresentationWindow
|
||||
from buzz.settings.settings import Settings
|
||||
from buzz.locale import _
|
||||
|
||||
class TestPresentationWindow:
|
||||
def test_should_set_window_title(self, qtbot: QtBot):
|
||||
"""Test that the window title is set correctly"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert _("Live Transcript Presentation") in window.windowTitle()
|
||||
window.close()
|
||||
|
||||
def test_should_have_window_flag(self, qtbot: QtBot):
|
||||
"""Test that window has the Window flag set"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert window.windowFlags() & Qt.WindowType.Window
|
||||
window.close()
|
||||
|
||||
def test_should_have_transcript_display(self, qtbot: QtBot):
|
||||
"""Test that the transcript display is created"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert window.transcript_display is not None
|
||||
assert window.transcript_display.isReadOnly()
|
||||
window.close()
|
||||
|
||||
def test_should_have_translation_display_hidden(self, qtbot: QtBot):
|
||||
"""Test that the translation display is created but hidden initially"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert window.translation_display is not None
|
||||
assert window.translation_display.isReadOnly()
|
||||
assert not window.translation_display.isVisible()
|
||||
window.close()
|
||||
|
||||
def test_should_have_default_size(self, qtbot: QtBot):
|
||||
"""Test that the window has default size"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert window.width() == 800
|
||||
assert window.height() == 600
|
||||
window.close()
|
||||
|
||||
|
||||
class TestPresentationWindowUpdateTranscripts:
|
||||
def test_update_transcripts_with_text(self, qtbot: QtBot):
|
||||
"""Test updating transcripts with text"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.update_transcripts("Hello world")
|
||||
|
||||
assert window._current_transcript == "Hello world"
|
||||
assert "Hello world" in window.transcript_display.toHtml()
|
||||
window.close()
|
||||
|
||||
def test_update_transcripts_with_empty_text(self, qtbot: QtBot):
|
||||
"""Test that empty text does not update the display"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.update_transcripts("")
|
||||
|
||||
assert window._current_transcript == ""
|
||||
window.close()
|
||||
|
||||
def test_update_transcripts_escapes_html(self, qtbot: QtBot):
|
||||
"""Test that special HTML characters are escaped"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.update_transcripts("<script>alert('xss')</script>")
|
||||
|
||||
html = window.transcript_display.toHtml()
|
||||
assert "<script>" not in html
|
||||
assert "<script>" in html
|
||||
window.close()
|
||||
|
||||
def test_update_transcripts_preserves_newlines(self, qtbot: QtBot):
|
||||
"""Test that newlines are converted to <br> tags"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.update_transcripts("Line 1\nLine 2")
|
||||
|
||||
html = window.transcript_display.toHtml()
|
||||
assert "<br>" in html or "<br/>" in html or "Line 1" in html
|
||||
window.close()
|
||||
|
||||
|
||||
class TestPresentationWindowUpdateTranslations:
|
||||
def test_update_translations_with_text(self, qtbot: QtBot):
|
||||
"""Test updating translations with text"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
window.show()
|
||||
|
||||
window.update_translations("Translated text")
|
||||
|
||||
assert window._current_translation == "Translated text"
|
||||
assert window.translation_display.isVisible()
|
||||
assert "Translated text" in window.translation_display.toHtml()
|
||||
window.close()
|
||||
|
||||
def test_update_translations_with_empty_text(self, qtbot: QtBot):
|
||||
"""Test that empty text does not update the display"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
window.show()
|
||||
|
||||
window.update_translations("")
|
||||
|
||||
assert window._current_translation == ""
|
||||
# translation_display should remain hidden when not updated with real text
|
||||
assert window.translation_display.isHidden()
|
||||
window.close()
|
||||
|
||||
def test_update_translations_escapes_html(self, qtbot: QtBot):
|
||||
"""Test that special HTML characters are escaped in translations"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.update_translations("<b>bold</b>")
|
||||
|
||||
html = window.translation_display.toHtml()
|
||||
assert "<b>" in html
|
||||
window.close()
|
||||
|
||||
|
||||
class TestPresentationWindowLoadSettings:
|
||||
def test_load_settings_light_theme(self, qtbot: QtBot):
|
||||
"""Test loading light theme settings"""
|
||||
settings = Settings()
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_THEME, "light")
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_TEXT_SIZE, 24)
|
||||
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert "#000000" in window.window_style or "color:" in window.window_style
|
||||
window.close()
|
||||
|
||||
def test_load_settings_dark_theme(self, qtbot: QtBot):
|
||||
"""Test loading dark theme settings"""
|
||||
settings = Settings()
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_THEME, "dark")
|
||||
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert "#FFFFFF" in window.window_style or "#000000" in window.window_style
|
||||
window.close()
|
||||
|
||||
def test_load_settings_custom_theme(self, qtbot: QtBot):
|
||||
"""Test loading custom theme settings"""
|
||||
settings = Settings()
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_THEME, "custom")
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "#FF0000")
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_BACKGROUND_COLOR, "#00FF00")
|
||||
settings.set_value(Settings.Key.PRESENTATION_WINDOW_TEXT_SIZE, 32)
|
||||
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
assert "#FF0000" in window.window_style or "#00FF00" in window.window_style
|
||||
window.close()
|
||||
|
||||
def test_load_settings_refreshes_content(self, qtbot: QtBot):
|
||||
"""Test that load_settings refreshes existing content"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.update_transcripts("Test transcript")
|
||||
window.update_translations("Test translation")
|
||||
|
||||
# Reload settings
|
||||
window.load_settings()
|
||||
|
||||
# Content should still be present
|
||||
assert "Test transcript" in window.transcript_display.toHtml()
|
||||
assert "Test translation" in window.translation_display.toHtml()
|
||||
window.close()
|
||||
|
||||
|
||||
class TestPresentationWindowApplyStyling:
|
||||
def test_apply_styling_creates_css(self, qtbot: QtBot):
|
||||
"""Test that apply_styling creates appropriate CSS"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
window.apply_styling("#123456", "#654321", 48)
|
||||
|
||||
assert "#123456" in window.window_style
|
||||
assert "#654321" in window.window_style
|
||||
assert "48pt" in window.window_style
|
||||
window.close()
|
||||
|
||||
def test_apply_styling_with_custom_css_file(self, qtbot: QtBot):
|
||||
"""Test that custom CSS file is loaded when it exists"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
css_path = window.get_css_file_path()
|
||||
custom_css = "body { color: red; font-size: 100pt; }"
|
||||
|
||||
try:
|
||||
with open(css_path, "w", encoding="utf-8") as f:
|
||||
f.write(custom_css)
|
||||
|
||||
window.apply_styling("#000", "#FFF", 24)
|
||||
|
||||
assert window.window_style == custom_css
|
||||
finally:
|
||||
if os.path.exists(css_path):
|
||||
os.remove(css_path)
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
class TestPresentationWindowFullscreen:
|
||||
def test_toggle_fullscreen_enters_fullscreen(self, qtbot: QtBot):
|
||||
"""Test that toggle_fullscreen enters fullscreen mode"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
window.show()
|
||||
|
||||
assert not window.isFullScreen()
|
||||
|
||||
window.toggle_fullscreen()
|
||||
|
||||
assert window.isFullScreen()
|
||||
window.close()
|
||||
|
||||
def test_toggle_fullscreen_exits_fullscreen(self, qtbot: QtBot):
|
||||
"""Test that toggle_fullscreen exits fullscreen mode"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
window.show()
|
||||
|
||||
window.showFullScreen()
|
||||
assert window.isFullScreen()
|
||||
|
||||
window.toggle_fullscreen()
|
||||
|
||||
assert not window.isFullScreen()
|
||||
window.close()
|
||||
|
||||
class TestPresentationWindowKeyPressEvent:
|
||||
def test_escape_exits_fullscreen(self, qtbot: QtBot):
|
||||
"""Test that ESC key exits fullscreen mode"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
window.show()
|
||||
window.showFullScreen()
|
||||
|
||||
assert window.isFullScreen()
|
||||
|
||||
# Simulate ESC key press
|
||||
event = QKeyEvent(
|
||||
QKeyEvent.Type.KeyPress,
|
||||
Qt.Key.Key_Escape,
|
||||
Qt.KeyboardModifier.NoModifier
|
||||
)
|
||||
window.keyPressEvent(event)
|
||||
|
||||
assert not window.isFullScreen()
|
||||
window.close()
|
||||
|
||||
def test_escape_does_not_affect_normal_mode(self, qtbot: QtBot):
|
||||
"""Test that ESC key does nothing in normal mode"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
window.show()
|
||||
|
||||
assert not window.isFullScreen()
|
||||
|
||||
# Simulate ESC key press
|
||||
event = QKeyEvent(
|
||||
QKeyEvent.Type.KeyPress,
|
||||
Qt.Key.Key_Escape,
|
||||
Qt.KeyboardModifier.NoModifier
|
||||
)
|
||||
window.keyPressEvent(event)
|
||||
|
||||
assert not window.isFullScreen()
|
||||
window.close()
|
||||
|
||||
class TestPresentationWindowGetCssFilePath:
|
||||
def test_get_css_file_path_returns_path(self, qtbot: QtBot):
|
||||
"""Test that get_css_file_path returns a valid path"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
css_path = window.get_css_file_path()
|
||||
|
||||
assert css_path.endswith("presentation_window_style.css")
|
||||
assert "Buzz" in css_path
|
||||
window.close()
|
||||
|
||||
def test_get_css_file_path_creates_directory(self, qtbot: QtBot):
|
||||
"""Test that get_css_file_path creates the cache directory"""
|
||||
window = PresentationWindow()
|
||||
qtbot.add_widget(window)
|
||||
|
||||
css_path = window.get_css_file_path()
|
||||
parent_dir = os.path.dirname(css_path)
|
||||
|
||||
assert os.path.isdir(parent_dir)
|
||||
window.close()
|
||||
|
|
@ -4,12 +4,15 @@ import pytest
|
|||
import platform
|
||||
import tempfile
|
||||
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import patch, MagicMock
|
||||
from pytestqt.qtbot import QtBot
|
||||
from PyQt6.QtWidgets import QColorDialog
|
||||
from PyQt6.QtGui import QColor
|
||||
|
||||
from buzz.locale import _
|
||||
from buzz.settings.recording_transcriber_mode import RecordingTranscriberMode
|
||||
from buzz.widgets.recording_transcriber_widget import RecordingTranscriberWidget
|
||||
from buzz.widgets.presentation_window import PresentationWindow
|
||||
from buzz.settings.settings import Settings
|
||||
|
||||
from tests.mock_sounddevice import MockSoundDevice, MockInputStream
|
||||
|
|
@ -187,3 +190,438 @@ class TestRecordingTranscriberWidget:
|
|||
qtbot.wait(500)
|
||||
|
||||
widget.close()
|
||||
|
||||
|
||||
class TestRecordingTranscriberWidgetPresentation:
|
||||
"""Tests for presentation window related functionality"""
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_presentation_options_bar_created(self, qtbot: QtBot):
|
||||
"""Test that presentation options bar is created"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
assert widget.presentation_options_bar is not None
|
||||
assert not widget.presentation_options_bar.isVisible()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_presentation_options_bar_has_buttons(self, qtbot: QtBot):
|
||||
"""Test that presentation options bar has all expected buttons"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
assert widget.show_presentation_button is not None
|
||||
assert widget.fullscreen_button is not None
|
||||
assert widget.text_size_spinbox is not None
|
||||
assert widget.theme_combo is not None
|
||||
assert widget.text_color_button is not None
|
||||
assert widget.bg_color_button is not None
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_presentation_window_initially_none(self, qtbot: QtBot):
|
||||
"""Test that presentation window is None initially"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
assert widget.presentation_window is None
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_show_presentation_clicked_creates_window(self, qtbot: QtBot):
|
||||
"""Test that clicking show presentation button creates the window"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_show_presentation_clicked()
|
||||
|
||||
assert widget.presentation_window is not None
|
||||
assert isinstance(widget.presentation_window, PresentationWindow)
|
||||
assert widget.presentation_window.isVisible()
|
||||
assert widget.fullscreen_button.isEnabled()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_show_presentation_clicked_syncs_content(self, qtbot: QtBot):
|
||||
"""Test that clicking show presentation button syncs existing content"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
# Add some text to the transcription box
|
||||
widget.transcription_text_box.setPlainText("Test transcript text")
|
||||
|
||||
widget.on_show_presentation_clicked()
|
||||
|
||||
assert widget.presentation_window._current_transcript == "Test transcript text"
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_show_presentation_clicked_brings_existing_to_front(self, qtbot: QtBot):
|
||||
"""Test that clicking show presentation button brings existing window to front"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
# Create window first
|
||||
widget.on_show_presentation_clicked()
|
||||
first_window = widget.presentation_window
|
||||
|
||||
# Click again
|
||||
widget.on_show_presentation_clicked()
|
||||
|
||||
# Should be the same window
|
||||
assert widget.presentation_window is first_window
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_text_size_changed(self, qtbot: QtBot):
|
||||
"""Test that text size change updates settings"""
|
||||
settings = Settings()
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_text_size_changed(36)
|
||||
|
||||
# Wait for debounce
|
||||
qtbot.wait(200)
|
||||
|
||||
saved_size = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_SIZE, 24, int)
|
||||
assert saved_size == 36
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_theme_changed_light(self, qtbot: QtBot):
|
||||
"""Test that theme change to light works"""
|
||||
settings = Settings()
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_theme_changed(0) # light theme
|
||||
|
||||
saved_theme = settings.value(Settings.Key.PRESENTATION_WINDOW_THEME, "")
|
||||
assert saved_theme == "light"
|
||||
# Color buttons should be hidden for light theme
|
||||
assert widget.text_color_button.isHidden()
|
||||
assert widget.bg_color_button.isHidden()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_theme_changed_dark(self, qtbot: QtBot):
|
||||
"""Test that theme change to dark works"""
|
||||
settings = Settings()
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_theme_changed(1) # dark theme
|
||||
|
||||
saved_theme = settings.value(Settings.Key.PRESENTATION_WINDOW_THEME, "")
|
||||
assert saved_theme == "dark"
|
||||
# Color buttons should be hidden for dark theme
|
||||
assert widget.text_color_button.isHidden()
|
||||
assert widget.bg_color_button.isHidden()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_theme_changed_custom(self, qtbot: QtBot):
|
||||
"""Test that theme change to custom shows color buttons"""
|
||||
settings = Settings()
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_theme_changed(2) # custom theme
|
||||
|
||||
saved_theme = settings.value(Settings.Key.PRESENTATION_WINDOW_THEME, "")
|
||||
assert saved_theme == "custom"
|
||||
# Color buttons should NOT be hidden for custom theme
|
||||
assert not widget.text_color_button.isHidden()
|
||||
assert not widget.bg_color_button.isHidden()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_text_color_clicked(self, qtbot: QtBot):
|
||||
"""Test that text color button opens color dialog and saves selection"""
|
||||
settings = Settings()
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings"),
|
||||
patch("buzz.widgets.recording_transcriber_widget.QColorDialog.getColor",
|
||||
return_value=QColor("#FF5500"))):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_text_color_clicked()
|
||||
|
||||
saved_color = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "")
|
||||
assert saved_color == "#ff5500"
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_text_color_clicked_cancel(self, qtbot: QtBot):
|
||||
"""Test that cancelling color dialog does not save"""
|
||||
settings = Settings()
|
||||
original_color = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "#000000")
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings"),
|
||||
patch("buzz.widgets.recording_transcriber_widget.QColorDialog.getColor",
|
||||
return_value=QColor())): # Invalid color = cancelled
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_text_color_clicked()
|
||||
|
||||
saved_color = settings.value(Settings.Key.PRESENTATION_WINDOW_TEXT_COLOR, "")
|
||||
assert saved_color == original_color
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_bg_color_clicked(self, qtbot: QtBot):
|
||||
"""Test that background color button opens color dialog and saves selection"""
|
||||
settings = Settings()
|
||||
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings"),
|
||||
patch("buzz.widgets.recording_transcriber_widget.QColorDialog.getColor",
|
||||
return_value=QColor("#00AA55"))):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_bg_color_clicked()
|
||||
|
||||
saved_color = settings.value(Settings.Key.PRESENTATION_WINDOW_BACKGROUND_COLOR, "")
|
||||
assert saved_color == "#00aa55"
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_fullscreen_clicked(self, qtbot: QtBot):
|
||||
"""Test that fullscreen button toggles presentation window fullscreen"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
# Create presentation window first
|
||||
widget.on_show_presentation_clicked()
|
||||
|
||||
assert not widget.presentation_window.isFullScreen()
|
||||
|
||||
widget.on_fullscreen_clicked()
|
||||
|
||||
assert widget.presentation_window.isFullScreen()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_on_fullscreen_clicked_without_window(self, qtbot: QtBot):
|
||||
"""Test that fullscreen button does nothing without presentation window"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
# Should not raise exception
|
||||
widget.on_fullscreen_clicked()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_presentation_window_updates_on_transcription(self, qtbot: QtBot):
|
||||
"""Test that presentation window updates when new transcription arrives"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_show_presentation_clicked()
|
||||
|
||||
widget.transcriber_mode = RecordingTranscriberMode.APPEND_BELOW
|
||||
widget.on_next_transcription("Hello world")
|
||||
|
||||
assert "Hello world" in widget.presentation_window._current_transcript
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_close_event_closes_presentation_window(self, qtbot: QtBot):
|
||||
"""Test that closing widget also closes presentation window"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
widget.on_show_presentation_clicked()
|
||||
presentation_window = widget.presentation_window
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
widget.close()
|
||||
|
||||
assert widget.presentation_window is None
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_fullscreen_button_disabled_initially(self, qtbot: QtBot):
|
||||
"""Test that fullscreen button is disabled when no presentation window"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
assert not widget.fullscreen_button.isEnabled()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
def test_presentation_bar_shown_when_recording(self, qtbot: QtBot):
|
||||
"""Test that presentation bar is shown when recording starts"""
|
||||
with (patch("sounddevice.InputStream", side_effect=MockInputStream),
|
||||
patch("buzz.transcriber.recording_transcriber.RecordingTranscriber.get_device_sample_rate",
|
||||
return_value=16_000),
|
||||
patch("sounddevice.check_input_settings")):
|
||||
widget = RecordingTranscriberWidget(
|
||||
custom_sounddevice=MockSoundDevice()
|
||||
)
|
||||
widget.device_sample_rate = 16_000
|
||||
qtbot.add_widget(widget)
|
||||
|
||||
# Initially hidden
|
||||
assert widget.presentation_options_bar.isHidden()
|
||||
|
||||
# Simulate clicking record by directly calling the handler
|
||||
# This avoids starting actual recording threads
|
||||
widget.current_status = widget.RecordingStatus.RECORDING
|
||||
widget.record_button.set_recording()
|
||||
widget.transcription_options_group_box.setEnabled(False)
|
||||
widget.audio_devices_combo_box.setEnabled(False)
|
||||
widget.presentation_options_bar.show()
|
||||
|
||||
# Should no longer be hidden after recording starts
|
||||
assert not widget.presentation_options_bar.isHidden()
|
||||
|
||||
time.sleep(0.5)
|
||||
widget.close()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue