From a0a959d94ed14c4dffa1965aed7cfb27aa50acb4 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 15 Apr 2019 17:23:45 +0530 Subject: [PATCH 01/20] feat: add a is default field in user permission --- .../user_permission/user_permission.json | 76 ++++++++++++++++++- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.json b/frappe/core/doctype/user_permission/user_permission.json index c2ea05e731..50c253aeae 100644 --- a/frappe/core/doctype/user_permission/user_permission.json +++ b/frappe/core/doctype/user_permission/user_permission.json @@ -20,6 +20,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "user", "fieldtype": "Link", "hidden": 0, @@ -53,6 +54,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "allow", "fieldtype": "Link", "hidden": 0, @@ -86,6 +88,39 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, + "fieldname": "column_break_3", + "fieldtype": "Column Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, "fieldname": "for_value", "fieldtype": "Dynamic Link", "hidden": 0, @@ -119,6 +154,40 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, + "fieldname": "is_default", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "is default", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, "fieldname": "advanced_control_section", "fieldtype": "Section Break", "hidden": 0, @@ -152,6 +221,7 @@ "collapsible": 0, "columns": 0, "default": "1", + "fetch_if_empty": 0, "fieldname": "apply_to_all_doctypes", "fieldtype": "Check", "hidden": 0, @@ -185,6 +255,7 @@ "collapsible": 0, "columns": 0, "depends_on": "eval:!doc.apply_to_all_doctypes", + "fetch_if_empty": 0, "fieldname": "applicable_for", "fieldtype": "Link", "hidden": 0, @@ -213,16 +284,14 @@ } ], "has_web_view": 0, - "hide_heading": 0, "hide_toolbar": 0, "idx": 0, - "image_view": 0, "in_create": 0, "is_submittable": 0, "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-02-13 22:58:27.428741", + "modified": "2019-04-13 17:27:22.420985", "modified_by": "Administrator", "module": "Core", "name": "User Permission", @@ -251,7 +320,6 @@ ], "quick_entry": 0, "read_only": 0, - "read_only_onload": 0, "show_name_in_global_search": 0, "sort_field": "modified", "sort_order": "DESC", From aa849109461f34ee8be27b3b58f9f33d3abf76d5 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 15 Apr 2019 17:24:41 +0530 Subject: [PATCH 02/20] style: change comment formatting --- frappe/model/create_new.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py index a4e50f704c..0f846f4bf3 100644 --- a/frappe/model/create_new.py +++ b/frappe/model/create_new.py @@ -61,7 +61,7 @@ def set_user_and_static_default_values(doc): user_default_value = get_user_default_value(df, defaults, doctype_user_permissions, allowed_records) if user_default_value != None: - # do not set default if the field on which current field is dependent is not set + # do not set default if the field on which current field is dependent is not set if is_dependent_field_set(df.depends_on, doc): doc.set(df.fieldname, user_default_value) else: From 34256b8ff5396b40ceccbe351f3e1617437837ab Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 15 Apr 2019 17:25:26 +0530 Subject: [PATCH 03/20] feat: add validation for overlap default entries --- .../user_permission/user_permission.py | 63 ++++++++++++++----- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index 88144f8078..97e922eb14 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -7,21 +7,14 @@ import frappe, json from frappe.model.document import Document from frappe.permissions import (get_valid_perms, update_permission_property) from frappe import _ +from frappe.utils import cstr from frappe.core.utils import find from frappe.desk.form.linked_with import get_linked_doctypes class UserPermission(Document): def validate(self): - duplicate_exists = frappe.db.get_all(self.doctype, filters={ - 'allow': self.allow, - 'for_value': self.for_value, - 'user': self.user, - 'applicable_for': self.applicable_for, - 'apply_to_all_doctypes': self.apply_to_all_doctypes, - 'name': ['!=', self.name] - }, limit=1) - if duplicate_exists: - frappe.throw(_("User permission already exists"), frappe.DuplicateEntryError) + self.validate_user_permission() + self.validate_permission_overlap() def on_update(self): frappe.cache().delete_value('user_permissions') @@ -31,6 +24,45 @@ class UserPermission(Document): frappe.cache().delete_value('user_permissions') frappe.publish_realtime('update_user_permissions') + def validate_user_permission(self): + ''' checks for duplicate user permission records''' + + duplicate_exists = frappe.db.get_all(self.doctype, filters={ + 'allow': self.allow, + 'for_value': self.for_value, + 'user': self.user, + 'applicable_for': cstr(self.applicable_for), + 'apply_to_all_doctypes': self.apply_to_all_doctypes, + 'name': ['!=', self.name] + }, limit=1) + if duplicate_exists: + frappe.throw(_("User permission already exists"), frappe.DuplicateEntryError) + + def validate_permission_overlap(self): + ''' validate user permission overlap for default value of a particular doctype ''' + overlap_exists = [] + if self.is_default: + overlap_exists = frappe.db.sql(""" + SELECT + name + FROM `tabUser Permission` + WHERE + allow=%(allow)s + AND user=%(user)s + AND is_default=1 + AND name!=%(name)s + AND (applicable_for=%(applicable_for)s + OR apply_to_all_doctypes=1) + LIMIT 1 + """, { + 'allow': self.allow, + 'user': self.user, + 'applicable_for': self.applicable_for, + 'name': self.name + }, as_dict=1) + if overlap_exists: + frappe.throw(_("User permission {0} has already assigned default vaue for {1}.".format(overlap_exists[0].name, self.allow))) + @frappe.whitelist() def get_user_permissions(user=None): '''Get all users permissions for the user as a dict of doctype''' @@ -52,7 +84,7 @@ def get_user_permissions(user=None): out = {} - def add_doc_to_perm(perm, doc_name): + def add_doc_to_perm(perm, doc_name, is_default): # group rules for each type # for example if allow is "Customer", then build all allowed customers # in a list @@ -61,21 +93,22 @@ def get_user_permissions(user=None): out[perm.allow].append(frappe._dict({ 'doc': doc_name, - 'applicable_for': perm.get('applicable_for') + 'applicable_for': perm.get('applicable_for'), + 'is_default': is_default })) try: for perm in frappe.get_all('User Permission', - fields=['allow', 'for_value', 'applicable_for'], + fields=['allow', 'for_value', 'applicable_for', 'is_default'], filters=dict(user=user)): meta = frappe.get_meta(perm.allow) - add_doc_to_perm(perm, perm.for_value) + add_doc_to_perm(perm, perm.for_value, perm.is_default) if meta.is_nested_set(): decendants = frappe.db.get_descendants(perm.allow, perm.for_value) for doc in decendants: - add_doc_to_perm(perm, doc) + add_doc_to_perm(perm, doc, False) out = frappe._dict(out) frappe.cache().hset("user_permissions", user, out) From b53ff42bcdc33d45e8830232f244f7a6a219d101 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 15 Apr 2019 18:00:35 +0530 Subject: [PATCH 04/20] feat: assign default value to link field based on the user permission --- frappe/permissions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/permissions.py b/frappe/permissions.py index 6c3c5b7739..f8f733e12c 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -525,7 +525,7 @@ def allow_everything(): def get_allowed_docs_for_doctype(user_permissions, doctype): '''Returns all the docs from the passed user_permission that are allowed under provide doctype''' - return [d.get('doc') for d in user_permissions if not d.get('applicable_for') or d.get('applicable_for') == doctype] + return [d.get('doc') for d in user_permissions if (not d.get('applicable_for') or d.get('applicable_for') == doctype) and (d.get('is_default') or len(user_permissions) == 1)] def push_perm_check_log(log): if frappe.flags.get('has_permission_check_logs') == None: return From 1f5a30418727b84d1e7bcfe2135ed99eb6987292 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 15 Apr 2019 18:01:18 +0530 Subject: [PATCH 05/20] feat: fetch default value for link field based on user permission --- frappe/public/js/frappe/model/perm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/model/perm.js b/frappe/public/js/frappe/model/perm.js index 2396962b94..caae36e559 100644 --- a/frappe/public/js/frappe/model/perm.js +++ b/frappe/public/js/frappe/model/perm.js @@ -255,7 +255,7 @@ $.extend(frappe.perm, { get_allowed_docs_for_doctype: (user_permissions, doctype) => { return (user_permissions || []).filter(perm => { - return (perm.applicable_for === doctype || !perm.applicable_for); + return ((perm.applicable_for === doctype || !perm.applicable_for) && (perm.is_default === 1 || user_permissions.length === 1)); }).map(perm => perm.doc); } }); From 01393b9838ab4edcf8573b2ce21cce71fb3f790c Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 16 Apr 2019 22:29:22 +0530 Subject: [PATCH 06/20] feat: pass default value to create user permission via user permission list --- frappe/core/doctype/user_permission/user_permission.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index 97e922eb14..f650b543fa 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -193,24 +193,25 @@ def add_user_permissions(data): exists = frappe.db.exists("User Permission", {"user": data.user, "allow": data.doctype, "for_value": data.docname, "apply_to_all_doctypes": 1}) if data.apply_to_all_doctypes == 1 and not exists: remove_applicable(d, data.user, data.doctype, data.docname) - insert_user_perm(data.user, data.doctype, data.docname, apply_to_all = 1) + insert_user_perm(data.user, data.doctype, data.docname, data.is_default, apply_to_all = 1) return 1 else: remove_apply_to_all(data.user, data.doctype, data.docname) update_applicable(d, data.applicable_doctypes, data.user, data.doctype, data.docname) for applicable in data.applicable_doctypes : if applicable not in d: - insert_user_perm(data.user, data.doctype, data.docname, applicable = applicable) + insert_user_perm(data.user, data.doctype, data.docname, data.is_default, applicable = applicable) elif exists: - insert_user_perm(data.user, data.doctype, data.docname, applicable = applicable) + insert_user_perm(data.user, data.doctype, data.docname, data.is_default, applicable = applicable) return 1 return 0 -def insert_user_perm(user, doctype, docname, apply_to_all=None, applicable=None): +def insert_user_perm(user, doctype, docname, is_default=False, apply_to_all=None, applicable=None): user_perm = frappe.new_doc("User Permission") user_perm.user = user user_perm.allow = doctype user_perm.for_value = docname + user_perm.is_default = is_default if applicable: user_perm.applicable_for = applicable user_perm.apply_to_all_doctypes = 0 From 4aad4a2d3d1aa52175474fa6555ebba1e5a22242 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 16 Apr 2019 22:29:54 +0530 Subject: [PATCH 07/20] style: change formatting for is default --- frappe/core/doctype/user_permission/user_permission.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.json b/frappe/core/doctype/user_permission/user_permission.json index 50c253aeae..33a8d58bbb 100644 --- a/frappe/core/doctype/user_permission/user_permission.json +++ b/frappe/core/doctype/user_permission/user_permission.json @@ -164,7 +164,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "is default", + "label": "Is Default", "length": 0, "no_copy": 0, "permlevel": 0, @@ -291,7 +291,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-04-13 17:27:22.420985", + "modified": "2019-04-16 19:17:23.644724", "modified_by": "Administrator", "module": "Core", "name": "User Permission", From 36750bae4dad63ecf0b0f9c3d3ea4a899c10d867 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 16 Apr 2019 22:30:57 +0530 Subject: [PATCH 08/20] feat: add is default option in add/update dialog in user permission list --- .../doctype/user_permission/user_permission_list.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/user_permission/user_permission_list.js b/frappe/core/doctype/user_permission/user_permission_list.js index 00d829b2a0..d9514f0406 100644 --- a/frappe/core/doctype/user_permission/user_permission_list.js +++ b/frappe/core/doctype/user_permission/user_permission_list.js @@ -16,6 +16,7 @@ frappe.listview_settings['User Permission'] = { dialog.fields_dict.doctype.set_input(undefined); dialog.fields_dict.docname.set_input(undefined); dialog.set_df_property("docname", "hidden", 1); + dialog.set_df_property("is_default", "hidden", 1); dialog.set_df_property("apply_to_all_doctypes", "hidden", 1); dialog.set_df_property("applicable_doctypes", "hidden", 1); } @@ -53,6 +54,13 @@ frappe.listview_settings['User Permission'] = { } } }, + { + fieldname: 'is_default', + label: __('Is Default'), + fieldtype: 'Check', + checked: 1, + hidden: 1 + }, { fieldname: 'apply_to_all_doctypes', label: __('Apply to all Documents Types'), @@ -205,8 +213,10 @@ frappe.listview_settings['User Permission'] = { on_doctype_change: function(dialog) { dialog.set_df_property("docname", "hidden", 0); dialog.set_df_property("docname", "reqd", 1); + dialog.set_df_property("is_default", "hidden", 0); + dialog.set_value("is_default", "checked", 0); dialog.set_df_property("apply_to_all_doctypes", "hidden", 0); - dialog.set_value("apply_to_all_doctypes","checked",1); + dialog.set_value("apply_to_all_doctypes", "checked", 1); }, on_docname_change: function(dialog, options, applicable) { From 9079e7965e53a727ac885ef3f1b63cff4e47a42c Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 16 Apr 2019 23:34:28 +0530 Subject: [PATCH 09/20] feat: pass default value to add user permission --- frappe/permissions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/permissions.py b/frappe/permissions.py index f8f733e12c..fef4e61996 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -395,7 +395,7 @@ def set_user_permission_if_allowed(doctype, name, user, with_message=False): if get_role_permissions(frappe.get_meta(doctype), user).set_user_permissions!=1: add_user_permission(doctype, name, user) -def add_user_permission(doctype, name, user, ignore_permissions=False, applicable_for=None): +def add_user_permission(doctype, name, user, is_default=False, ignore_permissions=False, applicable_for=None): '''Add user permission''' from frappe.core.doctype.user_permission.user_permission import user_permission_exists @@ -408,6 +408,7 @@ def add_user_permission(doctype, name, user, ignore_permissions=False, applicabl user=user, allow=doctype, for_value=name, + is_default=is_default, applicable_for=applicable_for, )).insert(ignore_permissions=ignore_permissions) From 229c0d9a96f04313e87b273e0846fe395467b671 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 16 Apr 2019 23:36:08 +0530 Subject: [PATCH 10/20] test: check default user permission overlap validation --- .../user_permission/test_user_permission.py | 47 ++++++++++++------- .../user_permission/user_permission.py | 4 +- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/frappe/core/doctype/user_permission/test_user_permission.py b/frappe/core/doctype/user_permission/test_user_permission.py index b83d103013..79da4328a0 100644 --- a/frappe/core/doctype/user_permission/test_user_permission.py +++ b/frappe/core/doctype/user_permission/test_user_permission.py @@ -8,17 +8,28 @@ import frappe import unittest class TestUserPermission(unittest.TestCase): + def test_default_user_permission(self): + user = create_user('test_bulk_creation_update@example.com') + param = get_params(user, 'User', user.name, True) + add_user_permissions(param) + + #create a duplicate entry with default + perm_user = create_user('test_perm@example.com') + + param = get_params(user, 'User', perm_user.name, True) + self.assertRaises(frappe.ValidationError, add_user_permissions, param) + def test_apply_to_all(self): ''' Create User permission for User having access to all applicable Doctypes''' - user = get_user() - param = get_params(user, apply = 1) + user = create_user('test_bulk_creation_update@example.com') + param = get_params(user, 'User', user.name) created = add_user_permissions(param) self.assertEquals(created, 1) def test_for_applicable_on_update_from_apply_to_all(self): ''' Update User Permission from all to some applicable Doctypes''' - user = get_user() - param = get_params(user, applicable = ["Chat Room", "Chat Message"]) + user = create_user('test_bulk_creation_update@example.com') + param = get_params(user, 'User', user.name , applicable = ["Chat Room", "Chat Message"]) create = add_user_permissions(param) frappe.db.commit() @@ -33,8 +44,8 @@ class TestUserPermission(unittest.TestCase): def test_for_apply_to_all_on_update_from_applicable(self): ''' Update User Permission from some to all applicable Doctypes''' - user = get_user() - param = get_params(user, apply = 1) + user = create_user('test_bulk_creation_update@example.com') + param = get_params(user, 'User', user.name) created = add_user_permissions(param) created_apply_to_all = frappe.db.exists("User Permission", get_exists_param(user)) removed_applicable_first = frappe.db.exists("User Permission", get_exists_param(user, applicable = "Chat Room")) @@ -46,26 +57,26 @@ class TestUserPermission(unittest.TestCase): self.assertIsNone(removed_applicable_second) self.assertEquals(created, 1) -def get_user(): - if frappe.db.exists('User', 'test_bulk_creation_update@example.com'): - return frappe.get_doc('User', 'test_bulk_creation_update@example.com') +def create_user(user): + if frappe.db.exists('User', user): + return frappe.get_doc('User', user) else: user = frappe.new_doc('User') - user.email = 'test_bulk_creation_update@example.com' - user.first_name = 'Test_Bulk_Creation' + user.email = user + user.first_name = user.split("@")[0] user.add_roles("System Manager") return user -def get_params(user, apply = None , applicable = None): +def get_params(user, doctype, docname, is_default=False, applicable=None): ''' Return param to insert ''' param = { "user": user.name, - "doctype":"User", - "docname":user.name + "doctype":doctype, + "docname":docname, + "is_default": is_default, + "apply_to_all_doctypes": 1, + "applicable_doctypes": [] } - if apply: - param.update({"apply_to_all_doctypes": 1}) - param.update({"applicable_doctypes": []}) if applicable: param.update({"apply_to_all_doctypes": 0}) param.update({"applicable_doctypes": applicable}) @@ -82,4 +93,4 @@ def get_exists_param(user, applicable = None): param.update({"applicable_for": applicable}) else: param.update({"apply_to_all_doctypes": 1}) - return param + return param \ No newline at end of file diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index f650b543fa..604bfc7973 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -14,7 +14,7 @@ from frappe.desk.form.linked_with import get_linked_doctypes class UserPermission(Document): def validate(self): self.validate_user_permission() - self.validate_permission_overlap() + self.validate_default_permission() def on_update(self): frappe.cache().delete_value('user_permissions') @@ -38,7 +38,7 @@ class UserPermission(Document): if duplicate_exists: frappe.throw(_("User permission already exists"), frappe.DuplicateEntryError) - def validate_permission_overlap(self): + def validate_default_permission(self): ''' validate user permission overlap for default value of a particular doctype ''' overlap_exists = [] if self.is_default: From ff98540857d2c6ef991c621b9fde698df6434d7e Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Tue, 16 Apr 2019 23:37:41 +0530 Subject: [PATCH 11/20] test: validate default value fetch in multiple user permission case --- frappe/tests/test_permissions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index 2a9ac69fe6..c6359001f4 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -86,7 +86,7 @@ class TestPermissions(unittest.TestCase): self.assertFalse(doc.get("blog_category")) # Fetch default based on single user permission - add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com") + add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com", is_default=True) frappe.set_user("test2@example.com") doc = frappe.new_doc("Blog Post") @@ -96,7 +96,7 @@ class TestPermissions(unittest.TestCase): add_user_permission("Blog Category", "_Test Blog Category", "test2@example.com", ignore_permissions=True) frappe.clear_cache() doc = frappe.new_doc("Blog Post") - self.assertFalse(doc.get("blog_category")) + self.assertEqual(doc.get("blog_category"), "_Test Blog Category 1") def test_user_link_match_doc(self): blogger = frappe.get_doc("Blogger", "_Test Blogger 1") From 1250a931ed0c6156ccc304f56c7c9d1fa6750187 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 17 Apr 2019 14:26:23 +0530 Subject: [PATCH 12/20] fix: change raw sql to orm --- .../user_permission/user_permission.py | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index 604bfc7973..60c55fcfed 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -42,24 +42,15 @@ class UserPermission(Document): ''' validate user permission overlap for default value of a particular doctype ''' overlap_exists = [] if self.is_default: - overlap_exists = frappe.db.sql(""" - SELECT - name - FROM `tabUser Permission` - WHERE - allow=%(allow)s - AND user=%(user)s - AND is_default=1 - AND name!=%(name)s - AND (applicable_for=%(applicable_for)s - OR apply_to_all_doctypes=1) - LIMIT 1 - """, { + overlap_exists = frappe.get_all(self.doctype, filters={ 'allow': self.allow, 'user': self.user, - 'applicable_for': self.applicable_for, - 'name': self.name - }, as_dict=1) + 'is_default': 1, + 'name': ['!=', self.name] + }, or_filters={ + 'applicable_for': cstr(self.applicable_for), + 'apply_to_all_doctypes': 1 + }, limit=1) if overlap_exists: frappe.throw(_("User permission {0} has already assigned default vaue for {1}.".format(overlap_exists[0].name, self.allow))) From fe007f426d199c17a48fee996e6bd67d1d1a353b Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 17 Apr 2019 18:49:39 +0530 Subject: [PATCH 13/20] fix: default user permission to handle small int values --- .../user_permission/test_user_permission.py | 23 +++++++++---------- .../user_permission/user_permission.py | 2 +- .../user_permission/user_permission_list.js | 3 --- frappe/permissions.py | 2 +- frappe/tests/test_permissions.py | 2 +- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/frappe/core/doctype/user_permission/test_user_permission.py b/frappe/core/doctype/user_permission/test_user_permission.py index 79da4328a0..72a00a7374 100644 --- a/frappe/core/doctype/user_permission/test_user_permission.py +++ b/frappe/core/doctype/user_permission/test_user_permission.py @@ -9,14 +9,12 @@ import unittest class TestUserPermission(unittest.TestCase): def test_default_user_permission(self): - user = create_user('test_bulk_creation_update@example.com') - param = get_params(user, 'User', user.name, True) + user = create_user('test_default_permission@example.com') + param = get_params(user, 'User', user.name, is_default=1) add_user_permissions(param) - #create a duplicate entry with default - perm_user = create_user('test_perm@example.com') - - param = get_params(user, 'User', perm_user.name, True) + perm_user = create_user('test_user_perm@example.com') + param = get_params(user, 'User', perm_user.name, is_default=1) self.assertRaises(frappe.ValidationError, add_user_permissions, param) def test_apply_to_all(self): @@ -57,17 +55,18 @@ class TestUserPermission(unittest.TestCase): self.assertIsNone(removed_applicable_second) self.assertEquals(created, 1) -def create_user(user): - if frappe.db.exists('User', user): - return frappe.get_doc('User', user) +def create_user(email): + ''' create user with role system manager ''' + if frappe.db.exists('User', email): + return frappe.get_doc('User', email) else: user = frappe.new_doc('User') - user.email = user - user.first_name = user.split("@")[0] + user.email = email + user.first_name = email.split("@")[0] user.add_roles("System Manager") return user -def get_params(user, doctype, docname, is_default=False, applicable=None): +def get_params(user, doctype, docname, is_default=0, applicable=None): ''' Return param to insert ''' param = { "user": user.name, diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index 60c55fcfed..c82a509258 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -197,7 +197,7 @@ def add_user_permissions(data): return 1 return 0 -def insert_user_perm(user, doctype, docname, is_default=False, apply_to_all=None, applicable=None): +def insert_user_perm(user, doctype, docname, is_default=0, apply_to_all=None, applicable=None): user_perm = frappe.new_doc("User Permission") user_perm.user = user user_perm.allow = doctype diff --git a/frappe/core/doctype/user_permission/user_permission_list.js b/frappe/core/doctype/user_permission/user_permission_list.js index d9514f0406..a0b553c43a 100644 --- a/frappe/core/doctype/user_permission/user_permission_list.js +++ b/frappe/core/doctype/user_permission/user_permission_list.js @@ -58,14 +58,12 @@ frappe.listview_settings['User Permission'] = { fieldname: 'is_default', label: __('Is Default'), fieldtype: 'Check', - checked: 1, hidden: 1 }, { fieldname: 'apply_to_all_doctypes', label: __('Apply to all Documents Types'), fieldtype: 'Check', - checked: 1, hidden: 1, onchange: function() { if(dialog.fields_dict.doctype.value && dialog.fields_dict.docname.value && dialog.fields_dict.user.value){ @@ -214,7 +212,6 @@ frappe.listview_settings['User Permission'] = { dialog.set_df_property("docname", "hidden", 0); dialog.set_df_property("docname", "reqd", 1); dialog.set_df_property("is_default", "hidden", 0); - dialog.set_value("is_default", "checked", 0); dialog.set_df_property("apply_to_all_doctypes", "hidden", 0); dialog.set_value("apply_to_all_doctypes", "checked", 1); }, diff --git a/frappe/permissions.py b/frappe/permissions.py index fef4e61996..083471ab5c 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -395,7 +395,7 @@ def set_user_permission_if_allowed(doctype, name, user, with_message=False): if get_role_permissions(frappe.get_meta(doctype), user).set_user_permissions!=1: add_user_permission(doctype, name, user) -def add_user_permission(doctype, name, user, is_default=False, ignore_permissions=False, applicable_for=None): +def add_user_permission(doctype, name, user, ignore_permissions=False, applicable_for=None, is_default=0): '''Add user permission''' from frappe.core.doctype.user_permission.user_permission import user_permission_exists diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index c6359001f4..34a5bfdb8f 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -86,7 +86,7 @@ class TestPermissions(unittest.TestCase): self.assertFalse(doc.get("blog_category")) # Fetch default based on single user permission - add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com", is_default=True) + add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com", is_default=1) frappe.set_user("test2@example.com") doc = frappe.new_doc("Blog Post") From 8d8ef7ad3c2424ada6755ba9af89b79f65305bc5 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Sun, 21 Apr 2019 23:39:24 +0530 Subject: [PATCH 14/20] fix: return allowed docs along with default doc --- frappe/model/create_new.py | 13 ++++++------- frappe/permissions.py | 15 +++++++++++---- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py index 0f846f4bf3..f7a0adb029 100644 --- a/frappe/model/create_new.py +++ b/frappe/model/create_new.py @@ -56,10 +56,10 @@ def set_user_and_static_default_values(doc): if df.fieldtype in data_fieldtypes: # user permissions for link options doctype_user_permissions = user_permissions.get(df.options, []) - # Allowed records for the reference doctype (link field) - allowed_records = get_allowed_docs_for_doctype(doctype_user_permissions, df.parent) + # Allowed records for the reference doctype (link field) along with default doc + allowed_records, default_doc = get_allowed_docs_for_doctype(doctype_user_permissions, df.parent, get_default=True) - user_default_value = get_user_default_value(df, defaults, doctype_user_permissions, allowed_records) + user_default_value = get_user_default_value(df, defaults, doctype_user_permissions, allowed_records, default_doc) if user_default_value != None: # do not set default if the field on which current field is dependent is not set if is_dependent_field_set(df.depends_on, doc): @@ -78,14 +78,14 @@ def is_dependent_field_set(fieldname, doc): if fieldname not in value_dict: return True return value_dict[fieldname] -def get_user_default_value(df, defaults, doctype_user_permissions, allowed_records): +def get_user_default_value(df, defaults, doctype_user_permissions, allowed_records, default_doc): # don't set defaults for "User" link field using User Permissions! if df.fieldtype == "Link" and df.options != "User": # 1 - look in user permissions only for document_type==Setup # We don't want to include permissions of transactions to be used for defaults. if (frappe.get_meta(df.options).document_type=="Setup" - and len(allowed_records)==1 and not df.ignore_user_permissions): - return allowed_records[0] + and not df.ignore_user_permissions and default_doc): + return default_doc # 2 - Look in user defaults user_default = defaults.get(df.fieldname) @@ -147,7 +147,6 @@ def user_permissions_exist(df, doctype_user_permissions): def get_default_based_on_another_field(df, user_permissions, parent_doc): # default value based on another document - from frappe.permissions import get_allowed_docs_for_doctype ref_doctype = df.default[1:] ref_fieldname = ref_doctype.lower().replace(" ", "_") diff --git a/frappe/permissions.py b/frappe/permissions.py index 083471ab5c..64e9886045 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -523,10 +523,17 @@ def allow_everything(): perm = {ptype: 1 for ptype in rights} return perm -def get_allowed_docs_for_doctype(user_permissions, doctype): - '''Returns all the docs from the passed user_permission - that are allowed under provide doctype''' - return [d.get('doc') for d in user_permissions if (not d.get('applicable_for') or d.get('applicable_for') == doctype) and (d.get('is_default') or len(user_permissions) == 1)] +def get_allowed_docs_for_doctype(user_permissions, doctype, get_default=False): + '''Returns all the docs from the passed user_permissions that are + allowed under provided doctype along with default doc value if get_default is set ''' + allowed_doc = [] + for doc in user_permissions: + if not doc.get('applicable_for') or doc.get('applicable_for') == doctype: + allowed_doc.append(doc.get('doc')) + if doc.get('is_default') or len(user_permissions) == 1 and get_default: + default_doc = doc.get('doc') + + return (allowed_doc, default_doc) if default_doc else allowed_doc def push_perm_check_log(log): if frappe.flags.get('has_permission_check_logs') == None: return From c23876198d4fd26c3896a6d7b76e4580870eb6cb Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 22 Apr 2019 13:52:10 +0530 Subject: [PATCH 15/20] fix: filter default docs from allowed docs --- frappe/model/create_new.py | 5 +++-- frappe/permissions.py | 16 +++++++++----- frappe/public/js/frappe/model/create_new.js | 7 +++--- frappe/public/js/frappe/model/perm.js | 24 ++++++++++++++++++--- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py index f7a0adb029..e882508c99 100644 --- a/frappe/model/create_new.py +++ b/frappe/model/create_new.py @@ -12,7 +12,7 @@ import frappe.defaults from frappe.model import data_fieldtypes from frappe.utils import nowdate, nowtime, now_datetime from frappe.core.doctype.user_permission.user_permission import get_user_permissions -from frappe.permissions import get_allowed_docs_for_doctype +from frappe.permissions import filter_allowed_docs_for_doctype def get_new_doc(doctype, parent_doc = None, parentfield = None, as_dict=False): if doctype not in frappe.local.new_doc_templates: @@ -57,7 +57,7 @@ def set_user_and_static_default_values(doc): # user permissions for link options doctype_user_permissions = user_permissions.get(df.options, []) # Allowed records for the reference doctype (link field) along with default doc - allowed_records, default_doc = get_allowed_docs_for_doctype(doctype_user_permissions, df.parent, get_default=True) + allowed_records, default_doc = filter_allowed_docs_for_doctype(doctype_user_permissions, df.parent, with_default_doc=True) user_default_value = get_user_default_value(df, defaults, doctype_user_permissions, allowed_records, default_doc) if user_default_value != None: @@ -147,6 +147,7 @@ def user_permissions_exist(df, doctype_user_permissions): def get_default_based_on_another_field(df, user_permissions, parent_doc): # default value based on another document + from frappe.permissions import get_allowed_docs_for_doctype ref_doctype = df.default[1:] ref_fieldname = ref_doctype.lower().replace(" ", "_") diff --git a/frappe/permissions.py b/frappe/permissions.py index 64e9886045..3809bb3e9c 100644 --- a/frappe/permissions.py +++ b/frappe/permissions.py @@ -523,17 +523,23 @@ def allow_everything(): perm = {ptype: 1 for ptype in rights} return perm -def get_allowed_docs_for_doctype(user_permissions, doctype, get_default=False): - '''Returns all the docs from the passed user_permissions that are - allowed under provided doctype along with default doc value if get_default is set ''' +def get_allowed_docs_for_doctype(user_permissions, doctype): + ''' Returns all the docs from the passed user_permissions that are + allowed under provided doctype ''' + return filter_allowed_docs_for_doctype(user_permissions, doctype, with_default_doc=False) + +def filter_allowed_docs_for_doctype(user_permissions, doctype, with_default_doc=True): + ''' Returns all the docs from the passed user_permissions that are + allowed under provided doctype along with default doc value if with_default_doc is set ''' allowed_doc = [] + default_doc = None for doc in user_permissions: if not doc.get('applicable_for') or doc.get('applicable_for') == doctype: allowed_doc.append(doc.get('doc')) - if doc.get('is_default') or len(user_permissions) == 1 and get_default: + if doc.get('is_default') or len(user_permissions) == 1 and with_default_doc: default_doc = doc.get('doc') - return (allowed_doc, default_doc) if default_doc else allowed_doc + return (allowed_doc, default_doc) if with_default_doc else allowed_doc def push_perm_check_log(log): if frappe.flags.get('has_permission_check_logs') == None: return diff --git a/frappe/public/js/frappe/model/create_new.js b/frappe/public/js/frappe/model/create_new.js index 90828ab5b0..74ce746123 100644 --- a/frappe/public/js/frappe/model/create_new.js +++ b/frappe/public/js/frappe/model/create_new.js @@ -125,8 +125,9 @@ $.extend(frappe.model, { var user_default = ""; var user_permissions = frappe.defaults.get_user_permissions(); let allowed_records = []; + let default_doc = null; if(user_permissions) { - allowed_records = frappe.perm.get_allowed_docs_for_doctype(user_permissions[df.options], doc.doctype); + ({allowed_records, default_doc} = frappe.perm.filter_allowed_docs_for_doctype(user_permissions[df.options], doc.doctype)); } var meta = frappe.get_meta(doc.doctype); var has_user_permissions = (df.fieldtype==="Link" @@ -139,8 +140,8 @@ $.extend(frappe.model, { // 1 - look in user permissions for document_type=="Setup". // We don't want to include permissions of transactions to be used for defaults. if (df.linked_document_type==="Setup" - && has_user_permissions && allowed_records.length===1) { - return allowed_records[0]; + && has_user_permissions && default_doc) { + return default_doc; } if(!df.ignore_user_permissions) { diff --git a/frappe/public/js/frappe/model/perm.js b/frappe/public/js/frappe/model/perm.js index caae36e559..bfbd560d08 100644 --- a/frappe/public/js/frappe/model/perm.js +++ b/frappe/public/js/frappe/model/perm.js @@ -254,8 +254,26 @@ $.extend(frappe.perm, { }, get_allowed_docs_for_doctype: (user_permissions, doctype) => { - return (user_permissions || []).filter(perm => { - return ((perm.applicable_for === doctype || !perm.applicable_for) && (perm.is_default === 1 || user_permissions.length === 1)); - }).map(perm => perm.doc); + // returns docs from the list of user permissions that are allowed under provided doctype + filter_allowed_docs_for_doctype(user_permissions, doctype, false) + }, + + filter_allowed_docs_for_doctype: (user_permissions, doctype, with_default_doc=true) => { + // returns docs from the list of user permissions that are allowed under provided doctype + // also returns default doc when with_default_doc is set + const allowed_docs = (user_permissions || []).filter(perm => { + return (perm.applicable_for === doctype || !perm.applicable_for); + }); + const allowed_docs_name = (allowed_docs || []).map(perm => perm.doc); + if (with_default_doc && allowed_docs_name) { + const default_doc = allowed_docs_name.length === 1? allowed_docs_name: allowed_docs.filter(perm => perm.is_default).map(record => record.doc); + + return { + allowed_records: allowed_docs_name, + default_doc: default_doc[0] + } + } else { + return allowed_docs_name; + } } }); From 2d2556f502e12275a671d4365f1746bfff826d3c Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 22 Apr 2019 16:49:15 +0530 Subject: [PATCH 16/20] style: change permissions format --- .../user_permission/user_permission.py | 3 ++- frappe/public/js/frappe/model/perm.js | 24 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index c82a509258..af197dcf24 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -52,7 +52,8 @@ class UserPermission(Document): 'apply_to_all_doctypes': 1 }, limit=1) if overlap_exists: - frappe.throw(_("User permission {0} has already assigned default vaue for {1}.".format(overlap_exists[0].name, self.allow))) + ref_link = frappe.get_desk_link(self.doctype, overlap_exists[0].name) + frappe.throw(_("{0} has already assigned default vaue for {1}.".format(ref_link, self.allow))) @frappe.whitelist() def get_user_permissions(user=None): diff --git a/frappe/public/js/frappe/model/perm.js b/frappe/public/js/frappe/model/perm.js index bfbd560d08..f30368bbc3 100644 --- a/frappe/public/js/frappe/model/perm.js +++ b/frappe/public/js/frappe/model/perm.js @@ -255,25 +255,29 @@ $.extend(frappe.perm, { get_allowed_docs_for_doctype: (user_permissions, doctype) => { // returns docs from the list of user permissions that are allowed under provided doctype - filter_allowed_docs_for_doctype(user_permissions, doctype, false) + return frappe.perm.filter_allowed_docs_for_doctype(user_permissions, doctype, false); }, filter_allowed_docs_for_doctype: (user_permissions, doctype, with_default_doc=true) => { // returns docs from the list of user permissions that are allowed under provided doctype // also returns default doc when with_default_doc is set - const allowed_docs = (user_permissions || []).filter(perm => { - return (perm.applicable_for === doctype || !perm.applicable_for); + const filtered_perms = (user_permissions || []).filter(perm => { + return (perm.applicable_for === doctype || !perm.applicable_for); }); - const allowed_docs_name = (allowed_docs || []).map(perm => perm.doc); - if (with_default_doc && allowed_docs_name) { - const default_doc = allowed_docs_name.length === 1? allowed_docs_name: allowed_docs.filter(perm => perm.is_default).map(record => record.doc); + + const allowed_docs = (filtered_perms).map(perm => perm.doc); + + if (with_default_doc) { + const default_doc = allowed_docs.length === 1 ? allowed_docs : filtered_perms + .filter(perm => perm.is_default) + .map(record => record.doc); return { - allowed_records: allowed_docs_name, + allowed_records: allowed_docs, default_doc: default_doc[0] - } + }; } else { - return allowed_docs_name; + return allowed_docs; } } -}); +}); \ No newline at end of file From 6ae866bd8434d581b11528d29ee1599c1f3f0993 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 24 Apr 2019 12:04:23 +0530 Subject: [PATCH 17/20] fix: add a more descriptive method name Co-Authored-By: Mangesh-Khairnar --- frappe/core/doctype/user_permission/test_user_permission.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/user_permission/test_user_permission.py b/frappe/core/doctype/user_permission/test_user_permission.py index 72a00a7374..2fa9917daf 100644 --- a/frappe/core/doctype/user_permission/test_user_permission.py +++ b/frappe/core/doctype/user_permission/test_user_permission.py @@ -8,7 +8,7 @@ import frappe import unittest class TestUserPermission(unittest.TestCase): - def test_default_user_permission(self): + def test_default_user_permission_validation(self): user = create_user('test_default_permission@example.com') param = get_params(user, 'User', user.name, is_default=1) add_user_permissions(param) @@ -92,4 +92,4 @@ def get_exists_param(user, applicable = None): param.update({"applicable_for": applicable}) else: param.update({"apply_to_all_doctypes": 1}) - return param \ No newline at end of file + return param From c81fa6db3ca6c0f2322a962864a4368200585a16 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 24 Apr 2019 13:04:32 +0530 Subject: [PATCH 18/20] test: validate no fetch for multiple non default user permission --- frappe/tests/test_permissions.py | 10 +++++++-- .../doctype/blog_category/test_records.json | 22 ++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index 34a5bfdb8f..15597aef39 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -86,7 +86,7 @@ class TestPermissions(unittest.TestCase): self.assertFalse(doc.get("blog_category")) # Fetch default based on single user permission - add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com", is_default=1) + add_user_permission("Blog Category", "_Test Blog Category 1", "test2@example.com") frappe.set_user("test2@example.com") doc = frappe.new_doc("Blog Post") @@ -96,7 +96,13 @@ class TestPermissions(unittest.TestCase): add_user_permission("Blog Category", "_Test Blog Category", "test2@example.com", ignore_permissions=True) frappe.clear_cache() doc = frappe.new_doc("Blog Post") - self.assertEqual(doc.get("blog_category"), "_Test Blog Category 1") + self.assertFalse(doc.get("blog_category")) + + # Fetch user permission set as default from multiple user permission + add_user_permission("Blog Category", "_Test Blog Category 2", "test2@example.com", ignore_permissions=True, is_default=1) + frappe.clear_cache() + doc = frappe.new_doc("Blog Post") + self.assertEqual(doc.get("blog_category"), "_Test Blog Category 2") def test_user_link_match_doc(self): blogger = frappe.get_doc("Blogger", "_Test Blogger 1") diff --git a/frappe/website/doctype/blog_category/test_records.json b/frappe/website/doctype/blog_category/test_records.json index d4533ed27c..5ea6cbf9ad 100644 --- a/frappe/website/doctype/blog_category/test_records.json +++ b/frappe/website/doctype/blog_category/test_records.json @@ -1,14 +1,20 @@ [ { - "category_name": "_Test Blog Category", - "doctype": "Blog Category", - "parent_website_route": "blog", + "category_name": "_Test Blog Category", + "doctype": "Blog Category", + "parent_website_route": "blog", "title": "_Test Blog Category" - }, + }, { - "category_name": "_Test Blog Category 1", - "doctype": "Blog Category", - "parent_website_route": "blog", + "category_name": "_Test Blog Category 1", + "doctype": "Blog Category", + "parent_website_route": "blog", "title": "_Test Blog Category 1" - } + }, + { + "category_name": "_Test Blog Category 2", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category 2" +} ] \ No newline at end of file From 21c46250ca21067892db542d66cc50f747c24d67 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 24 Apr 2019 14:06:34 +0530 Subject: [PATCH 19/20] style: formatting changes --- .../doctype/blog_category/test_records.json | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/frappe/website/doctype/blog_category/test_records.json b/frappe/website/doctype/blog_category/test_records.json index 5ea6cbf9ad..bb68886077 100644 --- a/frappe/website/doctype/blog_category/test_records.json +++ b/frappe/website/doctype/blog_category/test_records.json @@ -1,20 +1,20 @@ [ { - "category_name": "_Test Blog Category", - "doctype": "Blog Category", - "parent_website_route": "blog", - "title": "_Test Blog Category" + "category_name": "_Test Blog Category", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category" }, { - "category_name": "_Test Blog Category 1", - "doctype": "Blog Category", - "parent_website_route": "blog", - "title": "_Test Blog Category 1" + "category_name": "_Test Blog Category 1", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category 1" }, { - "category_name": "_Test Blog Category 2", - "doctype": "Blog Category", - "parent_website_route": "blog", - "title": "_Test Blog Category 2" + "category_name": "_Test Blog Category 2", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category 2" } ] \ No newline at end of file From c9dc0a8379c3dd2090930e2bd5cc516b4159da59 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Wed, 24 Apr 2019 14:29:10 +0530 Subject: [PATCH 20/20] style(linting): minor fixes --- .../doctype/blog_category/test_records.json | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/frappe/website/doctype/blog_category/test_records.json b/frappe/website/doctype/blog_category/test_records.json index bb68886077..3334bbc4f9 100644 --- a/frappe/website/doctype/blog_category/test_records.json +++ b/frappe/website/doctype/blog_category/test_records.json @@ -1,20 +1,20 @@ [ - { - "category_name": "_Test Blog Category", - "doctype": "Blog Category", - "parent_website_route": "blog", - "title": "_Test Blog Category" - }, - { - "category_name": "_Test Blog Category 1", - "doctype": "Blog Category", - "parent_website_route": "blog", - "title": "_Test Blog Category 1" - }, - { - "category_name": "_Test Blog Category 2", - "doctype": "Blog Category", - "parent_website_route": "blog", - "title": "_Test Blog Category 2" -} + { + "category_name": "_Test Blog Category", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category" + }, + { + "category_name": "_Test Blog Category 1", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category 1" + }, + { + "category_name": "_Test Blog Category 2", + "doctype": "Blog Category", + "parent_website_route": "blog", + "title": "_Test Blog Category 2" + } ] \ No newline at end of file