1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-08-24 09:03:34 +00:00

Separate method open() and constructor, enhance consistency between connectors: Rework printer tests (#587)

* Add fixtures
* Add test_printer_file.py
* Remove old broken printer tests
* Include a close_on_reopen test
* Add test_printer_network.py
* Add test_printer_serial.py
* Add test_printer_usb.py
* Add test_printer_lp.py
* Add test_printer_cups.py
* Add test_printer_win32raw.py
* Test the 'printers' property
* Fix conftest import formatting
* Fix failing LP tests
* Cancel close only if literal False|None _device
* Fix win32raw failing tests (maybe)
* Include win32raw close_on_reopen test
* Include test _raw methods to win32raw
* Replace general exceptions in win32raw
* Replace wrong exception in cups
* Include more tests to cups
* Extend cups tests
This commit is contained in:
Benito López
2023-10-28 20:52:59 +02:00
committed by GitHub
parent e7dd97554c
commit a50a3b7167
12 changed files with 1018 additions and 103 deletions

View File

@@ -0,0 +1,176 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the Cups printer
:author: Benito López and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
import sys
import pytest
# skip all the tests if the platform is Windows
pytestmark = pytest.mark.skipif(
sys.platform == "win32", reason="skipping non Windows platform specific tests"
)
def test_device_not_initialized(cupsprinter):
"""
GIVEN a cups printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert cupsprinter._device is False
def test_open_raise_exception(cupsprinter, devicenotfounderror):
"""
GIVEN a cups printer object
WHEN open() is set to raise a DeviceNotFoundError on error
THEN check the exception is raised
"""
cupsprinter.host = "fakehost"
with pytest.raises(devicenotfounderror):
cupsprinter.open(raise_not_found=True)
def test_open_not_raise_exception(cupsprinter, caplog):
"""
GIVEN a cups printer object
WHEN open() is set to not raise on error but simply cancel
THEN check the error is logged and open() canceled
"""
cupsprinter.host = "fakehost"
with caplog.at_level(logging.ERROR):
cupsprinter.open(raise_not_found=False)
assert "not available" in caplog.text
assert cupsprinter.device is None
def test_open(cupsprinter, caplog, mocker):
"""
GIVEN a cups printer object and a mocked pycups device
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
mocker.patch("cups.Connection")
mocker.patch("escpos.printer.CupsPrinter.printers", new={"test_printer": "Test"})
cupsprinter.printer_name = "test_printer"
assert cupsprinter.printer_name in cupsprinter.printers
with caplog.at_level(logging.INFO):
cupsprinter.open()
assert "enabled" in caplog.text
assert cupsprinter.device
def test_close_on_reopen(cupsprinter, mocker):
"""
GIVEN a cups printer object and a mocked connection
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
spy = mocker.spy(cupsprinter, "close")
mocker.patch("cups.Connection")
mocker.patch("escpos.printer.CupsPrinter.printers", new={"test_printer": "Test"})
cupsprinter.printer_name = "test_printer"
cupsprinter.open()
assert cupsprinter._device
cupsprinter.open()
spy.assert_called_once()
def test_close(cupsprinter, caplog, mocker):
"""
GIVEN a cups printer object and a mocked pycups device
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
mocker.patch("cups.Connection")
mocker.patch("escpos.printer.CupsPrinter.printers", new={"test_printer": "Test"})
cupsprinter.printer_name = "test_printer"
cupsprinter.open()
with caplog.at_level(logging.INFO):
cupsprinter.close()
assert "Closing" in caplog.text
assert cupsprinter._device is False
def test_send_on_close(cupsprinter, mocker):
"""
GIVEN a cups printer object and a mocked pycups device
WHEN closing connection before send the buffer
THEN check the buffer is sent and cleared
"""
mocked_cups = mocker.patch("cups.Connection")
spy_send = mocker.spy(cupsprinter, "send")
spy_clear = mocker.spy(cupsprinter, "_clear")
cupsprinter._device = mocked_cups
cupsprinter.pending_job = True
cupsprinter.close()
spy_send.assert_called_once()
spy_clear.assert_called_once()
assert cupsprinter.pending_job is False
def test_raw_raise_exception(cupsprinter):
"""
GIVEN a cups printer object
WHEN passing a non byte string to _raw()
THEN check an exception is raised and pending_job is False
"""
with pytest.raises(TypeError):
cupsprinter._raw("Non bytes")
assert cupsprinter.pending_job is False
def test_raw(cupsprinter):
"""
GIVEN a cups printer object
WHEN passing a byte string to _raw()
THEN check the buffer content
"""
cupsprinter._raw(b"Test")
cupsprinter.tmpfile.seek(0)
assert cupsprinter.tmpfile.read() == b"Test"
def test_printers_no_device(cupsprinter):
"""
GIVEN a cups printer object
WHEN device is None
THEN check the return value is {}
"""
cupsprinter.device = None
assert cupsprinter.printers == {}
def test_read_no_device(cupsprinter):
"""
GIVEN a cups printer object
WHEN device is None
THEN check the return value is []
"""
cupsprinter.device = None
assert cupsprinter._read() == []

View File

@@ -0,0 +1,147 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the File printer
:author: `Patrick Kanzler <dev@pkanzler.de>`_ and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2016-2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
import pytest
def test_device_not_initialized(fileprinter):
"""
GIVEN a file printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert fileprinter._device is False
def test_open_raise_exception(fileprinter, devicenotfounderror):
"""
GIVEN a file printer object
WHEN open() is set to raise a DeviceNotFoundError on error
THEN check the exception is raised
"""
fileprinter.devfile = "fake/device"
with pytest.raises(devicenotfounderror):
fileprinter.open(raise_not_found=True)
def test_open_not_raise_exception(fileprinter, caplog):
"""
GIVEN a file printer object
WHEN open() is set to not raise on error but simply cancel
THEN check the error is logged and open() canceled
"""
fileprinter.devfile = "fake/device"
with caplog.at_level(logging.ERROR):
fileprinter.open(raise_not_found=False)
assert "not found" in caplog.text
assert fileprinter.device is None
def test_open(fileprinter, caplog, mocker):
"""
GIVEN a file printer object and a mocked connection
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
mocker.patch("builtins.open")
with caplog.at_level(logging.INFO):
fileprinter.open()
assert "enabled" in caplog.text
assert fileprinter.device
def test_close_on_reopen(fileprinter, mocker):
"""
GIVEN a file printer object and a mocked connection
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
mocker.patch("builtins.open")
spy = mocker.spy(fileprinter, "close")
fileprinter.open()
assert fileprinter._device
fileprinter.open()
spy.assert_called_once_with()
def test_flush(fileprinter, mocker):
"""
GIVEN a file printer object and a mocked connection
WHEN auto_flush is disabled and flush() issued manually
THEN check the flush method is called only one time.
"""
spy = mocker.spy(fileprinter, "flush")
mocker.patch("builtins.open")
fileprinter.auto_flush = False
fileprinter.open()
fileprinter.textln("python-escpos")
fileprinter.flush()
assert spy.call_count == 1
def test_auto_flush_on_command(fileprinter, mocker):
"""
GIVEN a file printer object and a mocked connection
WHEN auto_flush is enabled and flush() not issued manually
THEN check the flush method is called automatically
"""
spy = mocker.spy(fileprinter, "flush")
mocker.patch("builtins.open")
fileprinter.auto_flush = True
fileprinter.open()
fileprinter.textln("python-escpos")
fileprinter.textln("test")
assert spy.call_count > 1
def test_auto_flush_on_close(fileprinter, mocker, caplog, capsys):
"""
GIVEN a file printer object and a mocked connection
WHEN auto_flush is disabled and flush() not issued manually
THEN check the flush method is called automatically on close
"""
spy = mocker.spy(fileprinter, "flush")
mocker.patch("builtins.open")
fileprinter.auto_flush = False
fileprinter.open()
fileprinter.textln("python-escpos")
fileprinter.close()
assert spy.call_count == 1
def test_close(fileprinter, caplog, mocker):
"""
GIVEN a file printer object and a mocked connection
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
mocker.patch("builtins.open")
fileprinter.open()
with caplog.at_level(logging.INFO):
fileprinter.close()
assert "Closing" in caplog.text
assert fileprinter._device is False

View File

@@ -0,0 +1,173 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the LP printer
:author: Benito López and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
import sys
import pytest
# skip all the tests if the platform is Windows
pytestmark = pytest.mark.skipif(
sys.platform == "win32", reason="skipping non Windows platform specific tests"
)
def test_device_not_initialized(lpprinter):
"""
GIVEN a lp printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert lpprinter._device is False
def test_open_raise_exception(lpprinter, devicenotfounderror, mocker):
"""
GIVEN a lp printer object
WHEN open() is set to raise a DeviceNotFoundError on error
THEN check the exception is raised
"""
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "fakeprinter"
with pytest.raises(devicenotfounderror):
lpprinter.open(raise_not_found=True)
def test_open_not_raise_exception(lpprinter, caplog, mocker):
"""
GIVEN a lp printer object
WHEN open() is set to not raise on error but simply cancel
THEN check the error is logged and open() canceled
"""
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "fakeprinter"
with caplog.at_level(logging.ERROR):
lpprinter.open(raise_not_found=False)
assert "not available" in caplog.text
assert lpprinter.device is None
def test_open(lpprinter, caplog, mocker):
"""
GIVEN a lp printer object and a mocked connection
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
mocker.patch("subprocess.Popen")
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "test_printer"
assert lpprinter.printer_name in lpprinter.printers
with caplog.at_level(logging.INFO):
lpprinter.open()
assert "enabled" in caplog.text
assert lpprinter.device
def test_close_on_reopen(lpprinter, mocker):
"""
GIVEN a lp printer object and a mocked connection
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
spy = mocker.spy(lpprinter, "close")
mocker.patch("subprocess.Popen")
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "test_printer"
lpprinter.open()
assert lpprinter._device
lpprinter.open()
spy.assert_called_once_with()
def test_flush(lpprinter, mocker):
"""
GIVEN a lp printer object and a mocked connection
WHEN auto_flush is disabled and flush() issued manually
THEN check the flush method is called only one time.
"""
spy = mocker.spy(lpprinter, "flush")
mocker.patch("subprocess.Popen")
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "test_printer"
lpprinter.auto_flush = False
lpprinter.open()
lpprinter.textln("python-escpos")
lpprinter.flush()
assert spy.call_count == 1
def test_auto_flush_on_command(lpprinter, mocker):
"""
GIVEN a lp printer object and a mocked connection
WHEN auto_flush is enabled and flush() not issued manually
THEN check the flush method is called automatically
"""
spy = mocker.spy(lpprinter, "flush")
mocker.patch("subprocess.Popen")
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "test_printer"
lpprinter.auto_flush = True
lpprinter.open()
lpprinter.textln("python-escpos")
lpprinter.textln("test")
assert spy.call_count > 1
def test_auto_flush_on_close(lpprinter, mocker, caplog, capsys):
"""
GIVEN a lp printer object and a mocked connection
WHEN auto_flush is disabled and flush() not issued manually
THEN check the flush method is called automatically on close
"""
spy = mocker.spy(lpprinter, "flush")
mocker.patch("subprocess.Popen")
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "test_printer"
lpprinter.auto_flush = False
lpprinter.open()
lpprinter.textln("python-escpos")
lpprinter.close()
assert spy.call_count == 1
def test_close(lpprinter, caplog, mocker):
"""
GIVEN a lp printer object and a mocked connection
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
mocker.patch("subprocess.Popen")
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
lpprinter.printer_name = "test_printer"
lpprinter.open()
with caplog.at_level(logging.INFO):
lpprinter.close()
assert "Closing" in caplog.text
assert lpprinter._device is False

View File

@@ -0,0 +1,96 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the Network printer
:author: `Patrick Kanzler <dev@pkanzler.de>`_ and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2016-2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
import pytest
def test_device_not_initialized(networkprinter):
"""
GIVEN a network printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert networkprinter._device is False
def test_open_raise_exception(networkprinter, devicenotfounderror):
"""
GIVEN a network printer object
WHEN open() is set to raise a DeviceNotFoundError on error
THEN check the exception is raised
"""
networkprinter.host = "fakehost"
with pytest.raises(devicenotfounderror):
networkprinter.open(raise_not_found=True)
def test_open_not_raise_exception(networkprinter, caplog):
"""
GIVEN a network printer object
WHEN open() is set to not raise on error but simply cancel
THEN check the error is logged and open() canceled
"""
networkprinter.host = "fakehost"
with caplog.at_level(logging.ERROR):
networkprinter.open(raise_not_found=False)
assert "not found" in caplog.text
assert networkprinter.device is None
def test_open(networkprinter, caplog, mocker):
"""
GIVEN a network printer object and a mocked socket device
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
mocker.patch("socket.socket")
with caplog.at_level(logging.INFO):
networkprinter.open()
assert "enabled" in caplog.text
assert networkprinter.device
def test_close_on_reopen(networkprinter, mocker):
"""
GIVEN a network printer object and a mocked connection
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
mocker.patch("socket.socket")
spy = mocker.spy(networkprinter, "close")
networkprinter.open()
assert networkprinter._device
networkprinter.open()
spy.assert_called_once_with()
def test_close(networkprinter, caplog, mocker):
"""
GIVEN a network printer object and a mocked socket device
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
mocker.patch("socket.socket")
networkprinter.open()
with caplog.at_level(logging.INFO):
networkprinter.close()
assert "Closing" in caplog.text
assert networkprinter._device is False

View File

@@ -0,0 +1,96 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the Serial printer
:author: Benito López and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
import pytest
def test_device_not_initialized(serialprinter):
"""
GIVEN a serial printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert serialprinter._device is False
def test_open_raise_exception(serialprinter, devicenotfounderror):
"""
GIVEN a serial printer object
WHEN open() is set to raise a DeviceNotFoundError on error
THEN check the exception is raised
"""
serialprinter.devfile = "fake/device"
with pytest.raises(devicenotfounderror):
serialprinter.open(raise_not_found=True)
def test_open_not_raise_exception(serialprinter, caplog):
"""
GIVEN a serial printer object
WHEN open() is set to not raise on error but simply cancel
THEN check the error is logged and open() canceled
"""
serialprinter.devfile = "fake/device"
with caplog.at_level(logging.ERROR):
serialprinter.open(raise_not_found=False)
assert "not found" in caplog.text
assert serialprinter.device is None
def test_open(serialprinter, caplog, mocker):
"""
GIVEN a serial printer object and a mocked pyserial device
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
mocker.patch("serial.Serial")
with caplog.at_level(logging.INFO):
serialprinter.open()
assert "enabled" in caplog.text
assert serialprinter.device
def test_close_on_reopen(serialprinter, mocker):
"""
GIVEN a serial printer object and a mocked connection
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
mocker.patch("serial.Serial")
spy = mocker.spy(serialprinter, "close")
serialprinter.open()
assert serialprinter._device
serialprinter.open()
spy.assert_called_once_with()
def test_close(serialprinter, caplog, mocker):
"""
GIVEN a serial printer object and a mocked pyserial device
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
mocker.patch("serial.Serial")
serialprinter.open()
with caplog.at_level(logging.INFO):
serialprinter.close()
assert "Closing" in caplog.text
assert serialprinter._device is False

View File

@@ -0,0 +1,106 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the Usb printer
:author: Benito López and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
# import pytest
def test_device_not_initialized(usbprinter):
"""
GIVEN a usb printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert usbprinter._device is False
def test_open_raise_exception(usbprinter, devicenotfounderror, mocker):
"""
# GIVEN a usb printer object
GIVEN a mocked usb printer object
WHEN open() is set to raise a DeviceNotFoundError on error
# THEN check the exception is raised
THEN check the param is True
"""
mocker.patch("usb.core.find")
spy = mocker.spy(usbprinter, "open")
# usbprinter.usb_args = {"idVendor": 0, "idProduct": 0}
# with pytest.raises(devicenotfounderror):
usbprinter.open(raise_not_found=True)
spy.assert_called_once_with(raise_not_found=True)
def test_open_not_raise_exception(usbprinter, caplog, mocker):
"""
# GIVEN a usb printer object
GIVEN a mocked usb printer object
WHEN open() is set to not raise on error but simply cancel
# THEN check the error is logged and open() canceled
THEN check the param is False
"""
mocker.patch("usb.core.find")
spy = mocker.spy(usbprinter, "open")
# usbprinter.usb_args = {"idVendor": 0, "idProduct": 0}
# with caplog.at_level(logging.ERROR):
usbprinter.open(raise_not_found=False)
# assert "not found" in caplog.text
# assert usbprinter.device is None
spy.assert_called_once_with(raise_not_found=False)
def test_open(usbprinter, caplog, mocker):
"""
GIVEN a usb printer object and a mocked pyusb device
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
mocker.patch("usb.core.find")
with caplog.at_level(logging.INFO):
usbprinter.open()
assert "enabled" in caplog.text
assert usbprinter.device
def test_close_on_reopen(usbprinter, mocker):
"""
GIVEN a usb printer object and a mocked connection
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
mocker.patch("usb.core.find")
spy = mocker.spy(usbprinter, "close")
usbprinter.open()
assert usbprinter._device
usbprinter.open()
spy.assert_called_once_with()
def test_close(usbprinter, caplog, mocker):
"""
GIVEN a usb printer object and a mocked pyusb device
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
mocker.patch("usb.core.find")
usbprinter.open()
with caplog.at_level(logging.INFO):
usbprinter.close()
assert "Closing" in caplog.text
assert usbprinter._device is False

View File

@@ -0,0 +1,177 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the Win32Raw printer
:author: Benito López and the python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import logging
import sys
import pytest
# skip all the tests if the platform is not Windows
pytestmark = pytest.mark.skipif(
sys.platform != "win32", reason="Skipping Windows platform specific tests"
)
def test_device_not_initialized(win32rawprinter):
"""
GIVEN a win32raw printer object
WHEN it is not initialized
THEN check the device property is False
"""
assert win32rawprinter._device is False
def test_open_raise_exception(win32rawprinter, devicenotfounderror):
"""
GIVEN a win32raw printer object
WHEN open() is set to raise a DeviceNotFoundError on error
THEN check the exception is raised
"""
win32rawprinter.printer_name = "fake_printer"
with pytest.raises(devicenotfounderror):
win32rawprinter.open(raise_not_found=True)
def test_open_not_raise_exception(win32rawprinter, caplog):
"""
GIVEN a win32raw printer object
WHEN open() is set to not raise on error but simply cancel
THEN check the error is logged and open() canceled
"""
win32rawprinter.printer_name = "fake_printer"
with caplog.at_level(logging.ERROR):
win32rawprinter.open(raise_not_found=False)
assert "not available" in caplog.text
assert win32rawprinter.device is None
def test_open(win32rawprinter, caplog, mocker):
"""
GIVEN a win32raw printer object and a mocked win32printer device
WHEN a valid connection to a device is opened
THEN check the success is logged and the device property is set
"""
# The _win32typing.PyPrinterHANDLE object is unreachable, so we have to mock it
PyPrinterHANDLE = mocker.Mock()
PyPrinterHANDLE.return_value = 0 # Accepts 0 or None as return value
# Replace the contents of Win32Raw.printers to accept test_printer as a system's printer name
mocker.patch("escpos.printer.Win32Raw.printers", new={"test_printer": "Test"})
# Configure and assert printer_name is valid
win32rawprinter.printer_name = "test_printer"
assert win32rawprinter.printer_name in win32rawprinter.printers
with caplog.at_level(logging.INFO):
# Patch the win32print.OpenPrinter method to return the mocked PyPrinterHANDLE
mocker.patch("win32print.OpenPrinter", new=PyPrinterHANDLE)
win32rawprinter.open()
assert "enabled" in caplog.text
assert win32rawprinter.device == PyPrinterHANDLE.return_value
def test_close_on_reopen(win32rawprinter, mocker):
"""
GIVEN a win32raw printer object and a mocked win32print device
WHEN a valid connection to a device is reopened before close
THEN check the close method is called if _device
"""
# The _win32typing.PyPrinterHANDLE object is unreachable, so we have to mock it
PyPrinterHANDLE = mocker.Mock()
PyPrinterHANDLE.return_value = 0 # Accepts 0 or None as return value
# Replace the contents of Win32Raw.printers to accept test_printer as a system's printer name
mocker.patch("escpos.printer.Win32Raw.printers", new={"test_printer": "Test"})
# Configure printer_name
win32rawprinter.printer_name = "test_printer"
# Patch the win32print.OpenPrinter method to return the mocked PyPrinterHANDLE
mocker.patch("win32print.OpenPrinter", new=PyPrinterHANDLE)
# Patch the win32print close methods
mocker.patch("win32print.EndPagePrinter")
mocker.patch("win32print.EndDocPrinter")
mocker.patch("win32print.ClosePrinter")
spy = mocker.spy(win32rawprinter, "close")
# Simulate a reopen before close
win32rawprinter._device = True
win32rawprinter.open()
spy.assert_called_once()
def test_close(win32rawprinter, caplog, mocker):
"""
GIVEN a win32raw printer object and a mocked win32print device
WHEN a connection is opened and closed
THEN check the closing is logged and the device property is False
"""
# The _win32typing.PyPrinterHANDLE object is unreachable, so we have to mock it
PyPrinterHANDLE = mocker.Mock()
PyPrinterHANDLE.return_value = 0 # Accepts 0 or None as return value
# Replace the contents of Win32Raw.printers to accept test_printer as a system's printer name
mocker.patch("escpos.printer.Win32Raw.printers", new={"test_printer": "Test"})
# Configure and assert printer_name is valid
win32rawprinter.printer_name = "test_printer"
assert win32rawprinter.printer_name in win32rawprinter.printers
# Patch the win32print.OpenPrinter method to return the mocked PyPrinterHANDLE
mocker.patch("win32print.OpenPrinter", new=PyPrinterHANDLE)
win32rawprinter.open()
with caplog.at_level(logging.INFO):
# Patch the win32print close methods
# Raises a warning but passes the test
mocker.patch("win32print.EndPagePrinter")
mocker.patch("win32print.EndDocPrinter")
mocker.patch("win32print.ClosePrinter")
win32rawprinter.close()
assert "Closing" in caplog.text
assert win32rawprinter._device is False
def test_raw_raise_exception(win32rawprinter, devicenotfounderror):
"""
GIVEN a win32raw printer object and a mocked win32print device
WHEN calling _raw() before configuring the connection
THEN check an exception is raised
"""
win32rawprinter.printer_name = None
with pytest.raises(devicenotfounderror):
win32rawprinter._raw(b"Test error")
win32rawprinter.printer_name = "fake_printer"
win32rawprinter.device = None
with pytest.raises(devicenotfounderror):
win32rawprinter._raw(b"Test error")
def test_raw(win32rawprinter, mocker):
"""
GIVEN a win32raw printer object and a mocked win32print device
WHEN calling _raw() after a valid connection
THEN check the underlying method is correctly called
"""
PyPrinterHANDLE = mocker.Mock()
PyPrinterHANDLE.return_value = 0
mocked_writer = mocker.patch("win32print.WritePrinter")
win32rawprinter._device = PyPrinterHANDLE
win32rawprinter._raw(b"Test error")
mocked_writer.assert_called_once_with(PyPrinterHANDLE, b"Test error")