From 2cbffa75b890ad94653631343db1a6b440980e5c Mon Sep 17 00:00:00 2001 From: Sylvain Garancher Date: Wed, 9 Nov 2016 00:04:33 +0100 Subject: [PATCH] [8.0] printer_tray: Add unit tests (#64) * [ADD] printer_tray: Add unit tests * [FIX] Fixed lint errors --- printer_tray/__openerp__.py | 4 +- printer_tray/printer.py | 10 +- printer_tray/tests/__init__.py | 6 + printer_tray/tests/test_printing_printer.py | 275 ++++++++++++++++++++ printer_tray/tests/test_printing_tray.py | 50 ++++ printer_tray/users_view.xml | 2 +- 6 files changed, 344 insertions(+), 3 deletions(-) create mode 100644 printer_tray/tests/__init__.py create mode 100644 printer_tray/tests/test_printing_printer.py create mode 100644 printer_tray/tests/test_printing_tray.py diff --git a/printer_tray/__openerp__.py b/printer_tray/__openerp__.py index 73178aa..9f69f4b 100644 --- a/printer_tray/__openerp__.py +++ b/printer_tray/__openerp__.py @@ -34,7 +34,9 @@ 'report_xml_action_view.xml', 'security/ir.model.access.csv', ], - 'test': [], + 'external_dependencies': { + 'python': ['cups'], + }, 'installable': True, 'auto_install': False, 'application': True, diff --git a/printer_tray/printer.py b/printer_tray/printer.py index f2790cb..2d46059 100644 --- a/printer_tray/printer.py +++ b/printer_tray/printer.py @@ -18,12 +18,20 @@ # along with this program. If not, see . # ############################################################################## -import cups + import errno +import logging import os from openerp import models, fields, api +_logger = logging.getLogger(__name__) + +try: + import cups +except ImportError: + _logger.debug('Cannot `import cups`.') + class Printer(models.Model): _inherit = 'printing.printer' diff --git a/printer_tray/tests/__init__.py b/printer_tray/tests/__init__.py new file mode 100644 index 0000000..7e74318 --- /dev/null +++ b/printer_tray/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 LasLabs Inc. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_printing_printer +from . import test_printing_tray diff --git a/printer_tray/tests/test_printing_printer.py b/printer_tray/tests/test_printing_printer.py new file mode 100644 index 0000000..14559ac --- /dev/null +++ b/printer_tray/tests/test_printing_printer.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 LasLabs Inc. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import mock +import tempfile +from openerp.tests.common import TransactionCase + + +model = 'openerp.addons.base_report_to_printer.printing' + +ppd_header = '*PPD-Adobe: "4.3"' +ppd_input_slot_header = """ +*OpenUI *InputSlot: PickOne +*DefaultInputSlot: Auto +*InputSlot Auto/Auto (Default): " + << /DeferredMediaSelection true /ManualFeed false + /MediaPosition null /MediaType null >> setpagedevice + userdict /TSBMediaType 0 put" +*End +""" +ppd_input_slot_body = """ +*InputSlot {name}/{text}: " + << /DeferredMediaSelection true /ManualFeed false + /MediaPosition null /MediaType null >> setpagedevice + userdict /TSBMediaType 0 put" +*End +""" +ppd_input_slot_footer = """ +*CloseUI: *InputSlot +""" + + +class TestPrintingPrinter(TransactionCase): + + def setUp(self): + super(TestPrintingPrinter, self).setUp() + self.Model = self.env['printing.printer'] + self.printer = self.env['printing.printer'].create({ + 'name': 'Printer', + 'system_name': 'Sys Name', + 'default': True, + 'status': 'unknown', + 'status_message': 'Msg', + 'model': 'res.users', + 'location': 'Location', + 'uri': 'URI', + }) + self.tray_vals = { + 'name': 'Tray', + 'system_name': 'TrayName', + 'printer_id': self.printer.id, + } + + def new_tray(self, vals=None): + values = self.tray_vals + if vals is not None: + values.update(vals) + return self.env['printing.tray'].create(values) + + def build_ppd(self, input_slots=None): + """ + Builds a fake PPD file declaring defined input slots + """ + ppd_contents = ppd_header + ppd_contents += ppd_input_slot_header + if input_slots is not None: + for input_slot in input_slots: + ppd_contents += ppd_input_slot_body.format( + name=input_slot['name'], + text=input_slot['text'], + ) + ppd_contents += ppd_input_slot_footer + + return ppd_contents + + def mock_cups_ppd(self, cups, file_name=None, input_slots=None): + """ + Create a fake PPD file (if needed), then mock the getPPD3 method + return value to give that file + """ + if file_name is None: + fd, file_name = tempfile.mkstemp() + + if file_name: + ppd_contents = self.build_ppd(input_slots=input_slots) + with open(file_name, 'w') as fp: + fp.write(ppd_contents) + + cups.Connection().getPPD3.return_value = (200, 0, file_name) + + def test_print_options(self): + """ + It should generate the right options dictionnary + """ + report = self.env['ir.actions.report.xml'].search([], limit=1) + action = self.env['printing.report.xml.action'].create({ + 'user_id': self.env.user.id, + 'report_id': report.id, + 'action': 'server', + }) + user_tray = self.new_tray({ + 'system_name': 'User tray', + }) + report_tray = self.new_tray({ + 'system_name': 'Report tray', + }) + action_tray = self.new_tray({ + 'system_name': 'Action tray', + }) + + # No tray defined + self.env.user.printer_tray_id = False + report.printer_tray_id = False + action.printer_tray_id = False + options = self.Model.print_options(report, 'pdf') + self.assertFalse('InputSlot' in options) + + # Only user tray is defined + self.env.user.printer_tray_id = user_tray + report.printer_tray_id = False + action.printer_tray_id = False + options = self.Model.print_options(report, 'pdf') + self.assertEquals(options, { + 'InputSlot': 'User tray', + }) + + # Only report tray is defined + self.env.user.printer_tray_id = False + report.printer_tray_id = report_tray + action.printer_tray_id = False + options = self.Model.print_options(report, 'pdf') + self.assertEquals(options, { + 'InputSlot': 'Report tray', + }) + + # Only action tray is defined + self.env.user.printer_tray_id = False + report.printer_tray_id = False + action.printer_tray_id = action_tray + options = self.Model.print_options(report, 'pdf') + self.assertEquals(options, { + 'InputSlot': 'Action tray', + }) + + # All trays are defined + self.env.user.printer_tray_id = user_tray + report.printer_tray_id = report_tray + action.printer_tray_id = action_tray + options = self.Model.print_options(report, 'pdf') + self.assertEquals(options, { + 'InputSlot': 'Action tray', + }) + + @mock.patch('%s.cups' % model) + def test_update_printers(self, cups): + """ + Check that the update_printers method calls _prepare_update_from_cups + """ + self.mock_cups_ppd(cups, file_name=False) + + with mock.patch.object( + self.Model, '_prepare_update_from_cups' + ) as prepare_update_from_cups: + self.Model.update_printers_status() + prepare_update_from_cups.assert_called_once() + + @mock.patch('%s.cups' % model) + def test_prepare_update_from_cups_no_ppd(self, cups): + """ + Check that the tray_ids field has no value when no PPD is available + """ + self.mock_cups_ppd(cups, file_name=False) + + connection = cups.Connection() + cups_printer = connection.getPrinters() + + vals = self.printer._prepare_update_from_cups(connection, cups_printer) + self.assertFalse('tray_ids' in vals) + + @mock.patch('%s.cups' % model) + def test_prepare_update_from_cups_empty_ppd(self, cups): + """ + Check that the tray_ids field has no value when the PPD file has + no input slot declared + """ + fd, file_name = tempfile.mkstemp() + self.mock_cups_ppd(cups, file_name=file_name) + # Replace the ppd file's contents by an empty file + with open(file_name, 'w') as fp: + fp.write(ppd_header) + + connection = cups.Connection() + cups_printer = connection.getPrinters() + + vals = self.printer._prepare_update_from_cups(connection, cups_printer) + self.assertFalse('tray_ids' in vals) + + @mock.patch('%s.cups' % model) + def test_prepare_update_from_cups(self, cups): + """ + Check the return value when adding a single tray + """ + self.mock_cups_ppd(cups) + + connection = cups.Connection() + cups_printer = connection.getPrinters() + + vals = self.printer._prepare_update_from_cups(connection, cups_printer) + self.assertEqual(vals['tray_ids'], [(0, 0, { + 'name': 'Auto (Default)', + 'system_name': 'Auto', + })]) + + @mock.patch('%s.cups' % model) + def test_prepare_update_from_cups_with_multiple_trays(self, cups): + """ + Check the return value when adding multiple trays at once + """ + self.mock_cups_ppd(cups, input_slots=[ + {'name': 'Tray1', 'text': 'Tray 1'}, + ]) + + connection = cups.Connection() + cups_printer = connection.getPrinters() + + vals = self.printer._prepare_update_from_cups(connection, cups_printer) + self.assertEqual(vals['tray_ids'], [(0, 0, { + 'name': 'Auto (Default)', + 'system_name': 'Auto', + }), (0, 0, { + 'name': 'Tray 1', + 'system_name': 'Tray1', + })]) + + @mock.patch('%s.cups' % model) + def test_prepare_update_from_cups_already_known_trays(self, cups): + """ + Check that calling the method twice doesn't create the trays multiple + times + """ + self.mock_cups_ppd(cups, input_slots=[ + {'name': 'Tray1', 'text': 'Tray 1'}, + ]) + + connection = cups.Connection() + cups_printer = connection.getPrinters() + + # Create a tray which is in the PPD file + self.new_tray({'system_name': 'Tray1'}) + + vals = self.printer._prepare_update_from_cups(connection, cups_printer) + self.assertEqual(vals['tray_ids'], [(0, 0, { + 'name': 'Auto (Default)', + 'system_name': 'Auto', + })]) + + @mock.patch('%s.cups' % model) + def test_prepare_update_from_cups_unknown_trays(self, cups): + """ + Check that trays which are not in the PPD file are removed from Odoo + """ + self.mock_cups_ppd(cups) + + connection = cups.Connection() + cups_printer = connection.getPrinters() + + # Create a tray which is absent from the PPD file + tray = self.new_tray() + + vals = self.printer._prepare_update_from_cups(connection, cups_printer) + self.assertEqual(vals['tray_ids'], [(0, 0, { + 'name': 'Auto (Default)', + 'system_name': 'Auto', + }), (2, tray.id)]) diff --git a/printer_tray/tests/test_printing_tray.py b/printer_tray/tests/test_printing_tray.py new file mode 100644 index 0000000..685a9d1 --- /dev/null +++ b/printer_tray/tests/test_printing_tray.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 LasLabs Inc. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests.common import TransactionCase + + +model = 'openerp.addons.base_report_to_printer.printing' + + +class TestPrintingTray(TransactionCase): + + def setUp(self): + super(TestPrintingTray, self).setUp() + self.Model = self.env['printing.tray'] + self.printer = self.env['printing.printer'].create({ + 'name': 'Printer', + 'system_name': 'Sys Name', + 'default': True, + 'status': 'unknown', + 'status_message': 'Msg', + 'model': 'res.users', + 'location': 'Location', + 'uri': 'URI', + }) + self.tray_vals = { + 'name': 'Tray', + 'system_name': 'TrayName', + 'printer_id': self.printer.id, + } + + def new_tray(self): + return self.env['printing.tray'].create(self.tray_vals) + + def test_report_behaviour(self): + """ It should add the selected tray in the report data """ + ir_report = self.env['ir.actions.report.xml'].search([], limit=1) + report = self.env['printing.report.xml.action'].create({ + 'user_id': self.env.user.id, + 'report_id': ir_report.id, + 'action': 'server', + }) + report.printer_tray_id = False + behaviour = report.behaviour() + self.assertEqual(behaviour['tray'], False) + + # Check that we have te right value + report.printer_tray_id = self.new_tray() + behaviour = report.behaviour() + self.assertEqual(behaviour['tray'], report.printer_tray_id.system_name) diff --git a/printer_tray/users_view.xml b/printer_tray/users_view.xml index 381583c..a8bc8f0 100644 --- a/printer_tray/users_view.xml +++ b/printer_tray/users_view.xml @@ -15,7 +15,7 @@ - + res.users.form.printing.tray res.users