1
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2026-03-08 01:37:52 +01:00
Files
bec_widgets/tests/unit_tests/test_feedback_dialog.py
2026-02-21 14:47:19 +01:00

263 lines
10 KiB
Python

import pytest
from qtpy.QtCore import Qt
from qtpy.QtWidgets import QDialog
from bec_widgets.utils.colors import apply_theme
from bec_widgets.widgets.utility.feedback_dialog.feedback_dialog import FeedbackDialog, StarRating
@pytest.fixture
def star_rating(qtbot):
"""Create a StarRating widget for testing."""
widget = StarRating()
qtbot.addWidget(widget)
qtbot.waitExposed(widget)
yield widget
widget.close()
@pytest.fixture
def feedback_dialog(qtbot):
"""Create a FeedbackDialog for testing."""
dialog = FeedbackDialog()
qtbot.addWidget(dialog)
qtbot.waitExposed(dialog)
yield dialog
dialog.close()
class TestStarRating:
"""Tests for the StarRating widget."""
def test_initial_state(self, star_rating):
"""Test that StarRating initializes with rating 0."""
assert star_rating.rating() == 0
assert star_rating._hovered_star == 0
assert len(star_rating._star_buttons) == 5
def test_set_rating_via_method(self, star_rating):
"""Test setting rating programmatically."""
star_rating.set_rating(3)
assert star_rating.rating() == 3
star_rating.set_rating(5)
assert star_rating.rating() == 5
def test_set_rating_bounds(self, star_rating):
"""Test that rating is bounded between 0 and 5."""
star_rating.set_rating(0)
assert star_rating.rating() == 0
star_rating.set_rating(5)
assert star_rating.rating() == 5
# Out of bounds should not change rating
initial_rating = star_rating.rating()
star_rating.set_rating(6)
assert star_rating.rating() == initial_rating
star_rating.set_rating(-1)
assert star_rating.rating() == initial_rating
def test_rating_signal_emission(self, star_rating, qtbot):
"""Test that rating_changed signal is emitted when rating changes."""
with qtbot.waitSignal(star_rating.rating_changed, timeout=1000) as blocker:
star_rating.set_rating(4)
assert blocker.args == [4]
def test_rating_signal_not_emitted_on_same_value(self, star_rating, qtbot):
"""Test that signal is not emitted when setting the same rating."""
star_rating.set_rating(3)
# Should not emit signal when setting same value
with qtbot.assertNotEmitted(star_rating.rating_changed, wait=100):
star_rating.set_rating(3)
def test_click_star_button(self, star_rating, qtbot):
"""Test clicking on star buttons."""
# Click the third star (index 2)
with qtbot.waitSignal(star_rating.rating_changed, timeout=1000):
qtbot.mouseClick(star_rating._star_buttons[2], Qt.LeftButton)
assert star_rating.rating() == 3
# Click the first star
with qtbot.waitSignal(star_rating.rating_changed, timeout=1000):
qtbot.mouseClick(star_rating._star_buttons[0], Qt.LeftButton)
assert star_rating.rating() == 1
def test_mouse_hover(self, star_rating, qtbot):
"""Test mouse hover behavior."""
# Set initial rating
star_rating.set_rating(2)
assert star_rating._hovered_star == 0
# Simulate mouse move over the fourth button
btn = star_rating._star_buttons[3]
btn_center = btn.geometry().center()
event = qtbot.mouseMove(star_rating, pos=btn_center)
# Note: _hovered_star should be updated by mouseMoveEvent
# This is a bit tricky to test directly, so we verify the method exists
assert hasattr(star_rating, "mouseMoveEvent")
assert hasattr(star_rating, "leaveEvent")
def test_leave_event(self, star_rating, qtbot):
"""Test that leaving the widget clears hover state."""
star_rating.set_rating(2)
star_rating._hovered_star = 4 # Simulate hover
# Trigger leave event
star_rating.leaveEvent(None)
assert star_rating._hovered_star == 0
assert star_rating.rating() == 2 # Rating should remain unchanged
def test_update_theme_colors(self, star_rating):
"""Test that theme colors are applied correctly."""
assert hasattr(star_rating, "_inactive_color")
assert hasattr(star_rating, "_active_color")
# Colors should be initialized
assert star_rating._inactive_color is not None
assert star_rating._active_color is not None
def test_display_update(self, star_rating):
"""Test that display updates when rating changes."""
star_rating.set_rating(3)
# If this doesn't raise an exception, the display was updated successfully
star_rating._update_display()
class TestFeedbackDialog:
"""Tests for the FeedbackDialog widget."""
def test_initial_state(self, feedback_dialog):
"""Test that FeedbackDialog initializes correctly."""
assert feedback_dialog.windowTitle() == "Feedback"
assert feedback_dialog.isModal() is True
assert feedback_dialog._star_rating is not None
assert feedback_dialog._comment_field is not None
assert feedback_dialog._email_field is not None
assert feedback_dialog._submit_button is not None
assert feedback_dialog._cancel_button is not None
def test_get_feedback_initial(self, feedback_dialog):
"""Test getting feedback from unmodified dialog."""
rating, comment, email = feedback_dialog.get_feedback()
assert rating == 0
assert comment == ""
assert email == ""
def test_set_and_get_rating(self, feedback_dialog):
"""Test setting and getting rating."""
feedback_dialog.set_rating(4)
rating, _, _ = feedback_dialog.get_feedback()
assert rating == 4
def test_set_and_get_comment(self, feedback_dialog):
"""Test setting and getting comment."""
test_comment = "This is a test comment"
feedback_dialog.set_comment(test_comment)
_, comment, _ = feedback_dialog.get_feedback()
assert comment == test_comment
def test_set_and_get_email(self, feedback_dialog):
"""Test setting and getting email."""
test_email = "test@example.com"
feedback_dialog.set_email(test_email)
_, _, email = feedback_dialog.get_feedback()
assert email == test_email
def test_set_all_feedback(self, feedback_dialog):
"""Test setting all feedback fields."""
feedback_dialog.set_rating(5)
feedback_dialog.set_comment("Great widget!")
feedback_dialog.set_email("user@example.com")
rating, comment, email = feedback_dialog.get_feedback()
assert rating == 5
assert comment == "Great widget!"
assert email == "user@example.com"
def test_submit_button_emits_signal(self, feedback_dialog, qtbot):
"""Test that clicking submit emits feedback_submitted signal."""
feedback_dialog.set_rating(3)
feedback_dialog.set_comment("Test feedback")
feedback_dialog.set_email("test@test.com")
with qtbot.waitSignal(feedback_dialog.feedback_submitted, timeout=1000) as blocker:
qtbot.mouseClick(feedback_dialog._submit_button, Qt.LeftButton)
assert blocker.args == [3, "Test feedback", "test@test.com"]
def test_submit_button_accepts_dialog(self, feedback_dialog, qtbot):
"""Test that clicking submit accepts the dialog."""
feedback_dialog.set_rating(4)
qtbot.mouseClick(feedback_dialog._submit_button, Qt.LeftButton)
qtbot.wait(100)
# Dialog should be accepted
assert feedback_dialog.result() == QDialog.DialogCode.Accepted
def test_cancel_button_rejects_dialog(self, feedback_dialog, qtbot):
"""Test that clicking cancel rejects the dialog."""
qtbot.mouseClick(feedback_dialog._cancel_button, Qt.LeftButton)
qtbot.wait(100)
# Dialog should be rejected
assert feedback_dialog.result() == QDialog.DialogCode.Rejected
def test_submit_with_empty_fields(self, feedback_dialog, qtbot):
"""Test submitting with empty fields."""
# Don't set any values
with qtbot.waitSignal(feedback_dialog.feedback_submitted, timeout=1000) as blocker:
qtbot.mouseClick(feedback_dialog._submit_button, Qt.LeftButton)
# Should emit with empty values
assert blocker.args == [0, "", ""]
def test_submit_strips_whitespace(self, feedback_dialog, qtbot):
"""Test that whitespace is stripped from comment and email."""
feedback_dialog.set_comment(" Test comment ")
feedback_dialog.set_email(" test@example.com ")
with qtbot.waitSignal(feedback_dialog.feedback_submitted, timeout=1000) as blocker:
qtbot.mouseClick(feedback_dialog._submit_button, Qt.LeftButton)
rating, comment, email = blocker.args
assert comment == "Test comment"
assert email == "test@example.com"
def test_dialog_has_correct_properties(self, feedback_dialog):
"""Test that dialog has correct class properties."""
assert hasattr(FeedbackDialog, "ICON_NAME")
assert FeedbackDialog.ICON_NAME == "feedback"
assert hasattr(FeedbackDialog, "PLUGIN")
assert FeedbackDialog.PLUGIN is True
def test_comment_field_placeholder(self, feedback_dialog):
"""Test that comment field has placeholder text."""
assert feedback_dialog._comment_field.placeholderText() != ""
def test_email_field_placeholder(self, feedback_dialog):
"""Test that email field has placeholder text."""
assert feedback_dialog._email_field.placeholderText() != ""
def test_submit_button_is_default(self, feedback_dialog):
"""Test that submit button is set as default."""
assert feedback_dialog._submit_button.isDefault() is True
def test_star_rating_embedded_correctly(self, feedback_dialog, qtbot):
"""Test that StarRating widget is properly embedded."""
# Verify we can interact with the embedded star rating
feedback_dialog._star_rating.set_rating(5)
assert feedback_dialog._star_rating.rating() == 5
# Verify rating is reflected in feedback
rating, _, _ = feedback_dialog.get_feedback()
assert rating == 5