From 11fffbf9a40bb235bfbbcbf0a064b9ec4cef0717 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 23 Dec 2020 12:07:31 +0530 Subject: [PATCH] fix(minor): validate links in customize form --- frappe/core/doctype/doctype/doctype.py | 43 +++++++-------------- frappe/core/doctype/doctype/test_doctype.py | 18 ++++++--- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index 7c0c270277..2c6bf4d9e1 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -79,7 +79,7 @@ class DocType(Document): self.make_repeatable() self.validate_nestedset() self.validate_website() - self.validate_links_table_fieldnames() + validate_links_table_fieldnames(self) if not self.is_new(): self.before_update = frappe.get_doc('DocType', self.name) @@ -282,7 +282,6 @@ class DocType(Document): def on_update(self): """Update database schema, make controller templates if `custom` is not set and clear cache.""" - self.delete_duplicate_custom_fields() try: frappe.db.updatedb(self.name, Meta(self)) except Exception as e: @@ -321,18 +320,6 @@ class DocType(Document): clear_linked_doctype_cache() - def delete_duplicate_custom_fields(self): - if not (frappe.db.table_exists(self.name) and frappe.db.table_exists("Custom Field")): - return - - fields = [d.fieldname for d in self.fields if d.fieldtype in data_fieldtypes] - if fields: - frappe.db.sql('''delete from - `tabCustom Field` - where - dt = {0} and fieldname in ({1}) - '''.format('%s', ', '.join(['%s'] * len(fields))), tuple([self.name] + fields), as_dict=True) - def sync_global_search(self): '''If global search settings are changed, rebuild search properties for this table''' global_search_fields_before_update = [d.fieldname for d in @@ -666,24 +653,22 @@ class DocType(Document): if not re.match("^(?![\W])[^\d_\s][\w ]+$", name, **flags): frappe.throw(_("DocType's name should start with a letter and it can only consist of letters, numbers, spaces and underscores"), frappe.NameError) - def validate_links_table_fieldnames(self): - """Validate fieldnames in Links table""" - if frappe.flags.in_patch: return - if frappe.flags.in_fixtures: return - if not self.links: return - - for index, link in enumerate(self.links): - meta = frappe.get_meta(link.link_doctype) - if not meta.get_field(link.link_fieldname): - message = _("Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.link_fieldname), frappe.bold(link.link_doctype)) - frappe.throw(message, InvalidFieldNameError, _("Invalid Fieldname")) - +def validate_links_table_fieldnames(meta): + """Validate fieldnames in Links table""" + if frappe.flags.in_patch: return + if frappe.flags.in_fixtures: return + if not meta.links: return + for index, link in enumerate(meta.links): + link_meta = frappe.get_meta(link.link_doctype) + if not link_meta.get_field(link.link_fieldname): + message = _("Row #{0}: Could not find field {1} in {2} DocType").format(index+1, frappe.bold(link.link_fieldname), frappe.bold(link.link_doctype)) + frappe.throw(message, InvalidFieldNameError, _("Invalid Fieldname")) def validate_fields_for_doctype(doctype): - doc = frappe.get_doc("DocType", doctype) - doc.delete_duplicate_custom_fields() - validate_fields(frappe.get_meta(doctype, cached=False)) + meta = frappe.get_meta(doctype, cached=False) + validate_links_table_fieldnames(meta) + validate_fields(meta) # this is separate because it is also called via custom field def validate_fields(meta): diff --git a/frappe/core/doctype/doctype/test_doctype.py b/frappe/core/doctype/doctype/test_doctype.py index 10169073e5..047d1aa6e2 100644 --- a/frappe/core/doctype/doctype/test_doctype.py +++ b/frappe/core/doctype/doctype/test_doctype.py @@ -5,12 +5,18 @@ from __future__ import unicode_literals import frappe import unittest -from frappe.core.doctype.doctype.doctype import UniqueFieldnameError, IllegalMandatoryError, DoctypeLinkError, WrongOptionsDoctypeLinkError,\ - HiddenAndMandatoryWithoutDefaultError, CannotIndexedError, InvalidFieldNameError, CannotCreateStandardDoctypeError +from frappe.core.doctype.doctype.doctype import (UniqueFieldnameError, + IllegalMandatoryError, + DoctypeLinkError, + WrongOptionsDoctypeLinkError, + HiddenAndMandatoryWithoutDefaultError, + CannotIndexedError, + InvalidFieldNameError, + CannotCreateStandardDoctypeError, + validate_links_table_fieldnames) # test_records = frappe.get_test_records('DocType') - class TestDocType(unittest.TestCase): def test_validate_name(self): self.assertRaises(frappe.NameError, new_doctype("_Some DocType").insert) @@ -459,7 +465,7 @@ class TestDocType(unittest.TestCase): 'link_doctype': "User", 'link_fieldname': "first_name" }) - doc.validate_links_table_fieldnames() # no error + validate_links_table_fieldnames(doc) # no error doc.links = [] # reset links table # check invalid doctype @@ -467,7 +473,7 @@ class TestDocType(unittest.TestCase): 'link_doctype': "User2", 'link_fieldname': "first_name" }) - self.assertRaises(frappe.DoesNotExistError, doc.validate_links_table_fieldnames) + self.assertRaises(frappe.DoesNotExistError, validate_links_table_fieldnames, doc) doc.links = [] # reset links table # check invalid fieldname @@ -475,7 +481,7 @@ class TestDocType(unittest.TestCase): 'link_doctype': "User", 'link_fieldname': "a_field_that_does_not_exists" }) - self.assertRaises(InvalidFieldNameError, doc.validate_links_table_fieldnames) + self.assertRaises(InvalidFieldNameError, validate_links_table_fieldnames, doc) def new_doctype(name, unique=0, depends_on='', fields=None):