From 95816f03408fe85059a7d1b665853cb33229e179 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 23 Apr 2022 17:59:54 +0530 Subject: [PATCH] fix: better validation for child insert --- frappe/client.py | 5 ++++- frappe/tests/test_client.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/frappe/client.py b/frappe/client.py index a8223cdeee..1bad2bed2f 100644 --- a/frappe/client.py +++ b/frappe/client.py @@ -189,7 +189,10 @@ def insert(doc=None): if isinstance(doc, str): doc = json.loads(doc) - if doc.get("parenttype"): + doc = frappe._dict(doc) + if frappe.is_table(doc.doctype): + if not (doc.parenttype and doc.parent and doc.parentfield): + frappe.throw(_("parenttype, parent and parentfield are required to insert a child record")) # inserting a child record parent = frappe.get_doc(doc.parenttype, doc.parent) parent.append(doc.parentfield, doc) diff --git a/frappe/tests/test_client.py b/frappe/tests/test_client.py index c86c482651..677f59a366 100644 --- a/frappe/tests/test_client.py +++ b/frappe/tests/test_client.py @@ -141,3 +141,40 @@ class TestClient(unittest.TestCase): self.assertEqual(get("ToDo", filters=filters_json).description, "test") todo.delete() + + def test_client_insert(self): + from frappe.client import insert + + def get_random_title(): + return "test-{0}".format(frappe.generate_hash()) + + # test insert dict + doc = {"doctype": "Note", "title": get_random_title(), "content": "test"} + note1 = insert(doc) + self.assertTrue(note1) + + # test insert json + doc["title"] = get_random_title() + json_doc = frappe.as_json(doc) + note2 = insert(json_doc) + self.assertTrue(note2) + + # test insert child doc without parent fields + child_doc = {"doctype": "Note Seen By", "user": "Administrator"} + with self.assertRaises(frappe.ValidationError): + insert(child_doc) + + # test insert child doc with parent fields + child_doc = { + "doctype": "Note Seen By", + "user": "Administrator", + "parenttype": "Note", + "parent": note1.name, + "parentfield": "seen_by", + } + note3 = insert(child_doc) + self.assertTrue(note3) + + # cleanup + frappe.delete_doc("Note", note1.name) + frappe.delete_doc("Note", note2.name)