mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[MIG] base_report_to_printer: Migration to 18.0
This commit is contained in:
@@ -175,6 +175,13 @@ Contributors
|
|||||||
- Hughes Damry <hughes.damry@acsone.eu>
|
- Hughes Damry <hughes.damry@acsone.eu>
|
||||||
- Akim Juillerat <akim.juillerat@camptocamp.com>
|
- Akim Juillerat <akim.juillerat@camptocamp.com>
|
||||||
- Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
- Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
|
- Tris Doan <tridm@trobz.com>
|
||||||
|
|
||||||
|
Other credits
|
||||||
|
-------------
|
||||||
|
|
||||||
|
The migration of this module from 17.0 to 18.0 was financially supported
|
||||||
|
by Camptocamp.
|
||||||
|
|
||||||
Maintainers
|
Maintainers
|
||||||
-----------
|
-----------
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"name": "Report to printer",
|
"name": "Report to printer",
|
||||||
"version": "17.0.1.0.1",
|
"version": "18.0.1.0.0",
|
||||||
"category": "Generic Modules/Base",
|
"category": "Generic Modules/Base",
|
||||||
"author": "Agile Business Group & Domsense, Pegueroles SCP, NaN,"
|
"author": "Agile Business Group & Domsense, Pegueroles SCP, NaN,"
|
||||||
" LasLabs, Camptocamp, Odoo Community Association (OCA),"
|
" LasLabs, Camptocamp, Odoo Community Association (OCA),"
|
||||||
|
|||||||
@@ -9,25 +9,19 @@
|
|||||||
<field name="name">Send to Client</field>
|
<field name="name">Send to Client</field>
|
||||||
<field name="action_type">client</field>
|
<field name="action_type">client</field>
|
||||||
</record>
|
</record>
|
||||||
<!-- properties -->
|
|
||||||
<record forcecreate="True" id="property_printing_action_id" model="ir.property">
|
|
||||||
<field name="name">property_printing_action_id</field>
|
|
||||||
<field
|
|
||||||
name="fields_id"
|
|
||||||
search="[('model', '=', 'ir.actions.report'), ('name', '=', 'property_printing_action_id')]"
|
|
||||||
/>
|
|
||||||
<field name="value" eval="'printing.action,' + str(printing_action_2)" />
|
|
||||||
</record>
|
|
||||||
<record forcecreate="True" id="ir_cron_update_printers" model="ir.cron">
|
<record forcecreate="True" id="ir_cron_update_printers" model="ir.cron">
|
||||||
<field name="name">Update Printers Jobs</field>
|
<field name="name">Update Printers Jobs</field>
|
||||||
<field name="active" eval="True" />
|
<field name="active" eval="True" />
|
||||||
<field name="user_id" ref="base.user_root" />
|
<field name="user_id" ref="base.user_root" />
|
||||||
<field name="interval_number">1</field>
|
<field name="interval_number">1</field>
|
||||||
<field name="interval_type">minutes</field>
|
<field name="interval_type">minutes</field>
|
||||||
<field name="numbercall">-1</field>
|
|
||||||
<field name="doall" eval="False" />
|
|
||||||
<field name="model_id" ref="base_report_to_printer.model_printing_server" />
|
<field name="model_id" ref="base_report_to_printer.model_printing_server" />
|
||||||
<field name="state">code</field>
|
<field name="state">code</field>
|
||||||
<field name="code">model.action_update_jobs()</field>
|
<field name="code">model.action_update_jobs()</field>
|
||||||
</record>
|
</record>
|
||||||
|
<function
|
||||||
|
model="ir.default"
|
||||||
|
name="set"
|
||||||
|
eval="('ir.actions.report', 'property_printing_action_id', obj().env.ref('base_report_to_printer.printing_action_2').id)"
|
||||||
|
/>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ class IrActionsReport(models.Model):
|
|||||||
_("This report type (%s) is not supported by direct printing!")
|
_("This report type (%s) is not supported by direct printing!")
|
||||||
% str(self.report_type)
|
% str(self.report_type)
|
||||||
)
|
)
|
||||||
method_name = "_render_qweb_%s" % (report_type)
|
method_name = f"_render_qweb_{report_type}"
|
||||||
document, doc_format = getattr(
|
document, doc_format = getattr(
|
||||||
self.with_context(must_skip_send_to_printer=True), method_name
|
self.with_context(must_skip_send_to_printer=True), method_name
|
||||||
)(self.report_name, record_ids, data=data)
|
)(self.report_name, record_ids, data=data)
|
||||||
|
|||||||
@@ -5,14 +5,14 @@
|
|||||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import api, fields, models
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
class PrintingAction(models.Model):
|
class PrintingAction(models.Model):
|
||||||
_name = "printing.action"
|
_name = "printing.action"
|
||||||
_description = "Print Job Action"
|
_description = "Print Job Action"
|
||||||
|
|
||||||
@api.model
|
@property
|
||||||
def _available_action_types(self):
|
def _available_action_types(self):
|
||||||
return [
|
return [
|
||||||
("server", "Send to Printer"),
|
("server", "Send to Printer"),
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ class PrintingPrinter(models.Model):
|
|||||||
options = {}
|
options = {}
|
||||||
for option, value in print_opts.items():
|
for option, value in print_opts.items():
|
||||||
try:
|
try:
|
||||||
options.update(getattr(self, "_set_option_%s" % option)(report, value))
|
options.update(getattr(self, f"_set_option_{option}")(report, value))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
options[option] = str(value)
|
options[option] = str(value)
|
||||||
return options
|
return options
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class PrintingReportXmlAction(models.Model):
|
|||||||
comodel_name="res.users", string="User", required=True, ondelete="cascade"
|
comodel_name="res.users", string="User", required=True, ondelete="cascade"
|
||||||
)
|
)
|
||||||
action = fields.Selection(
|
action = fields.Selection(
|
||||||
selection=lambda s: s.env["printing.action"]._available_action_types(),
|
selection=lambda s: s.env["printing.action"]._available_action_types,
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
printer_id = fields.Many2one(comodel_name="printing.printer", string="Printer")
|
printer_id = fields.Many2one(comodel_name="printing.printer", string="Printer")
|
||||||
|
|||||||
@@ -11,19 +11,27 @@ from odoo import api, fields, models
|
|||||||
class ResUsers(models.Model):
|
class ResUsers(models.Model):
|
||||||
_inherit = "res.users"
|
_inherit = "res.users"
|
||||||
|
|
||||||
@api.model
|
@property
|
||||||
def _user_available_action_types(self):
|
def _user_available_action_types(self):
|
||||||
return [
|
return [
|
||||||
(code, string)
|
(code, string)
|
||||||
for code, string in self.env["printing.action"]._available_action_types()
|
for code, string in self.env["printing.action"]._available_action_types
|
||||||
if code != "user_default"
|
if code != "user_default"
|
||||||
]
|
]
|
||||||
|
|
||||||
printing_action = fields.Selection(selection=_user_available_action_types)
|
printing_action = fields.Selection(
|
||||||
|
selection=lambda self: self._user_available_action_types
|
||||||
|
)
|
||||||
printing_printer_id = fields.Many2one(
|
printing_printer_id = fields.Many2one(
|
||||||
comodel_name="printing.printer", string="Default Printer"
|
comodel_name="printing.printer", string="Default Printer"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@api.constrains("printing_action")
|
||||||
|
def _check_printing_action(self):
|
||||||
|
for rec in self:
|
||||||
|
if rec.printing_action == "user_default":
|
||||||
|
raise ValueError("user_default should not be available")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def SELF_READABLE_FIELDS(self):
|
def SELF_READABLE_FIELDS(self):
|
||||||
return super().SELF_READABLE_FIELDS + ["printing_action", "printing_printer_id"]
|
return super().SELF_READABLE_FIELDS + ["printing_action", "printing_printer_id"]
|
||||||
|
|||||||
@@ -15,3 +15,4 @@
|
|||||||
- Hughes Damry \<<hughes.damry@acsone.eu>\>
|
- Hughes Damry \<<hughes.damry@acsone.eu>\>
|
||||||
- Akim Juillerat \<<akim.juillerat@camptocamp.com>\>
|
- Akim Juillerat \<<akim.juillerat@camptocamp.com>\>
|
||||||
- Jacques-Etienne Baudoux (BCIM) \<<je@bcim.be>\>
|
- Jacques-Etienne Baudoux (BCIM) \<<je@bcim.be>\>
|
||||||
|
- Tris Doan \<<tridm@trobz.com>\>
|
||||||
|
|||||||
1
base_report_to_printer/readme/CREDITS.md
Normal file
1
base_report_to_printer/readme/CREDITS.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp.
|
||||||
@@ -409,7 +409,8 @@ preprinted paper such as payment slip.</p>
|
|||||||
<li><a class="reference internal" href="#credits" id="toc-entry-9">Credits</a><ul>
|
<li><a class="reference internal" href="#credits" id="toc-entry-9">Credits</a><ul>
|
||||||
<li><a class="reference internal" href="#authors" id="toc-entry-10">Authors</a></li>
|
<li><a class="reference internal" href="#authors" id="toc-entry-10">Authors</a></li>
|
||||||
<li><a class="reference internal" href="#contributors" id="toc-entry-11">Contributors</a></li>
|
<li><a class="reference internal" href="#contributors" id="toc-entry-11">Contributors</a></li>
|
||||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-12">Maintainers</a></li>
|
<li><a class="reference internal" href="#other-credits" id="toc-entry-12">Other credits</a></li>
|
||||||
|
<li><a class="reference internal" href="#maintainers" id="toc-entry-13">Maintainers</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -528,10 +529,16 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
|||||||
<li>Hughes Damry <<a class="reference external" href="mailto:hughes.damry@acsone.eu">hughes.damry@acsone.eu</a>></li>
|
<li>Hughes Damry <<a class="reference external" href="mailto:hughes.damry@acsone.eu">hughes.damry@acsone.eu</a>></li>
|
||||||
<li>Akim Juillerat <<a class="reference external" href="mailto:akim.juillerat@camptocamp.com">akim.juillerat@camptocamp.com</a>></li>
|
<li>Akim Juillerat <<a class="reference external" href="mailto:akim.juillerat@camptocamp.com">akim.juillerat@camptocamp.com</a>></li>
|
||||||
<li>Jacques-Etienne Baudoux (BCIM) <<a class="reference external" href="mailto:je@bcim.be">je@bcim.be</a>></li>
|
<li>Jacques-Etienne Baudoux (BCIM) <<a class="reference external" href="mailto:je@bcim.be">je@bcim.be</a>></li>
|
||||||
|
<li>Tris Doan <<a class="reference external" href="mailto:tridm@trobz.com">tridm@trobz.com</a>></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section" id="other-credits">
|
||||||
|
<h2><a class="toc-backref" href="#toc-entry-12">Other credits</a></h2>
|
||||||
|
<p>The migration of this module from 17.0 to 18.0 was financially supported
|
||||||
|
by Camptocamp.</p>
|
||||||
|
</div>
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
<h2><a class="toc-backref" href="#toc-entry-12">Maintainers</a></h2>
|
<h2><a class="toc-backref" href="#toc-entry-13">Maintainers</a></h2>
|
||||||
<p>This module is maintained by the OCA.</p>
|
<p>This module is maintained by the OCA.</p>
|
||||||
<a class="reference external image-reference" href="https://odoo-community.org">
|
<a class="reference external image-reference" href="https://odoo-community.org">
|
||||||
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
/** @odoo-module */
|
import {markup} from "@odoo/owl";
|
||||||
import {Markup} from "web.utils";
|
|
||||||
import {_t} from "@web/core/l10n/translation";
|
import {_t} from "@web/core/l10n/translation";
|
||||||
import {registry} from "@web/core/registry";
|
import {registry} from "@web/core/registry";
|
||||||
|
|
||||||
@@ -38,14 +37,14 @@ async function cupsReportActionHandler(action, options, env) {
|
|||||||
// Just so the translation engine detects them as it doesn't do it inside
|
// Just so the translation engine detects them as it doesn't do it inside
|
||||||
// template strings
|
// template strings
|
||||||
const terms = {
|
const terms = {
|
||||||
the_report: env._t("The report"),
|
the_report: _t("The report"),
|
||||||
couldnt_be_printed: env._t(
|
couldnt_be_printed: _t(
|
||||||
"couldn't be printed. Click on the button below to download it"
|
"couldn't be printed. Click on the button below to download it"
|
||||||
),
|
),
|
||||||
issue_on: env._t("Issue on"),
|
issue_on: _t("Issue on"),
|
||||||
};
|
};
|
||||||
const notificationRemove = env.services.notification.add(
|
const notificationRemove = env.services.notification.add(
|
||||||
Markup(
|
markup(
|
||||||
`<p>${terms.the_report} <strong>${action.name}</strong> ${terms.couldnt_be_printed}</p>`
|
`<p>${terms.the_report} <strong>${action.name}</strong> ${terms.couldnt_be_printed}</p>`
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
@@ -55,7 +54,7 @@ async function cupsReportActionHandler(action, options, env) {
|
|||||||
messageIsHtml: true,
|
messageIsHtml: true,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
name: env._t("Print"),
|
name: _t("Print"),
|
||||||
primary: true,
|
primary: true,
|
||||||
icon: "fa-print",
|
icon: "fa-print",
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Copyright 2016 SYLEAM
|
# Copyright 2016 SYLEAM
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
@@ -57,14 +58,14 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
|
|
||||||
def test_print_action_for_report_name_gets_report(self):
|
def test_print_action_for_report_name_gets_report(self):
|
||||||
"""It should get report by name"""
|
"""It should get report by name"""
|
||||||
with mock.patch("%s._get_report_from_name" % model) as mk:
|
with mock.patch(f"{model}._get_report_from_name") as mk:
|
||||||
expect = "test"
|
expect = "test"
|
||||||
self.Model.print_action_for_report_name(expect)
|
self.Model.print_action_for_report_name(expect)
|
||||||
mk.assert_called_once_with(expect)
|
mk.assert_called_once_with(expect)
|
||||||
|
|
||||||
def test_print_action_for_report_name_returns_if_no_report(self):
|
def test_print_action_for_report_name_returns_if_no_report(self):
|
||||||
"""It should return empty dict when no matching report"""
|
"""It should return empty dict when no matching report"""
|
||||||
with mock.patch("%s._get_report_from_name" % model) as mk:
|
with mock.patch(f"{model}._get_report_from_name") as mk:
|
||||||
expect = "test"
|
expect = "test"
|
||||||
mk.return_value = False
|
mk.return_value = False
|
||||||
res = self.Model.print_action_for_report_name(expect)
|
res = self.Model.print_action_for_report_name(expect)
|
||||||
@@ -72,7 +73,7 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
|
|
||||||
def test_print_action_for_report_name_returns_if_report(self):
|
def test_print_action_for_report_name_returns_if_report(self):
|
||||||
"""It should return correct serializable result for behaviour"""
|
"""It should return correct serializable result for behaviour"""
|
||||||
with mock.patch("%s._get_report_from_name" % model) as mk:
|
with mock.patch(f"{model}._get_report_from_name") as mk:
|
||||||
res = self.Model.print_action_for_report_name("test")
|
res = self.Model.print_action_for_report_name("test")
|
||||||
behaviour = mk().behaviour()
|
behaviour = mk().behaviour()
|
||||||
expect = {
|
expect = {
|
||||||
@@ -102,6 +103,9 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = "client"
|
self.env.user.printing_action = "client"
|
||||||
self.env.user.printing_printer_id = self.new_printer()
|
self.env.user.printing_printer_id = self.new_printer()
|
||||||
|
with (
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
report.behaviour(),
|
report.behaviour(),
|
||||||
{
|
{
|
||||||
@@ -110,6 +114,8 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
"tray": False,
|
"tray": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_behaviour_report_values(self):
|
def test_behaviour_report_values(self):
|
||||||
"""It should return the action and printer from report"""
|
"""It should return the action and printer from report"""
|
||||||
@@ -117,6 +123,9 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
self.env.user.printing_action = "client"
|
self.env.user.printing_action = "client"
|
||||||
report.property_printing_action_id = self.new_action()
|
report.property_printing_action_id = self.new_action()
|
||||||
report.printing_printer_id = self.new_printer()
|
report.printing_printer_id = self.new_printer()
|
||||||
|
with (
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
report.behaviour(),
|
report.behaviour(),
|
||||||
{
|
{
|
||||||
@@ -125,6 +134,8 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
"tray": False,
|
"tray": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_behaviour_user_action(self):
|
def test_behaviour_user_action(self):
|
||||||
"""It should return the action and printer from user action"""
|
"""It should return the action and printer from user action"""
|
||||||
@@ -188,6 +199,9 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
printing_action = self.new_printing_action()
|
printing_action = self.new_printing_action()
|
||||||
printing_action.user_id = self.env.user
|
printing_action.user_id = self.env.user
|
||||||
printing_action.printer_id = self.new_printer()
|
printing_action.printer_id = self.new_printer()
|
||||||
|
with (
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
report.behaviour(),
|
report.behaviour(),
|
||||||
{
|
{
|
||||||
@@ -196,6 +210,8 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
"tray": False,
|
"tray": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_behaviour_printing_action_user_defaults(self):
|
def test_behaviour_printing_action_user_defaults(self):
|
||||||
"""It should return the action and printer from user with printing
|
"""It should return the action and printer from user with printing
|
||||||
@@ -215,12 +231,23 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
"""
|
"""
|
||||||
It should return the correct tray
|
It should return the correct tray
|
||||||
"""
|
"""
|
||||||
|
with (
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
action = self.env["printing.report.xml.action"].create(
|
action = self.env["printing.report.xml.action"].create(
|
||||||
{"user_id": self.env.user.id, "report_id": report.id, "action": "server"}
|
{
|
||||||
|
"user_id": self.env.user.id,
|
||||||
|
"report_id": report.id,
|
||||||
|
"action": "server",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
tray_vals = {"name": "Tray", "system_name": "Tray", "printer_id": printer.id}
|
tray_vals = {
|
||||||
|
"name": "Tray",
|
||||||
|
"system_name": "Tray",
|
||||||
|
"printer_id": printer.id,
|
||||||
|
}
|
||||||
user_tray = self.new_tray({"system_name": "User tray"}, tray_vals)
|
user_tray = self.new_tray({"system_name": "User tray"}, tray_vals)
|
||||||
report_tray = self.new_tray({"system_name": "Report 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)
|
action_tray = self.new_tray({"system_name": "Action tray"}, tray_vals)
|
||||||
@@ -266,6 +293,9 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
report.printer_tray_id = report_tray
|
report.printer_tray_id = report_tray
|
||||||
action.printer_tray_id = action_tray
|
action.printer_tray_id = action_tray
|
||||||
self.assertEqual("Action tray", report.behaviour()["tray"])
|
self.assertEqual("Action tray", report.behaviour()["tray"])
|
||||||
|
self.assertEqual(len(logs.records), 6)
|
||||||
|
for record in logs.records:
|
||||||
|
self.assertEqual(record.levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_empty(self):
|
def test_onchange_printer_tray_id_empty(self):
|
||||||
action = self.Model.new({"printer_tray_id": False})
|
action = self.Model.new({"printer_tray_id": False})
|
||||||
@@ -305,6 +335,9 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
printing_action.user_id = self.env.user
|
printing_action.user_id = self.env.user
|
||||||
printing_action.printer_id = self.new_printer()
|
printing_action.printer_id = self.new_printer()
|
||||||
printing_action.printer_id.multi_thread = True
|
printing_action.printer_id.multi_thread = True
|
||||||
|
with (
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
report.behaviour(),
|
report.behaviour(),
|
||||||
{
|
{
|
||||||
@@ -313,3 +346,5 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
"tray": False,
|
"tray": False,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Copyright 2016 LasLabs Inc.
|
# Copyright 2016 LasLabs Inc.
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from odoo import fields
|
from odoo import fields
|
||||||
@@ -42,9 +43,12 @@ class TestPrintingJob(TransactionCase):
|
|||||||
values["printer_id"] = printer.id
|
values["printer_id"] = printer.id
|
||||||
return self.env["printing.job"].create(values)
|
return self.env["printing.job"].create(values)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
def test_cancel_job_error(self):
|
||||||
def test_cancel_job_error(self, cups):
|
|
||||||
"""It should catch any exception from CUPS and update status"""
|
"""It should catch any exception from CUPS and update status"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
job = self.new_job(printer, {"job_id_cups": 2})
|
job = self.new_job(printer, {"job_id_cups": 2})
|
||||||
@@ -52,7 +56,10 @@ class TestPrintingJob(TransactionCase):
|
|||||||
cups.Connection.side_effect = None
|
cups.Connection.side_effect = None
|
||||||
self.assertEqual(cups.Connection().cancelJob.call_count, 0)
|
self.assertEqual(cups.Connection().cancelJob.call_count, 0)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
self.assertEqual(len(logs.records), 3)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
|
@mock.patch(f"{model}.cups")
|
||||||
def test_cancel_job(self, cups):
|
def test_cancel_job(self, cups):
|
||||||
"""It should catch any exception from CUPS and update status"""
|
"""It should catch any exception from CUPS and update status"""
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Copyright 2016 LasLabs Inc.
|
# Copyright 2016 LasLabs Inc.
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
import logging
|
||||||
import tempfile
|
import tempfile
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
@@ -79,11 +80,11 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
)
|
)
|
||||||
self.assertTrue("InputSlot" in self.Model.print_options(report, tray="Test"))
|
self.assertTrue("InputSlot" in self.Model.print_options(report, tray="Test"))
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_print_report(self, cups):
|
def test_print_report(self, cups):
|
||||||
"""It should print a report through CUPS"""
|
"""It should print a report through CUPS"""
|
||||||
fd, file_name = tempfile.mkstemp()
|
fd, file_name = tempfile.mkstemp()
|
||||||
with mock.patch("%s.mkstemp" % model) as mkstemp:
|
with mock.patch(f"{model}.mkstemp") as mkstemp:
|
||||||
mkstemp.return_value = fd, file_name
|
mkstemp.return_value = fd, file_name
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.print_document(self.report, b"content to print", doc_format="pdf")
|
printer.print_document(self.report, b"content to print", doc_format="pdf")
|
||||||
@@ -91,37 +92,52 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
printer.system_name, file_name, file_name, options={}
|
printer.system_name, file_name, file_name, options={}
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
def test_print_report_error(self):
|
||||||
def test_print_report_error(self, cups):
|
|
||||||
"""It should print a report through CUPS"""
|
"""It should print a report through CUPS"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
fd, file_name = tempfile.mkstemp()
|
fd, file_name = tempfile.mkstemp()
|
||||||
with mock.patch("%s.mkstemp" % model) as mkstemp:
|
with mock.patch(f"{model}.mkstemp") as mkstemp:
|
||||||
mkstemp.return_value = fd, file_name
|
mkstemp.return_value = fd, file_name
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
printer.print_document(
|
printer.print_document(
|
||||||
self.report, b"content to print", doc_format="pdf"
|
self.report, b"content to print", doc_format="pdf"
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
def test_print_file(self):
|
||||||
def test_print_file(self, cups):
|
|
||||||
"""It should print a file through CUPS"""
|
"""It should print a file through CUPS"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{server_model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
file_name = "file_name"
|
file_name = "file_name"
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.print_file(file_name, "pdf")
|
printer.print_file(file_name, "pdf")
|
||||||
cups.Connection().printFile.assert_called_once_with(
|
cups.Connection().printFile.assert_called_once_with(
|
||||||
printer.system_name, file_name, file_name, options={}
|
printer.system_name, file_name, file_name, options={}
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
def test_print_file_error(self):
|
||||||
def test_print_file_error(self, cups):
|
|
||||||
"""It should print a file through CUPS"""
|
"""It should print a file through CUPS"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{server_model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
file_name = "file_name"
|
file_name = "file_name"
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
printer.print_file(file_name)
|
printer.print_file(file_name)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_set_default(self):
|
def test_set_default(self):
|
||||||
"""It should set a single record as default"""
|
"""It should set a single record as default"""
|
||||||
@@ -142,7 +158,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
printer.unset_default()
|
printer.unset_default()
|
||||||
self.assertFalse(printer.default)
|
self.assertFalse(printer.default)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_cancel_all_jobs(self, cups):
|
def test_cancel_all_jobs(self, cups):
|
||||||
"""It should cancel all jobs"""
|
"""It should cancel all jobs"""
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
@@ -151,7 +167,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
name=printer.system_name, purge_jobs=False
|
name=printer.system_name, purge_jobs=False
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_cancel_and_purge_all_jobs(self, cups):
|
def test_cancel_and_purge_all_jobs(self, cups):
|
||||||
"""It should cancel all jobs"""
|
"""It should cancel all jobs"""
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
@@ -160,21 +176,21 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
name=printer.system_name, purge_jobs=True
|
name=printer.system_name, purge_jobs=True
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_enable_printer(self, cups):
|
def test_enable_printer(self, cups):
|
||||||
"""It should enable the printer"""
|
"""It should enable the printer"""
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.enable()
|
printer.enable()
|
||||||
cups.Connection().enablePrinter.assert_called_once_with(printer.system_name)
|
cups.Connection().enablePrinter.assert_called_once_with(printer.system_name)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_disable_printer(self, cups):
|
def test_disable_printer(self, cups):
|
||||||
"""It should disable the printer"""
|
"""It should disable the printer"""
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.disable()
|
printer.disable()
|
||||||
cups.Connection().disablePrinter.assert_called_once_with(printer.system_name)
|
cups.Connection().disablePrinter.assert_called_once_with(printer.system_name)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_print_test_page(self, cups):
|
def test_print_test_page(self, cups):
|
||||||
"""It should print a test page"""
|
"""It should print a test page"""
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_update_printers(self, cups):
|
def test_update_printers(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that the update_printers method calls _prepare_update_from_cups
|
Check that the update_printers method calls _prepare_update_from_cups
|
||||||
@@ -111,7 +111,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
self.ServerModel.update_printers()
|
self.ServerModel.update_printers()
|
||||||
self.assertEqual(self.printer.name, "My custom name")
|
self.assertEqual(self.printer.name, "My custom name")
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_prepare_update_from_cups_no_ppd(self, cups):
|
def test_prepare_update_from_cups_no_ppd(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that the tray_ids field has no value when no PPD is available
|
Check that the tray_ids field has no value when no PPD is available
|
||||||
@@ -124,7 +124,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertFalse("tray_ids" in vals)
|
self.assertFalse("tray_ids" in vals)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_prepare_update_from_cups_empty_ppd(self, cups):
|
def test_prepare_update_from_cups_empty_ppd(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that the tray_ids field has no value when the PPD file has
|
Check that the tray_ids field has no value when the PPD file has
|
||||||
@@ -142,7 +142,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertFalse("tray_ids" in vals)
|
self.assertFalse("tray_ids" in vals)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
@mock.patch("os.unlink")
|
@mock.patch("os.unlink")
|
||||||
def test_prepare_update_from_cups_unlink_error(self, os_unlink, cups):
|
def test_prepare_update_from_cups_unlink_error(self, os_unlink, cups):
|
||||||
"""
|
"""
|
||||||
@@ -159,7 +159,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
with self.assertRaises(OSError):
|
with self.assertRaises(OSError):
|
||||||
self.printer._prepare_update_from_cups(connection, cups_printer)
|
self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
@mock.patch("os.unlink")
|
@mock.patch("os.unlink")
|
||||||
def test_prepare_update_from_cups_unlink_error_enoent(self, os_unlink, cups):
|
def test_prepare_update_from_cups_unlink_error_enoent(self, os_unlink, cups):
|
||||||
"""
|
"""
|
||||||
@@ -181,7 +181,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_prepare_update_from_cups(self, cups):
|
def test_prepare_update_from_cups(self, cups):
|
||||||
"""
|
"""
|
||||||
Check the return value when adding a single tray
|
Check the return value when adding a single tray
|
||||||
@@ -197,7 +197,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_prepare_update_from_cups_with_multiple_trays(self, cups):
|
def test_prepare_update_from_cups_with_multiple_trays(self, cups):
|
||||||
"""
|
"""
|
||||||
Check the return value when adding multiple trays at once
|
Check the return value when adding multiple trays at once
|
||||||
@@ -216,7 +216,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_prepare_update_from_cups_already_known_trays(self, cups):
|
def test_prepare_update_from_cups_already_known_trays(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that calling the method twice doesn't create the trays multiple
|
Check that calling the method twice doesn't create the trays multiple
|
||||||
@@ -236,7 +236,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % server_model)
|
@mock.patch(f"{server_model}.cups")
|
||||||
def test_prepare_update_from_cups_unknown_trays(self, cups):
|
def test_prepare_update_from_cups_unknown_trays(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that trays which are not in the PPD file are removed from Odoo
|
Check that trays which are not in the PPD file are removed from Odoo
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Copyright 2016 LasLabs Inc.
|
# Copyright 2016 LasLabs Inc.
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
@@ -36,7 +37,7 @@ class TestPrintingPrinterWizard(TransactionCase):
|
|||||||
"uri": self.printer_vals["device-uri"],
|
"uri": self.printer_vals["device-uri"],
|
||||||
}
|
}
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_action_ok_inits_connection(self, cups):
|
def test_action_ok_inits_connection(self, cups):
|
||||||
"""It should initialize CUPS connection"""
|
"""It should initialize CUPS connection"""
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
@@ -44,7 +45,7 @@ class TestPrintingPrinterWizard(TransactionCase):
|
|||||||
host=self.server.address, port=self.server.port
|
host=self.server.address, port=self.server.port
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_action_ok_gets_printers(self, cups):
|
def test_action_ok_gets_printers(self, cups):
|
||||||
"""It should get printers from CUPS"""
|
"""It should get printers from CUPS"""
|
||||||
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
||||||
@@ -52,14 +53,19 @@ class TestPrintingPrinterWizard(TransactionCase):
|
|||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
cups.Connection().getPrinters.assert_called_once_with()
|
cups.Connection().getPrinters.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
def test_action_ok_raises_warning_on_error(self):
|
||||||
def test_action_ok_raises_warning_on_error(self, cups):
|
|
||||||
"""It should raise Warning on any error"""
|
"""It should raise Warning on any error"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
cups.Connection.side_effect = StopTest
|
cups.Connection.side_effect = StopTest
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_action_ok_creates_new_printer(self, cups):
|
def test_action_ok_creates_new_printer(self, cups):
|
||||||
"""It should create new printer w/ proper vals"""
|
"""It should create new printer w/ proper vals"""
|
||||||
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
||||||
@@ -75,7 +81,7 @@ class TestPrintingPrinterWizard(TransactionCase):
|
|||||||
|
|
||||||
self.assertEqual(val, rec_id[key])
|
self.assertEqual(val, rec_id[key])
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_action_ok_skips_existing_printer(self, cups):
|
def test_action_ok_skips_existing_printer(self, cups):
|
||||||
"""It should not recreate existing printers"""
|
"""It should not recreate existing printers"""
|
||||||
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Copyright 2016 LasLabs Inc.
|
# Copyright 2016 LasLabs Inc.
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from odoo import fields
|
from odoo import fields
|
||||||
@@ -43,15 +44,20 @@ class TestPrintingServer(TransactionCase):
|
|||||||
values["printer_id"] = printer.id
|
values["printer_id"] = printer.id
|
||||||
return self.env["printing.job"].create(values)
|
return self.env["printing.job"].create(values)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
def test_update_printers_error(self):
|
||||||
def test_update_printers_error(self, cups):
|
|
||||||
"""It should catch any exception from CUPS and update status"""
|
"""It should catch any exception from CUPS and update status"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
rec_id = self.new_printer()
|
rec_id = self.new_printer()
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
self.assertEqual("server-error", rec_id.status)
|
self.assertEqual("server-error", rec_id.status)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_printers_inits_cups(self, cups):
|
def test_update_printers_inits_cups(self, cups):
|
||||||
"""It should init CUPS connection"""
|
"""It should init CUPS connection"""
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
@@ -60,29 +66,29 @@ class TestPrintingServer(TransactionCase):
|
|||||||
host=self.server.address, port=self.server.port
|
host=self.server.address, port=self.server.port
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_printers_gets_all_printers(self, cups):
|
def test_update_printers_gets_all_printers(self, cups):
|
||||||
"""It should get all printers from CUPS server"""
|
"""It should get all printers from CUPS server"""
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
cups.Connection().getPrinters.assert_called_once_with()
|
cups.Connection().getPrinters.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_printers_search(self, cups):
|
def test_update_printers_search(self, cups):
|
||||||
"""It should search all when no domain"""
|
"""It should search all when no domain"""
|
||||||
with mock.patch("%s.search" % model_base) as search:
|
with mock.patch(f"{model_base}.search") as search:
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
search.assert_called_once_with([])
|
search.assert_called_once_with([])
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_printers_search_domain(self, cups):
|
def test_update_printers_search_domain(self, cups):
|
||||||
"""It should use specific domain for search"""
|
"""It should use specific domain for search"""
|
||||||
with mock.patch("%s.search" % model_base) as search:
|
with mock.patch(f"{model_base}.search") as search:
|
||||||
expect = [("id", ">", 0)]
|
expect = [("id", ">", 0)]
|
||||||
self.Model.update_printers(expect)
|
self.Model.update_printers(expect)
|
||||||
search.assert_called_once_with(expect)
|
search.assert_called_once_with(expect)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_printers_update_unavailable(self, cups):
|
def test_update_printers_update_unavailable(self, cups):
|
||||||
"""It should update status when printer is unavailable"""
|
"""It should update status when printer is unavailable"""
|
||||||
rec_id = self.new_printer()
|
rec_id = self.new_printer()
|
||||||
@@ -90,7 +96,7 @@ class TestPrintingServer(TransactionCase):
|
|||||||
self.Model.action_update_printers()
|
self.Model.action_update_printers()
|
||||||
self.assertEqual("unavailable", rec_id.status)
|
self.assertEqual("unavailable", rec_id.status)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_archived_printers(self, cups):
|
def test_update_archived_printers(self, cups):
|
||||||
"""It should update status even if printer is archived"""
|
"""It should update status even if printer is archived"""
|
||||||
rec_id = self.new_printer()
|
rec_id = self.new_printer()
|
||||||
@@ -103,7 +109,7 @@ class TestPrintingServer(TransactionCase):
|
|||||||
rec_id.status,
|
rec_id.status,
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_jobs_cron(self, cups):
|
def test_update_jobs_cron(self, cups):
|
||||||
"""It should get all jobs from CUPS server"""
|
"""It should get all jobs from CUPS server"""
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
@@ -125,7 +131,7 @@ class TestPrintingServer(TransactionCase):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_jobs_button(self, cups):
|
def test_update_jobs_button(self, cups):
|
||||||
"""It should get all jobs from CUPS server"""
|
"""It should get all jobs from CUPS server"""
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
@@ -147,17 +153,22 @@ class TestPrintingServer(TransactionCase):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
def test_update_jobs_error(self):
|
||||||
def test_update_jobs_error(self, cups):
|
|
||||||
"""It should catch any exception from CUPS and update status"""
|
"""It should catch any exception from CUPS and update status"""
|
||||||
|
with (
|
||||||
|
mock.patch(f"{model}.cups") as cups,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.server.update_jobs()
|
self.server.update_jobs()
|
||||||
cups.Connection.assert_called_with(
|
cups.Connection.assert_called_with(
|
||||||
host=self.server.address, port=self.server.port
|
host=self.server.address, port=self.server.port
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 2)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_jobs_uncompleted(self, cups):
|
def test_update_jobs_uncompleted(self, cups):
|
||||||
"""
|
"""
|
||||||
It should search which jobs have been completed since last update
|
It should search which jobs have been completed since last update
|
||||||
@@ -182,7 +193,7 @@ class TestPrintingServer(TransactionCase):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch("%s.cups" % model)
|
@mock.patch(f"{model}.cups")
|
||||||
def test_update_jobs(self, cups):
|
def test_update_jobs(self, cups):
|
||||||
"""
|
"""
|
||||||
It should update all jobs, known or not
|
It should update all jobs, known or not
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# Copyright 2017 Tecnativa - Jairo Llopis
|
# Copyright 2017 Tecnativa - Jairo Llopis
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
from odoo import exceptions
|
from odoo import exceptions
|
||||||
@@ -128,11 +129,14 @@ class TestReport(common.HttpCase):
|
|||||||
|
|
||||||
def test_render_qweb_pdf_printable(self):
|
def test_render_qweb_pdf_printable(self):
|
||||||
"""It should print the report, only if it is printable"""
|
"""It should print the report, only if it is printable"""
|
||||||
with mock.patch(
|
with (
|
||||||
|
mock.patch(
|
||||||
"odoo.addons.base_report_to_printer.models."
|
"odoo.addons.base_report_to_printer.models."
|
||||||
"printing_printer.PrintingPrinter."
|
"printing_printer.PrintingPrinter."
|
||||||
"print_document"
|
"print_document"
|
||||||
) as print_document:
|
) as print_document,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.report.property_printing_action_id.action_type = "server"
|
self.report.property_printing_action_id.action_type = "server"
|
||||||
self.report.printing_printer_id = self.new_printer()
|
self.report.printing_printer_id = self.new_printer()
|
||||||
document = self.report._render_qweb_pdf(
|
document = self.report._render_qweb_pdf(
|
||||||
@@ -145,14 +149,19 @@ class TestReport(common.HttpCase):
|
|||||||
doc_format="qweb-pdf",
|
doc_format="qweb-pdf",
|
||||||
tray=False,
|
tray=False,
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_render_qweb_text_printable(self):
|
def test_render_qweb_text_printable(self):
|
||||||
"""It should print the report, only if it is printable"""
|
"""It should print the report, only if it is printable"""
|
||||||
with mock.patch(
|
with (
|
||||||
|
mock.patch(
|
||||||
"odoo.addons.base_report_to_printer.models."
|
"odoo.addons.base_report_to_printer.models."
|
||||||
"printing_printer.PrintingPrinter."
|
"printing_printer.PrintingPrinter."
|
||||||
"print_document"
|
"print_document"
|
||||||
) as print_document:
|
) as print_document,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.report_text.property_printing_action_id.action_type = "server"
|
self.report_text.property_printing_action_id.action_type = "server"
|
||||||
self.report_text.printing_printer_id = self.new_printer()
|
self.report_text.printing_printer_id = self.new_printer()
|
||||||
document = self.report_text._render_qweb_text(
|
document = self.report_text._render_qweb_text(
|
||||||
@@ -165,29 +174,41 @@ class TestReport(common.HttpCase):
|
|||||||
doc_format="qweb-text",
|
doc_format="qweb-text",
|
||||||
tray=False,
|
tray=False,
|
||||||
)
|
)
|
||||||
|
self.assertEqual(len(logs.records), 1)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_print_document_not_printable(self):
|
def test_print_document_not_printable(self):
|
||||||
"""It should print the report, regardless of the defined behaviour"""
|
"""It should print the report, regardless of the defined behaviour"""
|
||||||
self.report.printing_printer_id = self.new_printer()
|
self.report.printing_printer_id = self.new_printer()
|
||||||
with mock.patch(
|
with (
|
||||||
|
mock.patch(
|
||||||
"odoo.addons.base_report_to_printer.models."
|
"odoo.addons.base_report_to_printer.models."
|
||||||
"printing_printer.PrintingPrinter."
|
"printing_printer.PrintingPrinter."
|
||||||
"print_document"
|
"print_document"
|
||||||
) as print_document:
|
) as print_document,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.report.print_document(self.partners.ids)
|
self.report.print_document(self.partners.ids)
|
||||||
print_document.assert_called_once()
|
print_document.assert_called_once()
|
||||||
|
self.assertEqual(len(logs.records), 2)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_print_document_printable(self):
|
def test_print_document_printable(self):
|
||||||
"""It should print the report, regardless of the defined behaviour"""
|
"""It should print the report, regardless of the defined behaviour"""
|
||||||
self.report.property_printing_action_id.action_type = "server"
|
self.report.property_printing_action_id.action_type = "server"
|
||||||
self.report.printing_printer_id = self.new_printer()
|
self.report.printing_printer_id = self.new_printer()
|
||||||
with mock.patch(
|
with (
|
||||||
|
mock.patch(
|
||||||
"odoo.addons.base_report_to_printer.models."
|
"odoo.addons.base_report_to_printer.models."
|
||||||
"printing_printer.PrintingPrinter."
|
"printing_printer.PrintingPrinter."
|
||||||
"print_document"
|
"print_document"
|
||||||
) as print_document:
|
) as print_document,
|
||||||
|
self.assertLogs(level=logging.WARNING) as logs,
|
||||||
|
):
|
||||||
self.report.print_document(self.partners.ids)
|
self.report.print_document(self.partners.ids)
|
||||||
print_document.assert_called_once()
|
print_document.assert_called_once()
|
||||||
|
self.assertEqual(len(logs.records), 2)
|
||||||
|
self.assertEqual(logs.records[0].levelno, logging.WARNING)
|
||||||
|
|
||||||
def test_print_document_no_printer(self):
|
def test_print_document_no_printer(self):
|
||||||
"""It should raise an error"""
|
"""It should raise an error"""
|
||||||
|
|||||||
@@ -36,11 +36,11 @@
|
|||||||
<field name="name">printing.job.tree (in base_report_to_printer)</field>
|
<field name="name">printing.job.tree (in base_report_to_printer)</field>
|
||||||
<field name="model">printing.job</field>
|
<field name="model">printing.job</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree>
|
<list>
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="job_id_cups" />
|
<field name="job_id_cups" />
|
||||||
<field name="job_state" />
|
<field name="job_state" />
|
||||||
</tree>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
<field name="name">printing.printer.tree (in base_report_to_printer)</field>
|
<field name="name">printing.printer.tree (in base_report_to_printer)</field>
|
||||||
<field name="model">printing.printer</field>
|
<field name="model">printing.printer</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree
|
<list
|
||||||
decoration-success="status=='available'"
|
decoration-success="status=='available'"
|
||||||
decoration-warning="status=='printing'"
|
decoration-warning="status=='printing'"
|
||||||
decoration-danger="status not in ['printing', 'available']"
|
decoration-danger="status not in ['printing', 'available']"
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
<field name="system_name" />
|
<field name="system_name" />
|
||||||
<field name="server_id" />
|
<field name="server_id" />
|
||||||
<field name="status" />
|
<field name="status" />
|
||||||
</tree>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.ui.view" id="printing_printer_view_search">
|
<record model="ir.ui.view" id="printing_printer_view_search">
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
<field name="name">Show Printers</field>
|
<field name="name">Show Printers</field>
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">printing.printer</field>
|
<field name="res_model">printing.printer</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">list,form</field>
|
||||||
</record>
|
</record>
|
||||||
<menuitem
|
<menuitem
|
||||||
name="Printers"
|
name="Printers"
|
||||||
|
|||||||
@@ -21,12 +21,12 @@
|
|||||||
>printing.report.xml.action.tree (in base_report_to_printer)</field>
|
>printing.report.xml.action.tree (in base_report_to_printer)</field>
|
||||||
<field name="model">printing.report.xml.action</field>
|
<field name="model">printing.report.xml.action</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree>
|
<list>
|
||||||
<field name="user_id" />
|
<field name="user_id" />
|
||||||
<field name="action" />
|
<field name="action" />
|
||||||
<field name="printer_id" />
|
<field name="printer_id" />
|
||||||
<field name="printer_tray_id" />
|
<field name="printer_tray_id" />
|
||||||
</tree>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
<!-- Add a shorcut to "Actions/Report" in the Printing menu -->
|
<!-- Add a shorcut to "Actions/Report" in the Printing menu -->
|
||||||
|
|||||||
@@ -45,11 +45,11 @@
|
|||||||
<field name="name">printing.server.tree (in base_report_to_printer)</field>
|
<field name="name">printing.server.tree (in base_report_to_printer)</field>
|
||||||
<field name="model">printing.server</field>
|
<field name="model">printing.server</field>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<tree>
|
<list>
|
||||||
<field name="name" />
|
<field name="name" />
|
||||||
<field name="address" />
|
<field name="address" />
|
||||||
<field name="port" />
|
<field name="port" />
|
||||||
</tree>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
<record model="ir.ui.view" id="printing_server_view_search">
|
<record model="ir.ui.view" id="printing_server_view_search">
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<field name="name">Servers</field>
|
<field name="name">Servers</field>
|
||||||
<field name="type">ir.actions.act_window</field>
|
<field name="type">ir.actions.act_window</field>
|
||||||
<field name="res_model">printing.server</field>
|
<field name="res_model">printing.server</field>
|
||||||
<field name="view_mode">tree,form</field>
|
<field name="view_mode">list,form</field>
|
||||||
</record>
|
</record>
|
||||||
<menuitem
|
<menuitem
|
||||||
name="Servers"
|
name="Servers"
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
<group>
|
<group>
|
||||||
<field name="printer_id" />
|
<field name="printer_id" />
|
||||||
<field name="attachment_line_ids">
|
<field name="attachment_line_ids">
|
||||||
<tree editable="top">
|
<list editable="top">
|
||||||
<field name="attachment_id" create="0" />
|
<field name="attachment_id" create="0" />
|
||||||
<field name="record_name" />
|
<field name="record_name" />
|
||||||
<field name="copies" />
|
<field name="copies" />
|
||||||
</tree>
|
</list>
|
||||||
</field>
|
</field>
|
||||||
</group>
|
</group>
|
||||||
<footer>
|
<footer>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class PrintingPrinterUpdateWizard(models.TransientModel):
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"name": "Printers",
|
"name": "Printers",
|
||||||
"view_mode": "tree,form",
|
"view_mode": "list,form",
|
||||||
"res_model": "printing.printer",
|
"res_model": "printing.printer",
|
||||||
"type": "ir.actions.act_window",
|
"type": "ir.actions.act_window",
|
||||||
"target": "current",
|
"target": "current",
|
||||||
|
|||||||
Reference in New Issue
Block a user