Merge pull request #13240 from codescientist703/link-field-fix

fix: added suitable filtering mechanism to link field
This commit is contained in:
gavin 2021-07-14 12:40:45 +05:30 committed by GitHub
commit f4d67d617b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 3 deletions

View file

@ -168,7 +168,18 @@ def search_widget(doctype, txt, query=None, searchfield=None, start=0,
strict=False)
if doctype in UNTRANSLATED_DOCTYPES:
values = tuple([v for v in list(values) if re.search(re.escape(txt)+".*", (_(v.name) if as_dict else _(v[0])), re.IGNORECASE)])
# Filtering the values array so that query is included in very element
values = (
v for v in values
if re.search(
f"{re.escape(txt)}.*", _(v.name if as_dict else v[0]), re.IGNORECASE
)
)
# Sorting the values array so that relevant results always come first
# This will first bring elements on top in which query is a prefix of element
# Then it will bring the rest of the elements and sort them in lexicographical order
values = sorted(values, key=lambda x: relevance_sorter(x, txt, as_dict))
# remove _relevance from results
if as_dict:
@ -208,6 +219,13 @@ def scrub_custom_query(query, key, txt):
query = query.replace('%s', ((txt or '') + '%'))
return query
def relevance_sorter(key, query, as_dict):
value = _(key.name if as_dict else key[0])
return (
value.lower().startswith(query.lower()) is not True,
value
)
@wrapt.decorator
def validate_and_sanitize_search_inputs(fn, instance, args, kwargs):
kwargs.update(dict(zip(fn.__code__.co_varnames, args)))

View file

@ -1,4 +1,4 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
import unittest
@ -6,7 +6,16 @@ import frappe
from frappe.desk.search import search_link
from frappe.desk.search import search_widget
class TestSearch(unittest.TestCase):
def setUp(self):
if self._testMethodName == "test_link_field_order":
setup_test_link_field_order(self)
def tearDown(self):
if self._testMethodName == "test_link_field_order":
teardown_test_link_field_order(self)
def test_search_field_sanitizer(self):
# pass
search_link('DocType', 'User', query=None, filters=None, page_length=20, searchfield='name')
@ -38,6 +47,18 @@ class TestSearch(unittest.TestCase):
search_link, 'DocType', 'Customer', query=None, filters=None,
page_length=20, searchfield=';')
def test_link_field_order(self):
# Making a request to the search_link with the tree doctype
search_link(doctype=self.tree_doctype_name, txt='all', query=None,
filters=None, page_length=20, searchfield=None)
result = frappe.response['results']
# Check whether the result is sorted or not
self.assertEquals(self.parent_doctype_name, result[0]['value'])
# Check whether searching for parent also list out children
self.assertEquals(len(result), len(self.child_doctypes_names) + 1)
#Search for the word "pay", part of the word "pays" (country) in french.
def test_link_search_in_foreign_language(self):
try:
@ -80,4 +101,58 @@ class TestSearch(unittest.TestCase):
@frappe.validate_and_sanitize_search_inputs
def get_data(doctype, txt, searchfield, start, page_len, filters):
return [doctype, txt, searchfield, start, page_len, filters]
return [doctype, txt, searchfield, start, page_len, filters]
def setup_test_link_field_order(TestCase):
TestCase.tree_doctype_name = 'Test Tree Order'
TestCase.child_doctype_list = []
TestCase.child_doctypes_names = ['USA', 'India', 'Russia', 'China']
TestCase.parent_doctype_name = 'All Territories'
# Create Tree doctype
TestCase.tree_doc = frappe.get_doc({
'doctype': 'DocType',
'name': TestCase.tree_doctype_name,
'module': 'Custom',
'custom': 1,
'is_tree': 1,
'autoname': 'field:random',
'fields': [{
'fieldname': 'random',
'label': 'Random',
'fieldtype': 'Data'
}]
}).insert()
TestCase.tree_doc.search_fields = 'parent_test_tree_order'
TestCase.tree_doc.save()
# Create root for the tree doctype
frappe.get_doc({
"doctype": TestCase.tree_doctype_name,
"random": TestCase.parent_doctype_name,
"is_group": 1
}).insert()
# Create children for the root
for child_name in TestCase.child_doctypes_names:
temp = frappe.get_doc({
"doctype": TestCase.tree_doctype_name,
"random": child_name,
"parent_test_tree_order": TestCase.parent_doctype_name
}).insert()
TestCase.child_doctype_list.append(temp)
def teardown_test_link_field_order(TestCase):
# Deleting all the created doctype
for child_doctype in TestCase.child_doctype_list:
child_doctype.delete()
frappe.delete_doc(
TestCase.tree_doctype_name,
TestCase.parent_doctype_name,
ignore_permissions=True,
force=True,
for_reload=True,
)
TestCase.tree_doc.delete()