From d724f69a1d3fd22bf2b20009877900c858f15d71 Mon Sep 17 00:00:00 2001 From: Laurent Smet Date: Wed, 1 Feb 2023 08:25:03 +0000 Subject: [PATCH] [FIX] web: Fix useless search_count with count_limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When count_limit is set and lower than the current number of fetched records, making an extra search_count is useless. closes odoo/odoo#111895 X-original-commit: 6f90d6924e24e700694111732ee85465f802b22f Signed-off-by: Rémy Voet --- addons/web/models/models.py | 8 ++++-- addons/web/tests/__init__.py | 1 + addons/web/tests/test_web_search_read.py | 36 ++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 addons/web/tests/test_web_search_read.py diff --git a/addons/web/models/models.py b/addons/web/models/models.py index 13507e54263..69f0374830d 100644 --- a/addons/web/models/models.py +++ b/addons/web/models/models.py @@ -57,10 +57,14 @@ class Base(models.AbstractModel): 'length': 0, 'records': [] } - if limit and (len(records) == limit or self.env.context.get('force_search_count')): + current_length = len(records) + offset + limit_reached = len(records) == limit + force_search_count = self._context.get('force_search_count') + count_limit_reached = count_limit and count_limit <= current_length + if limit and ((limit_reached and not count_limit_reached) or force_search_count): length = self.search_count(domain, limit=count_limit) else: - length = len(records) + offset + length = current_length return { 'length': length, 'records': records diff --git a/addons/web/tests/__init__.py b/addons/web/tests/__init__.py index 4995f496933..a285835440b 100644 --- a/addons/web/tests/__init__.py +++ b/addons/web/tests/__init__.py @@ -15,3 +15,4 @@ from . import test_read_progress_bar from . import test_assets from . import test_assets_xml from . import test_login +from . import test_web_search_read diff --git a/addons/web/tests/test_web_search_read.py b/addons/web/tests/test_web_search_read.py new file mode 100644 index 00000000000..613ee99c816 --- /dev/null +++ b/addons/web/tests/test_web_search_read.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from odoo.tests import common +from unittest.mock import patch + + +@common.tagged('post_install', '-at_install') +class TestWebSearchRead(common.TransactionCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.ResCurrency = cls.env['res.currency'].with_context(active_test=False) + cls.max = cls.ResCurrency.search_count([]) + + def assert_web_search_read(self, expected_length, expected_records_length, expected_search_count_called=True, **kwargs): + original_search_count = self.ResCurrency.search_count + search_count_called = [False] + + def search_count(obj, *method_args, **method_kwargs): + search_count_called[0] = True + return original_search_count(*method_args, **method_kwargs) + + with patch('odoo.addons.base.models.res_currency.Currency.search_count', new=search_count): + results = self.ResCurrency.web_search_read(domain=[], fields=['id'], **kwargs) + + self.assertEqual(results['length'], expected_length) + self.assertEqual(len(results['records']), expected_records_length) + self.assertEqual(search_count_called[0], expected_search_count_called) + + def test_web_search_read(self): + self.assert_web_search_read(self.max, self.max, expected_search_count_called=False) + self.assert_web_search_read(self.max, 2, limit=2) + self.assert_web_search_read(self.max, 2, limit=2, offset=10) + self.assert_web_search_read(2, 2, limit=2, count_limit=2, expected_search_count_called=False) + self.assert_web_search_read(20, 2, limit=2, offset=10, count_limit=20) + self.assert_web_search_read(12, 2, limit=2, offset=10, count_limit=12, expected_search_count_called=False)