From f7a0bf08bb1c1cbb5afcf593c5ba32f311ac371a Mon Sep 17 00:00:00 2001 From: Laurent Mignon Date: Tue, 4 Oct 2016 16:39:50 +0200 Subject: [PATCH] Add simple tests and fix call to fusion server --- report_py3o/__openerp__.py | 2 +- report_py3o/demo/.~lock.res_user.odt# | 1 + report_py3o/demo/report_py3o.xml | 28 ++++++++++++++++++++++++++ report_py3o/demo/res_user.odt | Bin 0 -> 8671 bytes report_py3o/i18n/fr.po | 2 +- report_py3o/models/ir_report.py | 16 +++++++-------- report_py3o/py3o_parser.py | 13 ++++++------ report_py3o/tests/__init__.py | 1 + report_py3o/tests/test_report_py3o.py | 27 +++++++++++++++++++++++++ report_py3o/views/ir_report.xml | 2 +- 10 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 report_py3o/demo/.~lock.res_user.odt# create mode 100644 report_py3o/demo/report_py3o.xml create mode 100644 report_py3o/demo/res_user.odt create mode 100644 report_py3o/tests/__init__.py create mode 100644 report_py3o/tests/test_report_py3o.py diff --git a/report_py3o/__openerp__.py b/report_py3o/__openerp__.py index b5b8d052..e86cc6fa 100644 --- a/report_py3o/__openerp__.py +++ b/report_py3o/__openerp__.py @@ -24,11 +24,11 @@ The py3o.template package is required; install it with: }, 'data': [ 'security/ir.model.access.csv', - 'views/menu.xml', 'views/py3o_template.xml', 'views/py3o_server.xml', 'views/ir_report.xml', + 'demo/report_py3o.xml', ], 'installable': True, } diff --git a/report_py3o/demo/.~lock.res_user.odt# b/report_py3o/demo/.~lock.res_user.odt# new file mode 100644 index 00000000..3f8e53eb --- /dev/null +++ b/report_py3o/demo/.~lock.res_user.odt# @@ -0,0 +1 @@ +,lmi,nbacsonelmi,04.10.2016 15:56,file:///home/lmi/.config/libreoffice/4; \ No newline at end of file diff --git a/report_py3o/demo/report_py3o.xml b/report_py3o/demo/report_py3o.xml new file mode 100644 index 00000000..b57342f1 --- /dev/null +++ b/report_py3o/demo/report_py3o.xml @@ -0,0 +1,28 @@ + + + + + + + Py3o Demo Report + ir.actions.report.xml + res.users + py3o_user_info + py3o + odt + + odt + report_py3o + demo/res_user.odt + + + + + + res.users + Py3o Demo Report + + + + diff --git a/report_py3o/demo/res_user.odt b/report_py3o/demo/res_user.odt new file mode 100644 index 0000000000000000000000000000000000000000..f0d66bb89cedef8090f8e9848f09df270517f5c2 GIT binary patch literal 8671 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 literal 0 HcmV?d00001 diff --git a/report_py3o/i18n/fr.po b/report_py3o/i18n/fr.po index 39653c67..171e2e55 100644 --- a/report_py3o/i18n/fr.po +++ b/report_py3o/i18n/fr.po @@ -102,7 +102,7 @@ msgid "No Py3o server configuration found" msgstr "Pas de configuration trouvée du serveur Py3o" #. module: report_py3o -#: field:ir.actions.report.xml,py3o_fusion_filetype:0 +#: field:ir.actions.report.xml,py3o_filetype:0 msgid "Output Format" msgstr "Format de sortie" diff --git a/report_py3o/models/ir_report.py b/report_py3o/models/ir_report.py index 7c9686c7..418b7105 100644 --- a/report_py3o/models/ir_report.py +++ b/report_py3o/models/ir_report.py @@ -19,17 +19,17 @@ class ReportXml(models.Model): _inherit = 'ir.actions.report.xml' @api.one - @api.constrains("py3o_fusion_filetype", "report_type") - def _check_py3o_fusion_filetype(self): - if self.report_type == "py3o" and not self.py3o_fusion_filetype: + @api.constrains("py3o_filetype", "report_type") + def _check_py3o_filetype(self): + if self.report_type == "py3o" and not self.py3o_filetype: raise ValidationError( "Field 'Output Format' is required for Py3O report") @api.one @api.constrains("py3o_is_local_fusion", "py3o_server_id", - "py3o_fusion_filetype") + "py3o_filetype") def _check_py3o_server_id(self): - is_native = Formats().get_format(self.py3o_fusion_filetype) + is_native = Formats().get_format(self.py3o_filetype) if ((not is_native or not self.py3o_is_local_fusion) and not self.py3o_server_id): raise ValidationError( @@ -37,7 +37,7 @@ class ReportXml(models.Model): "Please specify a Fusion Server") @api.model - def _get_py3o_fusion_filetypes(self): + def _get_py3o_filetypes(self): formats = Formats() names = formats.get_known_format_names() selections = [] @@ -48,8 +48,8 @@ class ReportXml(models.Model): selections.append((name, description)) return selections - py3o_fusion_filetype = fields.Selection( - selection="_get_py3o_fusion_filetypes", + py3o_filetype = fields.Selection( + selection="_get_py3o_filetypes", string="Output Format") py3o_template_id = fields.Many2one( 'py3o.template', diff --git a/report_py3o/py3o_parser.py b/report_py3o/py3o_parser.py index f3e9c687..b3f4380d 100644 --- a/report_py3o/py3o_parser.py +++ b/report_py3o/py3o_parser.py @@ -143,26 +143,27 @@ class Py3oParser(report_sxw): localcontext = parser_instance.localcontext if report_xml.py3o_is_local_fusion: template.render(localcontext) - input = out_stream.getvalue() + in_stream = out_stream + datadict = {} else: expressions = template.get_all_user_python_expression() py_expression = template.convert_py3o_to_python_ast(expressions) convertor = Py3oConvertor() data_struct = convertor(py_expression) - input = data_struct.render(localcontext) + datadict = data_struct.render(localcontext) - filetype = report_xml.py3o_fusion_filetype + filetype = report_xml.py3o_filetype is_native = Formats().get_format(filetype).native if is_native: - res = input + res = out_stream.getvalue() else: # Call py3o.server to render the template in the desired format in_stream.seek(0) files = { 'tmpl_file': in_stream, } fields = { - "targetformat": filetype.fusion_ext, - "datadict": json.dumps(input), + "targetformat": filetype, + "datadict": json.dumps(datadict), "image_mapping": "{}", } r = requests.post( diff --git a/report_py3o/tests/__init__.py b/report_py3o/tests/__init__.py new file mode 100644 index 00000000..13bc3247 --- /dev/null +++ b/report_py3o/tests/__init__.py @@ -0,0 +1 @@ +from . import test_report_py3o diff --git a/report_py3o/tests/test_report_py3o.py b/report_py3o/tests/test_report_py3o.py new file mode 100644 index 00000000..c8afa04a --- /dev/null +++ b/report_py3o/tests/test_report_py3o.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).). + + +import mock + +from openerp.tests.common import TransactionCase +import openerp.tests + + +@openerp.tests.common.at_install(False) +@openerp.tests.common.post_install(True) +class TestReportPy3o(TransactionCase): + + def test_reports(self): + domain = [('report_type', '=', 'py3o'), + ('report_name', '=', 'py3o_user_info')] + reports = self.env['ir.actions.report.xml'].search(domain) + self.assertEqual(1, len(reports)) + for r in reports: + with mock.patch('openerp.addons.report_py3o.py3o_parser.' + 'Py3oParser.create_single_pdf') as patched_pdf: + r.render_report(self.env.user.ids, + r.report_name, + {}) + self.assertEqual(1, patched_pdf.call_count) diff --git a/report_py3o/views/ir_report.xml b/report_py3o/views/ir_report.xml index e3469464..f06b4468 100644 --- a/report_py3o/views/ir_report.xml +++ b/report_py3o/views/ir_report.xml @@ -14,7 +14,7 @@ attrs="{'invisible': [('report_type', '!=', 'py3o')]}"> - +