[WIP] Commit before rebase on latest #109 for user and view updates

Migration of printer_tray to v11 and integration with base_report_to_printer
This commit is contained in:
Graeme Gellatly
2017-10-06 01:16:33 +13:00
committed by David Montull
parent f61b1cc5c6
commit 7b0c679f33
44 changed files with 2619 additions and 767 deletions

View File

@@ -4,7 +4,9 @@
from . import test_printing_job
from . import test_printing_printer
from . import test_printing_printer_tray
from . import test_printing_server
from . import test_printing_tray
from . import test_report
from . import test_res_users
from . import test_ir_actions_report

View File

@@ -44,6 +44,12 @@ class TestIrActionsReportXml(TransactionCase):
'uri': 'URI',
})
def new_tray(self, vals=None, defaults=None):
values = dict(defaults)
if vals is not None:
values.update(vals)
return self.env['printing.tray'].create(values)
def test_print_action_for_report_name_gets_report(self):
""" It should get report by name """
with mock.patch.object(self.Model, '_get_report_from_name') as mk:
@@ -67,7 +73,7 @@ class TestIrActionsReportXml(TransactionCase):
""" It should return correct serializable result for behaviour """
with mock.patch.object(self.Model, '_get_report_from_name') as mk:
res = self.Model.print_action_for_report_name('test')
behaviour = mk().behaviour()[mk()]
behaviour = mk().behaviour()
expect = {
'action': behaviour['action'],
'printer_name': behaviour['printer'].name,
@@ -85,11 +91,11 @@ class TestIrActionsReportXml(TransactionCase):
report.property_printing_action_id = False
report.printing_printer_id = False
self.assertEqual(report.behaviour(), {
report: {
'action': 'client',
'printer': self.env['printing.printer'],
},
})
'action': 'client',
'printer': self.env['printing.printer'],
'tray': False,
},
)
def test_behaviour_user_values(self):
""" It should return the action and printer from user """
@@ -97,11 +103,11 @@ class TestIrActionsReportXml(TransactionCase):
self.env.user.printing_action = 'client'
self.env.user.printing_printer_id = self.new_printer()
self.assertEqual(report.behaviour(), {
report: {
'action': 'client',
'printer': self.env.user.printing_printer_id,
},
})
'action': 'client',
'printer': self.env.user.printing_printer_id,
'tray': False,
},
)
def test_behaviour_report_values(self):
""" It should return the action and printer from report """
@@ -110,11 +116,11 @@ class TestIrActionsReportXml(TransactionCase):
report.property_printing_action_id = self.new_action()
report.printing_printer_id = self.new_printer()
self.assertEqual(report.behaviour(), {
report: {
'action': report.property_printing_action_id.action_type,
'printer': report.printing_printer_id,
},
})
'action': report.property_printing_action_id.action_type,
'printer': report.printing_printer_id,
'tray': False,
},
)
def test_behaviour_user_action(self):
""" It should return the action and printer from user action"""
@@ -122,11 +128,11 @@ class TestIrActionsReportXml(TransactionCase):
self.env.user.printing_action = 'client'
report.property_printing_action_id.action_type = 'user_default'
self.assertEqual(report.behaviour(), {
report: {
'action': 'client',
'printer': report.printing_printer_id,
},
})
'action': 'client',
'printer': report.printing_printer_id,
'tray': False,
},
)
def test_behaviour_printing_action_on_wrong_user(self):
""" It should return the action and printer ignoring printing action
@@ -138,11 +144,11 @@ class TestIrActionsReportXml(TransactionCase):
('id', '!=', self.env.user.id),
], limit=1)
self.assertEqual(report.behaviour(), {
report: {
'action': 'client',
'printer': report.printing_printer_id,
},
})
'action': 'client',
'printer': report.printing_printer_id,
'tray': False,
},
)
def test_behaviour_printing_action_on_wrong_report(self):
""" It should return the action and printer ignoring printing action
@@ -155,11 +161,11 @@ class TestIrActionsReportXml(TransactionCase):
('id', '!=', report.id),
], limit=1)
self.assertEqual(report.behaviour(), {
report: {
'action': 'client',
'printer': report.printing_printer_id,
},
})
'action': 'client',
'printer': report.printing_printer_id,
'tray': False,
},
)
def test_behaviour_printing_action_with_no_printer(self):
""" It should return the action from printing action and printer from other
@@ -170,11 +176,11 @@ class TestIrActionsReportXml(TransactionCase):
printing_action.user_id = self.env.user
printing_action.report_id = report
self.assertEqual(report.behaviour(), {
report: {
'action': printing_action.action,
'printer': report.printing_printer_id,
},
})
'action': printing_action.action,
'printer': report.printing_printer_id,
'tray': False,
},
)
def test_behaviour_printing_action_with_printer(self):
""" It should return the action and printer from printing action """
@@ -184,11 +190,11 @@ class TestIrActionsReportXml(TransactionCase):
printing_action.user_id = self.env.user
printing_action.printer_id = self.new_printer()
self.assertEqual(report.behaviour(), {
report: {
'action': printing_action.action,
'printer': printing_action.printer_id,
},
})
'action': printing_action.action,
'printer': printing_action.printer_id,
'tray': False,
},
)
def test_behaviour_printing_action_user_defaults(self):
""" It should return the action and printer from user with printing action
@@ -199,8 +205,101 @@ class TestIrActionsReportXml(TransactionCase):
printing_action.user_id = self.env.user
printing_action.action = 'user_default'
self.assertEqual(report.behaviour(), {
report: {
'action': 'client',
'printer': report.printing_printer_id,
},
'action': 'client',
'printer': report.printing_printer_id,
'tray': False,
},
)
def test_print_tray_behaviour(self):
"""
It should return the correct tray
"""
report = self.env['ir.actions.report'].search([], limit=1)
action = self.env['printing.report.xml.action'].create({
'user_id': self.env.user.id,
'report_id': report.id,
'action': 'server',
})
printer = self.new_printer()
tray_vals = {
'name': 'Tray',
'system_name': 'Tray',
'printer_id': printer.id,
}
user_tray = self.new_tray({'system_name': 'User tray'}, tray_vals)
report_tray = self.new_tray({'system_name': 'Report tray'}, tray_vals)
action_tray = self.new_tray({'system_name': 'Action tray'}, tray_vals)
# No report passed
self.env.user.printer_tray_id = False
options = printer.print_options()
self.assertFalse('InputSlot' in options)
# No tray defined
self.env.user.printer_tray_id = False
report.printer_tray_id = False
action.printer_tray_id = False
options = report.behaviour()
self.assertTrue('tray' 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
self.assertEqual('User tray', report.behaviour()['tray'])
# Only report tray is defined
self.env.user.printer_tray_id = False
report.printer_tray_id = report_tray
action.printer_tray_id = False
self.assertEqual('Report tray', report.behaviour()['tray'])
# Only action tray is defined
self.env.user.printer_tray_id = False
report.printer_tray_id = False
action.printer_tray_id = action_tray
self.assertEqual('Action tray', report.behaviour()['tray'])
# User and report tray defined
self.env.user.printer_tray_id = user_tray
report.printer_tray_id = report_tray
action.printer_tray_id = False
self.assertEqual('Report tray', report.behaviour()['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
self.assertEqual('Action tray', report.behaviour()['tray'])
def test_onchange_printer_tray_id_empty(self):
action = self.env['ir.actions.report'].new(
{'printer_tray_id': False})
action.onchange_printing_printer_id()
self.assertFalse(action.printer_tray_id)
def test_onchange_printer_tray_id_not_empty(self):
server = self.env['printing.server'].create({})
printer = self.env['printing.printer'].create({
'name': 'Printer',
'server_id': server.id,
'system_name': 'Sys Name',
'default': True,
'status': 'unknown',
'status_message': 'Msg',
'model': 'res.users',
'location': 'Location',
'uri': 'URI',
})
tray = self.env['printing.tray'].create({
'name': 'Tray',
'system_name': 'TrayName',
'printer_id': printer.id,
})
action = self.env['ir.actions.report'].new(
{'printer_tray_id': tray.id})
self.assertEqual(action.printer_tray_id, tray)
action.onchange_printing_printer_id()
self.assertFalse(action.printer_tray_id)

View File

@@ -35,18 +35,54 @@ class TestPrintingPrinter(TransactionCase):
def new_record(self):
return self.Model.create(self.printer_vals)
def test_printing_options(self):
def test_option_tray(self):
"""
It should put the value in InputSlot
"""
self.assertEqual(self.Model._set_option_tray(None, 'Test Tray'),
{'InputSlot': 'Test Tray'})
self.assertEqual(self.Model._set_option_tray(None, False),
{})
def test_option_noops(self):
"""
Noops should return an empty dict
"""
self.assertEqual(self.Model._set_option_action(None, 'printer'), {})
self.assertEqual(self.Model._set_option_printer(None, self.Model), {})
def test_option_doc_format(self):
"""
Raw documents should set raw boolean.
"""
self.assertEqual(self.Model._set_option_doc_format(None, 'raw'),
{'raw': 'True'})
# Deprecate _set_option_format in v12.
self.assertEqual(self.Model._set_option_format(None, 'raw'),
{'raw': 'True'})
self.assertEqual(self.Model._set_option_doc_format(None, 'pdf'), {})
# Deprecate _set_option_format in v12.
self.assertEqual(self.Model._set_option_format(None, 'pdf'), {})
def test_print_options(self):
""" It should generate the right options dictionnary """
self.assertEqual(self.Model.print_options('report', 'raw'), {
'raw': 'True',
})
self.assertEqual(self.Model.print_options('report', 'pdf', 2), {
'copies': '2',
})
self.assertEqual(self.Model.print_options('report', 'raw', 2), {
'raw': 'True',
'copies': '2',
})
# TODO: None here used as report - tests here should be merged
# with tests in test_printing_printer_tray from when modules merged
report = self.env['ir.actions.report'].search([], limit=1)
self.assertEqual(self.Model.print_options(
report, doc_format='raw'), {'raw': 'True'}
)
self.assertEqual(self.Model.print_options(
report, doc_format='pdf', copies=2), {'copies': '2'}
)
self.assertEqual(self.Model.print_options(
report, doc_format='raw', copies=2),
{'raw': 'True', 'copies': '2'}
)
self.assertTrue('InputSlot' in self.Model.print_options(report,
tray='Test'))
@mock.patch('%s.cups' % server_model)
def test_print_report(self, cups):
@@ -55,7 +91,8 @@ class TestPrintingPrinter(TransactionCase):
with mock.patch('%s.mkstemp' % model) as mkstemp:
mkstemp.return_value = fd, file_name
printer = self.new_record()
printer.print_document('report_name', b'content to print', 'pdf')
printer.print_document(self.report, b'content to print',
doc_format='pdf')
cups.Connection().printFile.assert_called_once_with(
printer.system_name,
file_name,
@@ -72,7 +109,7 @@ class TestPrintingPrinter(TransactionCase):
printer = self.new_record()
with self.assertRaises(UserError):
printer.print_document(
'report_name', b'content to print', 'pdf')
self.report, b'content to print', doc_format='pdf')
@mock.patch('%s.cups' % server_model)
def test_print_file(self, cups):

View File

@@ -0,0 +1,262 @@
# -*- coding: utf-8 -*-
# Copyright 2016 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import errno
import mock
import tempfile
from odoo.tests.common import TransactionCase
model = 'odoo.addons.base_report_to_printer.models.printing_printer'
server_model = 'odoo.addons.base_report_to_printer.models.printing_server'
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.ServerModel = self.env['printing.server']
self.server = self.env['printing.server'].create({})
self.printer = self.env['printing.printer'].create({
'name': 'Printer',
'server_id': self.server.id,
'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)
cups.Connection().getPrinters.return_value = {
self.printer.system_name: {
'printer-info': 'info',
'printer-uri-supported': 'uri',
},
}
@mock.patch('%s.cups' % server_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)
self.assertEqual(self.printer.name, 'Printer')
self.ServerModel.update_printers()
self.assertEqual(self.printer.name, 'info')
@mock.patch('%s.cups' % server_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()[self.printer.system_name]
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
self.assertFalse('tray_ids' in vals)
@mock.patch('%s.cups' % server_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()[self.printer.system_name]
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
self.assertFalse('tray_ids' in vals)
@mock.patch('%s.cups' % server_model)
@mock.patch('os.unlink')
def test_prepare_update_from_cups_unlink_error(self, os_unlink, cups):
"""
When OSError other than ENOENT is encountered, the exception is raised
"""
# Break os.unlink
os_unlink.side_effect = OSError(errno.EIO, 'Error')
self.mock_cups_ppd(cups)
connection = cups.Connection()
cups_printer = connection.getPrinters()[self.printer.system_name]
with self.assertRaises(OSError):
self.printer._prepare_update_from_cups(connection, cups_printer)
@mock.patch('%s.cups' % server_model)
@mock.patch('os.unlink')
def test_prepare_update_from_cups_unlink_error_enoent(
self, os_unlink, cups):
"""
When a ENOENT error is encountered, the file has already been unlinked
This is not an issue, as we were trying to delete the file.
The update can continue.
"""
# Break os.unlink
os_unlink.side_effect = OSError(errno.ENOENT, 'Error')
self.mock_cups_ppd(cups)
connection = cups.Connection()
cups_printer = connection.getPrinters()[self.printer.system_name]
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' % server_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()[self.printer.system_name]
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' % server_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()[self.printer.system_name]
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
self.assertItemsEqual(vals['tray_ids'], [(0, 0, {
'name': 'Auto (Default)',
'system_name': 'Auto',
}), (0, 0, {
'name': 'Tray 1',
'system_name': 'Tray1',
})])
@mock.patch('%s.cups' % server_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()[self.printer.system_name]
# 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' % server_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()[self.printer.system_name]
# 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)])

View File

@@ -56,3 +56,34 @@ class TestPrintingReportXmlAction(TransactionCase):
})
self.assertEqual(self.Model.behaviour(), {})
def test_onchange_printer_tray_id_empty(self):
action = self.env['printing.report.xml.action'].new(
{'printer_tray_id': False})
action.onchange_printer_id()
self.assertFalse(action.printer_tray_id)
def test_onchange_printer_tray_id_not_empty(self):
server = self.env['printing.server'].create({})
printer = self.env['printing.printer'].create({
'name': 'Printer',
'server_id': server.id,
'system_name': 'Sys Name',
'default': True,
'status': 'unknown',
'status_message': 'Msg',
'model': 'res.users',
'location': 'Location',
'uri': 'URI',
})
tray = self.env['printing.tray'].create({
'name': 'Tray',
'system_name': 'TrayName',
'printer_id': printer.id,
})
action = self.env['printing.report.xml.action'].new(
{'printer_tray_id': tray.id})
self.assertEqual(action.printer_tray_id, tray)
action.onchange_printer_id()
self.assertFalse(action.printer_tray_id)

View File

@@ -0,0 +1,52 @@
# -*- coding: utf-8 -*-
# Copyright 2016 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase
model = 'odoo.addons.base_report_to_printer.models.printing_server'
class TestPrintingTray(TransactionCase):
def setUp(self):
super(TestPrintingTray, self).setUp()
self.Model = self.env['printing.tray']
self.server = self.env['printing.server'].create({})
self.printer = self.env['printing.printer'].create({
'name': 'Printer',
'server_id': self.server.id,
'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'].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)

View File

@@ -90,7 +90,8 @@ class TestReport(HttpCase):
records = self.env[report.model].search([], limit=5)
document, doc_format = report.render_qweb_pdf(records.ids)
print_document.assert_called_once_with(
report, document, report.report_type)
report, document,
action='server', doc_format='qweb-pdf', tray=False)
def test_print_document_not_printable(self):
""" It should print the report, regardless of the defined behaviour """

View File

@@ -26,3 +26,34 @@ class TestResUsers(TransactionCase):
""" It should still contain other valid keys """
self.user_vals['printing_action'] = 'server'
self.assertTrue(self.new_record())
def test_onchange_printer_tray_id_empty(self):
user = self.env['res.users'].new(
{'printer_tray_id': False})
user.onchange_printing_printer_id()
self.assertFalse(user.printer_tray_id)
def test_onchange_printer_tray_id_not_empty(self):
server = self.env['printing.server'].create({})
printer = self.env['printing.printer'].create({
'name': 'Printer',
'server_id': server.id,
'system_name': 'Sys Name',
'default': True,
'status': 'unknown',
'status_message': 'Msg',
'model': 'res.users',
'location': 'Location',
'uri': 'URI',
})
tray = self.env['printing.tray'].create({
'name': 'Tray',
'system_name': 'TrayName',
'printer_id': printer.id,
})
user = self.env['res.users'].new(
{'printer_tray_id': tray.id})
self.assertEqual(user.printer_tray_id, tray)
user.onchange_printing_printer_id()
self.assertFalse(user.printer_tray_id)