mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[10.0][MIG] base_report_to_printer (#68)
* Set api.multi for action called as `object` on view * Merge syleam printers module into base_report_to_printer (#60) * [IMP] Updated unit tests * [FIX] Fixed renamed attributes * [FIX] Remove deleted fields * [IMP] Add printing.server and printing.job models * [IMP] Allow to cancel all jobs, enable, and disable printers * [IMP] Split the cups part of print_document into a new print_file method * [IMP] Updated cron job to run the action_update_jobs method * [ADD] Add a migration script to create a printing server from configuration * [MIG] Migrate base_report_to_printer to v10.0 Removed deprecated methods on printing.printer (replaced by methods on printing.server) * [IMP] Add wkhtmltopdf in travis configuration file * [FIX] base_report_to_printer: Fix Update Job Cron * Fix API issue with Update Job Cron ** Forward Port from 9.0 * [FIX] Fixed the res.users view The string attribute should not be used as a selector, because it is translatable. * [FIX] Fixed the print_document method of report The new API migration was made to @api.multi because of the "cr, uid, ids" signature, but "ids" was the ids of the records to print here, not the report's ids. Also, the new API version of "get_pdf" get directly the ids of the records to print in the standard module, not a recordset. * [FIX] UI is now (un)blocked only when using qweb-pdf reports in standard addons
This commit is contained in:
committed by
Carlos Roca
parent
6c943e09b8
commit
5dda3b475e
@@ -2,8 +2,11 @@
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import test_printing_job
|
||||
from . import test_printing_printer
|
||||
from . import test_printing_server
|
||||
from . import test_report
|
||||
from . import test_res_users
|
||||
from . import test_ir_actions_report_xml
|
||||
from . import test_printing_printer_wizard
|
||||
from . import test_printing_report_xml_action
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# Copyright 2016 SYLEAM
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import mock
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestIrActionsReportXml(TransactionCase):
|
||||
@@ -14,8 +15,34 @@ class TestIrActionsReportXml(TransactionCase):
|
||||
self.Model = self.env['ir.actions.report.xml']
|
||||
self.vals = {}
|
||||
|
||||
def new_record(self):
|
||||
return self.Model.create(self.vals)
|
||||
self.report = self.env['ir.actions.report.xml'].search([], limit=1)
|
||||
self.server = self.env['printing.server'].create({})
|
||||
|
||||
def new_action(self):
|
||||
return self.env['printing.action'].create({
|
||||
'name': 'Printing Action',
|
||||
'action_type': 'server',
|
||||
})
|
||||
|
||||
def new_printing_action(self):
|
||||
return self.env['printing.report.xml.action'].create({
|
||||
'report_id': self.report.id,
|
||||
'user_id': self.env.ref('base.user_demo').id,
|
||||
'action': 'server',
|
||||
})
|
||||
|
||||
def new_printer(self):
|
||||
return 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',
|
||||
})
|
||||
|
||||
def test_print_action_for_report_name_gets_report(self):
|
||||
""" It should get report by name """
|
||||
@@ -51,3 +78,131 @@ class TestIrActionsReportXml(TransactionCase):
|
||||
expect, res,
|
||||
'Expect %s, Got %s' % (expect, res),
|
||||
)
|
||||
|
||||
def test_behaviour_default_values(self):
|
||||
""" It should return the default action and printer """
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = False
|
||||
self.env.user.printing_printer_id = False
|
||||
report.property_printing_action_id = False
|
||||
report.printing_printer_id = False
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': 'client',
|
||||
'printer': self.env['printing.printer'],
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_user_values(self):
|
||||
""" It should return the action and printer from user """
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
self.env.user.printing_printer_id = self.new_printer()
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': 'client',
|
||||
'printer': self.env.user.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_report_values(self):
|
||||
""" It should return the action and printer from report """
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
report.property_printing_action_id = self.new_action()
|
||||
report.printing_printer_id = self.new_printer()
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': report.property_printing_action_id.action_type,
|
||||
'printer': report.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_user_action(self):
|
||||
""" It should return the action and printer from user action"""
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
report.property_printing_action_id.action_type = 'user_default'
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': 'client',
|
||||
'printer': report.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_printing_action_on_wrong_user(self):
|
||||
""" It should return the action and printer ignoring printing action
|
||||
"""
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
printing_action = self.new_printing_action()
|
||||
printing_action.user_id = self.env['res.users'].search([
|
||||
('id', '!=', self.env.user.id),
|
||||
], limit=1)
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': 'client',
|
||||
'printer': report.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_printing_action_on_wrong_report(self):
|
||||
""" It should return the action and printer ignoring printing action
|
||||
"""
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
printing_action = self.new_printing_action()
|
||||
printing_action.user_id = self.env.user
|
||||
printing_action.report_id = self.env['ir.actions.report.xml'].search([
|
||||
('id', '!=', report.id),
|
||||
], limit=1)
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': 'client',
|
||||
'printer': report.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_printing_action_with_no_printer(self):
|
||||
""" It should return the action from printing action and printer from other
|
||||
"""
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
printing_action = self.new_printing_action()
|
||||
printing_action.user_id = self.env.user
|
||||
printing_action.report_id = report
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': printing_action.action,
|
||||
'printer': report.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_printing_action_with_printer(self):
|
||||
""" It should return the action and printer from printing action """
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
printing_action = self.new_printing_action()
|
||||
printing_action.user_id = self.env.user
|
||||
printing_action.printer_id = self.new_printer()
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': printing_action.action,
|
||||
'printer': printing_action.printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
def test_behaviour_printing_action_user_defaults(self):
|
||||
""" It should return the action and printer from user with printing action
|
||||
"""
|
||||
report = self.Model.search([], limit=1)
|
||||
self.env.user.printing_action = 'client'
|
||||
printing_action = self.new_printing_action()
|
||||
printing_action.user_id = self.env.user
|
||||
printing_action.action = 'user_default'
|
||||
self.assertEqual(report.behaviour(), {
|
||||
report.id: {
|
||||
'action': 'client',
|
||||
'printer': report.printing_printer_id,
|
||||
},
|
||||
})
|
||||
|
||||
66
base_report_to_printer/tests/test_printing_job.py
Normal file
66
base_report_to_printer/tests/test_printing_job.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import mock
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
||||
|
||||
|
||||
class TestPrintingJob(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPrintingJob, self).setUp()
|
||||
self.Model = self.env['printing.server']
|
||||
self.server = self.Model.create({})
|
||||
self.printer_vals = {
|
||||
'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.job_vals = {
|
||||
'server_id': self.server.id,
|
||||
'job_id_cups': 1,
|
||||
'job_media_progress': 0,
|
||||
'time_at_creation': fields.Datetime.now(),
|
||||
}
|
||||
|
||||
def new_printer(self):
|
||||
return self.env['printing.printer'].create(self.printer_vals)
|
||||
|
||||
def new_job(self, printer, vals=None):
|
||||
values = self.job_vals
|
||||
if vals is not None:
|
||||
values.update(vals)
|
||||
values['printer_id'] = printer.id
|
||||
return self.env['printing.job'].create(values)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_cancel_job_error(self, cups):
|
||||
""" It should catch any exception from CUPS and update status """
|
||||
cups.Connection.side_effect = Exception
|
||||
printer = self.new_printer()
|
||||
job = self.new_job(printer, {'job_id_cups': 2})
|
||||
job.action_cancel()
|
||||
cups.Connection.side_effect = None
|
||||
self.assertEquals(cups.Connection().cancelJob.call_count, 0)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_cancel_job(self, cups):
|
||||
""" It should catch any exception from CUPS and update status """
|
||||
printer = self.new_printer()
|
||||
job = self.new_job(printer)
|
||||
job.cancel()
|
||||
cups.Connection().cancelJob.assert_called_once_with(
|
||||
job.job_id_cups, purge_job=False,
|
||||
)
|
||||
@@ -2,17 +2,15 @@
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import tempfile
|
||||
import mock
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
from openerp.addons.base_report_to_printer.models.printing_printer import (
|
||||
CUPS_HOST,
|
||||
CUPS_PORT,
|
||||
)
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
model = 'openerp.addons.base_report_to_printer.models.printing_printer'
|
||||
model = 'odoo.addons.base_report_to_printer.models.printing_printer'
|
||||
server_model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
||||
|
||||
|
||||
class TestPrintingPrinter(TransactionCase):
|
||||
@@ -20,8 +18,11 @@ 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_vals = {
|
||||
'name': 'Printer',
|
||||
'server_id': self.server.id,
|
||||
'system_name': 'Sys Name',
|
||||
'default': True,
|
||||
'status': 'unknown',
|
||||
@@ -34,74 +35,110 @@ class TestPrintingPrinter(TransactionCase):
|
||||
def new_record(self):
|
||||
return self.Model.create(self.printer_vals)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_error(self, cups):
|
||||
""" It should catch any exception from CUPS and update status """
|
||||
def test_printing_options(self):
|
||||
""" It should generate the right options dictionnary """
|
||||
self.assertEquals(self.Model.print_options('report', 'raw'), {
|
||||
'raw': 'True',
|
||||
})
|
||||
self.assertEquals(self.Model.print_options('report', 'pdf', 2), {
|
||||
'copies': '2',
|
||||
})
|
||||
self.assertEquals(self.Model.print_options('report', 'raw', 2), {
|
||||
'raw': 'True',
|
||||
'copies': '2',
|
||||
})
|
||||
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_print_report(self, cups):
|
||||
""" It should print a report through CUPS """
|
||||
fd, file_name = tempfile.mkstemp()
|
||||
with mock.patch('%s.mkstemp' % model) as mkstemp:
|
||||
mkstemp.return_value = fd, file_name
|
||||
printer = self.new_record()
|
||||
printer.print_document('report_name', 'content to print', 'pdf')
|
||||
cups.Connection().printFile.assert_called_once_with(
|
||||
printer.system_name,
|
||||
file_name,
|
||||
file_name,
|
||||
options={})
|
||||
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_print_report_error(self, cups):
|
||||
""" It should print a report through CUPS """
|
||||
cups.Connection.side_effect = Exception
|
||||
rec_id = self.new_record()
|
||||
self.Model.update_printers_status()
|
||||
self.assertEqual(
|
||||
'server-error', rec_id.status,
|
||||
fd, file_name = tempfile.mkstemp()
|
||||
with mock.patch('%s.mkstemp' % model) as mkstemp:
|
||||
mkstemp.return_value = fd, file_name
|
||||
printer = self.new_record()
|
||||
with self.assertRaises(UserError):
|
||||
printer.print_document(
|
||||
'report_name', 'content to print', 'pdf')
|
||||
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_print_file(self, cups):
|
||||
""" It should print a file through CUPS """
|
||||
file_name = 'file_name'
|
||||
printer = self.new_record()
|
||||
printer.print_file(file_name, 'pdf')
|
||||
cups.Connection().printFile.assert_called_once_with(
|
||||
printer.system_name,
|
||||
file_name,
|
||||
file_name,
|
||||
options={})
|
||||
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_print_file_error(self, cups):
|
||||
""" It should print a file through CUPS """
|
||||
cups.Connection.side_effect = Exception
|
||||
file_name = 'file_name'
|
||||
printer = self.new_record()
|
||||
with self.assertRaises(UserError):
|
||||
printer.print_file(file_name)
|
||||
|
||||
def test_set_default(self):
|
||||
""" It should set a single record as default """
|
||||
printer = self.new_record()
|
||||
self.assertTrue(printer.default)
|
||||
other_printer = self.new_record()
|
||||
other_printer.set_default()
|
||||
self.assertFalse(printer.default)
|
||||
self.assertTrue(other_printer.default)
|
||||
# Check that calling the method on an empty recordset does nothing
|
||||
self.Model.set_default()
|
||||
self.assertEquals(other_printer, self.Model.get_default())
|
||||
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_cancel_all_jobs(self, cups):
|
||||
""" It should cancel all jobs """
|
||||
printer = self.new_record()
|
||||
printer.action_cancel_all_jobs()
|
||||
cups.Connection().cancelAllJobs.assert_called_once_with(
|
||||
name=printer.system_name,
|
||||
purge_jobs=False,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_inits_cups(self, cups):
|
||||
""" It should init CUPS connection """
|
||||
self.new_record()
|
||||
self.Model.update_printers_status()
|
||||
cups.Connection.assert_called_once_with(
|
||||
CUPS_HOST, CUPS_PORT,
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_cancel_and_purge_all_jobs(self, cups):
|
||||
""" It should cancel all jobs """
|
||||
printer = self.new_record()
|
||||
printer.cancel_all_jobs(purge_jobs=True)
|
||||
cups.Connection().cancelAllJobs.assert_called_once_with(
|
||||
name=printer.system_name,
|
||||
purge_jobs=True,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_gets_all_printers(self, cups):
|
||||
""" It should get all printers from CUPS server """
|
||||
self.new_record()
|
||||
self.Model.update_printers_status()
|
||||
cups.Connection().getPrinters.assert_called_once_with()
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_enable_printer(self, cups):
|
||||
""" It should enable the printer """
|
||||
printer = self.new_record()
|
||||
printer.enable()
|
||||
cups.Connection().enablePrinter.assert_called_once_with(
|
||||
printer.system_name)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_gets_printer(self, cups):
|
||||
""" It should get printer from CUPS by system_name """
|
||||
rec_id = self.new_record()
|
||||
self.Model.update_printers_status()
|
||||
cups.Connection().getPrinters().get.assert_called_once_with(
|
||||
rec_id.system_name,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_search(self, cups):
|
||||
""" It should search all when no domain """
|
||||
with mock.patch.object(self.Model, 'search') as search:
|
||||
self.Model.update_printers_status()
|
||||
search.assert_called_once_with([])
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_search_domain(self, cups):
|
||||
""" It should use specific domain for search """
|
||||
with mock.patch.object(self.Model, 'search') as search:
|
||||
expect = [('id', '>', 0)]
|
||||
self.Model.update_printers_status(expect)
|
||||
search.assert_called_once_with(expect)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_update_printer(self, cups):
|
||||
""" It should update from CUPS when printer identified """
|
||||
with mock.patch.object(self.Model, 'search') as search:
|
||||
printer_mk = mock.MagicMock()
|
||||
search.return_value = [printer_mk]
|
||||
self.Model.update_printers_status()
|
||||
printer_mk.update_from_cups.assert_called_once_with(
|
||||
cups.Connection(),
|
||||
cups.Connection().getPrinters().get(),
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_status_update_unavailable(self, cups):
|
||||
""" It should update status when printer is unavailable """
|
||||
rec_id = self.new_record()
|
||||
cups.Connection().getPrinters().get.return_value = False
|
||||
self.Model.update_printers_status()
|
||||
self.assertEqual(
|
||||
'unavailable', rec_id.status,
|
||||
)
|
||||
@mock.patch('%s.cups' % server_model)
|
||||
def test_disable_printer(self, cups):
|
||||
""" It should disable the printer """
|
||||
printer = self.new_record()
|
||||
printer.disable()
|
||||
cups.Connection().disablePrinter.assert_called_once_with(
|
||||
printer.system_name)
|
||||
|
||||
@@ -4,17 +4,11 @@
|
||||
|
||||
import mock
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
from openerp.exceptions import UserError
|
||||
|
||||
from openerp.addons.base_report_to_printer.models.printing_printer import (
|
||||
CUPS_HOST,
|
||||
CUPS_PORT,
|
||||
)
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
model = '%s.%s' % ('openerp.addons.base_report_to_printer.wizards',
|
||||
'printing_printer_update_wizard')
|
||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
||||
|
||||
|
||||
class StopTest(Exception):
|
||||
@@ -26,6 +20,7 @@ class TestPrintingPrinterWizard(TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestPrintingPrinterWizard, self).setUp()
|
||||
self.Model = self.env['printing.printer.update.wizard']
|
||||
self.server = self.env['printing.server'].create({})
|
||||
self.printer_vals = {
|
||||
'printer-info': 'Info',
|
||||
'printer-make-and-model': 'Make and Model',
|
||||
@@ -36,6 +31,7 @@ class TestPrintingPrinterWizard(TransactionCase):
|
||||
def _record_vals(self, sys_name='sys_name'):
|
||||
return {
|
||||
'name': self.printer_vals['printer-info'],
|
||||
'server_id': self.server.id,
|
||||
'system_name': sys_name,
|
||||
'model': self.printer_vals['printer-make-and-model'],
|
||||
'location': self.printer_vals['printer-location'],
|
||||
@@ -45,12 +41,9 @@ class TestPrintingPrinterWizard(TransactionCase):
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_action_ok_inits_connection(self, cups):
|
||||
""" It should initialize CUPS connection """
|
||||
try:
|
||||
self.Model.action_ok()
|
||||
except:
|
||||
pass
|
||||
self.Model.action_ok()
|
||||
cups.Connection.assert_called_once_with(
|
||||
CUPS_HOST, CUPS_PORT,
|
||||
host=self.server.address, port=self.server.port,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
@@ -83,8 +76,11 @@ class TestPrintingPrinterWizard(TransactionCase):
|
||||
)
|
||||
self.assertTrue(rec_id)
|
||||
for key, val in self._record_vals().iteritems():
|
||||
if rec_id._fields[key].type == 'many2one':
|
||||
val = self.env[rec_id._fields[key].comodel_name].browse(val)
|
||||
|
||||
self.assertEqual(
|
||||
val, getattr(rec_id, key),
|
||||
val, rec_id[key],
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 SYLEAM
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestPrintingReportXmlAction(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPrintingReportXmlAction, self).setUp()
|
||||
self.Model = self.env['printing.report.xml.action']
|
||||
|
||||
self.report = self.env['ir.actions.report.xml'].search([], limit=1)
|
||||
self.server = self.env['printing.server'].create({})
|
||||
|
||||
self.report_vals = {
|
||||
'report_id': self.report.id,
|
||||
'user_id': self.env.ref('base.user_demo').id,
|
||||
'action': 'server',
|
||||
}
|
||||
|
||||
def new_record(self, vals=None):
|
||||
values = self.report_vals
|
||||
if vals is not None:
|
||||
values.update(vals)
|
||||
|
||||
return self.Model.create(values)
|
||||
|
||||
def new_printer(self):
|
||||
return 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',
|
||||
})
|
||||
|
||||
def test_behaviour(self):
|
||||
""" It should return some action's data, unless called on empty recordset
|
||||
"""
|
||||
xml_action = self.new_record()
|
||||
self.assertEqual(xml_action.behaviour(), {
|
||||
'action': xml_action.action,
|
||||
'printer': xml_action.printer_id,
|
||||
})
|
||||
|
||||
xml_action = self.new_record({'printer_id': self.new_printer().id})
|
||||
self.assertEqual(xml_action.behaviour(), {
|
||||
'action': xml_action.action,
|
||||
'printer': xml_action.printer_id,
|
||||
})
|
||||
|
||||
self.assertEqual(self.Model.behaviour(), {})
|
||||
213
base_report_to_printer/tests/test_printing_server.py
Normal file
213
base_report_to_printer/tests/test_printing_server.py
Normal file
@@ -0,0 +1,213 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
import mock
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
||||
|
||||
|
||||
class TestPrintingServer(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPrintingServer, self).setUp()
|
||||
self.Model = self.env['printing.server']
|
||||
self.server = self.Model.create({})
|
||||
self.printer_vals = {
|
||||
'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.job_vals = {
|
||||
'server_id': self.server.id,
|
||||
'job_id_cups': 1,
|
||||
'job_media_progress': 0,
|
||||
'time_at_creation': fields.Datetime.now(),
|
||||
}
|
||||
|
||||
def new_printer(self):
|
||||
return self.env['printing.printer'].create(self.printer_vals)
|
||||
|
||||
def new_job(self, printer, vals=None):
|
||||
values = self.job_vals
|
||||
if vals is not None:
|
||||
values.update(vals)
|
||||
values['printer_id'] = printer.id
|
||||
return self.env['printing.job'].create(values)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_error(self, cups):
|
||||
""" It should catch any exception from CUPS and update status """
|
||||
cups.Connection.side_effect = Exception
|
||||
rec_id = self.new_printer()
|
||||
self.Model.update_printers()
|
||||
self.assertEqual(
|
||||
'server-error', rec_id.status,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_inits_cups(self, cups):
|
||||
""" It should init CUPS connection """
|
||||
self.new_printer()
|
||||
self.Model.update_printers()
|
||||
cups.Connection.assert_called_once_with(
|
||||
host=self.server.address, port=self.server.port,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_gets_all_printers(self, cups):
|
||||
""" It should get all printers from CUPS server """
|
||||
self.new_printer()
|
||||
self.Model.update_printers()
|
||||
cups.Connection().getPrinters.assert_called_once_with()
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_search(self, cups):
|
||||
""" It should search all when no domain """
|
||||
with mock.patch.object(self.Model, 'search') as search:
|
||||
self.Model.update_printers()
|
||||
search.assert_called_once_with([])
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_search_domain(self, cups):
|
||||
""" It should use specific domain for search """
|
||||
with mock.patch.object(self.Model, 'search') as search:
|
||||
expect = [('id', '>', 0)]
|
||||
self.Model.update_printers(expect)
|
||||
search.assert_called_once_with(expect)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_printers_update_unavailable(self, cups):
|
||||
""" It should update status when printer is unavailable """
|
||||
rec_id = self.new_printer()
|
||||
cups.Connection().getPrinters().get.return_value = False
|
||||
self.Model.action_update_printers()
|
||||
self.assertEqual(
|
||||
'unavailable', rec_id.status,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_jobs_cron(self, cups):
|
||||
""" It should get all jobs from CUPS server """
|
||||
self.new_printer()
|
||||
self.Model.action_update_jobs()
|
||||
cups.Connection().getPrinters.assert_called_once_with()
|
||||
cups.Connection().getJobs.assert_called_once_with(
|
||||
which_jobs='all',
|
||||
first_job_id=-1,
|
||||
requested_attributes=[
|
||||
'job-name',
|
||||
'job-id',
|
||||
'printer-uri',
|
||||
'job-media-progress',
|
||||
'time-at-creation',
|
||||
'job-state',
|
||||
'job-state-reasons',
|
||||
'time-at-processing',
|
||||
'time-at-completed',
|
||||
],
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_jobs_button(self, cups):
|
||||
""" It should get all jobs from CUPS server """
|
||||
self.new_printer()
|
||||
self.server.action_update_jobs()
|
||||
cups.Connection().getPrinters.assert_called_once_with()
|
||||
cups.Connection().getJobs.assert_called_once_with(
|
||||
which_jobs='all',
|
||||
first_job_id=-1,
|
||||
requested_attributes=[
|
||||
'job-name',
|
||||
'job-id',
|
||||
'printer-uri',
|
||||
'job-media-progress',
|
||||
'time-at-creation',
|
||||
'job-state',
|
||||
'job-state-reasons',
|
||||
'time-at-processing',
|
||||
'time-at-completed',
|
||||
],
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_jobs_error(self, cups):
|
||||
""" It should catch any exception from CUPS and update status """
|
||||
cups.Connection.side_effect = Exception
|
||||
self.new_printer()
|
||||
self.server.update_jobs()
|
||||
cups.Connection.assert_called_with(
|
||||
host=self.server.address, port=self.server.port,
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_jobs_uncompleted(self, cups):
|
||||
"""
|
||||
It should search which jobs have been completed since last update
|
||||
"""
|
||||
printer = self.new_printer()
|
||||
self.new_job(printer, vals={'job_state': 'completed'})
|
||||
self.new_job(printer, vals={
|
||||
'job_id_cups': 2,
|
||||
'job_state': 'processing',
|
||||
})
|
||||
self.server.update_jobs(which='not-completed')
|
||||
cups.Connection().getJobs.assert_any_call(
|
||||
which_jobs='completed', first_job_id=2,
|
||||
requested_attributes=[
|
||||
'job-name',
|
||||
'job-id',
|
||||
'printer-uri',
|
||||
'job-media-progress',
|
||||
'time-at-creation',
|
||||
'job-state',
|
||||
'job-state-reasons',
|
||||
'time-at-processing',
|
||||
'time-at-completed',
|
||||
],
|
||||
)
|
||||
|
||||
@mock.patch('%s.cups' % model)
|
||||
def test_update_jobs(self, cups):
|
||||
"""
|
||||
It should update all jobs, known or not
|
||||
"""
|
||||
printer = self.new_printer()
|
||||
printer_uri = 'hostname:port/' + printer.system_name
|
||||
cups.Connection().getJobs.return_value = {
|
||||
1: {
|
||||
'printer-uri': printer_uri,
|
||||
},
|
||||
2: {
|
||||
'printer-uri': printer_uri,
|
||||
'job-state': 9,
|
||||
},
|
||||
4: {
|
||||
'printer-uri': printer_uri,
|
||||
'job-state': 5,
|
||||
},
|
||||
}
|
||||
self.new_job(printer, vals={'job_state': 'completed'})
|
||||
completed_job = self.new_job(printer, vals={
|
||||
'job_id_cups': 2,
|
||||
'job_state': 'processing',
|
||||
})
|
||||
purged_job = self.new_job(printer, vals={
|
||||
'job_id_cups': 3,
|
||||
'job_state': 'processing',
|
||||
})
|
||||
self.server.update_jobs()
|
||||
new_job = self.env['printing.job'].search([('job_id_cups', '=', 4)])
|
||||
self.assertEqual(completed_job.job_state, 'completed')
|
||||
self.assertEqual(purged_job.active, False)
|
||||
self.assertEqual(new_job.job_state, 'processing')
|
||||
@@ -2,7 +2,9 @@
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
import mock
|
||||
from odoo.tests.common import TransactionCase
|
||||
from odoo import exceptions
|
||||
|
||||
|
||||
class StopTest(Exception):
|
||||
@@ -14,11 +16,25 @@ class TestReport(TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestReport, self).setUp()
|
||||
self.Model = self.env['report']
|
||||
self.server = self.env['printing.server'].create({})
|
||||
self.report_vals = {}
|
||||
|
||||
def new_record(self):
|
||||
return self.Model.create(self.report_vals)
|
||||
|
||||
def new_printer(self):
|
||||
return 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',
|
||||
})
|
||||
|
||||
def test_can_print_report_context_skip(self):
|
||||
""" It should return False based on context """
|
||||
rec_id = self.new_record().with_context(
|
||||
@@ -42,3 +58,72 @@ class TestReport(TransactionCase):
|
||||
{'action': 'server'}, True, False
|
||||
)
|
||||
self.assertFalse(res)
|
||||
|
||||
def test_get_pdf_not_printable(self):
|
||||
""" It should print the report, only if it is printable
|
||||
"""
|
||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
||||
'printing_printer.PrintingPrinter.'
|
||||
'print_document') as print_document:
|
||||
report = self.env['ir.actions.report.xml'].search([
|
||||
('report_type', '=', 'qweb-pdf'),
|
||||
], limit=1)
|
||||
records = self.env[report.model].search([], limit=5)
|
||||
self.env['report'].get_pdf(records.ids, report.report_name)
|
||||
print_document.assert_not_called()
|
||||
|
||||
def test_get_pdf_printable(self):
|
||||
""" It should print the report, only if it is printable
|
||||
"""
|
||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
||||
'printing_printer.PrintingPrinter.'
|
||||
'print_document') as print_document:
|
||||
report = self.env['ir.actions.report.xml'].search([
|
||||
('report_type', '=', 'qweb-pdf'),
|
||||
], limit=1)
|
||||
report.property_printing_action_id.action_type = 'server'
|
||||
report.printing_printer_id = self.new_printer()
|
||||
records = self.env[report.model].search([], limit=5)
|
||||
document = self.env['report'].get_pdf(
|
||||
records.ids, report.report_name)
|
||||
print_document.assert_called_once_with(
|
||||
report, document, report.report_type)
|
||||
|
||||
def test_print_document_not_printable(self):
|
||||
""" It should print the report, regardless of the defined behaviour """
|
||||
report = self.env['ir.actions.report.xml'].search([
|
||||
('report_type', '=', 'qweb-pdf'),
|
||||
], limit=1)
|
||||
report.printing_printer_id = self.new_printer()
|
||||
records = self.env[report.model].search([], limit=5)
|
||||
|
||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
||||
'printing_printer.PrintingPrinter.'
|
||||
'print_document') as print_document:
|
||||
self.env['report'].print_document(records.ids, report.report_name)
|
||||
print_document.assert_called_once()
|
||||
|
||||
def test_print_document_printable(self):
|
||||
""" It should print the report, regardless of the defined behaviour """
|
||||
report = self.env['ir.actions.report.xml'].search([
|
||||
('report_type', '=', 'qweb-pdf'),
|
||||
], limit=1)
|
||||
report.property_printing_action_id.action_type = 'server'
|
||||
report.printing_printer_id = self.new_printer()
|
||||
records = self.env[report.model].search([], limit=5)
|
||||
|
||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
||||
'printing_printer.PrintingPrinter.'
|
||||
'print_document') as print_document:
|
||||
self.env['report'].print_document(records.ids, report.report_name)
|
||||
print_document.assert_called_once()
|
||||
|
||||
def test_print_document_no_printer(self):
|
||||
""" It should raise an error """
|
||||
report = self.env['ir.actions.report.xml'].search([
|
||||
('report_type', '=', 'qweb-pdf'),
|
||||
], limit=1)
|
||||
records = self.env[report.model].search([], limit=5)
|
||||
|
||||
with self.assertRaises(exceptions.UserError):
|
||||
self.env['report'].print_document(records.ids, report.report_name)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright 2016 LasLabs Inc.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestResUsers(TransactionCase):
|
||||
|
||||
Reference in New Issue
Block a user