選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

159 行
5.4 KiB

  1. # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
  2. # MIT License. See license.txt
  3. import unittest
  4. import frappe
  5. from frappe.desk.search import search_link
  6. from frappe.desk.search import search_widget
  7. class TestSearch(unittest.TestCase):
  8. def setUp(self):
  9. if self._testMethodName == "test_link_field_order":
  10. setup_test_link_field_order(self)
  11. def tearDown(self):
  12. if self._testMethodName == "test_link_field_order":
  13. teardown_test_link_field_order(self)
  14. def test_search_field_sanitizer(self):
  15. # pass
  16. search_link('DocType', 'User', query=None, filters=None, page_length=20, searchfield='name')
  17. result = frappe.response['results'][0]
  18. self.assertTrue('User' in result['value'])
  19. #raise exception on injection
  20. self.assertRaises(frappe.DataError,
  21. search_link, 'DocType', 'Customer', query=None, filters=None,
  22. page_length=20, searchfield='1=1')
  23. self.assertRaises(frappe.DataError,
  24. search_link, 'DocType', 'Customer', query=None, filters=None,
  25. page_length=20, searchfield='select * from tabSessions) --')
  26. self.assertRaises(frappe.DataError,
  27. search_link, 'DocType', 'Customer', query=None, filters=None,
  28. page_length=20, searchfield='name or (select * from tabSessions)')
  29. self.assertRaises(frappe.DataError,
  30. search_link, 'DocType', 'Customer', query=None, filters=None,
  31. page_length=20, searchfield='*')
  32. self.assertRaises(frappe.DataError,
  33. search_link, 'DocType', 'Customer', query=None, filters=None,
  34. page_length=20, searchfield=';')
  35. self.assertRaises(frappe.DataError,
  36. search_link, 'DocType', 'Customer', query=None, filters=None,
  37. page_length=20, searchfield=';')
  38. def test_link_field_order(self):
  39. # Making a request to the search_link with the tree doctype
  40. search_link(doctype=self.tree_doctype_name, txt='all', query=None,
  41. filters=None, page_length=20, searchfield=None)
  42. result = frappe.response['results']
  43. # Check whether the result is sorted or not
  44. self.assertEquals(self.parent_doctype_name, result[0]['value'])
  45. # Check whether searching for parent also list out children
  46. self.assertEquals(len(result), len(self.child_doctypes_names) + 1)
  47. #Search for the word "pay", part of the word "pays" (country) in french.
  48. def test_link_search_in_foreign_language(self):
  49. try:
  50. frappe.local.lang = 'fr'
  51. search_widget(doctype="DocType", txt="pay", page_length=20)
  52. output = frappe.response["values"]
  53. result = [['found' for x in y if x=="Country"] for y in output]
  54. self.assertTrue(['found'] in result)
  55. finally:
  56. frappe.local.lang = 'en'
  57. def test_validate_and_sanitize_search_inputs(self):
  58. # should raise error if searchfield is injectable
  59. self.assertRaises(frappe.DataError,
  60. get_data, *('User', 'Random', 'select * from tabSessions) --', '1', '10', dict()))
  61. # page_len and start should be converted to int
  62. self.assertListEqual(get_data('User', 'Random', 'email', 'name or (select * from tabSessions)', '10', dict()),
  63. ['User', 'Random', 'email', 0, 10, {}])
  64. self.assertListEqual(get_data('User', 'Random', 'email', page_len='2', start='10', filters=dict()),
  65. ['User', 'Random', 'email', 10, 2, {}])
  66. # DocType can be passed as None which should be accepted
  67. self.assertListEqual(get_data(None, 'Random', 'email', '2', '10', dict()),
  68. [None, 'Random', 'email', 2, 10, {}])
  69. # return empty string if passed doctype is invalid
  70. self.assertListEqual(get_data("Random DocType", 'Random', 'email', '2', '10', dict()), [])
  71. # should not fail if function is called via frappe.call with extra arguments
  72. args = ("Random DocType", 'Random', 'email', '2', '10', dict())
  73. kwargs = {'as_dict': False}
  74. self.assertListEqual(frappe.call('frappe.tests.test_search.get_data', *args, **kwargs), [])
  75. # should not fail if query has @ symbol in it
  76. search_link('User', 'user@random', searchfield='name')
  77. self.assertListEqual(frappe.response['results'], [])
  78. @frappe.validate_and_sanitize_search_inputs
  79. def get_data(doctype, txt, searchfield, start, page_len, filters):
  80. return [doctype, txt, searchfield, start, page_len, filters]
  81. def setup_test_link_field_order(TestCase):
  82. TestCase.tree_doctype_name = 'Test Tree Order'
  83. TestCase.child_doctype_list = []
  84. TestCase.child_doctypes_names = ['USA', 'India', 'Russia', 'China']
  85. TestCase.parent_doctype_name = 'All Territories'
  86. # Create Tree doctype
  87. TestCase.tree_doc = frappe.get_doc({
  88. 'doctype': 'DocType',
  89. 'name': TestCase.tree_doctype_name,
  90. 'module': 'Custom',
  91. 'custom': 1,
  92. 'is_tree': 1,
  93. 'autoname': 'field:random',
  94. 'fields': [{
  95. 'fieldname': 'random',
  96. 'label': 'Random',
  97. 'fieldtype': 'Data'
  98. }]
  99. }).insert()
  100. TestCase.tree_doc.search_fields = 'parent_test_tree_order'
  101. TestCase.tree_doc.save()
  102. # Create root for the tree doctype
  103. frappe.get_doc({
  104. "doctype": TestCase.tree_doctype_name,
  105. "random": TestCase.parent_doctype_name,
  106. "is_group": 1
  107. }).insert()
  108. # Create children for the root
  109. for child_name in TestCase.child_doctypes_names:
  110. temp = frappe.get_doc({
  111. "doctype": TestCase.tree_doctype_name,
  112. "random": child_name,
  113. "parent_test_tree_order": TestCase.parent_doctype_name
  114. }).insert()
  115. TestCase.child_doctype_list.append(temp)
  116. def teardown_test_link_field_order(TestCase):
  117. # Deleting all the created doctype
  118. for child_doctype in TestCase.child_doctype_list:
  119. child_doctype.delete()
  120. frappe.delete_doc(
  121. TestCase.tree_doctype_name,
  122. TestCase.parent_doctype_name,
  123. ignore_permissions=True,
  124. force=True,
  125. for_reload=True,
  126. )
  127. TestCase.tree_doc.delete()