# Copyright 2016 ForgeFlow S.L. # Copyright 2016 Serpent Consulting Services Pvt. Ltd. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo.osv import expression from odoo.tools.sql import SQL from odoo.addons.base.tests.common import BaseCommon class QueryGenerationCase(BaseCommon): @classmethod def setUpClass(self): super().setUpClass() self.ResPartner = self.env["res.partner"] self.TrgmIndex = self.env["trgm.index"] self.ResPartnerCategory = self.env["res.partner.category"] def test_fuzzy_where_generation(self): """Check the generation of the where clause.""" # the added fuzzy search operator should be available in the allowed # operators self.assertIn("%", expression.TERM_OPERATORS) self.assertEqual(SQL("%%"), expression.SQL_OPERATORS["%"]) # create new query with fuzzy search operator query = self.ResPartner._where_calc([("name", "%", "test")], active_test=False) from_clause = query.from_clause.code where_clause = query.where_clause.code where_clause_params = query.where_clause.params # the % parameter has to be escaped (%%) for the string replation self.assertEqual(where_clause, """("res_partner"."name" %% %s)""") # test the right sql query statement creation # now there should be only one '%' complete_where = self.env.cr.mogrify( f"SELECT FROM {from_clause} WHERE {where_clause}", where_clause_params, ) self.assertEqual( complete_where, b'SELECT FROM "res_partner" WHERE ' b'("res_partner"."name" % \'test\')', ) def test_fuzzy_where_generation_translatable(self): """Check the generation of the where clause for translatable fields.""" # create new query with fuzzy search operator query = self.ResPartnerCategory.with_context(lang="en_US")._where_calc( [("name", "%", "Goschaeftlic")], active_test=False ) from_clause = query.from_clause.code where_clause = query.where_clause.code where_clause_params = query.where_clause.params # the % parameter has to be escaped (%%) for the string replation self.assertIn( """("res_partner_category"."name"->>%s %% %s)""", where_clause, ) self.assertEqual( ["en_US", "Goschaeftlic"], where_clause_params, ) complete_where = self.env.cr.mogrify( f"SELECT FROM {from_clause} WHERE {where_clause}", where_clause_params, ) self.assertIn( b'SELECT FROM "res_partner_category" WHERE ("res_partner_category"."name"->>\'en_US\' % \'Goschaeftlic\')', # noqa complete_where, ) def test_fuzzy_search(self): """Test the fuzzy search itself.""" if self.TrgmIndex._trgm_extension_exists() != "installed": return if not self.TrgmIndex.index_exists("res.partner", "name"): field_partner_name = self.env.ref("base.field_res_partner__name") self.TrgmIndex.create( {"field_id": field_partner_name.id, "index_type": "gin"} ) partner1, partner2, partner3 = self.ResPartner.create( [{"name": "John Smith"}, {"name": "John Smizz"}, {"name": "Linus Torvalds"}] ) res = self.ResPartner.search([("name", "%", "Jon Smith")]) self.assertIn(partner1.id, res.ids) self.assertIn(partner2.id, res.ids) self.assertNotIn(partner3.id, res.ids) res = self.ResPartner.search([("name", "%", "Smith John")]) self.assertIn(partner1.id, res.ids) self.assertIn(partner2.id, res.ids) self.assertNotIn(partner3.id, res.ids)