From dd58993fc18060cef86f293f1143ddf109a0ed67 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Mon, 26 Jun 2023 23:33:04 +0200 Subject: [PATCH 1/3] [FIX] report_csv: Assign 'reportname' variable before accessing it --- report_csv/controllers/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/report_csv/controllers/main.py b/report_csv/controllers/main.py index 41f1bfbf55..19e9173570 100644 --- a/report_csv/controllers/main.py +++ b/report_csv/controllers/main.py @@ -54,6 +54,7 @@ def report_routes(self, reportname, docids=None, converter=None, **data): def report_download(self, data, context=None): requestcontent = json.loads(data) url, report_type = requestcontent[0], requestcontent[1] + reportname = "" try: if report_type == "csv": reportname = url.split("/report/csv/")[1].split("?")[0] From 8a7b3274cdd06e156815ac363339af49c0d286f4 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Tue, 27 Jun 2023 12:01:33 +0200 Subject: [PATCH 2/3] [FIX] report_csv: Return werkzeug Exception --- report_csv/controllers/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/report_csv/controllers/main.py b/report_csv/controllers/main.py index 19e9173570..ae956a6557 100644 --- a/report_csv/controllers/main.py +++ b/report_csv/controllers/main.py @@ -4,6 +4,7 @@ import json import logging +from werkzeug.exceptions import InternalServerError from werkzeug.urls import url_decode from odoo.http import ( @@ -103,4 +104,5 @@ def report_download(self, data, context=None): _logger.exception("Error while generating report %s", reportname) se = _serialize_exception(e) error = {"code": 200, "message": "Odoo Server Error", "data": se} - return request.make_response(html_escape(json.dumps(error))) + res = request.make_response(html_escape(json.dumps(error))) + raise InternalServerError(response=res) from e From e1430a7cf5f7143cf61a0d70e7a9769ea737ee74 Mon Sep 17 00:00:00 2001 From: Denis Roussel Date: Tue, 27 Jun 2023 15:24:46 +0200 Subject: [PATCH 3/3] [IMP] report_csv: Add controller tests --- report_csv/tests/test_report.py | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/report_csv/tests/test_report.py b/report_csv/tests/test_report.py index edce4e4db8..3436347f4c 100644 --- a/report_csv/tests/test_report.py +++ b/report_csv/tests/test_report.py @@ -1,9 +1,15 @@ # Copyright 2019 Creu Blanca # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +import json import logging from io import StringIO +from unittest import mock +from odoo import http from odoo.tests import common +from odoo.tools import mute_logger + +from odoo.addons.web.controllers.report import ReportController _logger = logging.getLogger(__name__) try: @@ -12,6 +18,14 @@ _logger.debug("Can not import csv.") +class TestCsvException(Exception): + def __init__(self, message): + """ + :param message: exception message and frontend modal content + """ + super().__init__(message) + + class TestReport(common.TransactionCase): def setUp(self): super().setUp() @@ -55,3 +69,49 @@ def test_id_retrieval(self): # Typical call from render objs = self.csv_report._get_objs_for_report(self.docs.ids, {}) self.assertEqual(objs, self.docs) + + +class TestCsvReport(common.HttpCase): + """ + Some tests calling controller + """ + + def setUp(self): + super().setUp() + self.report_object = self.env["ir.actions.report"] + self.csv_report = self.env["report.report_csv.abstract"].with_context( + active_model="res.partner" + ) + self.report_name = "report_csv.partner_csv" + self.report = self.report_object._get_report_from_name(self.report_name) + self.docs = self.env["res.company"].search([], limit=1).partner_id + self.session = self.authenticate("admin", "admin") + + def test_csv(self): + filename = self.get_report_headers().headers.get("Content-Disposition") + self.assertTrue(".csv" in filename) + + @mute_logger("odoo.addons.web.controllers.report") + def test_pdf_error(self): + with mock.patch.object( + ReportController, "report_routes" + ) as route_patch, self.assertLogs( + "odoo.addons.report_csv.controllers.main", level=logging.ERROR + ) as cm: + route_patch.side_effect = TestCsvException("Test") + self.get_report_headers( + suffix="/report/pdf/test/10", f_type="qweb-pdf" + ).headers.get("Content-Disposition") + [msg] = cm.output + self.assertIn("Error while generating report", msg) + + def get_report_headers( + self, suffix="/report/csv/report_csv.partner_csv/1", f_type="csv" + ): + return self.url_open( + url="/report/download", + data={ + "data": json.dumps([suffix, f_type]), + "csrf_token": http.Request.csrf_token(self), + }, + )