Files
fenrir/tests/unit/test_clipboard_sync_manager.py

273 lines
8.2 KiB
Python

from unittest.mock import Mock
import pytest
from fenrirscreenreader.core.clipboardSyncManager import ClipboardSyncManager
def build_env(
sync_enabled=False,
sync_display="",
screen_driver="vcsaDriver",
keyboard_driver="evdevDriver",
fenrir_text=None,
):
def get_setting(section, setting):
values = {
("clipboard", "sync_display"): sync_display,
("screen", "driver"): screen_driver,
("keyboard", "driver"): keyboard_driver,
}
return values[(section, setting)]
settings_manager = Mock(
get_setting_as_bool=Mock(return_value=sync_enabled),
get_setting_as_float=Mock(return_value=0.5),
get_setting=Mock(side_effect=get_setting),
)
memory_manager = Mock(
is_index_list_empty=Mock(return_value=fenrir_text is None),
get_index_list_element=Mock(return_value=fenrir_text),
add_value_to_first_index=Mock(),
)
return {
"runtime": {
"SettingsManager": settings_manager,
"MemoryManager": memory_manager,
"DebugManager": Mock(write_debug_out=Mock()),
}
}
@pytest.mark.unit
def test_clipboard_sync_disabled_by_default():
manager = ClipboardSyncManager()
manager.start = Mock()
manager.initialize(build_env(sync_enabled=False))
assert manager.enabled is False
manager.start.assert_not_called()
@pytest.mark.unit
def test_clipboard_sync_enabled_in_x_mode_with_current_display(monkeypatch):
monkeypatch.setenv("DISPLAY", ":1")
manager = ClipboardSyncManager()
manager.start = Mock()
manager.initialize(
build_env(
sync_enabled=True,
screen_driver="ptyDriver",
keyboard_driver="x11Driver",
)
)
assert manager.enabled is True
assert manager.display == ":1"
manager.start.assert_called_once_with()
@pytest.mark.unit
def test_clipboard_sync_console_skips_empty_display(monkeypatch):
monkeypatch.delenv("DISPLAY", raising=False)
manager = ClipboardSyncManager()
manager.start = Mock()
manager.initialize(build_env(sync_enabled=True))
assert manager.enabled is False
manager.start.assert_not_called()
@pytest.mark.unit
def test_clipboard_sync_console_allows_configured_display(monkeypatch):
monkeypatch.delenv("DISPLAY", raising=False)
manager = ClipboardSyncManager()
manager.start = Mock()
manager.initialize(build_env(sync_enabled=True, sync_display=":0"))
assert manager.enabled is True
assert manager.display == ":0"
manager.start.assert_called_once_with()
@pytest.mark.unit
def test_mark_written_to_x_updates_observed_state():
manager = ClipboardSyncManager()
manager.mark_written_to_x("manual export")
assert manager.last_written_to_x == "manual export"
assert manager.last_observed_fenrir == "manual export"
assert manager.last_observed_x == "manual export"
@pytest.mark.unit
def test_fenrir_to_x_write_is_not_reimported(monkeypatch):
env = build_env(fenrir_text="from fenrir")
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
write_text = Mock(return_value=True)
read_text = Mock(side_effect=[None, "from fenrir"])
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.write_text",
write_text,
)
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
read_text,
)
manager.poll_once()
manager.poll_once()
write_text.assert_called_once_with("from fenrir", ":1")
env["runtime"]["MemoryManager"].add_value_to_first_index.assert_not_called()
@pytest.mark.unit
def test_conflicting_clipboards_do_not_swap_values(monkeypatch):
env = build_env(fenrir_text="from fenrir")
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
write_text = Mock(return_value=True)
read_text = Mock(return_value="from x")
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.write_text",
write_text,
)
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
read_text,
)
manager.poll_once()
write_text.assert_called_once_with("from fenrir", ":1")
env["runtime"]["MemoryManager"].add_value_to_first_index.assert_not_called()
assert manager.last_written_to_x == "from fenrir"
assert manager.last_observed_x == "from fenrir"
assert manager.last_observed_fenrir == "from fenrir"
@pytest.mark.unit
def test_matching_clipboards_are_observed_without_duplicate_import(monkeypatch):
env = build_env(fenrir_text="same text")
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
write_text = Mock(return_value=True)
read_text = Mock(return_value="same text")
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.write_text",
write_text,
)
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
read_text,
)
manager.poll_once()
write_text.assert_not_called()
env["runtime"]["MemoryManager"].add_value_to_first_index.assert_not_called()
assert manager.last_observed_x == "same text"
assert manager.last_observed_fenrir == "same text"
@pytest.mark.unit
def test_x_to_fenrir_import_is_not_reexported(monkeypatch):
env = build_env(fenrir_text=None)
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
write_text = Mock(return_value=True)
read_text = Mock(return_value="from x")
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.write_text",
write_text,
)
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
read_text,
)
manager.poll_once()
env["runtime"]["MemoryManager"].is_index_list_empty.return_value = False
env["runtime"]["MemoryManager"].get_index_list_element.return_value = (
"from x"
)
manager.poll_once()
env["runtime"]["MemoryManager"].add_value_to_first_index.assert_called_once_with(
"clipboardHistory", "from x"
)
write_text.assert_not_called()
@pytest.mark.unit
def test_selected_imported_text_can_export_after_x_changes(monkeypatch):
env = build_env(fenrir_text=None)
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
write_text = Mock(return_value=True)
read_text = Mock(side_effect=["from x", "other x"])
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.write_text",
write_text,
)
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
read_text,
)
manager.poll_once()
env["runtime"]["MemoryManager"].is_index_list_empty.return_value = False
env["runtime"]["MemoryManager"].get_index_list_element.return_value = (
"from x"
)
manager.last_observed_fenrir = "different fenrir entry"
manager.poll_once()
write_text.assert_called_once_with("from x", ":1")
@pytest.mark.unit
@pytest.mark.parametrize("x_value", [None, "", object()])
def test_x_clipboard_non_text_values_are_ignored(monkeypatch, x_value):
env = build_env(fenrir_text=None)
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
Mock(return_value=x_value),
)
manager.poll_once()
env["runtime"]["MemoryManager"].add_value_to_first_index.assert_not_called()
@pytest.mark.unit
def test_x_clipboard_paste_exception_is_ignored(monkeypatch):
env = build_env(fenrir_text=None)
manager = ClipboardSyncManager()
manager.env = env
manager.display = ":1"
monkeypatch.setattr(
"fenrirscreenreader.core.clipboardSyncManager.x_clipboard.read_text",
Mock(side_effect=RuntimeError("no text target")),
)
manager.poll_once()
env["runtime"]["MemoryManager"].add_value_to_first_index.assert_not_called()
env["runtime"]["DebugManager"].write_debug_out.assert_called_once()