Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

244 righe
6.7 KiB

  1. # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
  2. from unittest.mock import patch
  3. import frappe
  4. from frappe.tests.utils import FrappeTestCase
  5. class TestClient(FrappeTestCase):
  6. def test_set_value(self):
  7. todo = frappe.get_doc(dict(doctype="ToDo", description="test")).insert()
  8. frappe.set_value("ToDo", todo.name, "description", "test 1")
  9. self.assertEqual(frappe.get_value("ToDo", todo.name, "description"), "test 1")
  10. frappe.set_value("ToDo", todo.name, {"description": "test 2"})
  11. self.assertEqual(frappe.get_value("ToDo", todo.name, "description"), "test 2")
  12. def test_delete(self):
  13. from frappe.client import delete
  14. from frappe.desk.doctype.note.note import Note
  15. note = frappe.get_doc(
  16. doctype="Note",
  17. title=frappe.generate_hash(length=8),
  18. content="test",
  19. seen_by=[{"user": "Administrator"}],
  20. ).insert()
  21. child_row_name = note.seen_by[0].name
  22. with patch.object(Note, "save") as save:
  23. delete("Note Seen By", child_row_name)
  24. save.assert_called()
  25. delete("Note", note.name)
  26. self.assertFalse(frappe.db.exists("Note", note.name))
  27. self.assertRaises(frappe.DoesNotExistError, delete, "Note", note.name)
  28. self.assertRaises(frappe.DoesNotExistError, delete, "Note Seen By", child_row_name)
  29. def test_http_valid_method_access(self):
  30. from frappe.client import delete
  31. from frappe.handler import execute_cmd
  32. frappe.set_user("Administrator")
  33. frappe.local.request = frappe._dict()
  34. frappe.local.request.method = "POST"
  35. frappe.local.form_dict = frappe._dict(
  36. {"doc": dict(doctype="ToDo", description="Valid http method"), "cmd": "frappe.client.save"}
  37. )
  38. todo = execute_cmd("frappe.client.save")
  39. self.assertEqual(todo.get("description"), "Valid http method")
  40. delete("ToDo", todo.name)
  41. def test_http_invalid_method_access(self):
  42. from frappe.handler import execute_cmd
  43. frappe.set_user("Administrator")
  44. frappe.local.request = frappe._dict()
  45. frappe.local.request.method = "GET"
  46. frappe.local.form_dict = frappe._dict(
  47. {"doc": dict(doctype="ToDo", description="Invalid http method"), "cmd": "frappe.client.save"}
  48. )
  49. self.assertRaises(frappe.PermissionError, execute_cmd, "frappe.client.save")
  50. def test_run_doc_method(self):
  51. from frappe.handler import execute_cmd
  52. if not frappe.db.exists("Report", "Test Run Doc Method"):
  53. report = frappe.get_doc(
  54. {
  55. "doctype": "Report",
  56. "ref_doctype": "User",
  57. "report_name": "Test Run Doc Method",
  58. "report_type": "Query Report",
  59. "is_standard": "No",
  60. "roles": [{"role": "System Manager"}],
  61. }
  62. ).insert()
  63. else:
  64. report = frappe.get_doc("Report", "Test Run Doc Method")
  65. frappe.local.request = frappe._dict()
  66. frappe.local.request.method = "GET"
  67. # Whitelisted, works as expected
  68. frappe.local.form_dict = frappe._dict(
  69. {
  70. "dt": report.doctype,
  71. "dn": report.name,
  72. "method": "toggle_disable",
  73. "cmd": "run_doc_method",
  74. "args": 0,
  75. }
  76. )
  77. execute_cmd(frappe.local.form_dict.cmd)
  78. # Not whitelisted, throws permission error
  79. frappe.local.form_dict = frappe._dict(
  80. {
  81. "dt": report.doctype,
  82. "dn": report.name,
  83. "method": "create_report_py",
  84. "cmd": "run_doc_method",
  85. "args": 0,
  86. }
  87. )
  88. self.assertRaises(frappe.PermissionError, execute_cmd, frappe.local.form_dict.cmd)
  89. def test_array_values_in_request_args(self):
  90. import requests
  91. from frappe.auth import CookieManager, LoginManager
  92. frappe.utils.set_request(path="/")
  93. frappe.local.cookie_manager = CookieManager()
  94. frappe.local.login_manager = LoginManager()
  95. frappe.local.login_manager.login_as("Administrator")
  96. params = {
  97. "doctype": "DocType",
  98. "fields": ["name", "modified"],
  99. "sid": frappe.session.sid,
  100. }
  101. headers = {
  102. "accept": "application/json",
  103. "content-type": "application/json",
  104. }
  105. url = (
  106. f"http://{frappe.local.site}:{frappe.conf.webserver_port}/api/method/frappe.client.get_list"
  107. )
  108. res = requests.post(url, json=params, headers=headers)
  109. self.assertEqual(res.status_code, 200)
  110. data = res.json()
  111. first_item = data["message"][0]
  112. self.assertTrue("name" in first_item)
  113. self.assertTrue("modified" in first_item)
  114. frappe.local.login_manager.logout()
  115. def test_client_get(self):
  116. from frappe.client import get
  117. todo = frappe.get_doc(doctype="ToDo", description="test").insert()
  118. filters = {"name": todo.name}
  119. filters_json = frappe.as_json(filters)
  120. self.assertEqual(get("ToDo", filters=filters).description, "test")
  121. self.assertEqual(get("ToDo", filters=filters_json).description, "test")
  122. self.assertEqual(get("System Settings", "", "").doctype, "System Settings")
  123. self.assertEqual(get("ToDo", filters={}), get("ToDo", filters="{}"))
  124. todo.delete()
  125. def test_client_insert(self):
  126. from frappe.client import insert
  127. def get_random_title():
  128. return f"test-{frappe.generate_hash()}"
  129. # test insert dict
  130. doc = {"doctype": "Note", "title": get_random_title(), "content": "test"}
  131. note1 = insert(doc)
  132. self.assertTrue(note1)
  133. # test insert json
  134. doc["title"] = get_random_title()
  135. json_doc = frappe.as_json(doc)
  136. note2 = insert(json_doc)
  137. self.assertTrue(note2)
  138. # test insert child doc without parent fields
  139. child_doc = {"doctype": "Note Seen By", "user": "Administrator"}
  140. with self.assertRaises(frappe.ValidationError):
  141. insert(child_doc)
  142. # test insert child doc with parent fields
  143. child_doc = {
  144. "doctype": "Note Seen By",
  145. "user": "Administrator",
  146. "parenttype": "Note",
  147. "parent": note1.name,
  148. "parentfield": "seen_by",
  149. }
  150. note3 = insert(child_doc)
  151. self.assertTrue(note3)
  152. # cleanup
  153. frappe.delete_doc("Note", note1.name)
  154. frappe.delete_doc("Note", note2.name)
  155. def test_client_insert_many(self):
  156. from frappe.client import insert, insert_many
  157. def get_random_title():
  158. return f"test-{frappe.generate_hash(length=5)}"
  159. # insert a (parent) doc
  160. note1 = {"doctype": "Note", "title": get_random_title(), "content": "test"}
  161. note1 = insert(note1)
  162. doc_list = [
  163. {
  164. "doctype": "Note Seen By",
  165. "user": "Administrator",
  166. "parenttype": "Note",
  167. "parent": note1.name,
  168. "parentfield": "seen_by",
  169. },
  170. {
  171. "doctype": "Note Seen By",
  172. "user": "Administrator",
  173. "parenttype": "Note",
  174. "parent": note1.name,
  175. "parentfield": "seen_by",
  176. },
  177. {
  178. "doctype": "Note Seen By",
  179. "user": "Administrator",
  180. "parenttype": "Note",
  181. "parent": note1.name,
  182. "parentfield": "seen_by",
  183. },
  184. {"doctype": "Note", "title": get_random_title(), "content": "test"},
  185. {"doctype": "Note", "title": get_random_title(), "content": "test"},
  186. ]
  187. # insert all docs
  188. docs = insert_many(doc_list)
  189. # make sure only 1 name is returned for the parent upon insertion of child docs
  190. self.assertEqual(len(docs), 3)
  191. self.assertIn(note1.name, docs)
  192. # cleanup
  193. for doc in docs:
  194. frappe.delete_doc("Note", doc)