Co-authored-by: Carlo <carloantonio.patti@mistral.ai>
Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai>
Co-authored-by: Clement Sirieix <clem.sirieix@gmail.com>
Co-authored-by: Michel Thomazo <michel.thomazo@mistral.ai>
Co-authored-by: Clément Drouin <clement.drouin@mistral.ai>
Co-authored-by: Vincent Guilloux <vincent.guilloux@mistral.ai>
Co-authored-by: Thomas Kenbeek <thomas.kenbeek@mistral.ai>
Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Quentin 2026-02-27 17:31:58 +01:00 committed by GitHub
parent a560a47ce8
commit 5d2e01a6d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
139 changed files with 7152 additions and 1457 deletions

View file

@ -0,0 +1,151 @@
from __future__ import annotations
from unittest.mock import MagicMock, PropertyMock
import pytest
from vibe.cli.textual_ui.notifications import (
NotificationContext,
TextualNotificationAdapter,
)
def _make_fake_app(*, is_headless: bool = False) -> MagicMock:
app = MagicMock()
type(app).is_headless = PropertyMock(return_value=is_headless)
return app
@pytest.fixture
def fake_app() -> MagicMock:
return _make_fake_app()
@pytest.fixture
def adapter_enabled(fake_app: MagicMock) -> TextualNotificationAdapter:
return TextualNotificationAdapter(
fake_app, get_enabled=lambda: True, default_title="Vibe"
)
@pytest.fixture
def adapter_disabled(fake_app: MagicMock) -> TextualNotificationAdapter:
return TextualNotificationAdapter(
fake_app, get_enabled=lambda: False, default_title="Vibe"
)
class TestTextualNotificationAdapter:
def test_no_notification_when_disabled(
self, adapter_disabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_disabled.on_blur()
adapter_disabled.notify(NotificationContext.ACTION_REQUIRED)
fake_app.bell.assert_not_called()
def test_no_notification_when_focused(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
fake_app.bell.assert_not_called()
def test_notification_sent_when_unfocused_and_enabled(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.on_blur()
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
fake_app.bell.assert_called_once()
fake_app._driver.write.assert_called_once_with(
"\x1b]0;Vibe - Action Required\x07"
)
def test_throttle_prevents_rapid_notifications(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.on_blur()
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
assert fake_app.bell.call_count == 1
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
assert fake_app.bell.call_count == 1
def test_contextual_title_for_action_required(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.on_blur()
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
fake_app._driver.write.assert_called_once_with(
"\x1b]0;Vibe - Action Required\x07"
)
def test_contextual_title_for_complete(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.on_blur()
adapter_enabled.notify(NotificationContext.COMPLETE)
fake_app._driver.write.assert_called_once_with(
"\x1b]0;Vibe - Task Complete\x07"
)
def test_restore_sets_default_title(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.restore()
fake_app._driver.write.assert_called_once_with("\x1b]0;Vibe\x07")
def test_on_focus_restores_title(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.on_blur()
adapter_enabled.on_focus()
fake_app._driver.write.assert_called_once_with("\x1b]0;Vibe\x07")
def test_on_focus_prevents_notifications(
self, adapter_enabled: TextualNotificationAdapter, fake_app: MagicMock
) -> None:
adapter_enabled.on_blur()
adapter_enabled.on_focus()
fake_app.reset_mock()
adapter_enabled.notify(NotificationContext.ACTION_REQUIRED)
fake_app.bell.assert_not_called()
def test_no_title_write_when_headless(self) -> None:
app = _make_fake_app(is_headless=True)
adapter = TextualNotificationAdapter(
app, get_enabled=lambda: True, default_title="Vibe"
)
adapter.on_blur()
adapter.notify(NotificationContext.ACTION_REQUIRED)
app.bell.assert_called_once()
app._driver.write.assert_not_called()
def test_enabled_callback_reads_live_value(self, fake_app: MagicMock) -> None:
enabled = True
adapter = TextualNotificationAdapter(
fake_app, get_enabled=lambda: enabled, default_title="Vibe"
)
adapter.on_blur()
adapter.notify(NotificationContext.ACTION_REQUIRED)
assert fake_app.bell.call_count == 1
enabled = False
adapter._last_notification_time = 0.0
adapter.notify(NotificationContext.ACTION_REQUIRED)
assert fake_app.bell.call_count == 1