testsAndMisc/python_pkg/brother_printer/tests/test_query.py

91 lines
3.5 KiB
Python
Raw Normal View History

"""Tests for the shared brother_printer._query helpers."""
from __future__ import annotations
import subprocess
from unittest.mock import MagicMock, patch
from python_pkg.brother_printer._query import (
parse_cups_usb_uri,
printer_info_from_cups,
run_command_text,
)
MOD = "python_pkg.brother_printer._query"
class TestRunCommandText:
"""The shared subprocess wrapper."""
@patch(f"{MOD}.subprocess.run")
def test_returns_stdout(self, mock_run: MagicMock) -> None:
"""A successful run yields its captured stdout."""
mock_run.return_value = MagicMock(stdout="line one\nline two\n")
assert run_command_text(["echo", "hi"]) == "line one\nline two\n"
@patch(f"{MOD}.subprocess.run")
def test_timeout_is_empty(self, mock_run: MagicMock) -> None:
"""A timeout is swallowed and reported as empty output."""
mock_run.side_effect = subprocess.TimeoutExpired("cmd", 5)
assert run_command_text(["slow"]) == ""
@patch(f"{MOD}.subprocess.run")
def test_oserror_is_empty(self, mock_run: MagicMock) -> None:
"""An OS error (missing binary) is swallowed and reported as empty."""
mock_run.side_effect = OSError("no such file")
assert run_command_text(["missing"]) == ""
@patch(f"{MOD}.subprocess.run")
def test_subprocess_error_is_empty(self, mock_run: MagicMock) -> None:
"""A generic subprocess error is swallowed and reported as empty."""
mock_run.side_effect = subprocess.SubprocessError("boom")
assert run_command_text(["bad"]) == ""
class TestParseCupsUsbUri:
"""Parsing product/serial out of a CUPS ``usb://`` URI."""
def test_full_uri(self) -> None:
"""A URI with a serial fills both product and serial."""
info: dict[str, str] = {"product": "", "serial": ""}
parse_cups_usb_uri("usb://Brother/HL-1110%20series?serial=ABC123", info)
assert info["product"] == "HL-1110 series"
assert info["serial"] == "ABC123"
def test_no_serial(self) -> None:
"""A URI without a serial leaves the serial empty."""
info: dict[str, str] = {"product": "", "serial": ""}
parse_cups_usb_uri("usb://Brother/HL-1110", info)
assert info["product"] == "HL-1110"
assert info["serial"] == ""
class TestPrinterInfoFromCups:
"""Resolving model/serial from ``lpstat -v`` output."""
@patch(f"{MOD}.run_command_text")
def test_found(self, mock_text: MagicMock) -> None:
"""A Brother usb:// device line is parsed into product/serial."""
mock_text.return_value = "device for B: usb://Brother/HL-1110?serial=XYZ\n"
result = printer_info_from_cups()
assert result["product"] == "HL-1110"
assert result["serial"] == "XYZ"
@patch(f"{MOD}.run_command_text")
def test_no_brother(self, mock_text: MagicMock) -> None:
"""A non-Brother line yields no product."""
mock_text.return_value = "device for HP: ipp://hp.local\n"
assert printer_info_from_cups()["product"] == ""
@patch(f"{MOD}.run_command_text")
def test_brother_no_usb(self, mock_text: MagicMock) -> None:
"""A Brother line with no usb:// URI yields no product."""
mock_text.return_value = "device for B: ipp://Brother.local\n"
assert printer_info_from_cups()["product"] == ""
@patch(f"{MOD}.run_command_text")
def test_empty_output(self, mock_text: MagicMock) -> None:
"""No output (command failed) yields no product."""
mock_text.return_value = ""
assert printer_info_from_cups()["product"] == ""