import os import subprocess from unittest.mock import Mock import pytest from fenrirscreenreader.utils import x_clipboard def command_exists(command): if command == "xclip": return "/usr/bin/xclip" return None @pytest.mark.unit def test_write_text_uses_display_env_without_mutating_process_env( monkeypatch, ): monkeypatch.delenv("DISPLAY", raising=False) monkeypatch.setattr(x_clipboard.shutil, "which", command_exists) run_command = Mock( return_value=subprocess.CompletedProcess( ["xclip"], 0, stdout=b"", stderr=b"" ) ) monkeypatch.setattr(x_clipboard.subprocess, "run", run_command) assert x_clipboard.write_text("clipboard text", ":3") is True command = run_command.call_args.args[0] kwargs = run_command.call_args.kwargs assert command == ["xclip", "-selection", "clipboard"] assert kwargs["input"] == b"clipboard text" assert kwargs["env"]["DISPLAY"] == ":3" assert kwargs["timeout"] == 2.0 assert os.environ.get("DISPLAY") is None @pytest.mark.unit def test_read_text_scans_displays_until_text_is_found(monkeypatch): monkeypatch.delenv("DISPLAY", raising=False) monkeypatch.setattr(x_clipboard.shutil, "which", command_exists) displays = [] def run_command(command, **kwargs): displays.append(kwargs["env"].get("DISPLAY")) if kwargs["env"].get("DISPLAY") == ":1": return subprocess.CompletedProcess( command, 0, stdout=b"from x", stderr=b"" ) return subprocess.CompletedProcess( command, 1, stdout=b"", stderr=b"missing display" ) monkeypatch.setattr(x_clipboard.subprocess, "run", run_command) assert x_clipboard.read_text(scan_displays=True) == "from x" assert displays == [":0", ":1"] @pytest.mark.unit def test_read_text_empty_success_returns_none(monkeypatch): monkeypatch.setenv("DISPLAY", ":2") monkeypatch.setattr(x_clipboard.shutil, "which", command_exists) monkeypatch.setattr( x_clipboard.subprocess, "run", Mock( return_value=subprocess.CompletedProcess( ["xclip"], 0, stdout=b"", stderr=b"" ) ), ) assert x_clipboard.read_text() is None @pytest.mark.unit def test_write_text_propagates_clipboard_timeout(monkeypatch): monkeypatch.setattr(x_clipboard.shutil, "which", command_exists) timeout = subprocess.TimeoutExpired(["xclip"], 2.0) monkeypatch.setattr( x_clipboard.subprocess, "run", Mock(side_effect=timeout), ) with pytest.raises(subprocess.TimeoutExpired): x_clipboard.write_text("clipboard text", ":3")