From b2b44b5939c66ffc84d16b903146c2697e6b0874 Mon Sep 17 00:00:00 2001 From: Pruthvi Patel Date: Thu, 5 Aug 2021 16:49:20 +0530 Subject: [PATCH 01/74] feat: add autoreloader for ipython --- frappe/commands/utils.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 8fc6877d4f..73e8002bc6 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -494,7 +494,11 @@ def console(context): frappe.connect() frappe.local.lang = frappe.db.get_default("lang") - import IPython + from IPython.terminal import embed + terminal = embed.InteractiveShellEmbed() + terminal.extension_manager.load_extension("autoreload") + terminal.run_line_magic("autoreload", "2") + all_apps = frappe.get_installed_apps() failed_to_import = [] @@ -508,8 +512,10 @@ def console(context): print("Apps in this namespace:\n{}".format(", ".join(all_apps))) if failed_to_import: print("\nFailed to import:\n{}".format(", ".join(failed_to_import))) - - IPython.embed(display_banner="", header="", colors="neutral") + + terminal.colors = "neutral" + terminal.display_banner = False + terminal() @click.command('run-tests') From 6db4b6f2e629f05f7695b81b18ea8db270b348e6 Mon Sep 17 00:00:00 2001 From: Pruthvi Patel Date: Thu, 5 Aug 2021 17:51:38 +0530 Subject: [PATCH 02/74] fix: autoreload for only developer mode --- frappe/commands/utils.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 73e8002bc6..765028dfed 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -494,10 +494,12 @@ def console(context): frappe.connect() frappe.local.lang = frappe.db.get_default("lang") - from IPython.terminal import embed - terminal = embed.InteractiveShellEmbed() - terminal.extension_manager.load_extension("autoreload") - terminal.run_line_magic("autoreload", "2") + from IPython.terminal.embed import InteractiveShellEmbed + + terminal = InteractiveShellEmbed() + if frappe.conf.developer_mode: + terminal.extension_manager.load_extension("autoreload") + terminal.run_line_magic("autoreload", "2") all_apps = frappe.get_installed_apps() failed_to_import = [] @@ -512,7 +514,7 @@ def console(context): print("Apps in this namespace:\n{}".format(", ".join(all_apps))) if failed_to_import: print("\nFailed to import:\n{}".format(", ".join(failed_to_import))) - + terminal.colors = "neutral" terminal.display_banner = False terminal() From 4598b26c73814ec7170d533f637ce60f84ee091d Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Sat, 31 Jul 2021 13:24:18 +0530 Subject: [PATCH 03/74] fix: multiple issues with Email Inbox --- frappe/public/js/frappe/ui/toolbar/awesome_bar.js | 7 ++++++- frappe/public/js/frappe/views/inbox/inbox_view.js | 11 ++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js index b85de18be2..952fd62aa1 100644 --- a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js +++ b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js @@ -194,9 +194,14 @@ frappe.search.AwesomeBar = class AwesomeBar { var out = [], routes = []; options.forEach(function(option) { if(option.route) { - if(option.route[0] === "List" && option.route[2] !== 'Report') { + if ( + option.route[0] === "List" && + option.route[2] !== 'Report' && + option.route[2] !== 'Inbox' + ) { option.route.splice(2); } + var str_route = (typeof option.route==='string') ? option.route : option.route.join('/'); if(routes.indexOf(str_route)===-1) { diff --git a/frappe/public/js/frappe/views/inbox/inbox_view.js b/frappe/public/js/frappe/views/inbox/inbox_view.js index 8b53bd49a9..6c5b330a9f 100644 --- a/frappe/public/js/frappe/views/inbox/inbox_view.js +++ b/frappe/public/js/frappe/views/inbox/inbox_view.js @@ -94,19 +94,20 @@ frappe.views.InboxView = class InboxView extends frappe.views.ListView { this.render_list(); this.on_row_checked(); this.render_count(); - this.render_tags(); } get_meta_html(email) { const attachment = email.has_attachment ? `` : ''; - const form_link = frappe.utils.get_form_link(email.reference_doctype, email.reference_name); - const link = email.reference_doctype && email.reference_doctype !== this.doctype ? - ` - ` : ''; + `; + } const communication_date = comment_when(email.communication_date, true); const status = From 82b4a1ebc6d3768db04303c51e80d67ff63e3f81 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 09:29:17 +0530 Subject: [PATCH 04/74] refactor(user): Remove unused code --- frappe/core/doctype/user/user.py | 67 -------------------------------- 1 file changed, 67 deletions(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 5d799f8ee9..307ed69789 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -1048,73 +1048,6 @@ def update_gravatar(name): if gravatar: frappe.db.set_value('User', name, 'user_image', gravatar) -@frappe.whitelist(allow_guest=True) -def send_token_via_sms(tmp_id,phone_no=None,user=None): - try: - from frappe.core.doctype.sms_settings.sms_settings import send_request - except: - return False - - if not frappe.cache().ttl(tmp_id + '_token'): - return False - ss = frappe.get_doc('SMS Settings', 'SMS Settings') - if not ss.sms_gateway_url: - return False - - token = frappe.cache().get(tmp_id + '_token') - args = {ss.message_parameter: 'verification code is {}'.format(token)} - - for d in ss.get("parameters"): - args[d.parameter] = d.value - - if user: - user_phone = frappe.db.get_value('User', user, ['phone','mobile_no'], as_dict=1) - usr_phone = user_phone.mobile_no or user_phone.phone - if not usr_phone: - return False - else: - if phone_no: - usr_phone = phone_no - else: - return False - - args[ss.receiver_parameter] = usr_phone - status = send_request(ss.sms_gateway_url, args, use_post=ss.use_post) - - if 200 <= status < 300: - frappe.cache().delete(tmp_id + '_token') - return True - else: - return False - -@frappe.whitelist(allow_guest=True) -def send_token_via_email(tmp_id,token=None): - import pyotp - - user = frappe.cache().get(tmp_id + '_user') - count = token or frappe.cache().get(tmp_id + '_token') - - if ((not user) or (user == 'None') or (not count)): - return False - user_email = frappe.db.get_value('User',user, 'email') - if not user_email: - return False - - otpsecret = frappe.cache().get(tmp_id + '_otp_secret') - hotp = pyotp.HOTP(otpsecret) - - frappe.sendmail( - recipients=user_email, - sender=None, - subject="Verification Code", - template="verification_code", - args=dict(code=hotp.at(int(count))), - delayed=False, - retry=3 - ) - - return True - @frappe.whitelist(allow_guest=True) def reset_otp_secret(user): otp_issuer = frappe.db.get_value('System Settings', 'System Settings', 'otp_issuer_name') From 4c5959afd66f01c17d1fdda4421e2a982e66e12a Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 09:54:19 +0530 Subject: [PATCH 05/74] refactor: Move reset_otp_secret to twofactor.py --- frappe/core/doctype/user/user.js | 2 +- frappe/core/doctype/user/user.py | 18 ------------------ frappe/twofactor.py | 20 ++++++++++++++++++++ 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/frappe/core/doctype/user/user.js b/frappe/core/doctype/user/user.js index 8c5b89c5fc..96726d875c 100644 --- a/frappe/core/doctype/user/user.js +++ b/frappe/core/doctype/user/user.js @@ -166,7 +166,7 @@ frappe.ui.form.on('User', { frm.add_custom_button(__("Reset OTP Secret"), function() { frappe.call({ - method: "frappe.core.doctype.user.user.reset_otp_secret", + method: "frappe.twofactor.reset_otp_secret", args: { "user": frm.doc.name } diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 307ed69789..590af3af25 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -1048,24 +1048,6 @@ def update_gravatar(name): if gravatar: frappe.db.set_value('User', name, 'user_image', gravatar) -@frappe.whitelist(allow_guest=True) -def reset_otp_secret(user): - otp_issuer = frappe.db.get_value('System Settings', 'System Settings', 'otp_issuer_name') - user_email = frappe.db.get_value('User',user, 'email') - if frappe.session.user in ["Administrator", user] : - frappe.defaults.clear_default(user + '_otplogin') - frappe.defaults.clear_default(user + '_otpsecret') - email_args = { - 'recipients':user_email, 'sender':None, 'subject':'OTP Secret Reset - {}'.format(otp_issuer or "Frappe Framework"), - 'message':'

Your OTP secret on {} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.

'.format(otp_issuer or "Frappe Framework"), - 'delayed':False, - 'retry':3 - } - enqueue(method=frappe.sendmail, queue='short', timeout=300, event=None, is_async=True, job_name=None, now=False, **email_args) - return frappe.msgprint(_("OTP Secret has been reset. Re-registration will be required on next login.")) - else: - return frappe.throw(_("OTP secret can only be reset by the Administrator.")) - def throttle_user_creation(): if frappe.flags.in_import: return diff --git a/frappe/twofactor.py b/frappe/twofactor.py index c2fb6d5de9..b2f562c20d 100644 --- a/frappe/twofactor.py +++ b/frappe/twofactor.py @@ -398,3 +398,23 @@ def should_remove_barcode_image(barcode): def disable(): frappe.db.set_value('System Settings', None, 'enable_two_factor_auth', 0) + +@frappe.whitelist() +def reset_otp_secret(user): + otp_issuer = frappe.db.get_value('System Settings', 'System Settings', 'otp_issuer_name') + user_email = frappe.db.get_value('User', user, 'email') + if frappe.session.user in ["Administrator", user] : + frappe.defaults.clear_default(user + '_otplogin') + frappe.defaults.clear_default(user + '_otpsecret') + email_args = { + 'recipients': user_email, + 'sender': None, + 'subject': _('OTP Secret Reset - {0}').format(otp_issuer or "Frappe Framework"), + 'message': _('

Your OTP secret on {0} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.

').format(otp_issuer or "Frappe Framework"), + 'delayed':False, + 'retry':3 + } + enqueue(method=frappe.sendmail, queue='short', timeout=300, event=None, is_async=True, job_name=None, now=False, **email_args) + return frappe.msgprint(_("OTP Secret has been reset. Re-registration will be required on next login.")) + else: + return frappe.throw(_("OTP secret can only be reset by the Administrator.")) \ No newline at end of file From 3f2a93201b90bd7c130f576c5510aaf71d3c37c0 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 10:00:39 +0530 Subject: [PATCH 06/74] refactor: Move email account related code to email_account.py --- frappe/core/doctype/user/user.py | 71 ------------------- .../doctype/email_account/email_account.py | 70 ++++++++++++++++-- 2 files changed, 66 insertions(+), 75 deletions(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 590af3af25..5e80083791 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -21,11 +21,6 @@ from frappe.core.doctype.user_type.user_type import user_linked_with_permission_ STANDARD_USERS = ("Guest", "Administrator") - -class MaxUsersReachedError(frappe.ValidationError): - pass - - class User(Document): __new_password = None @@ -731,72 +726,6 @@ def set_email_password(email_account, user, password): return False return True - -def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_outgoing): - """ setup email inbox for user """ - def add_user_email(user): - user = frappe.get_doc("User", user) - row = user.append("user_emails", {}) - - row.email_id = email_id - row.email_account = email_account - row.awaiting_password = awaiting_password or 0 - row.enable_outgoing = enable_outgoing or 0 - - user.save(ignore_permissions=True) - - udpate_user_email_settings = False - if not all([email_account, email_id]): - return - - user_names = frappe.db.get_values("User", { "email": email_id }, as_dict=True) - if not user_names: - return - - for user in user_names: - user_name = user.get("name") - - # check if inbox is alreay configured - user_inbox = frappe.db.get_value("User Email", { - "email_account": email_account, - "parent": user_name - }, ["name"]) or None - - if not user_inbox: - add_user_email(user_name) - else: - # update awaiting password for email account - udpate_user_email_settings = True - - if udpate_user_email_settings: - frappe.db.sql("""UPDATE `tabUser Email` SET awaiting_password = %(awaiting_password)s, - enable_outgoing = %(enable_outgoing)s WHERE email_account = %(email_account)s""", { - "email_account": email_account, - "enable_outgoing": enable_outgoing, - "awaiting_password": awaiting_password or 0 - }) - else: - users = " and ".join([frappe.bold(user.get("name")) for user in user_names]) - frappe.msgprint(_("Enabled email inbox for user {0}").format(users)) - - ask_pass_update() - -def remove_user_email_inbox(email_account): - """ remove user email inbox settings if email account is deleted """ - if not email_account: - return - - users = frappe.get_all("User Email", filters={ - "email_account": email_account - }, fields=["parent as name"]) - - for user in users: - doc = frappe.get_doc("User", user.get("name")) - to_remove = [ row for row in doc.user_emails if row.email_account == email_account ] - [ doc.remove(row) for row in to_remove ] - - doc.save(ignore_permissions=True) - def ask_pass_update(): # update the sys defaults as to awaiting users from frappe.utils import set_default diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index ecd59f42bb..78e0be1017 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -137,8 +137,6 @@ class EmailAccount(Document): def on_update(self): """Check there is only one default of each type.""" - from frappe.core.doctype.user.user import setup_user_email_inbox - self.check_automatic_linking_email_account() self.there_must_be_only_one_default() setup_user_email_inbox(email_account=self.name, awaiting_password=self.awaiting_password, @@ -532,8 +530,6 @@ class EmailAccount(Document): def on_trash(self): """Clear communications where email account is linked""" - from frappe.core.doctype.user.user import remove_user_email_inbox - frappe.db.sql("update `tabCommunication` set email_account='' where email_account=%s", self.name) remove_user_email_inbox(email_account=self.name) @@ -724,3 +720,69 @@ def get_max_email_uid(email_account): else: max_uid = cint(result[0].get("uid", 0)) + 1 return max_uid + + +def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_outgoing): + """ setup email inbox for user """ + from frappe.core.doctype.user import ask_pass_update + def add_user_email(user): + user = frappe.get_doc("User", user) + row = user.append("user_emails", {}) + + row.email_id = email_id + row.email_account = email_account + row.awaiting_password = awaiting_password or 0 + row.enable_outgoing = enable_outgoing or 0 + + user.save(ignore_permissions=True) + + udpate_user_email_settings = False + if not all([email_account, email_id]): + return + + user_names = frappe.db.get_values("User", { "email": email_id }, as_dict=True) + if not user_names: + return + + for user in user_names: + user_name = user.get("name") + + # check if inbox is alreay configured + user_inbox = frappe.db.get_value("User Email", { + "email_account": email_account, + "parent": user_name + }, ["name"]) or None + + if not user_inbox: + add_user_email(user_name) + else: + # update awaiting password for email account + udpate_user_email_settings = True + + if udpate_user_email_settings: + frappe.db.sql("""UPDATE `tabUser Email` SET awaiting_password = %(awaiting_password)s, + enable_outgoing = %(enable_outgoing)s WHERE email_account = %(email_account)s""", { + "email_account": email_account, + "enable_outgoing": enable_outgoing, + "awaiting_password": awaiting_password or 0 + }) + else: + users = " and ".join([frappe.bold(user.get("name")) for user in user_names]) + frappe.msgprint(_("Enabled email inbox for user {0}").format(users)) + ask_pass_update() + +def remove_user_email_inbox(email_account): + """ remove user email inbox settings if email account is deleted """ + if not email_account: + return + + users = frappe.get_all("User Email", filters={ + "email_account": email_account + }, fields=["parent as name"]) + + for user in users: + doc = frappe.get_doc("User", user.get("name")) + to_remove = [ row for row in doc.user_emails if row.email_account == email_account ] + [ doc.remove(row) for row in to_remove ] + + doc.save(ignore_permissions=True) From f6a757be5087f4d3bc262fcc0003ac09e213e6f9 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 10:08:12 +0530 Subject: [PATCH 07/74] test: Add test case for user rename --- frappe/core/doctype/user/test_user.py | 93 ++++++++++----------------- 1 file changed, 33 insertions(+), 60 deletions(-) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 392128834d..383967a549 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -1,13 +1,10 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -import frappe, unittest, uuid +import frappe, unittest from frappe.model.delete_doc import delete_doc -from frappe.utils.data import today, add_to_date -from frappe import _dict from frappe.utils import get_url -from frappe.core.doctype.user.user import get_total_users -from frappe.core.doctype.user.user import MaxUsersReachedError, test_password_strength +from frappe.core.doctype.user.user import test_password_strength from frappe.core.doctype.user.user import extract_mentions from frappe.frappeclient import FrappeClient @@ -119,37 +116,6 @@ class TestUser(unittest.TestCase): # system manager now added by Administrator self.assertTrue("System Manager" in [d.role for d in me.get("roles")]) - # def test_deny_multiple_sessions(self): - # from frappe.installer import update_site_config - # clear_limit('users') - # - # # allow one session - # user = frappe.get_doc('User', 'test@example.com') - # user.simultaneous_sessions = 1 - # user.new_password = 'Eastern_43A1W' - # user.save() - # - # def test_request(conn): - # value = conn.get_value('User', 'first_name', {'name': 'test@example.com'}) - # self.assertTrue('first_name' in value) - # - # from frappe.frappeclient import FrappeClient - # update_site_config('deny_multiple_sessions', 0) - # - # conn1 = FrappeClient(get_url(), "test@example.com", "Eastern_43A1W", verify=False) - # test_request(conn1) - # - # conn2 = FrappeClient(get_url(), "test@example.com", "Eastern_43A1W", verify=False) - # test_request(conn2) - # - # update_site_config('deny_multiple_sessions', 1) - # conn3 = FrappeClient(get_url(), "test@example.com", "Eastern_43A1W", verify=False) - # test_request(conn3) - # - # # first connection should fail - # test_request(conn1) - - def test_delete_user(self): new_user = frappe.get_doc(dict(doctype='User', email='test-for-delete@example.com', first_name='Tester Delete User')).insert() @@ -227,6 +193,7 @@ class TestUser(unittest.TestCase): self.assertEqual(extract_mentions(comment)[0], "test_user@example.com") self.assertEqual(extract_mentions(comment)[1], "test.again@example1.com") + frappe.delete_doc("User Group", "Team") doc = frappe.get_doc({ 'doctype': 'User Group', 'name': 'Team', @@ -236,7 +203,8 @@ class TestUser(unittest.TestCase): 'user': 'test1@example.com' }] }) - doc.insert(ignore_if_duplicate=True) + + doc.insert() comment = '''
@@ -267,31 +235,36 @@ class TestUser(unittest.TestCase): self.assertEqual(res1.status_code, 200) self.assertEqual(res2.status_code, 417) - # def test_user_rollback(self): - # """ - # FIXME: This is failing with PR #12693 as Rollback can't happen if notifications sent on user creation. - # Make sure that notifications disabled. - # """ - # frappe.db.commit() - # frappe.db.begin() - # user_id = str(uuid.uuid4()) - # email = f'{user_id}@example.com' - # try: - # frappe.flags.in_import = True # disable throttling - # frappe.get_doc(dict( - # doctype='User', - # email=email, - # first_name=user_id, - # )).insert() - # finally: - # frappe.flags.in_import = False + def test_user_rename(self): + old_name = "test_user_rename@example.com" + new_name = "test_user_rename_new@example.com" + user = frappe.get_doc({ + "doctype": "User", + "email": old_name, + "enabled": 1, + "first_name": "_Test", + "new_password": "Eastern_43A1W", + "roles": [ + { + "doctype": "Has Role", + "parentfield": "roles", + "role": "System Manager" + }] + }).insert(ignore_permissions=True, ignore_if_duplicate=True) - # # Check user has been added - # self.assertIsNotNone(frappe.db.get("User", {"email": email})) + frappe.rename_doc('User', user.name, new_name) + self.assertTrue(frappe.db.exists("Notification Settings", new_name)) - # # Check that rollback works - # frappe.db.rollback() - # self.assertIsNone(frappe.db.get("User", {"email": email})) + frappe.delete_doc("User", new_name) + + def test_signup(self): + pass + + def test_password_update(self): + pass + + def test_password_verification(self): + pass def delete_contact(user): frappe.db.sql("DELETE FROM `tabContact` WHERE `email_id`= %s", user) From 475c3ec8b8eb13aa09922805a722f0d2f4d05c4f Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 10:24:12 +0530 Subject: [PATCH 08/74] fix: import error --- frappe/email/doctype/email_account/email_account.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index 78e0be1017..b29d4ee9cd 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -724,7 +724,7 @@ def get_max_email_uid(email_account): def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_outgoing): """ setup email inbox for user """ - from frappe.core.doctype.user import ask_pass_update + from frappe.core.doctype.user.user import ask_pass_update def add_user_email(user): user = frappe.get_doc("User", user) row = user.append("user_emails", {}) From 3e7e35351b043e6d36cc6e23a8250e6cf6e1d437 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 11:20:05 +0530 Subject: [PATCH 09/74] refactor: Move set_email_password code to email_account.py --- frappe/core/doctype/user/user.py | 13 ------------- .../email/doctype/email_account/email_account.py | 14 ++++++++++++++ frappe/public/js/frappe/desk.js | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 5e80083791..86d2f7726e 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -713,19 +713,6 @@ def get_email_awaiting(user): where parent = %(user)s""",{"user":user}) return False -@frappe.whitelist(allow_guest=False) -def set_email_password(email_account, user, password): - account = frappe.get_doc("Email Account", email_account) - if account.awaiting_password: - account.awaiting_password = 0 - account.password = password - try: - account.save(ignore_permissions=True) - except Exception: - frappe.db.rollback() - return False - - return True def ask_pass_update(): # update the sys defaults as to awaiting users from frappe.utils import set_default diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index b29d4ee9cd..a1ddbf7a68 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -786,3 +786,17 @@ def remove_user_email_inbox(email_account): [ doc.remove(row) for row in to_remove ] doc.save(ignore_permissions=True) + +@frappe.whitelist(allow_guest=False) +def set_email_password(email_account, user, password): + account = frappe.get_doc("Email Account", email_account) + if account.awaiting_password: + account.awaiting_password = 0 + account.password = password + try: + account.save(ignore_permissions=True) + except Exception: + frappe.db.rollback() + return False + + return True \ No newline at end of file diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 810b6a404a..99fc4da182 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -230,7 +230,7 @@ frappe.Application = class Application { s.fields_dict.checking.$wrapper.html(''); s.show(); frappe.call({ - method: 'frappe.core.doctype.user.user.set_email_password', + method: 'frappe.email.doctype.email_account.email_account.set_email_password', args: { "email_account": email_account[i]["email_account"], "user": user, From 7e72a0f304401c212a6460ba3cf5658ca28f7e26 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 11:21:31 +0530 Subject: [PATCH 10/74] fix: Disabled user check in signup --- frappe/core/doctype/user/user.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 86d2f7726e..378e10a409 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -764,10 +764,10 @@ def sign_up(email, full_name, redirect_to): user = frappe.db.get("User", {"email": email}) if user: - if user.disabled: - return 0, _("Registered but disabled") - else: + if user.enabled: return 0, _("Already Registered") + else: + return 0, _("Registered but disabled") else: if frappe.db.sql("""select count(*) from tabUser where HOUR(TIMEDIFF(CURRENT_TIMESTAMP, TIMESTAMP(modified)))=1""")[0][0] > 300: From 8924fd071606bb96ee01a383e11e96d077d85b87 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 11:22:04 +0530 Subject: [PATCH 11/74] test: Add signup test case --- frappe/core/doctype/user/test_user.py | 28 ++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 383967a549..41479fb05c 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -4,10 +4,11 @@ import frappe, unittest from frappe.model.delete_doc import delete_doc from frappe.utils import get_url -from frappe.core.doctype.user.user import test_password_strength -from frappe.core.doctype.user.user import extract_mentions +from frappe.core.doctype.user.user import test_password_strength, extract_mentions, sign_up from frappe.frappeclient import FrappeClient +from unittest.mock import patch + test_records = frappe.get_test_records('User') class TestUser(unittest.TestCase): @@ -258,7 +259,28 @@ class TestUser(unittest.TestCase): frappe.delete_doc("User", new_name) def test_signup(self): - pass + import frappe.website.utils + import frappe.exceptions + random_user = frappe.mock('email') + random_user_name = frappe.mock('name') + # disabled signup + with patch.object(frappe.core.doctype.user.user, "is_signup_disabled", return_value=True): + self.assertRaisesRegex(frappe.exceptions.ValidationError, "Sign Up is disabled", + sign_up, random_user, random_user_name, "/signup") + + self.assertTupleEqual(sign_up(random_user, random_user_name, "/welcome"), (1, "Please check your email for verification")) + self.assertEqual(frappe.cache().hget('redirect_after_login', random_user), "/welcome") + + # re-register + self.assertTupleEqual(sign_up(random_user, random_user_name, "/welcome"), (0, "Already Registered")) + + # disabled user + user = frappe.get_doc("User", random_user) + user.enabled = 0 + user.save() + + self.assertTupleEqual(sign_up(random_user, random_user_name, "/welcome"), (0, "Registered but disabled")) + def test_password_update(self): pass From d36d6055ae24469933993bf30458350a2b42dee5 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 13:45:39 +0530 Subject: [PATCH 12/74] refactor: Remove check demo and redundant code --- frappe/core/doctype/user/user.py | 46 ++++++++++++-------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 378e10a409..b33e6916f5 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -51,8 +51,6 @@ class User(Document): frappe.cache().delete_key('enabled_users') def validate(self): - self.check_demo() - # clear new password self.__new_password = self.new_password self.new_password = "" @@ -132,10 +130,6 @@ class User(Document): """Returns true if current user is the session user""" return self.name == frappe.session.user - def check_demo(self): - if frappe.session.user == 'demo@erpnext.com': - frappe.throw(_('Cannot change user details in demo. Please signup for a new account at https://erpnext.com'), title=_('Not Allowed')) - def set_full_name(self): self.full_name = " ".join(filter(None, [self.first_name, self.last_name])) @@ -393,7 +387,6 @@ class User(Document): def before_rename(self, old_name, new_name, merge=False): - self.check_demo() frappe.clear_cache(user=old_name) self.validate_rename(old_name, new_name) @@ -725,24 +718,19 @@ def ask_pass_update(): def _get_user_for_update_password(key, old_password): # verify old password + result = frappe._dict() if key: - user = frappe.db.get_value("User", {"reset_password_key": key}) - if not user: - return { - 'message': _("The Link specified has either been used before or Invalid") - } + result.user = frappe.db.get_value("User", {"reset_password_key": key}) + if not result.user: + result.message = _("The Link specified has either been used before or Invalid") elif old_password: # verify old password frappe.local.login_manager.check_password(frappe.session.user, old_password) user = frappe.session.user + result.user = user - else: - return - - return { - 'user': user - } + return result def reset_user_data(user): user_doc = frappe.get_doc("User", user) @@ -1048,18 +1036,18 @@ def generate_keys(user): :param user: str """ - if "System Manager" in frappe.get_roles(): - user_details = frappe.get_doc("User", user) - api_secret = frappe.generate_hash(length=15) - # if api key is not set generate api key - if not user_details.api_key: - api_key = frappe.generate_hash(length=15) - user_details.api_key = api_key - user_details.api_secret = api_secret - user_details.save() + frappe.only_for("System Manager") + user_details = frappe.get_doc("User", user) + api_secret = frappe.generate_hash(length=15) + # if api key is not set generate api key + if not user_details.api_key: + api_key = frappe.generate_hash(length=15) + user_details.api_key = api_key + user_details.api_secret = api_secret + user_details.save() + + return {"api_secret": api_secret} - return {"api_secret": api_secret} - frappe.throw(frappe._("Not Permitted"), frappe.PermissionError) @frappe.whitelist() def switch_theme(theme): From 81a59377518a566aca8c92a01eec8c2cfa05c7cc Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 13:47:58 +0530 Subject: [PATCH 13/74] test: Add "password update" test --- frappe/core/doctype/user/test_user.py | 59 +++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 41479fb05c..72650679ae 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -4,11 +4,14 @@ import frappe, unittest from frappe.model.delete_doc import delete_doc from frappe.utils import get_url -from frappe.core.doctype.user.user import test_password_strength, extract_mentions, sign_up +from frappe.core.doctype.user.user import (test_password_strength, + extract_mentions, sign_up, update_password, verify_password) from frappe.frappeclient import FrappeClient from unittest.mock import patch +import frappe.exceptions +user_module = frappe.core.doctype.user.user test_records = frappe.get_test_records('User') class TestUser(unittest.TestCase): @@ -21,7 +24,7 @@ class TestUser(unittest.TestCase): def test_user_type(self): new_user = frappe.get_doc(dict(doctype='User', email='test-for-type@example.com', - first_name='Tester')).insert() + first_name='Tester')).insert(ignore_if_duplicate=True) self.assertEqual(new_user.user_type, 'Website User') # social login userid for frappe @@ -119,7 +122,7 @@ class TestUser(unittest.TestCase): def test_delete_user(self): new_user = frappe.get_doc(dict(doctype='User', email='test-for-delete@example.com', - first_name='Tester Delete User')).insert() + first_name='Tester Delete User')).insert(ignore_if_duplicate=True) self.assertEqual(new_user.user_type, 'Website User') # role with desk access @@ -260,11 +263,10 @@ class TestUser(unittest.TestCase): def test_signup(self): import frappe.website.utils - import frappe.exceptions random_user = frappe.mock('email') random_user_name = frappe.mock('name') # disabled signup - with patch.object(frappe.core.doctype.user.user, "is_signup_disabled", return_value=True): + with patch.object(user_module, "is_signup_disabled", return_value=True): self.assertRaisesRegex(frappe.exceptions.ValidationError, "Sign Up is disabled", sign_up, random_user, random_user_name, "/signup") @@ -282,8 +284,51 @@ class TestUser(unittest.TestCase): self.assertTupleEqual(sign_up(random_user, random_user_name, "/welcome"), (0, "Registered but disabled")) - def test_password_update(self): - pass + def test_reset_password(self): + from frappe.utils import set_request + from frappe.auth import CookieManager + from frappe.auth import LoginManager + old_password = "Eastern_43A1W" + new_password = "easy_password" + + set_request(path="/random") + frappe.local.cookie_manager = CookieManager() + frappe.local.login_manager = LoginManager() + + frappe.set_user("test@example.com") + test_user = frappe.get_doc("User", "test@example.com") + test_user.reset_password() + frappe.cache().hset('redirect_after_login', test_user.email, "/some_portal_page") + self.assertEqual(update_password(new_password, key=test_user.reset_password_key), "/app") + self.assertEqual(update_password(new_password, key="wrong_key"), "The Link specified has either been used before or Invalid") + + # password verification should fail with old password + self.assertRaises(frappe.exceptions.AuthenticationError, verify_password, old_password) + verify_password(new_password) + + # reset password + update_password(old_password, old_password=new_password) + + self.assertRaisesRegex(frappe.exceptions.ValidationError, "Invalid key type", update_password, "test", 1, ['like', '%']) + + password_strength_response = { + "feedback": { + "password_policy_validation_passed": False, + "suggestions": ["Fix password"] + } + } + + # password strength failure test + with patch.object(user_module, "test_password_strength", return_value=password_strength_response): + self.assertRaisesRegex(frappe.exceptions.ValidationError, "Fix password", update_password, new_password, 0, test_user.reset_password_key) + + + # test redirect URL for website users + frappe.set_user("test2@example.com") + self.assertEqual(update_password(new_password, old_password=old_password), "/") + # reset password + update_password(old_password, old_password=new_password) + def test_password_verification(self): pass From 4a6b0e35df26edbf26f1cdee9fd4ef704f8b42cb Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 17 Aug 2021 14:06:39 +0530 Subject: [PATCH 14/74] fix: dom element for sections breaks in form tours --- frappe/public/js/frappe/form/form_tour.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/form_tour.js b/frappe/public/js/frappe/form/form_tour.js index 17547b243d..0694aa634a 100644 --- a/frappe/public/js/frappe/form/form_tour.js +++ b/frappe/public/js/frappe/form/form_tour.js @@ -82,10 +82,16 @@ frappe.ui.form.FormTour = class FormTour { get_step(step_info, on_next) { const { name, fieldname, title, description, position, is_table_field } = step_info; + let element = `.frappe-control[data-fieldname='${fieldname}']`; + const field = this.frm.get_field(fieldname); - let element = field ? field.wrapper : `.frappe-control[data-fieldname='${fieldname}']`; + if (field) { + // wrapper for section breaks returns in a list + element = field.wrapper[0] ? field.wrapper[0] : field.wrapper; + } if (is_table_field) { + // TODO: fix wrapper for grid sections element = `.grid-row-open .frappe-control[data-fieldname='${fieldname}']`; } From ddf4bb80b88403f1fa61f05e1d0e4d06e2bb5332 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 14:30:17 +0530 Subject: [PATCH 15/74] fix: Signup throttling for postgres --- frappe/core/doctype/user/user.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index b33e6916f5..3f91ebe54c 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -15,7 +15,6 @@ from frappe.desk.doctype.notification_settings.notification_settings import crea from frappe.utils.user import get_system_managers from frappe.website.utils import is_signup_disabled from frappe.rate_limiter import rate_limit -from frappe.utils.background_jobs import enqueue from frappe.core.doctype.user_type.user_type import user_linked_with_permission_on_doctype @@ -757,9 +756,7 @@ def sign_up(email, full_name, redirect_to): else: return 0, _("Registered but disabled") else: - if frappe.db.sql("""select count(*) from tabUser where - HOUR(TIMEDIFF(CURRENT_TIMESTAMP, TIMESTAMP(modified)))=1""")[0][0] > 300: - + if frappe.db.get_creation_count('User', 60) > 300: frappe.respond_as_web_page(_('Temporarily Disabled'), _('Too many users signed up recently, so the registration is disabled. Please try back in an hour'), http_status_code=429) From ba369da61b395c63e7aad096a36dbff22b446c9d Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 17 Aug 2021 14:33:34 +0530 Subject: [PATCH 16/74] test: Add test case to validate user signup throttling --- frappe/core/doctype/user/test_user.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 72650679ae..d901bfa608 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -283,6 +283,11 @@ class TestUser(unittest.TestCase): self.assertTupleEqual(sign_up(random_user, random_user_name, "/welcome"), (0, "Registered but disabled")) + # throttle user creation + with patch.object(user_module.frappe.db, "get_creation_count", return_value=301): + self.assertRaisesRegex(frappe.exceptions.ValidationError, "Throttled", + sign_up, frappe.mock('email'), random_user_name, "/signup") + def test_reset_password(self): from frappe.utils import set_request From 604263929f91ae03a69b28b82e4d750b5e4061a9 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Aug 2021 08:20:22 +0530 Subject: [PATCH 17/74] test: Add more assersions to test cases - for better coverage --- frappe/core/doctype/user/test_user.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index d901bfa608..6a6ec8d2f4 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -144,7 +144,7 @@ class TestUser(unittest.TestCase): self.assertFalse(frappe.db.exists('User', new_user.name)) def test_password_strength(self): - # Test Password without Password Strenth Policy + # Test Password without Password Strength Policy frappe.db.set_value("System Settings", "System Settings", "enable_password_policy", 0) # password policy is disabled, test_password_strength should be ignored @@ -163,6 +163,17 @@ class TestUser(unittest.TestCase): result = test_password_strength("Eastern_43A1W") self.assertEqual(result['feedback']['password_policy_validation_passed'], True) + + # test password strength while saving user with new password + user = frappe.get_doc("User", "test@example.com") + frappe.flags.in_test = False + user.new_password = "password" + self.assertRaisesRegex(frappe.exceptions.ValidationError, "Invalid Password", user.save) + user.reload() + user.new_password = "Eastern_43A1W" + user.save() + frappe.flags.in_test = True + def test_comment_mentions(self): comment = ''' @@ -215,7 +226,10 @@ class TestUser(unittest.TestCase): Testing comment for @Team - + and + + @Unknown Team + please check
''' From d1c63a4b54356505262be88cca5dda990df3a920 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Aug 2021 08:22:48 +0530 Subject: [PATCH 18/74] refactor: Move code to appropriate location - update_roles had no use in user.py so moved it to role_profile.py where it is actually used --- frappe/core/doctype/role_profile/role_profile.py | 9 +++++++-- frappe/core/doctype/user/user.py | 9 --------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/frappe/core/doctype/role_profile/role_profile.py b/frappe/core/doctype/role_profile/role_profile.py index 0f58da5b5e..986cf834eb 100644 --- a/frappe/core/doctype/role_profile/role_profile.py +++ b/frappe/core/doctype/role_profile/role_profile.py @@ -3,6 +3,7 @@ # For license information, please see license.txt from frappe.model.document import Document +import frappe class RoleProfile(Document): def autoname(self): @@ -11,5 +12,9 @@ class RoleProfile(Document): def on_update(self): """ Changes in role_profile reflected across all its user """ - from frappe.core.doctype.user.user import update_roles - update_roles(self.name) + users = frappe.get_all('User', filters={'role_profile_name': self.name}) + roles = [role.role for role in self.roles] + for d in users: + user = frappe.get_doc('User', d) + user.set('roles', []) + user.add_roles(*roles) diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index 3f91ebe54c..1336f6eab7 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -966,15 +966,6 @@ def get_module_profile(module_profile): module_profile = frappe.get_doc('Module Profile', {'module_profile_name': module_profile}) return module_profile.get('block_modules') -def update_roles(role_profile): - users = frappe.get_all('User', filters={'role_profile_name': role_profile}) - role_profile = frappe.get_doc('Role Profile', role_profile) - roles = [role.role for role in role_profile.roles] - for d in users: - user = frappe.get_doc('User', d) - user.set('roles', []) - user.add_roles(*roles) - def create_contact(user, ignore_links=False, ignore_mandatory=False): from frappe.contacts.doctype.contact.contact import get_contact_name if user.name in ["Administrator", "Guest"]: return From 7217277394cbc5d677463a9564af12bf3a1cc073 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Aug 2021 09:03:03 +0530 Subject: [PATCH 19/74] test: Fix flaky test --- frappe/core/doctype/user/test_user.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 6a6ec8d2f4..1ce22e758c 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -317,8 +317,9 @@ class TestUser(unittest.TestCase): frappe.set_user("test@example.com") test_user = frappe.get_doc("User", "test@example.com") test_user.reset_password() - frappe.cache().hset('redirect_after_login', test_user.email, "/some_portal_page") - self.assertEqual(update_password(new_password, key=test_user.reset_password_key), "/app") + pwd_key = test_user.reset_password_key + test_user.reload() + self.assertEqual(update_password(new_password, key=pwd_key), "/app") self.assertEqual(update_password(new_password, key="wrong_key"), "The Link specified has either been used before or Invalid") # password verification should fail with old password @@ -347,6 +348,7 @@ class TestUser(unittest.TestCase): self.assertEqual(update_password(new_password, old_password=old_password), "/") # reset password update_password(old_password, old_password=new_password) + frappe.set_user("Administrator") def test_password_verification(self): From 093c72e9635b8f0060645812871a3d5b98e4c384 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Aug 2021 09:04:01 +0530 Subject: [PATCH 20/74] test: Update role profile test case with more assertions --- .../doctype/role_profile/test_role_profile.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frappe/core/doctype/role_profile/test_role_profile.py b/frappe/core/doctype/role_profile/test_role_profile.py index 53e0a1b043..57b77d868b 100644 --- a/frappe/core/doctype/role_profile/test_role_profile.py +++ b/frappe/core/doctype/role_profile/test_role_profile.py @@ -8,6 +8,7 @@ test_dependencies = ['Role'] class TestRoleProfile(unittest.TestCase): def test_make_new_role_profile(self): + frappe.delete_doc_if_exists('Role Profile', 'Test 1', force=1) new_role_profile = frappe.get_doc(dict(doctype='Role Profile', role_profile='Test 1')).insert() self.assertEqual(new_role_profile.role_profile, 'Test 1') @@ -19,7 +20,25 @@ class TestRoleProfile(unittest.TestCase): new_role_profile.save() self.assertEqual(new_role_profile.roles[0].role, '_Test Role 2') + # user with a role profile + random_user = frappe.mock("email") + random_user_name = frappe.mock("name") + + random_user = frappe.get_doc({ + "doctype": "User", + "email": random_user, + "enabled": 1, + "first_name": random_user_name, + "new_password": "Eastern_43A1W", + "role_profile_name": 'Test 1' + }).insert(ignore_permissions=True, ignore_if_duplicate=True) + self.assertListEqual([role.role for role in random_user.roles], [role.role for role in new_role_profile.roles]) + # clear roles new_role_profile.roles = [] new_role_profile.save() self.assertEqual(new_role_profile.roles, []) + + # user roles with the role profile should also be updated + random_user.reload() + self.assertListEqual(random_user.roles, []) \ No newline at end of file From fe15028df3fa527dc0029678a1697232000cbb36 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 18 Aug 2021 10:20:08 +0530 Subject: [PATCH 21/74] test: Fix reset password test --- frappe/core/doctype/user/test_records.json | 16 +++++++++++++++- frappe/core/doctype/user/test_user.py | 8 +++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/frappe/core/doctype/user/test_records.json b/frappe/core/doctype/user/test_records.json index f9033d4660..21fe3ff69d 100644 --- a/frappe/core/doctype/user/test_records.json +++ b/frappe/core/doctype/user/test_records.json @@ -70,5 +70,19 @@ "role": "System Manager" } ] - } + }, + { + "doctype": "User", + "email": "testpassword@example.com", + "enabled": 1, + "first_name": "_Test", + "new_password": "Eastern_43A1W", + "roles": [ + { + "doctype": "Has Role", + "parentfield": "roles", + "role": "System Manager" + } + ] + } ] diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 1ce22e758c..6534e70235 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -314,12 +314,10 @@ class TestUser(unittest.TestCase): frappe.local.cookie_manager = CookieManager() frappe.local.login_manager = LoginManager() - frappe.set_user("test@example.com") - test_user = frappe.get_doc("User", "test@example.com") + frappe.set_user("testpassword@example.com") + test_user = frappe.get_doc("User", "testpassword@example.com") test_user.reset_password() - pwd_key = test_user.reset_password_key - test_user.reload() - self.assertEqual(update_password(new_password, key=pwd_key), "/app") + self.assertEqual(update_password(new_password, key=test_user.reset_password_key), "/app") self.assertEqual(update_password(new_password, key="wrong_key"), "The Link specified has either been used before or Invalid") # password verification should fail with old password From 68263b8663ba2e79622441209757db844c876be4 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 12:27:44 +0530 Subject: [PATCH 22/74] fix: App without home page gives error when navigate to home --- frappe/public/js/frappe/router.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 4360f3e887..c27e443c06 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -354,8 +354,8 @@ frappe.router = { return a; } }).join('/'); - - return '/app/' + (path_string || 'home'); + let default_page = frappe.workspaces['home'] ? 'home' : Object.keys(frappe.workspaces)[0]; + return '/app/' + (path_string || default_page); }, push_state(url) { From b96b4c90f76b5500ec6899265e2ea216e1c8f0eb Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 12:30:59 +0530 Subject: [PATCH 23/74] fix: Can't navigate to webpage with name same as private workspace --- frappe/public/js/frappe/router.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index c27e443c06..484f1ac911 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -129,7 +129,7 @@ frappe.router = { if (frappe.workspaces[route[0]]) { // public workspace route = ['Workspaces', frappe.workspaces[route[0]].title]; - } else if (frappe.workspaces[route[1]]) { + } else if (route[0] == 'private' && frappe.workspaces[route[1]]) { // private workspace route = ['Workspaces', 'private', frappe.workspaces[route[1]].title]; } else if (this.routes[route[0]]) { From 461dfd6c6e14a08fdd5f5e0e7bb06a1e8769192b Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 12:42:43 +0530 Subject: [PATCH 24/74] fix: Make Content hidden and added validation --- frappe/desk/doctype/workspace/workspace.json | 15 ++++++++------- frappe/desk/doctype/workspace/workspace.py | 3 +++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/frappe/desk/doctype/workspace/workspace.json b/frappe/desk/doctype/workspace/workspace.json index e2ae38faf1..e991ee3f8f 100644 --- a/frappe/desk/doctype/workspace/workspace.json +++ b/frappe/desk/doctype/workspace/workspace.json @@ -28,7 +28,6 @@ "pin_to_bottom", "hide_custom", "public", - "content_section", "content", "section_break_2", "charts_label", @@ -39,6 +38,7 @@ "section_break_18", "cards_label", "links", + "roles_section", "roles" ], "fields": [ @@ -239,14 +239,10 @@ "fieldtype": "Data", "label": "Parent Page" }, - { - "fieldname": "content_section", - "fieldtype": "Section Break", - "label": "Content" - }, { "fieldname": "content", "fieldtype": "Long Text", + "hidden": 1, "label": "Content" }, { @@ -259,10 +255,15 @@ "fieldtype": "Table", "label": "Roles", "options": "Has Role" + }, + { + "fieldname": "roles_section", + "fieldtype": "Section Break", + "label": "Roles" } ], "links": [], - "modified": "2021-08-05 11:49:09.028243", + "modified": "2021-08-19 12:36:29.825169", "modified_by": "Administrator", "module": "Desk", "name": "Workspace", diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index 0821ae03c4..693c34bcd1 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -17,6 +17,9 @@ class Workspace(Document): frappe.throw(_("You need to be in developer mode to edit this document")) validate_route_conflict(self.doctype, self.name) + if isinstance(self.content, list): + frappe.throw(_("Content data shoud be a list")) + duplicate_exists = frappe.db.exists("Workspace", { "name": ["!=", self.name], 'is_default': 1, 'extends': self.extends }) From 1032d3a7d1101b9e7d68032e7c9d7c244ca21cc3 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 12:49:45 +0530 Subject: [PATCH 25/74] fix: Removed default collapsing sidebar section --- frappe/public/js/frappe/views/workspace/workspace.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frappe/public/js/frappe/views/workspace/workspace.js b/frappe/public/js/frappe/views/workspace/workspace.js index b46c220d9d..8f11e711ca 100644 --- a/frappe/public/js/frappe/views/workspace/workspace.js +++ b/frappe/public/js/frappe/views/workspace/workspace.js @@ -174,10 +174,6 @@ frappe.views.Workspace = class Workspace { $(e.target).parent().find('.sidebar-item-container').toggleClass('hidden'); }); - if (!this.current_page.name) { - $title.trigger("click"); - } - if (Object.keys(root_pages).length === 0) { sidebar_section.addClass('hidden'); } From bb55ca4c29c584275ed6a14660552250da4744b9 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 12:51:40 +0530 Subject: [PATCH 26/74] fix: Make title and label field mandatory --- frappe/desk/doctype/workspace/workspace.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frappe/desk/doctype/workspace/workspace.json b/frappe/desk/doctype/workspace/workspace.json index e991ee3f8f..020f3153df 100644 --- a/frappe/desk/doctype/workspace/workspace.json +++ b/frappe/desk/doctype/workspace/workspace.json @@ -46,6 +46,7 @@ "fieldname": "label", "fieldtype": "Data", "label": "Name", + "reqd": 1, "unique": 1 }, { @@ -232,7 +233,8 @@ { "fieldname": "title", "fieldtype": "Data", - "label": "Title" + "label": "Title", + "reqd": 1 }, { "fieldname": "parent_page", @@ -263,7 +265,7 @@ } ], "links": [], - "modified": "2021-08-19 12:36:29.825169", + "modified": "2021-08-19 12:51:00.233017", "modified_by": "Administrator", "module": "Desk", "name": "Workspace", From 6a599f77ebf29a6e466ad44c75c915586ff8971a Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 14:07:52 +0530 Subject: [PATCH 27/74] fix: Content validation --- frappe/desk/doctype/workspace/workspace.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index 693c34bcd1..31ae5754c1 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -17,7 +17,10 @@ class Workspace(Document): frappe.throw(_("You need to be in developer mode to edit this document")) validate_route_conflict(self.doctype, self.name) - if isinstance(self.content, list): + try: + if not isinstance(loads(self.content), list): + raise + except: frappe.throw(_("Content data shoud be a list")) duplicate_exists = frappe.db.exists("Workspace", { From ca4d220f145d0678f2621e3631a8993c2c3d02b3 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Thu, 19 Aug 2021 14:20:18 +0530 Subject: [PATCH 28/74] fix: sider fix --- frappe/desk/doctype/workspace/workspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/desk/doctype/workspace/workspace.py b/frappe/desk/doctype/workspace/workspace.py index 31ae5754c1..7795d02616 100644 --- a/frappe/desk/doctype/workspace/workspace.py +++ b/frappe/desk/doctype/workspace/workspace.py @@ -20,7 +20,7 @@ class Workspace(Document): try: if not isinstance(loads(self.content), list): raise - except: + except Exception: frappe.throw(_("Content data shoud be a list")) duplicate_exists = frappe.db.exists("Workspace", { From c681b1af27fb3c975496e8b8679c4fff997586fd Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 14:40:20 +0530 Subject: [PATCH 29/74] fix: Make thumbnail function --- frappe/core/doctype/file/file.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index e79b2bd761..f09f5bcaa2 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -21,7 +21,7 @@ import zipfile import requests import requests.exceptions from PIL import Image, ImageFile, ImageOps -from io import StringIO +from io import BytesIO from urllib.parse import quote, unquote import frappe @@ -270,16 +270,12 @@ class File(Document): def make_thumbnail(self, set_as_thumbnail=True, width=300, height=300, suffix="small", crop=False): if self.file_url: - if self.file_url.startswith("/files"): - try: + try: + if self.file_url.startswith(("/files", "/private/files")): image, filename, extn = get_local_image(self.file_url) - except IOError: - return - - else: - try: + else: image, filename, extn = get_web_image(self.file_url) - except (requests.exceptions.HTTPError, requests.exceptions.SSLError, IOError, TypeError): + except (requests.exceptions.HTTPError, requests.exceptions.SSLError, IOError, TypeError): return size = width, height @@ -289,16 +285,13 @@ class File(Document): image.thumbnail(size, Image.ANTIALIAS) thumbnail_url = filename + "_" + suffix + "." + extn - path = os.path.abspath(frappe.get_site_path("public", thumbnail_url.lstrip("/"))) try: image.save(path) - if set_as_thumbnail: self.db_set("thumbnail_url", thumbnail_url) - self.db_set("thumbnail_url", thumbnail_url) except IOError: frappe.msgprint(_("Unable to write file format for {0}").format(path)) return @@ -704,7 +697,7 @@ def get_web_image(file_url): raise try: - image = Image.open(StringIO(frappe.safe_decode(r.content))) + image = Image.open(BytesIO(r.content)) except Exception as e: frappe.msgprint(_("Image link '{0}' is not valid").format(file_url), raise_exception=e) @@ -886,7 +879,7 @@ def extract_images_from_html(doc, content): if b"," in content: content = content.split(b",")[1] content = base64.b64decode(content) - + content = optimize_image(content, mtype) if "filename=" in headers: From 1427712c8817a01fa3631535eb15267fc5120465 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 14:41:25 +0530 Subject: [PATCH 30/74] test: Add test cases for file - file_url validations - make_thumbnail --- frappe/core/doctype/file/test_file.py | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index 649010c468..5b63da30ef 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -365,6 +365,58 @@ class TestFile(unittest.TestCase): file1.file_url = '/private/files/parent_dir2.txt' file1.save() + def test_file_url_validation(self): + test_file = frappe.get_doc({ + "doctype": "File", + "file_name": 'logo', + "file_url": 'https://frappe.io/files/frappe.png' + }) + + self.assertIsNone(test_file.validate()) + + # bad path + test_file.file_url = "/usr/bin/man" + self.assertRaisesRegex(frappe.exceptions.ValidationError, "URL must start with http:// or https://", test_file.validate) + + test_file.file_url = None + test_file.file_name = "/usr/bin/man" + self.assertRaisesRegex(frappe.exceptions.ValidationError, "There is some problem with the file url", test_file.validate) + + test_file.file_url = None + test_file.file_name = "_file" + self.assertRaisesRegex(IOError, "does not exist", test_file.validate) + + test_file.file_url = None + test_file.file_name = "/private/files/_file" + self.assertRaisesRegex(IOError, "does not exist", test_file.validate) + + def test_make_thumbnail(self): + # test web image + test_file = frappe.get_doc({ + "doctype": "File", + "file_name": 'logo', + "file_url": frappe.utils.get_url('/_test/assets/image.jpg'), + "docstatus": 0 + }).insert() + + test_file.make_thumbnail() + self.assertEquals(test_file.thumbnail_url, '/files/image_small.jpg') + + # test local image + test_file.db_set('thumbnail_url', None) + test_file.reload() + test_file.file_url = "/files/image_small.jpg" + test_file.make_thumbnail(suffix="xs") + self.assertEquals(test_file.thumbnail_url, '/files/image_small_xs.jpg') + + frappe.clear_messages() + test_file.db_set('thumbnail_url', None) + test_file.reload() + test_file.file_url = frappe.utils.get_url('unknown.jpg') + test_file.make_thumbnail(suffix="xs") + self.assertEqual(frappe.message_log[0], '{"message": "File \'http://test-site:8000/unknown.jpg\' not found"}') + self.assertEquals(test_file.thumbnail_url, None) + class TestAttachment(unittest.TestCase): test_doctype = 'Test For Attachment' From a7fb1816aa873e4afc8963f6dddc4b79640bfc9d Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 15:27:25 +0530 Subject: [PATCH 31/74] refactor: Remove unused and redundant code --- frappe/core/doctype/file/file.py | 75 ----------------- .../prepared_report/prepared_report.py | 3 +- frappe/desk/form/utils.py | 2 +- frappe/model/delete_doc.py | 2 +- frappe/utils/file_manager.py | 80 +++---------------- .../personal_data_download_request.py | 2 +- 6 files changed, 14 insertions(+), 150 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index f09f5bcaa2..b44a06876e 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -352,10 +352,6 @@ class File(Document): return files - def get_file_url(self): - data = frappe.db.get_value("File", self.file_data_name, ["file_name", "file_url"], as_dict=True) - return data.file_url or data.file_name - def exists_on_disk(self): exists = os.path.exists(self.get_full_path()) return exists @@ -424,33 +420,6 @@ class File(Document): return get_files_path(self.file_name, is_private=self.is_private) - def get_file_doc(self): - '''returns File object (Document) from given parameters or form_dict''' - r = frappe.form_dict - - if self.file_url is None: self.file_url = r.file_url - if self.file_name is None: self.file_name = r.file_name - if self.attached_to_doctype is None: self.attached_to_doctype = r.doctype - if self.attached_to_name is None: self.attached_to_name = r.docname - if self.attached_to_field is None: self.attached_to_field = r.docfield - if self.folder is None: self.folder = r.folder - if self.is_private is None: self.is_private = r.is_private - - if r.filedata: - file_doc = self.save_uploaded() - - elif r.file_url: - file_doc = self.save() - - return file_doc - - - def save_uploaded(self): - self.content = self.get_uploaded_content() - if self.content: - return self.save() - else: - raise Exception def get_uploaded_content(self): # should not be unicode when reading a file, hence using frappe.form @@ -532,14 +501,6 @@ class File(Document): 'file_url': self.file_url } - def get_file_data_from_hash(self): - for name in frappe.db.sql_list("select name from `tabFile` where content_hash=%s and is_private=%s", - (self.content_hash, self.is_private)): - b = frappe.get_doc('File', name) - return {k: b.get(k) for k in frappe.get_hooks()['write_file_keys']} - return False - - def check_max_file_size(self): max_file_size = get_max_file_size() file_size = len(self.content) @@ -733,48 +694,12 @@ def delete_file(path): os.remove(path) -def remove_file(fid=None, attached_to_doctype=None, attached_to_name=None, from_delete=False, delete_permanently=False): - """Remove file and File entry""" - file_name = None - if not (attached_to_doctype and attached_to_name): - attached = frappe.db.get_value("File", fid, - ["attached_to_doctype", "attached_to_name", "file_name"]) - if attached: - attached_to_doctype, attached_to_name, file_name = attached - - ignore_permissions, comment = False, None - if attached_to_doctype and attached_to_name and not from_delete: - doc = frappe.get_doc(attached_to_doctype, attached_to_name) - ignore_permissions = doc.has_permission("write") or False - if frappe.flags.in_web_form: - ignore_permissions = True - if not file_name: - file_name = frappe.db.get_value("File", fid, "file_name") - comment = doc.add_comment("Attachment Removed", _("Removed {0}").format(file_name)) - frappe.delete_doc("File", fid, ignore_permissions=ignore_permissions, delete_permanently=delete_permanently) - - return comment def get_max_file_size(): return cint(conf.get('max_file_size')) or 10485760 -def remove_all(dt, dn, from_delete=False, delete_permanently=False): - """remove all files in a transaction""" - try: - for fid in frappe.db.sql_list("""select name from `tabFile` where - attached_to_doctype=%s and attached_to_name=%s""", (dt, dn)): - if from_delete: - # If deleting a doc, directly delete files - frappe.delete_doc("File", fid, ignore_permissions=True, delete_permanently=delete_permanently) - else: - # Removes file and adds a comment in the document it is attached to - remove_file(fid=fid, attached_to_doctype=dt, attached_to_name=dn, - from_delete=from_delete, delete_permanently=delete_permanently) - except Exception as e: - if e.args[0]!=1054: raise # (temp till for patched) - def has_permission(doc, ptype=None, user=None): has_access = False diff --git a/frappe/core/doctype/prepared_report/prepared_report.py b/frappe/core/doctype/prepared_report/prepared_report.py index c68bb6a4f1..409aa6f217 100644 --- a/frappe/core/doctype/prepared_report/prepared_report.py +++ b/frappe/core/doctype/prepared_report/prepared_report.py @@ -11,8 +11,7 @@ from frappe.desk.query_report import generate_report_result from frappe.model.document import Document from frappe.utils import gzip_compress, gzip_decompress from frappe.utils.background_jobs import enqueue -from frappe.core.doctype.file.file import remove_all - +from frappe.utils.file_manager import remove_all class PreparedReport(Document): def before_insert(self): diff --git a/frappe/desk/form/utils.py b/frappe/desk/form/utils.py index bfceee6ea2..d7ac940d21 100644 --- a/frappe/desk/form/utils.py +++ b/frappe/desk/form/utils.py @@ -5,7 +5,7 @@ import frappe, json import frappe.desk.form.meta import frappe.desk.form.load from frappe.desk.form.document_follow import follow_document -from frappe.utils.file_manager import extract_images_from_html +from frappe.core.doctype.file.file import extract_images_from_html from frappe import _ diff --git a/frappe/model/delete_doc.py b/frappe/model/delete_doc.py index fbbf1a4852..c2f750b744 100644 --- a/frappe/model/delete_doc.py +++ b/frappe/model/delete_doc.py @@ -10,7 +10,7 @@ import frappe.model.meta from frappe import _ from frappe import get_module_path from frappe.model.dynamic_links import get_dynamic_link_map -from frappe.core.doctype.file.file import remove_all +from frappe.utils.file_manager import remove_all from frappe.utils.password import delete_all_passwords_for from frappe.model.naming import revert_series_if_last from frappe.utils.global_search import delete_for_document diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py index 7efdff299b..eb4556c47c 100644 --- a/frappe/utils/file_manager.py +++ b/frappe/utils/file_manager.py @@ -213,28 +213,22 @@ def write_file(content, fname, is_private=0): return get_files_path(fname, is_private=is_private) -def remove_all(dt, dn, from_delete=False): +def remove_all(dt, dn, from_delete=False, delete_permanently=False): """remove all files in a transaction""" try: for fid in frappe.db.sql_list("""select name from `tabFile` where attached_to_doctype=%s and attached_to_name=%s""", (dt, dn)): - remove_file(fid, dt, dn, from_delete) + if from_delete: + # If deleting a doc, directly delete files + frappe.delete_doc("File", fid, ignore_permissions=True, delete_permanently=delete_permanently) + else: + # Removes file and adds a comment in the document it is attached to + remove_file(fid=fid, attached_to_doctype=dt, attached_to_name=dn, + from_delete=from_delete, delete_permanently=delete_permanently) except Exception as e: if e.args[0]!=1054: raise # (temp till for patched) - -def remove_file_by_url(file_url, doctype=None, name=None): - if doctype and name: - fid = frappe.db.get_value("File", {"file_url": file_url, - "attached_to_doctype": doctype, "attached_to_name": name}) - else: - fid = frappe.db.get_value("File", {"file_url": file_url}) - - if fid: - return remove_file(fid) - - -def remove_file(fid, attached_to_doctype=None, attached_to_name=None, from_delete=False): +def remove_file(fid=None, attached_to_doctype=None, attached_to_name=None, from_delete=False, delete_permanently=False): """Remove file and File entry""" file_name = None if not (attached_to_doctype and attached_to_name): @@ -252,8 +246,7 @@ def remove_file(fid, attached_to_doctype=None, attached_to_name=None, from_delet if not file_name: file_name = frappe.db.get_value("File", fid, "file_name") comment = doc.add_comment("Attachment Removed", _("Removed {0}").format(file_name)) - - frappe.delete_doc("File", fid, ignore_permissions=ignore_permissions) + frappe.delete_doc("File", fid, ignore_permissions=ignore_permissions, delete_permanently=delete_permanently) return comment @@ -372,59 +365,6 @@ def download_file(file_url): frappe.local.response.filecontent = filedata frappe.local.response.type = "download" -def extract_images_from_doc(doc, fieldname): - content = doc.get(fieldname) - content = extract_images_from_html(doc, content) - if frappe.flags.has_dataurl: - doc.set(fieldname, content) - - -def extract_images_from_html(doc, content): - frappe.flags.has_dataurl = False - - def _save_file(match): - data = match.group(1) - data = data.split("data:")[1] - headers, content = data.split(",") - mtype = headers.split(";")[0] - - if isinstance(content, str): - content = content.encode("utf-8") - if b"," in content: - content = content.split(b",")[1] - content = base64.b64decode(content) - - content = optimize_image(content, mtype) - - if "filename=" in headers: - filename = headers.split("filename=")[-1] - - # decode filename - if not isinstance(filename, str): - filename = str(filename, 'utf-8') - else: - filename = get_random_filename(content_type=mtype) - - doctype = doc.parenttype if doc.parent else doc.doctype - name = doc.parent or doc.name - - if doc.doctype == "Comment": - doctype = doc.reference_doctype - name = doc.reference_name - - # TODO fix this - file_url = save_file(filename, content, doctype, name, decode=False).get("file_url") - if not frappe.flags.has_dataurl: - frappe.flags.has_dataurl = True - - return ']*src\s*=\s*["\'](?=data:)(.*?)["\']', _save_file, content) - - return content - - def get_random_filename(extn=None, content_type=None): if extn: if not extn.startswith("."): diff --git a/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py b/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py index 9255adb8c2..e74e8190c4 100644 --- a/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py +++ b/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py @@ -28,7 +28,7 @@ class PersonalDataDownloadRequest(Document): }) f.save(ignore_permissions=True) - file_link = frappe.utils.get_url("/api/method/frappe.core.doctype.file.file.download_file") +\ + file_link = frappe.utils.get_url("/api/method/frappe.utils.file_manager.download_file") +\ "?" + get_signed_params({"file_url": f.file_url}) host_name = frappe.local.site frappe.sendmail( From 6b1955b34afafa930c0c8882ef76f05a23a1e2eb Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 15:27:48 +0530 Subject: [PATCH 32/74] test: Add test image file --- frappe/core/doctype/file/test_file.py | 2 +- frappe/www/_test/assets/image.jpg | Bin 0 -> 161713 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 frappe/www/_test/assets/image.jpg diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index 5b63da30ef..1920148fca 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -397,7 +397,7 @@ class TestFile(unittest.TestCase): "file_name": 'logo', "file_url": frappe.utils.get_url('/_test/assets/image.jpg'), "docstatus": 0 - }).insert() + }).insert(ignore_permissions=True) test_file.make_thumbnail() self.assertEquals(test_file.thumbnail_url, '/files/image_small.jpg') diff --git a/frappe/www/_test/assets/image.jpg b/frappe/www/_test/assets/image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4a2c1552b991add9a356a460415626ad700f401b GIT binary patch literal 161713 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 literal 0 HcmV?d00001 From 21e664b23b07797765b79d42fc222985277e8ff7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 16:02:20 +0530 Subject: [PATCH 33/74] test: Fix file_name assertion --- frappe/core/doctype/file/test_file.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index 1920148fca..ce971221c5 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -2,6 +2,7 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # See license.txt import base64 +import json import frappe import os import unittest @@ -414,7 +415,7 @@ class TestFile(unittest.TestCase): test_file.reload() test_file.file_url = frappe.utils.get_url('unknown.jpg') test_file.make_thumbnail(suffix="xs") - self.assertEqual(frappe.message_log[0], '{"message": "File \'http://test-site:8000/unknown.jpg\' not found"}') + self.assertEqual(json.loads(frappe.message_log[0]), {"message": f"File '{frappe.utils.get_url('unknown.jpg')}' not found"}) self.assertEquals(test_file.thumbnail_url, None) class TestAttachment(unittest.TestCase): From 44c82276e830f7b720703e1aeffdfd724013fc0c Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 17:37:01 +0530 Subject: [PATCH 34/74] refactor: Remove unused methods --- frappe/utils/file_manager.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py index eb4556c47c..b1e088d641 100644 --- a/frappe/utils/file_manager.py +++ b/frappe/utils/file_manager.py @@ -365,23 +365,6 @@ def download_file(file_url): frappe.local.response.filecontent = filedata frappe.local.response.type = "download" -def get_random_filename(extn=None, content_type=None): - if extn: - if not extn.startswith("."): - extn = "." + extn - - elif content_type: - extn = mimetypes.guess_extension(content_type) - - return random_string(7) + (extn or "") - -@frappe.whitelist(allow_guest=True) -def validate_filename(filename): - from frappe.utils import now_datetime - timestamp = now_datetime().strftime(" %Y-%m-%d %H:%M:%S") - fname = get_file_name(filename, timestamp) - return fname - @frappe.whitelist() def add_attachments(doctype, name, attachments): '''Add attachments to the given DocType''' From bc234e9052d8de5f9c8a59fa51379d750f7c537c Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 17:38:09 +0530 Subject: [PATCH 35/74] test: Add test case for extract_image_from_doc --- frappe/core/doctype/file/test_file.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index ce971221c5..72fe3491d1 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -522,3 +522,22 @@ class TestAttachmentsAccess(unittest.TestCase): frappe.set_user('Administrator') frappe.db.rollback() + + +class TestFileUtils(unittest.TestCase): + def test_extract_images_from_doc(self): + # with filename in data URI + todo = frappe.get_doc({ + "doctype": "ToDo", + "description": 'Test ' + }).insert() + self.assertTrue(frappe.db.exists("File", {"attached_to_name": todo.name})) + self.assertIn('', todo.description) + + # withot filename in data URI + todo = frappe.get_doc({ + "doctype": "ToDo", + "description": 'Test ' + }).insert() + filename = frappe.db.exists("File", {"attached_to_name": todo.name}) + self.assertIn(f' Date: Thu, 19 Aug 2021 17:39:45 +0530 Subject: [PATCH 36/74] fix: File name from data URI headers --- frappe/core/doctype/file/file.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index b44a06876e..85e9a5f27b 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -25,7 +25,7 @@ from io import BytesIO from urllib.parse import quote, unquote import frappe -from frappe import _, conf +from frappe import _, conf, safe_decode from frappe.model.document import Document from frappe.utils import call_hook_method, cint, cstr, encode, get_files_path, get_hook_method, random_string, strip from frappe.utils.image import strip_exif_data, optimize_image @@ -809,10 +809,8 @@ def extract_images_from_html(doc, content): if "filename=" in headers: filename = headers.split("filename=")[-1] + filename = safe_decode(filename).split(";")[0] - # decode filename - if not isinstance(filename, str): - filename = str(filename, 'utf-8') else: filename = get_random_filename(content_type=mtype) @@ -840,12 +838,9 @@ def extract_images_from_html(doc, content): return content -def get_random_filename(extn=None, content_type=None): - if extn: - if not extn.startswith("."): - extn = "." + extn - - elif content_type: +def get_random_filename(content_type=None): + extn = None + if content_type: extn = mimetypes.guess_extension(content_type) return random_string(7) + (extn or "") @@ -897,13 +892,6 @@ def get_attached_images(doctype, names): return out -@frappe.whitelist() -def validate_filename(filename): - from frappe.utils import now_datetime - timestamp = now_datetime().strftime(" %Y-%m-%d %H:%M:%S") - fname = get_file_name(filename, timestamp) - return fname - @frappe.whitelist() def get_files_in_folder(folder, start=0, page_length=20): start = cint(start) From 1cf1bc1e068e38a9932cd4823a3a58c080dec621 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 17:48:40 +0530 Subject: [PATCH 37/74] refactor: Remove unused functions --- frappe/core/doctype/file/file.py | 14 -------------- frappe/utils/csvutils.py | 11 +---------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 85e9a5f27b..8d0eee8c69 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -420,20 +420,6 @@ class File(Document): return get_files_path(self.file_name, is_private=self.is_private) - - def get_uploaded_content(self): - # should not be unicode when reading a file, hence using frappe.form - if 'filedata' in frappe.form_dict: - if "," in frappe.form_dict.filedata: - frappe.form_dict.filedata = frappe.form_dict.filedata.rsplit(",", 1)[1] - frappe.uploaded_content = base64.b64decode(frappe.form_dict.filedata) - return frappe.uploaded_content - elif self.content: - return self.content - frappe.msgprint(_('No file attached')) - return None - - def save_file(self, content=None, decode=False, ignore_existing_file_check=False): file_exists = False self.content = content diff --git a/frappe/utils/csvutils.py b/frappe/utils/csvutils.py index 734d68fe8a..69b7f6f2d3 100644 --- a/frappe/utils/csvutils.py +++ b/frappe/utils/csvutils.py @@ -6,16 +6,7 @@ import json import csv import requests from io import StringIO -from frappe.utils import encode, cstr, cint, flt, comma_or - -def read_csv_content_from_uploaded_file(ignore_encoding=False): - if getattr(frappe, "uploaded_file", None): - with open(frappe.uploaded_file, "r") as upfile: - fcontent = upfile.read() - else: - _file = frappe.new_doc("File") - fcontent = _file.get_uploaded_content() - return read_csv_content(fcontent, ignore_encoding) +from frappe.utils import cstr, cint, flt, comma_or def read_csv_content_from_attached_file(doc): fileid = frappe.get_all("File", fields = ["name"], filters = {"attached_to_doctype": doc.doctype, From 133be72dfdbb9a108bd10e49f8b33f0ed4c4b331 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 18:21:40 +0530 Subject: [PATCH 38/74] fix: Do frappe.db.commit() only for GET request --- frappe/core/doctype/access_log/access_log.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/access_log/access_log.py b/frappe/core/doctype/access_log/access_log.py index 2ea014f981..82db450b4a 100644 --- a/frappe/core/doctype/access_log/access_log.py +++ b/frappe/core/doctype/access_log/access_log.py @@ -29,4 +29,5 @@ def make_access_log(doctype=None, document=None, method=None, file_type=None, doc.insert(ignore_permissions=True) # `frappe.db.commit` added because insert doesnt `commit` when called in GET requests like `printview` - frappe.db.commit() + if frappe.request and frappe.request.method == 'GET': + frappe.db.commit() From 6b789ec53ad789416638bd0ee34fcd739bf010e4 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 18:44:36 +0530 Subject: [PATCH 39/74] fix: Revert auto_commit after frappe.sendmail --- frappe/email/doctype/newsletter/newsletter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/email/doctype/newsletter/newsletter.py b/frappe/email/doctype/newsletter/newsletter.py index 667d0fb34c..a118240488 100755 --- a/frappe/email/doctype/newsletter/newsletter.py +++ b/frappe/email/doctype/newsletter/newsletter.py @@ -165,6 +165,7 @@ class Newsletter(WebsiteGenerator): sender = self.send_from or frappe.utils.get_formatted_email(self.owner) args = {"message": message, "name": self.name} + is_auto_commit_set = bool(frappe.db.auto_commit_on_many_writes) frappe.db.auto_commit_on_many_writes = not frappe.flags.in_test frappe.sendmail( @@ -184,7 +185,7 @@ class Newsletter(WebsiteGenerator): args=args, ) - frappe.db.auto_commit_on_many_writes = not frappe.flags.in_test + frappe.db.auto_commit_on_many_writes = is_auto_commit_set def get_message(self) -> str: if self.content_type == "HTML": From 07906594e3fb8cb24417932eb327132e282296d4 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 19:33:37 +0530 Subject: [PATCH 40/74] test: Fix failing test --- frappe/core/doctype/file/test_file.py | 2 +- frappe/core/doctype/user/test_user.py | 2 +- frappe/desk/doctype/notification_log/test_notification_log.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index 72fe3491d1..df0ba8c2ec 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -534,7 +534,7 @@ class TestFileUtils(unittest.TestCase): self.assertTrue(frappe.db.exists("File", {"attached_to_name": todo.name})) self.assertIn('', todo.description) - # withot filename in data URI + # without filename in data URI todo = frappe.get_doc({ "doctype": "ToDo", "description": 'Test ' diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 6534e70235..5fea8ed9d8 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -346,7 +346,7 @@ class TestUser(unittest.TestCase): self.assertEqual(update_password(new_password, old_password=old_password), "/") # reset password update_password(old_password, old_password=new_password) - frappe.set_user("Administrator") + def test_password_verification(self): diff --git a/frappe/desk/doctype/notification_log/test_notification_log.py b/frappe/desk/doctype/notification_log/test_notification_log.py index af4dee8df3..2d232cf942 100644 --- a/frappe/desk/doctype/notification_log/test_notification_log.py +++ b/frappe/desk/doctype/notification_log/test_notification_log.py @@ -55,6 +55,6 @@ def get_todo(): def get_user(): users = frappe.db.get_all('User', - filters={'name': ('not in', ['Administrator', 'Guest'])}, + filters={'name': ('not in', ['Administrator', 'Guest']), 'enabled': 1}, fields='name', limit=1) return users[0].name From c00a5003f482dd37326495ceda2cb418f5317839 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 19:46:50 +0530 Subject: [PATCH 41/74] refactor(tests): frappe.db.delete > frappe.db.sql Use frappe.db.delete wherever possible. Get rid of all the frappe.db.sql ;) This commit focuses on the frappe.tests module --- frappe/tests/test_assign.py | 2 +- frappe/tests/test_db_query.py | 2 +- frappe/tests/test_domainification.py | 6 +++--- frappe/tests/test_dynamic_links.py | 2 +- frappe/tests/test_email.py | 8 ++++---- frappe/tests/test_frappe_client.py | 24 ++++++++++++------------ frappe/tests/test_global_search.py | 10 +++++----- frappe/tests/test_goal.py | 2 +- frappe/tests/test_naming.py | 16 ++++++++-------- frappe/tests/test_permissions.py | 8 ++++---- frappe/tests/test_scheduler.py | 2 +- 11 files changed, 41 insertions(+), 41 deletions(-) diff --git a/frappe/tests/test_assign.py b/frappe/tests/test_assign.py index e9c1ccec6d..e553fc3f5d 100644 --- a/frappe/tests/test_assign.py +++ b/frappe/tests/test_assign.py @@ -22,7 +22,7 @@ class TestAssign(unittest.TestCase): self.assertEqual(len(assignments), 0) def test_assignment_count(self): - frappe.db.sql('delete from tabToDo') + frappe.db.delete("ToDo") if not frappe.db.exists("User", "test_assign1@example.com"): frappe.get_doc({"doctype":"User", "email":"test_assign1@example.com", "first_name":"Test", "roles": [{"role": "System Manager"}]}).insert() diff --git a/frappe/tests/test_db_query.py b/frappe/tests/test_db_query.py index 89975b46d6..3724b46d9d 100644 --- a/frappe/tests/test_db_query.py +++ b/frappe/tests/test_db_query.py @@ -105,7 +105,7 @@ class TestReportview(unittest.TestCase): def test_between_filters(self): """ test case to check between filter for date fields """ - frappe.db.sql("delete from tabEvent") + frappe.db.delete("Event") # create events to test the between operator filter todays_event = create_event() diff --git a/frappe/tests/test_domainification.py b/frappe/tests/test_domainification.py index c9acd9ec45..bc972efe1f 100644 --- a/frappe/tests/test_domainification.py +++ b/frappe/tests/test_domainification.py @@ -17,9 +17,9 @@ class TestDomainification(unittest.TestCase): self.add_active_domain("_Test Domain 1") def tearDown(self): - frappe.db.sql("delete from tabRole where name='_Test Role'") - frappe.db.sql("delete from `tabHas Role` where role='_Test Role'") - frappe.db.sql("delete from tabDomain where name in ('_Test Domain 1', '_Test Domain 2')") + frappe.db.delete("Role", {"name": "_Test Role"}) + frappe.db.delete("Has Role", {"role": "_Test Role"}) + frappe.db.delete("Domain", {"name": ("in", ("_Test Domain 1", "_Test Domain 2"))}) frappe.delete_doc('DocType', 'Test Domainification') self.remove_from_active_domains(remove_all=True) diff --git a/frappe/tests/test_dynamic_links.py b/frappe/tests/test_dynamic_links.py index 04ccc91ff2..5ca12ddf13 100644 --- a/frappe/tests/test_dynamic_links.py +++ b/frappe/tests/test_dynamic_links.py @@ -4,7 +4,7 @@ import frappe, unittest class TestDynamicLinks(unittest.TestCase): def setUp(self): - frappe.db.sql('delete from `tabEmail Unsubscribe`') + frappe.db.delete("Email Unsubscribe") def test_delete_normal(self): event = frappe.get_doc({ diff --git a/frappe/tests/test_email.py b/frappe/tests/test_email.py index a837a2c572..68ab80cb8b 100644 --- a/frappe/tests/test_email.py +++ b/frappe/tests/test_email.py @@ -7,9 +7,9 @@ test_dependencies = ['Email Account'] class TestEmail(unittest.TestCase): def setUp(self): - frappe.db.sql("""delete from `tabEmail Unsubscribe`""") - frappe.db.sql("""delete from `tabEmail Queue`""") - frappe.db.sql("""delete from `tabEmail Queue Recipient`""") + frappe.db.delete("Email Unsubscribe") + frappe.db.delete("Email Queue") + frappe.db.delete("Email Queue Recipient") def test_email_queue(self, send_after=None): frappe.sendmail(recipients=['test@example.com', 'test1@example.com'], @@ -170,7 +170,7 @@ class TestEmail(unittest.TestCase): import re email_account = frappe.get_doc('Email Account', '_Test Email Account 1') - frappe.db.sql('''delete from `tabCommunication` where sender = 'sukh@yyy.com' ''') + frappe.db.delete("Communication", {"sender": "sukh@yyy.com"}) with open(frappe.get_app_path('frappe', 'tests', 'data', 'email_with_image.txt'), 'r') as raw: mails = email_account.get_inbound_mails(test_mails=[raw.read()]) diff --git a/frappe/tests/test_frappe_client.py b/frappe/tests/test_frappe_client.py index e1cdbb6ccd..556828f843 100644 --- a/frappe/tests/test_frappe_client.py +++ b/frappe/tests/test_frappe_client.py @@ -12,7 +12,7 @@ import base64 class TestFrappeClient(unittest.TestCase): def test_insert_many(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabNote` where title in ('Sing','a','song','of','sixpence')") + frappe.db.delete("Note", {"title": ("in", ('Sing','a','song','of','sixpence'))}) frappe.db.commit() server.insert_many([ @@ -31,7 +31,7 @@ class TestFrappeClient(unittest.TestCase): def test_create_doc(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabNote` where title = 'test_create'") + frappe.db.delete("Note", {"title": "test_create"}) frappe.db.commit() server.insert({"doctype": "Note", "public": True, "title": "test_create"}) @@ -46,7 +46,7 @@ class TestFrappeClient(unittest.TestCase): def test_get_doc(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabNote` where title = 'get_this'") + frappe.db.delete("Note", {"title": "get_this"}) frappe.db.commit() server.insert_many([ @@ -57,7 +57,7 @@ class TestFrappeClient(unittest.TestCase): def test_get_value(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabNote` where title = 'get_value'") + frappe.db.delete("Note", {"title": "get_value"}) frappe.db.commit() test_content = "test get value" @@ -82,7 +82,7 @@ class TestFrappeClient(unittest.TestCase): def test_update_doc(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabNote` where title in ('Sing','sing')") + frappe.db.delete("Note", {"title": ("in" ("Sing", "sing"))}) frappe.db.commit() server.insert({"doctype":"Note", "public": True, "title": "Sing"}) @@ -94,12 +94,12 @@ class TestFrappeClient(unittest.TestCase): def test_update_child_doc(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabContact` where first_name = 'George' and last_name = 'Steevens'") - frappe.db.sql("delete from `tabContact` where first_name = 'William' and last_name = 'Shakespeare'") - frappe.db.sql("delete from `tabCommunication` where reference_doctype = 'Event'") - frappe.db.sql("delete from `tabCommunication Link` where link_doctype = 'Contact'") - frappe.db.sql("delete from `tabEvent` where subject = 'Sing a song of sixpence'") - frappe.db.sql("delete from `tabEvent Participants` where reference_doctype = 'Contact'") + frappe.db.delete("Contact", {"first_name": "George", "last_name": "Steevens"}) + frappe.db.delete("Contact", {"first_name": "William", "last_name": "Shakespeare"}) + frappe.db.delete("Communication", {"reference_doctype": "Event"}) + frappe.db.delete("Communication Link", {"link_doctype": "Contact"}) + frappe.db.delete("Event", {"subject": "Sing a song of sixpence"}) + frappe.db.delete("Event Participants", {"reference_doctype": "Contact"}) frappe.db.commit() # create multiple contacts @@ -131,7 +131,7 @@ class TestFrappeClient(unittest.TestCase): def test_delete_doc(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.sql("delete from `tabNote` where title = 'delete'") + frappe.db.delete("Note", {"title": "delete"}) frappe.db.commit() server.insert_many([ diff --git a/frappe/tests/test_global_search.py b/frappe/tests/test_global_search.py index 3921af6738..c227abfb99 100644 --- a/frappe/tests/test_global_search.py +++ b/frappe/tests/test_global_search.py @@ -24,15 +24,15 @@ class TestGlobalSearch(unittest.TestCase): make_property_setter(doctype, "repeat_on", "in_global_search", 0, "Int") def tearDown(self): - frappe.db.sql("DELETE FROM `tabProperty Setter` WHERE `doc_type`='Event'") + frappe.db.delete("Property Setter", {"doc_type": "Event"}) frappe.clear_cache(doctype='Event') - frappe.db.sql('DELETE FROM `tabEvent`') - frappe.db.sql('DELETE FROM `__global_search`') + frappe.db.delete("Event") + frappe.db.delete("__global_search") make_test_objects('Event') frappe.db.commit() def insert_test_events(self): - frappe.db.sql('DELETE FROM `tabEvent`') + frappe.db.delete("Event") phrases = ['"The Sixth Extinction II: Amor Fati" is the second episode of the seventh season of the American science fiction.', 'After Mulder awakens from his coma, he realizes his duty to prevent alien colonization. ', 'Carter explored themes of extraterrestrial involvement in ancient mass extinctions in this episode, the third in a trilogy.'] @@ -97,7 +97,7 @@ class TestGlobalSearch(unittest.TestCase): self.assertEqual(len(results), 0) def test_insert_child_table(self): - frappe.db.sql('delete from tabEvent') + frappe.db.delete("Event") phrases = ['Hydrus is a small constellation in the deep southern sky. ', 'It was first depicted on a celestial atlas by Johann Bayer in his 1603 Uranometria. ', 'The French explorer and astronomer Nicolas Louis de Lacaille charted the brighter stars and gave their Bayer designations in 1756. ', diff --git a/frappe/tests/test_goal.py b/frappe/tests/test_goal.py index 5a83baa1af..55b1b9aad8 100644 --- a/frappe/tests/test_goal.py +++ b/frappe/tests/test_goal.py @@ -13,7 +13,7 @@ class TestGoal(unittest.TestCase): make_test_objects('Event', reset=True) def tearDown(self): - frappe.db.sql('delete from `tabEvent`') + frappe.db.delete("Event") # make_test_objects('Event', reset=True) frappe.db.commit() diff --git a/frappe/tests/test_naming.py b/frappe/tests/test_naming.py index 830c39442e..3a8e2445d7 100644 --- a/frappe/tests/test_naming.py +++ b/frappe/tests/test_naming.py @@ -72,7 +72,7 @@ class TestNaming(unittest.TestCase): current_index = frappe.db.sql("""SELECT current from `tabSeries` where name = %s""", series, as_dict=True)[0] self.assertEqual(current_index.get('current'), 0) - frappe.db.sql("""delete from `tabSeries` where name = %s""", series) + frappe.db.delete("Series", {"name": series}) series = 'TEST-{}-'.format(year) key = 'TEST-.YYYY.-.#####' @@ -82,40 +82,40 @@ class TestNaming(unittest.TestCase): current_index = frappe.db.sql("""SELECT current from `tabSeries` where name = %s""", series, as_dict=True)[0] self.assertEqual(current_index.get('current'), 1) - frappe.db.sql("""delete from `tabSeries` where name = %s""", series) + frappe.db.delete("Series", {"name": series}) series = 'TEST-' key = 'TEST-' name = 'TEST-00003' - frappe.db.sql("DELETE FROM `tabSeries` WHERE `name`=%s", series) + frappe.db.delete("Series", {"name": series}) frappe.db.sql("""INSERT INTO `tabSeries` (name, current) values (%s, 3)""", (series,)) revert_series_if_last(key, name) current_index = frappe.db.sql("""SELECT current from `tabSeries` where name = %s""", series, as_dict=True)[0] self.assertEqual(current_index.get('current'), 2) - frappe.db.sql("""delete from `tabSeries` where name = %s""", series) + frappe.db.delete("Series", {"name": series}) series = 'TEST1-' key = 'TEST1-.#####.-2021-22' name = 'TEST1-00003-2021-22' - frappe.db.sql("DELETE FROM `tabSeries` WHERE `name`=%s", series) + frappe.db.delete("Series", {"name": series}) frappe.db.sql("""INSERT INTO `tabSeries` (name, current) values (%s, 3)""", (series,)) revert_series_if_last(key, name) current_index = frappe.db.sql("""SELECT current from `tabSeries` where name = %s""", series, as_dict=True)[0] self.assertEqual(current_index.get('current'), 2) - frappe.db.sql("""delete from `tabSeries` where name = %s""", series) + frappe.db.delete("Series", {"name": series}) series = '' key = '.#####.-2021-22' name = '00003-2021-22' - frappe.db.sql("DELETE FROM `tabSeries` WHERE `name`=%s", series) + frappe.db.delete("Series", {"name": series}) frappe.db.sql("""INSERT INTO `tabSeries` (name, current) values (%s, 3)""", (series,)) revert_series_if_last(key, name) current_index = frappe.db.sql("""SELECT current from `tabSeries` where name = %s""", series, as_dict=True)[0] self.assertEqual(current_index.get('current'), 2) - frappe.db.sql("""delete from `tabSeries` where name = %s""", series) + frappe.db.delete("Series", {"name": series}) def test_naming_for_cancelled_and_amended_doc(self): submittable_doctype = frappe.get_doc({ diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index ada64156de..9586660535 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -38,7 +38,7 @@ class TestPermissions(unittest.TestCase): reset('Blogger') reset('Blog Post') - frappe.db.sql('delete from `tabUser Permission`') + frappe.db.delete("User Permission") frappe.set_user("test1@example.com") @@ -334,9 +334,9 @@ class TestPermissions(unittest.TestCase): doctype""" frappe.set_user('Administrator') - frappe.db.sql('DELETE FROM `tabContact`') - frappe.db.sql('DELETE FROM `tabContact Email`') - frappe.db.sql('DELETE FROM `tabContact Phone`') + frappe.db.delete("Contact") + frappe.db.delete("Contact Email") + frappe.db.delete("Contact Phone") reset('Salutation') reset('Contact') diff --git a/frappe/tests/test_scheduler.py b/frappe/tests/test_scheduler.py index ec43c08ab7..f13bcbe06f 100644 --- a/frappe/tests/test_scheduler.py +++ b/frappe/tests/test_scheduler.py @@ -45,7 +45,7 @@ class TestScheduler(TestCase): # 1st job is in the queue (or running), don't enqueue it again self.assertFalse(job.enqueue()) - frappe.db.sql('DELETE FROM `tabScheduled Job Log` WHERE `scheduled_job_type`=%s', job.name) + frappe.db.delete("Scheduled Job Log", {"scheduled_job_type": job.name}) def test_is_dormant(self): self.assertTrue(is_dormant(check_time= get_datetime('2100-01-01 00:00:00'))) From ebc220db393e7549cb7d948e57dbb6a92897b35b Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 19:50:48 +0530 Subject: [PATCH 42/74] refactor(tests): frappe.db.delete > frappe.db.sql Use frappe.db.delete wherever possible. Get rid of all the frappe.db.sql ;) This commit focuses on the tests written under the doctype specific tests --- .../assignment_rule/test_assignment_rule.py | 8 ++++---- .../milestone_tracker/test_milestone_tracker.py | 4 ++-- frappe/core/doctype/comment/test_comment.py | 4 ++-- frappe/core/doctype/feedback/test_feedback.py | 4 ++-- .../core/doctype/translation/test_translation.py | 2 +- frappe/core/doctype/user/test_user.py | 6 +++--- frappe/desk/doctype/event/test_event.py | 2 +- frappe/desk/doctype/note/test_note.py | 6 +++--- frappe/desk/doctype/tag/test_tag.py | 2 +- frappe/desk/doctype/todo/test_todo.py | 6 +++--- .../doctype/email_account/test_email_account.py | 12 ++++++------ .../doctype/notification/test_notification.py | 16 ++++++++-------- .../integrations/doctype/webhook/test_webhook.py | 8 ++++---- .../energy_point_log/test_energy_point_log.py | 4 ++-- .../test_personal_data_download_request.py | 4 ++-- frappe/website/doctype/web_page/test_web_page.py | 2 +- .../workflow/doctype/workflow/test_workflow.py | 2 +- 17 files changed, 46 insertions(+), 46 deletions(-) diff --git a/frappe/automation/doctype/assignment_rule/test_assignment_rule.py b/frappe/automation/doctype/assignment_rule/test_assignment_rule.py index e287b83965..dfefd091fb 100644 --- a/frappe/automation/doctype/assignment_rule/test_assignment_rule.py +++ b/frappe/automation/doctype/assignment_rule/test_assignment_rule.py @@ -76,7 +76,7 @@ class TestAutoAssign(unittest.TestCase): # clear 5 assignments for first user # can't do a limit in "delete" since postgres does not support it for d in frappe.get_all('ToDo', dict(reference_type = 'Note', owner = 'test@example.com'), limit=5): - frappe.db.sql("delete from tabToDo where name = %s", d.name) + frappe.db.delete("ToDo", {"name": d.name}) # add 5 more assignments for i in range(5): @@ -177,7 +177,7 @@ class TestAutoAssign(unittest.TestCase): ), 'owner'), 'test@example.com') def check_assignment_rule_scheduling(self): - frappe.db.sql("DELETE FROM `tabAssignment Rule`") + frappe.db.delete("Assignment Rule") days_1 = [dict(day = 'Sunday'), dict(day = 'Monday'), dict(day = 'Tuesday')] @@ -204,7 +204,7 @@ class TestAutoAssign(unittest.TestCase): ), 'owner'), ['test3@example.com']) def test_assignment_rule_condition(self): - frappe.db.sql("DELETE FROM `tabAssignment Rule`") + frappe.db.delete("Assignment Rule") # Add expiry_date custom field from frappe.custom.doctype.custom_field.custom_field import create_custom_field @@ -253,7 +253,7 @@ class TestAutoAssign(unittest.TestCase): assignment_rule.delete() def clear_assignments(): - frappe.db.sql("delete from tabToDo where reference_type = 'Note'") + frappe.db.delete("ToDo", {"reference_type": "Note"}) def get_assignment_rule(days, assign=None): frappe.delete_doc_if_exists('Assignment Rule', 'For Note 1') diff --git a/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py b/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py index 21b2779018..1683e94827 100644 --- a/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py +++ b/frappe/automation/doctype/milestone_tracker/test_milestone_tracker.py @@ -7,7 +7,7 @@ import unittest class TestMilestoneTracker(unittest.TestCase): def test_milestone(self): - frappe.db.sql('delete from `tabMilestone Tracker`') + frappe.db.delete("Milestone Tracker") frappe.cache().delete_key('milestone_tracker_map') @@ -44,5 +44,5 @@ class TestMilestoneTracker(unittest.TestCase): self.assertEqual(milestones[0].value, 'Closed') # cleanup - frappe.db.sql('delete from tabMilestone') + frappe.db.delete("Milestone") milestone_tracker.delete() \ No newline at end of file diff --git a/frappe/core/doctype/comment/test_comment.py b/frappe/core/doctype/comment/test_comment.py index 13db92e7a8..12fe027fba 100644 --- a/frappe/core/doctype/comment/test_comment.py +++ b/frappe/core/doctype/comment/test_comment.py @@ -30,7 +30,7 @@ class TestComment(unittest.TestCase): from frappe.website.doctype.blog_post.test_blog_post import make_test_blog test_blog = make_test_blog() - frappe.db.sql("delete from `tabComment` where reference_doctype = 'Blog Post'") + frappe.db.delete("Comment", {"reference_doctype": "Blog Post"}) from frappe.templates.includes.comments.comments import add_comment add_comment('Good comment with 10 chars', 'test@test.com', 'Good Tester', @@ -41,7 +41,7 @@ class TestComment(unittest.TestCase): reference_name = test_blog.name ))[0].published, 1) - frappe.db.sql("delete from `tabComment` where reference_doctype = 'Blog Post'") + frappe.db.delete("Comment", {"reference_doctype": "Blog Post"}) add_comment('pleez vizits my site http://mysite.com', 'test@test.com', 'bad commentor', 'Blog Post', test_blog.name, test_blog.route) diff --git a/frappe/core/doctype/feedback/test_feedback.py b/frappe/core/doctype/feedback/test_feedback.py index 2a96d86874..c7551420c3 100644 --- a/frappe/core/doctype/feedback/test_feedback.py +++ b/frappe/core/doctype/feedback/test_feedback.py @@ -9,7 +9,7 @@ class TestFeedback(unittest.TestCase): from frappe.website.doctype.blog_post.test_blog_post import make_test_blog test_blog = make_test_blog() - frappe.db.sql("delete from `tabFeedback` where reference_doctype = 'Blog Post'") + frappe.db.delete("Feedback", {"reference_doctype": "Blog Post"}) from frappe.templates.includes.feedback.feedback import add_feedback, update_feedback feedback = add_feedback('Blog Post', test_blog.name, 5, 'New feedback') @@ -22,6 +22,6 @@ class TestFeedback(unittest.TestCase): self.assertEqual(updated_feedback.feedback, 'Updated feedback') self.assertEqual(updated_feedback.rating, 6) - frappe.db.sql("delete from `tabFeedback` where reference_doctype = 'Blog Post'") + frappe.db.delete("Feedback", {"reference_doctype": "Blog Post"}) test_blog.delete() \ No newline at end of file diff --git a/frappe/core/doctype/translation/test_translation.py b/frappe/core/doctype/translation/test_translation.py index ae1293b38f..e5b5d2d393 100644 --- a/frappe/core/doctype/translation/test_translation.py +++ b/frappe/core/doctype/translation/test_translation.py @@ -8,7 +8,7 @@ from frappe import _ class TestTranslation(unittest.TestCase): def setUp(self): - frappe.db.sql('delete from tabTranslation') + frappe.db.delete("Translation") def tearDown(self): frappe.local.lang = 'en' diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 392128834d..fbe1830844 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -52,7 +52,7 @@ class TestUser(unittest.TestCase): def test_delete(self): frappe.get_doc("User", "test@example.com").add_roles("_Test Role 2") self.assertRaises(frappe.LinkExistsError, delete_doc, "Role", "_Test Role 2") - frappe.db.sql("""delete from `tabHas Role` where role='_Test Role 2'""") + frappe.db.delete("Has Role", {"role": "_Test Role 2"}) delete_doc("Role","_Test Role 2") if frappe.db.exists("User", "_test@example.com"): @@ -294,5 +294,5 @@ class TestUser(unittest.TestCase): # self.assertIsNone(frappe.db.get("User", {"email": email})) def delete_contact(user): - frappe.db.sql("DELETE FROM `tabContact` WHERE `email_id`= %s", user) - frappe.db.sql("DELETE FROM `tabContact Email` WHERE `email_id`= %s", user) + frappe.db.delete("Contact", {"email_id": user}) + frappe.db.delete("Contact Email", {"email_id": user}) diff --git a/frappe/desk/doctype/event/test_event.py b/frappe/desk/doctype/event/test_event.py index 77211946a9..8f56d11da3 100644 --- a/frappe/desk/doctype/event/test_event.py +++ b/frappe/desk/doctype/event/test_event.py @@ -14,7 +14,7 @@ test_records = frappe.get_test_records('Event') class TestEvent(unittest.TestCase): def setUp(self): - frappe.db.sql('delete from tabEvent') + frappe.db.delete("Event") make_test_objects('Event', reset=True) self.test_records = frappe.get_test_records('Event') diff --git a/frappe/desk/doctype/note/test_note.py b/frappe/desk/doctype/note/test_note.py index 1bb1730357..3207fa9b8d 100644 --- a/frappe/desk/doctype/note/test_note.py +++ b/frappe/desk/doctype/note/test_note.py @@ -8,9 +8,9 @@ test_records = frappe.get_test_records('Note') class TestNote(unittest.TestCase): def insert_note(self): - frappe.db.sql('delete from tabVersion') - frappe.db.sql('delete from tabNote') - frappe.db.sql('delete from `tabNote Seen By`') + frappe.db.delete("Version") + frappe.db.delete("Note") + frappe.db.delete("Note Seen By") return frappe.get_doc(dict(doctype='Note', title='test note', content='test note content')).insert() diff --git a/frappe/desk/doctype/tag/test_tag.py b/frappe/desk/doctype/tag/test_tag.py index 6eb7219c26..b9c6e0b744 100644 --- a/frappe/desk/doctype/tag/test_tag.py +++ b/frappe/desk/doctype/tag/test_tag.py @@ -6,7 +6,7 @@ from frappe.desk.doctype.tag.tag import add_tag class TestTag(unittest.TestCase): def setUp(self) -> None: - frappe.db.sql("DELETE from `tabTag`") + frappe.db.delete("Tag") frappe.db.sql("UPDATE `tabDocType` set _user_tags=''") def test_tag_count_query(self): diff --git a/frappe/desk/doctype/todo/test_todo.py b/frappe/desk/doctype/todo/test_todo.py index b38e4a059a..4afe99597d 100644 --- a/frappe/desk/doctype/todo/test_todo.py +++ b/frappe/desk/doctype/todo/test_todo.py @@ -14,7 +14,7 @@ class TestToDo(unittest.TestCase): todo = frappe.get_doc(dict(doctype='ToDo', description='test todo', assigned_by='Administrator')).insert() - frappe.db.sql('delete from `tabDeleted Document`') + frappe.db.delete("Deleted Document") todo.delete() deleted = frappe.get_doc('Deleted Document', dict(deleted_doctype=todo.doctype, deleted_name=todo.name)) @@ -27,7 +27,7 @@ class TestToDo(unittest.TestCase): frappe.db.get_value('User', todo.assigned_by, 'full_name')) def test_fetch_setup(self): - frappe.db.sql('delete from tabToDo') + frappe.db.delete("ToDo") todo_meta = frappe.get_doc('DocType', 'ToDo') todo_meta.get('fields', dict(fieldname='assigned_by_full_name'))[0].fetch_from = '' @@ -105,7 +105,7 @@ class TestToDo(unittest.TestCase): frappe.db.rollback() def test_fetch_if_empty(self): - frappe.db.sql('delete from tabToDo') + frappe.db.delete("ToDo") # Allow user changes todo_meta = frappe.get_doc('DocType', 'ToDo') diff --git a/frappe/email/doctype/email_account/test_email_account.py b/frappe/email/doctype/email_account/test_email_account.py index 35cacac45a..da03a5959e 100644 --- a/frappe/email/doctype/email_account/test_email_account.py +++ b/frappe/email/doctype/email_account/test_email_account.py @@ -34,8 +34,8 @@ class TestEmailAccount(unittest.TestCase): def setUp(self): frappe.flags.mute_emails = False frappe.flags.sent_mail = None - frappe.db.sql('delete from `tabEmail Queue`') - frappe.db.sql('delete from `tabUnhandled Email`') + frappe.db.delete("Email Queue") + frappe.db.delete("Unhandled Email") def get_test_mail(self, fname): with open(os.path.join(os.path.dirname(__file__), "test_mails", fname), "r") as f: @@ -60,7 +60,7 @@ class TestEmailAccount(unittest.TestCase): comm = frappe.get_doc("Communication", {"sender": "test_sender@example.com"}) comm.db_set("creation", datetime.now() - timedelta(seconds = 30 * 60)) - frappe.db.sql("DELETE FROM `tabEmail Queue`") + frappe.db.delete("Email Queue") notify_unreplied() self.assertTrue(frappe.db.get_value("Email Queue", {"reference_doctype": comm.reference_doctype, "reference_name": comm.reference_name, "status":"Not Sent"})) @@ -183,7 +183,7 @@ class TestEmailAccount(unittest.TestCase): def test_threading_by_message_id(self): cleanup() - frappe.db.sql("""delete from `tabEmail Queue`""") + frappe.db.delete("Email Queue") # reference document for testing event = frappe.get_doc(dict(doctype='Event', subject='test-message')).insert() @@ -242,8 +242,8 @@ class TestInboundMail(unittest.TestCase): def setUp(self): cleanup() - frappe.db.sql('delete from `tabEmail Queue`') - frappe.db.sql('delete from `tabToDo`') + frappe.db.delete("Email Queue") + frappe.db.delete("ToDo") def get_test_mail(self, fname): with open(os.path.join(os.path.dirname(__file__), "test_mails", fname), "r") as f: diff --git a/frappe/email/doctype/notification/test_notification.py b/frappe/email/doctype/notification/test_notification.py index d6358ccbbe..2629050c1b 100644 --- a/frappe/email/doctype/notification/test_notification.py +++ b/frappe/email/doctype/notification/test_notification.py @@ -9,7 +9,7 @@ test_dependencies = ["User", "Notification"] class TestNotification(unittest.TestCase): def setUp(self): - frappe.db.sql("""delete from `tabEmail Queue`""") + frappe.db.delete("Email Queue") frappe.set_user("test@example.com") if not frappe.db.exists('Notification', {'name': 'ToDo Status Update'}, 'name'): @@ -50,7 +50,7 @@ class TestNotification(unittest.TestCase): self.assertTrue(frappe.db.get_value("Email Queue", {"reference_doctype": "Communication", "reference_name": communication.name, "status":"Not Sent"})) - frappe.db.sql("""delete from `tabEmail Queue`""") + frappe.db.delete("Email Queue") communication.reload() communication.content = "test 2" @@ -189,9 +189,9 @@ class TestNotification(unittest.TestCase): def test_cc_jinja(self): - frappe.db.sql("""delete from `tabUser` where email='test_jinja@example.com'""") - frappe.db.sql("""delete from `tabEmail Queue`""") - frappe.db.sql("""delete from `tabEmail Queue Recipient`""") + frappe.db.delete("User", {"email": "test_jinja@example.com"}) + frappe.db.delete("Email Queue") + frappe.db.delete("Email Queue Recipient") test_user = frappe.new_doc("User") test_user.name = 'test_jinja' @@ -205,9 +205,9 @@ class TestNotification(unittest.TestCase): self.assertTrue(frappe.db.get_value("Email Queue Recipient", {"recipient": "test_jinja@example.com"})) - frappe.db.sql("""delete from `tabUser` where email='test_jinja@example.com'""") - frappe.db.sql("""delete from `tabEmail Queue`""") - frappe.db.sql("""delete from `tabEmail Queue Recipient`""") + frappe.db.delete("User", {"email": "test_jinja@example.com"}) + frappe.db.delete("Email Queue") + frappe.db.delete("Email Queue Recipient") def test_notification_to_assignee(self): todo = frappe.new_doc('ToDo') diff --git a/frappe/integrations/doctype/webhook/test_webhook.py b/frappe/integrations/doctype/webhook/test_webhook.py index b77e311f7e..1470f666a1 100644 --- a/frappe/integrations/doctype/webhook/test_webhook.py +++ b/frappe/integrations/doctype/webhook/test_webhook.py @@ -11,9 +11,9 @@ class TestWebhook(unittest.TestCase): @classmethod def setUpClass(cls): # delete any existing webhooks - frappe.db.sql("DELETE FROM tabWebhook") + frappe.db.delete("Webhook") # Delete existing logs if any - frappe.db.sql("DELETE FROM `tabWebhook Request Log`") + frappe.db.delete("Webhook Request Log") # create test webhooks cls.create_sample_webhooks() @@ -46,7 +46,7 @@ class TestWebhook(unittest.TestCase): @classmethod def tearDownClass(cls): # delete any existing webhooks - frappe.db.sql("DELETE FROM tabWebhook") + frappe.db.delete("Webhook") def setUp(self): # retrieve or create a User webhook for `after_insert` @@ -168,7 +168,7 @@ class TestWebhook(unittest.TestCase): def test_webhook_req_log_creation(self): if not frappe.db.get_value('User', 'user2@integration.webhooks.test.com'): user = frappe.get_doc({ - 'doctype': 'User', + 'doctype': 'User', 'email': 'user2@integration.webhooks.test.com', 'first_name': 'user2' }).insert() diff --git a/frappe/social/doctype/energy_point_log/test_energy_point_log.py b/frappe/social/doctype/energy_point_log/test_energy_point_log.py index 4a6e86463e..eb03058760 100644 --- a/frappe/social/doctype/energy_point_log/test_energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/test_energy_point_log.py @@ -13,8 +13,8 @@ class TestEnergyPointLog(unittest.TestCase): def tearDown(self): frappe.set_user('Administrator') - frappe.db.sql('DELETE FROM `tabEnergy Point Log`') - frappe.db.sql('DELETE FROM `tabEnergy Point Rule`') + frappe.db.delete("Energy Point Log") + frappe.db.delete("Energy Point Rule") frappe.cache().delete_value('energy_point_rule_map') def test_user_energy_point(self): diff --git a/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py b/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py index 563b6b3843..2efac5af12 100644 --- a/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py +++ b/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py @@ -13,7 +13,7 @@ class TestRequestPersonalData(unittest.TestCase): create_user_if_not_exists(email='test_privacy@example.com') def tearDown(self): - frappe.db.sql("""DELETE FROM `tabPersonal Data Download Request`""") + frappe.db.delete("Personal Data Download Request") def test_user_data_creation(self): user_data = json.loads(get_user_data('test_privacy@example.com')) @@ -45,7 +45,7 @@ class TestRequestPersonalData(unittest.TestCase): limit=1) self.assertTrue("Subject: Download Your Data" in email_queue[0].message) - frappe.db.sql("delete from `tabEmail Queue`") + frappe.db.delete("Email Queue") def create_user_if_not_exists(email, first_name = None): frappe.delete_doc_if_exists("User", email) diff --git a/frappe/website/doctype/web_page/test_web_page.py b/frappe/website/doctype/web_page/test_web_page.py index 0d36d0f870..aebc6a38c1 100644 --- a/frappe/website/doctype/web_page/test_web_page.py +++ b/frappe/website/doctype/web_page/test_web_page.py @@ -8,7 +8,7 @@ test_records = frappe.get_test_records('Web Page') class TestWebPage(unittest.TestCase): def setUp(self): - frappe.db.sql("delete from `tabWeb Page`") + frappe.db.delete("Web Page") for t in test_records: frappe.get_doc(t).insert() diff --git a/frappe/workflow/doctype/workflow/test_workflow.py b/frappe/workflow/doctype/workflow/test_workflow.py index cd36fd2d0b..fb19352c67 100644 --- a/frappe/workflow/doctype/workflow/test_workflow.py +++ b/frappe/workflow/doctype/workflow/test_workflow.py @@ -76,7 +76,7 @@ class TestWorkflow(unittest.TestCase): self.assertListEqual(actions, ['Review']) def test_if_workflow_actions_were_processed(self): - frappe.db.sql('delete from `tabWorkflow Action`') + frappe.db.delete("Workflow Action") user = frappe.get_doc('User', 'test2@example.com') user.add_roles('Test Approver', 'System Manager') frappe.set_user('test2@example.com') From 32c6cf1c443c1c522848736da25cc0b22aea1425 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 19:53:16 +0530 Subject: [PATCH 43/74] refactor(misc): frappe.db.delete > frappe.db.sql Use frappe.db.delete wherever possible. Get rid of all the frappe.db.sql ;) This commit focuses on the pending modules that had relatively easier DELETE statements. --- frappe/model/delete_doc.py | 9 +++++---- frappe/model/document.py | 3 +-- frappe/modules/utils.py | 3 +-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/frappe/model/delete_doc.py b/frappe/model/delete_doc.py index fbbf1a4852..16fc960260 100644 --- a/frappe/model/delete_doc.py +++ b/frappe/model/delete_doc.py @@ -190,7 +190,7 @@ def delete_from_table(doctype, name, ignore_doctypes, doc): # delete from child tables for t in list(set(tables)): if t not in ignore_doctypes: - frappe.db.sql("delete from `tab%s` where parenttype=%s and parent = %s" % (t, '%s', '%s'), (doctype, name)) + frappe.db.delete(t, {"parenttype": doctype, "parent": name}) def update_flags(doc, flags=None, ignore_permissions=False): if ignore_permissions: @@ -323,9 +323,10 @@ def delete_dynamic_links(doctype, name): def delete_references(doctype, reference_doctype, reference_name, reference_doctype_field = 'reference_doctype', reference_name_field = 'reference_name'): - frappe.db.sql('''delete from `tab{0}` - where {1}=%s and {2}=%s'''.format(doctype, reference_doctype_field, reference_name_field), # nosec - (reference_doctype, reference_name)) + frappe.db.delete(doctype, { + reference_doctype_field: reference_doctype, + reference_name_field: reference_name + }) def clear_references(doctype, reference_doctype, reference_name, reference_doctype_field = 'reference_doctype', reference_name_field = 'reference_name'): diff --git a/frappe/model/document.py b/frappe/model/document.py index ee12fd89e0..37549e2001 100644 --- a/frappe/model/document.py +++ b/frappe/model/document.py @@ -385,8 +385,7 @@ class Document(BaseDocument): [self.name, self.doctype, fieldname] + rows) if len(deleted_rows) > 0: # delete rows that do not match the ones in the document - frappe.db.sql("""delete from `tab{0}` where name in ({1})""".format(df.options, - ','.join(['%s'] * len(deleted_rows))), tuple(row[0] for row in deleted_rows)) + frappe.db.delete(df.options, {"name": ("in", tuple(row[0] for row in deleted_rows))}) else: # no rows found, delete all rows diff --git a/frappe/modules/utils.py b/frappe/modules/utils.py index 0f3e57a5a0..ed2a839dc1 100644 --- a/frappe/modules/utils.py +++ b/frappe/modules/utils.py @@ -114,8 +114,7 @@ def sync_customizations_for_doctype(data, folder): doc.db_insert() if custom_doctype != 'Custom Field': - frappe.db.sql('delete from `tab{0}` where `{1}` =%s'.format( - custom_doctype, doctype_fieldname), doc_type) + frappe.db.delete(custom_doctype, {doctype_fieldname: doc_type}) for d in data[key]: _insert(d) From 4df118906f66dd7d06b6b85063f80dc157704862 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 20:10:11 +0530 Subject: [PATCH 44/74] fix: Run test skipped earlier due to missing indent --- frappe/desk/doctype/todo/test_todo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/desk/doctype/todo/test_todo.py b/frappe/desk/doctype/todo/test_todo.py index 4afe99597d..7e0fa115c9 100644 --- a/frappe/desk/doctype/todo/test_todo.py +++ b/frappe/desk/doctype/todo/test_todo.py @@ -104,7 +104,7 @@ class TestToDo(unittest.TestCase): clear_permissions_cache('ToDo') frappe.db.rollback() -def test_fetch_if_empty(self): + def test_fetch_if_empty(self): frappe.db.delete("ToDo") # Allow user changes From 380e9e7c080a616a34090992e910632a4daa0ff6 Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 20:30:13 +0530 Subject: [PATCH 45/74] fix(test): Add missing comma --- frappe/tests/test_frappe_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/tests/test_frappe_client.py b/frappe/tests/test_frappe_client.py index 556828f843..d192952e92 100644 --- a/frappe/tests/test_frappe_client.py +++ b/frappe/tests/test_frappe_client.py @@ -82,7 +82,7 @@ class TestFrappeClient(unittest.TestCase): def test_update_doc(self): server = FrappeClient(get_url(), "Administrator", "admin", verify=False) - frappe.db.delete("Note", {"title": ("in" ("Sing", "sing"))}) + frappe.db.delete("Note", {"title": ("in", ("Sing", "sing"))}) frappe.db.commit() server.insert({"doctype":"Note", "public": True, "title": "Sing"}) From b8f28fd28b94bc97011b1761b96059978728a53f Mon Sep 17 00:00:00 2001 From: Gavin D'souza Date: Thu, 19 Aug 2021 20:47:27 +0530 Subject: [PATCH 46/74] test(todo): Use doc.meta instead of doctype form --- frappe/desk/doctype/todo/test_todo.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frappe/desk/doctype/todo/test_todo.py b/frappe/desk/doctype/todo/test_todo.py index 7e0fa115c9..f6371c5921 100644 --- a/frappe/desk/doctype/todo/test_todo.py +++ b/frappe/desk/doctype/todo/test_todo.py @@ -122,9 +122,8 @@ class TestToDo(unittest.TestCase): self.assertEqual(todo.assigned_by_full_name, 'Admin') # Overwrite user changes - todo_meta = frappe.get_doc('DocType', 'ToDo') - todo_meta.get('fields', dict(fieldname='assigned_by_full_name'))[0].fetch_if_empty = 0 - todo_meta.save() + todo.meta.get('fields', dict(fieldname='assigned_by_full_name'))[0].fetch_if_empty = 0 + todo.meta.save() todo.reload() todo.save() From 36f698f0f8d7040966d31f12f4b9ca4f4c7976a7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 21:38:57 +0530 Subject: [PATCH 47/74] fix: Unzip functionality --- frappe/core/doctype/file/file.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 8d0eee8c69..a31119961d 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -319,12 +319,10 @@ class File(Document): def unzip(self): '''Unzip current file and replace it by its children''' - if not ".zip" in self.file_name: - frappe.msgprint(_("Not a zip file")) - return + if not ".zip" in self.file_url: + frappe.throw(_("{0} is not a zip file").format(self.file_name)) - zip_path = frappe.get_site_path(self.file_url.strip('/')) - base_url = os.path.dirname(self.file_url) + zip_path = self.get_full_path() files = [] with zipfile.ZipFile(zip_path) as z: @@ -837,7 +835,7 @@ def unzip_file(name): '''Unzip the given file and make file records for each of the extracted files''' file_obj = frappe.get_doc('File', name) files = file_obj.unzip() - return len(files) + return files @frappe.whitelist() def optimize_saved_image(doc_name): From 3acab8a7c7da04184ad5828a042250356cdfe8e3 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 21:40:12 +0530 Subject: [PATCH 48/74] test: Add test cases for unzip functionality --- frappe/core/doctype/file/test_file.py | 23 +++++++++++++++++++++++ frappe/www/_test/assets/file.zip | Bin 0 -> 156164 bytes 2 files changed, 23 insertions(+) create mode 100644 frappe/www/_test/assets/file.zip diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index df0ba8c2ec..f17c52150a 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -418,6 +418,29 @@ class TestFile(unittest.TestCase): self.assertEqual(json.loads(frappe.message_log[0]), {"message": f"File '{frappe.utils.get_url('unknown.jpg')}' not found"}) self.assertEquals(test_file.thumbnail_url, None) + def test_file_unzip(self): + file_path = frappe.get_app_path('frappe', 'www/_test/assets/file.zip') + public_file_path = frappe.get_site_path('public', 'files') + try: + import shutil + shutil.copy(file_path, public_file_path) + except Exception as e: + print(e) + + test_file = frappe.get_doc({ + "doctype": "File", + "file_url": '/files/file.zip', + }).insert(ignore_permissions=True) + + self.assertListEqual([file.file_name for file in unzip_file(test_file.name)], + ['css_asset.css', 'image.jpg', 'js_asset.min.js']) + + test_file = frappe.get_doc({ + "doctype": "File", + "file_url": frappe.utils.get_url('/_test/assets/image.jpg'), + }).insert(ignore_permissions=True) + self.assertRaisesRegex(frappe.exceptions.ValidationError, 'not a zip file', test_file.unzip) + class TestAttachment(unittest.TestCase): test_doctype = 'Test For Attachment' diff --git a/frappe/www/_test/assets/file.zip b/frappe/www/_test/assets/file.zip new file mode 100644 index 0000000000000000000000000000000000000000..06d70919d4b19cc415ed795b8a897a7fb9fba08b GIT binary patch literal 156164 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 W80cK0`U`N0baj%n60`ricK-)q-D;2k literal 0 HcmV?d00001 From ed41602526db31d7e12b33d6a26fdd3161fd7ba6 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Thu, 19 Aug 2021 21:43:43 +0530 Subject: [PATCH 49/74] test: Add more assersions and minor refactor --- frappe/core/doctype/file/file.py | 7 ++++--- frappe/core/doctype/file/test_file.py | 13 +++++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index a31119961d..06222872a6 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -257,7 +257,7 @@ class File(Document): with open(get_files_path(file_name, is_private=self.is_private), "rb") as f: self.content_hash = get_content_hash(f.read()) except IOError: - frappe.msgprint(_("File {0} does not exist").format(self.file_url)) + frappe.throw(_("File {0} does not exist").format(self.file_url)) raise def on_trash(self): @@ -559,7 +559,8 @@ def create_new_folder(file_name, folder): file.file_name = file_name file.is_folder = 1 file.folder = folder - file.insert() + file.insert(ignore_if_duplicate=True) + return file @frappe.whitelist() def move_file(file_list, new_parent, old_parent): @@ -610,7 +611,7 @@ def get_local_image(file_url): try: image = Image.open(file_path) except IOError: - frappe.msgprint(_("Unable to read file format for {0}").format(file_url), raise_exception=True) + frappe.throw(_("Unable to read file format for {0}").format(file_url)) content = None diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index f17c52150a..e054aed950 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -7,7 +7,7 @@ import frappe import os import unittest from frappe import _ -from frappe.core.doctype.file.file import move_file, get_files_in_folder +from frappe.core.doctype.file.file import get_attached_images, move_file, get_files_in_folder, unzip_file from frappe.utils import get_files_path # test_records = frappe.get_test_records('File') @@ -397,7 +397,6 @@ class TestFile(unittest.TestCase): "doctype": "File", "file_name": 'logo', "file_url": frappe.utils.get_url('/_test/assets/image.jpg'), - "docstatus": 0 }).insert(ignore_permissions=True) test_file.make_thumbnail() @@ -407,7 +406,7 @@ class TestFile(unittest.TestCase): test_file.db_set('thumbnail_url', None) test_file.reload() test_file.file_url = "/files/image_small.jpg" - test_file.make_thumbnail(suffix="xs") + test_file.make_thumbnail(suffix="xs", crop=True) self.assertEquals(test_file.thumbnail_url, '/files/image_small_xs.jpg') frappe.clear_messages() @@ -556,6 +555,7 @@ class TestFileUtils(unittest.TestCase): }).insert() self.assertTrue(frappe.db.exists("File", {"attached_to_name": todo.name})) self.assertIn('', todo.description) + self.assertListEqual(get_attached_images('ToDo', [todo.name])[todo.name], ['/files/pix.png']) # without filename in data URI todo = frappe.get_doc({ @@ -563,4 +563,9 @@ class TestFileUtils(unittest.TestCase): "description": 'Test ' }).insert() filename = frappe.db.exists("File", {"attached_to_name": todo.name}) - self.assertIn(f' Date: Thu, 19 Aug 2021 22:04:23 +0530 Subject: [PATCH 50/74] test: Fix typo --- frappe/core/doctype/file/test_file.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index e054aed950..f9d06429ff 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -423,8 +423,8 @@ class TestFile(unittest.TestCase): try: import shutil shutil.copy(file_path, public_file_path) - except Exception as e: - print(e) + except Exception: + pass test_file = frappe.get_doc({ "doctype": "File", @@ -567,5 +567,11 @@ class TestFileUtils(unittest.TestCase): def test_create_new_folder(self): from frappe.core.doctype.file.file import create_new_folder - folder = create_new_folder('test_folder', 'home') + folder = create_new_folder('test_folder', 'Home') self.assertTrue(folder.is_folder) + +# def get_files_by_search_text(text): +# def optimize_saved_image(doc_name): +# def download_file(file_url): +# def remove_file_by_url(file_url, doctype=None, name=None): +# def on_doctype_update(): \ No newline at end of file From 228253289f8ee6e670c4868d97ce1bc25da818e6 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 09:55:26 +0530 Subject: [PATCH 51/74] fix: Only select active numeric field after layout refresh --- frappe/public/js/frappe/form/layout.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index 88e0463fa5..f171c4f32e 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -252,14 +252,18 @@ frappe.ui.form.Layout = class Layout { } if (document.activeElement) { - document.activeElement.focus(); - - if (document.activeElement.tagName == 'INPUT') { + if (document.activeElement.tagName == 'INPUT' && this.is_numeric_field_active()) { document.activeElement.select(); } } } + is_numeric_field_active() { + const control = $(document.activeElement).closest(".frappe-control") + const fieldtype = control.data().fieldtype; + return frappe.model.numeric_fieldtypes.includes(fieldtype) + } + refresh_sections() { // hide invisible sections this.wrapper.find(".form-section:not(.hide-control)").each(function() { From 32148cadc51d24771fe98871a7816d8f5e50b4de Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 09:58:23 +0530 Subject: [PATCH 52/74] fix: Avoid input events for controls in grid --- frappe/public/js/frappe/form/controls/data.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/data.js b/frappe/public/js/frappe/form/controls/data.js index e4a7dd6d59..864a0562ef 100644 --- a/frappe/public/js/frappe/form/controls/data.js +++ b/frappe/public/js/frappe/form/controls/data.js @@ -163,7 +163,7 @@ frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlInp } }; this.$input.on("change", change_handler); - if (this.constructor.trigger_change_on_input_event) { + if (this.constructor.trigger_change_on_input_event && !this.in_grid()) { // debounce to avoid repeated validations on value change this.$input.on("input", frappe.utils.debounce(change_handler, 500)); } @@ -267,4 +267,7 @@ frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlInp let el = this.$input.parents(el_class)[0]; if (el) $(el).toggleClass(scroll_class, add); } + in_grid() { + return this.grid || this.layout && this.layout.grid; + } }; From ff552d5d1d61fc83568bd213cc537c9bc5a623c2 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 10:02:44 +0530 Subject: [PATCH 53/74] perf: Reduce debounce delay --- frappe/public/js/frappe/form/grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index 8de1600c05..05c70b214d 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -38,7 +38,7 @@ export default class Grid { this.is_grid = true; this.debounced_refresh = this.refresh.bind(this); - this.debounced_refresh = frappe.utils.debounce(this.debounced_refresh, 500); + this.debounced_refresh = frappe.utils.debounce(this.debounced_refresh, 100); } allow_on_grid_editing() { From ebcb3618cf95e7c9a65c3d7dea40b8cd84b32f34 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 10:23:49 +0530 Subject: [PATCH 54/74] style: Add missing semicolons --- frappe/public/js/frappe/form/layout.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index f171c4f32e..21d7a451ac 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -259,9 +259,9 @@ frappe.ui.form.Layout = class Layout { } is_numeric_field_active() { - const control = $(document.activeElement).closest(".frappe-control") + const control = $(document.activeElement).closest(".frappe-control"); const fieldtype = control.data().fieldtype; - return frappe.model.numeric_fieldtypes.includes(fieldtype) + return frappe.model.numeric_fieldtypes.includes(fieldtype); } refresh_sections() { From 09868c26a9687f5b35339772be1db42d58951b06 Mon Sep 17 00:00:00 2001 From: Pruthvi Patel Date: Fri, 20 Aug 2021 11:41:41 +0530 Subject: [PATCH 55/74] feat: add `--autoreload` flag --- frappe/commands/utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frappe/commands/utils.py b/frappe/commands/utils.py index 765028dfed..35e566794f 100644 --- a/frappe/commands/utils.py +++ b/frappe/commands/utils.py @@ -486,8 +486,13 @@ frappe.db.connect() @click.command('console') +@click.option( + '--autoreload', + is_flag=True, + help="Reload changes to code automatically" +) @pass_context -def console(context): +def console(context, autoreload=False): "Start ipython console for a site" site = get_site(context) frappe.init(site=site) @@ -497,7 +502,7 @@ def console(context): from IPython.terminal.embed import InteractiveShellEmbed terminal = InteractiveShellEmbed() - if frappe.conf.developer_mode: + if autoreload: terminal.extension_manager.load_extension("autoreload") terminal.run_line_magic("autoreload", "2") From 70f9f77df8caae76b80790954451407413336c64 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 12:16:55 +0530 Subject: [PATCH 56/74] fix: Handle exception --- frappe/public/js/frappe/form/layout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/layout.js b/frappe/public/js/frappe/form/layout.js index 21d7a451ac..8d52c8d592 100644 --- a/frappe/public/js/frappe/form/layout.js +++ b/frappe/public/js/frappe/form/layout.js @@ -260,7 +260,7 @@ frappe.ui.form.Layout = class Layout { is_numeric_field_active() { const control = $(document.activeElement).closest(".frappe-control"); - const fieldtype = control.data().fieldtype; + const fieldtype = (control.data() || {}).fieldtype; return frappe.model.numeric_fieldtypes.includes(fieldtype); } From 9781fb758f2223294dd818680cc85c0ee03b6cf7 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 22:06:50 +0530 Subject: [PATCH 57/74] fix: Rate limiter to allow kwargs --- frappe/rate_limiter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/rate_limiter.py b/frappe/rate_limiter.py index 023cdb9cb0..528e5d6b56 100644 --- a/frappe/rate_limiter.py +++ b/frappe/rate_limiter.py @@ -103,7 +103,7 @@ def rate_limit(key: str, limit: Union[int, Callable] = 5, seconds: int= 24*60*60 def wrapper(*args, **kwargs): # Do not apply rate limits if method is not opted to check if methods != 'ALL' and frappe.request.method.upper() not in methods: - return frappe.call(fun, **frappe.form_dict) + return frappe.call(fun, **frappe.form_dict or kwargs) _limit = limit() if callable(limit) else limit @@ -118,6 +118,6 @@ def rate_limit(key: str, limit: Union[int, Callable] = 5, seconds: int= 24*60*60 if value > _limit: frappe.throw(_("You hit the rate limit because of too many requests. Please try after sometime.")) - return frappe.call(fun, **frappe.form_dict) + return frappe.call(fun, **frappe.form_dict or kwargs) return wrapper return ratelimit_decorator From 6f72e79f1acce546c8ada707afa57c2353bf2b4b Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 22:35:01 +0530 Subject: [PATCH 58/74] test: Add more assertions for reset password --- frappe/core/doctype/user/test_user.py | 27 ++++++++++++++++++- .../notification_log/test_notification_log.py | 6 ++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 5fea8ed9d8..1c4c483fa8 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -1,11 +1,12 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt import frappe, unittest +import json from frappe.model.delete_doc import delete_doc from frappe.utils import get_url from frappe.core.doctype.user.user import (test_password_strength, - extract_mentions, sign_up, update_password, verify_password) + extract_mentions, sign_up, update_password, verify_password, reset_password) from frappe.frappeclient import FrappeClient from unittest.mock import patch @@ -347,6 +348,30 @@ class TestUser(unittest.TestCase): # reset password update_password(old_password, old_password=new_password) + # test API endpoint + with patch.object(user_module.frappe, 'sendmail') as sendmail: + frappe.clear_messages() + test_user = frappe.get_doc("User", "test2@example.com") + self.assertEqual(reset_password(user="test2@example.com"), None) + test_user.reload() + self.assertEqual(update_password(new_password, key=test_user.reset_password_key), "/") + update_password(old_password, old_password=new_password) + self.assertEqual(json.loads(frappe.message_log[0]), {"message": "Password reset instructions have been sent to your email"}) + sendmail.assert_called_once() + self.assertEqual(sendmail.call_args[1]["recipients"], "test2@example.com") + + self.assertEqual(reset_password(user="test2@example.com"), None) + self.assertEqual(reset_password(user="Administrator"), "not allowed") + self.assertEqual(reset_password(user="random"), "not found") + + def test_user_onload_modules(self): + from frappe.desk.form.load import getdoc + from frappe.config import get_modules_from_all_apps + frappe.response.docs = [] + getdoc("User", "Administrator") + doc = frappe.response.docs[0] + self.assertListEqual(doc.get("__onload").get('all_modules', []), + [m.get("module_name") for m in get_modules_from_all_apps()]) def test_password_verification(self): diff --git a/frappe/desk/doctype/notification_log/test_notification_log.py b/frappe/desk/doctype/notification_log/test_notification_log.py index 2d232cf942..bedb10b495 100644 --- a/frappe/desk/doctype/notification_log/test_notification_log.py +++ b/frappe/desk/doctype/notification_log/test_notification_log.py @@ -2,6 +2,7 @@ # Copyright (c) 2019, Frappe Technologies and Contributors # See license.txt import frappe +from frappe.core.doctype.user.user import get_system_users from frappe.desk.form.assign_to import add as assign_task import unittest @@ -54,7 +55,4 @@ def get_todo(): return frappe.get_cached_doc('ToDo', res[0].name) def get_user(): - users = frappe.db.get_all('User', - filters={'name': ('not in', ['Administrator', 'Guest']), 'enabled': 1}, - fields='name', limit=1) - return users[0].name + return get_system_users(limit=1)[0] From 9e4c8cc28ec93dc23be354ec2a8a33933c1a1719 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 23:35:55 +0530 Subject: [PATCH 59/74] chore: Remove commented text --- frappe/core/doctype/file/test_file.py | 6 ------ frappe/core/doctype/user/test_user.py | 3 --- 2 files changed, 9 deletions(-) diff --git a/frappe/core/doctype/file/test_file.py b/frappe/core/doctype/file/test_file.py index f9d06429ff..5478d7ab85 100644 --- a/frappe/core/doctype/file/test_file.py +++ b/frappe/core/doctype/file/test_file.py @@ -569,9 +569,3 @@ class TestFileUtils(unittest.TestCase): from frappe.core.doctype.file.file import create_new_folder folder = create_new_folder('test_folder', 'Home') self.assertTrue(folder.is_folder) - -# def get_files_by_search_text(text): -# def optimize_saved_image(doc_name): -# def download_file(file_url): -# def remove_file_by_url(file_url, doctype=None, name=None): -# def on_doctype_update(): \ No newline at end of file diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 1c4c483fa8..6ea744d553 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -374,9 +374,6 @@ class TestUser(unittest.TestCase): [m.get("module_name") for m in get_modules_from_all_apps()]) - def test_password_verification(self): - pass - def delete_contact(user): frappe.db.sql("DELETE FROM `tabContact` WHERE `email_id`= %s", user) frappe.db.sql("DELETE FROM `tabContact Email` WHERE `email_id`= %s", user) From 5587ab5a91ebb5c000c5ad9e9b249deffa7127ff Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Fri, 20 Aug 2021 23:54:42 +0530 Subject: [PATCH 60/74] style: Fix liinter warnings --- frappe/core/doctype/file/file.py | 2 +- .../prepared_report/prepared_report.py | 1 - frappe/core/doctype/user/test_user.py | 19 +++++++++---------- .../doctype/email_account/email_account.py | 13 +++++++------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 06222872a6..fcc8a860f3 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -319,7 +319,7 @@ class File(Document): def unzip(self): '''Unzip current file and replace it by its children''' - if not ".zip" in self.file_url: + if not self.file_url.endswith(".zip"): frappe.throw(_("{0} is not a zip file").format(self.file_name)) zip_path = self.get_full_path() diff --git a/frappe/core/doctype/prepared_report/prepared_report.py b/frappe/core/doctype/prepared_report/prepared_report.py index 409aa6f217..c9b5fd9d2e 100644 --- a/frappe/core/doctype/prepared_report/prepared_report.py +++ b/frappe/core/doctype/prepared_report/prepared_report.py @@ -11,7 +11,6 @@ from frappe.desk.query_report import generate_report_result from frappe.model.document import Document from frappe.utils import gzip_compress, gzip_decompress from frappe.utils.background_jobs import enqueue -from frappe.utils.file_manager import remove_all class PreparedReport(Document): def before_insert(self): diff --git a/frappe/core/doctype/user/test_user.py b/frappe/core/doctype/user/test_user.py index 6ea744d553..bcc273a784 100644 --- a/frappe/core/doctype/user/test_user.py +++ b/frappe/core/doctype/user/test_user.py @@ -1,16 +1,16 @@ # Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt -import frappe, unittest import json +import unittest +from unittest.mock import patch +import frappe +import frappe.exceptions +from frappe.core.doctype.user.user import (extract_mentions, reset_password, + sign_up, test_password_strength, update_password, verify_password) +from frappe.frappeclient import FrappeClient from frappe.model.delete_doc import delete_doc from frappe.utils import get_url -from frappe.core.doctype.user.user import (test_password_strength, - extract_mentions, sign_up, update_password, verify_password, reset_password) -from frappe.frappeclient import FrappeClient - -from unittest.mock import patch -import frappe.exceptions user_module = frappe.core.doctype.user.user test_records = frappe.get_test_records('User') @@ -305,9 +305,8 @@ class TestUser(unittest.TestCase): def test_reset_password(self): + from frappe.auth import CookieManager, LoginManager from frappe.utils import set_request - from frappe.auth import CookieManager - from frappe.auth import LoginManager old_password = "Eastern_43A1W" new_password = "easy_password" @@ -365,8 +364,8 @@ class TestUser(unittest.TestCase): self.assertEqual(reset_password(user="random"), "not found") def test_user_onload_modules(self): - from frappe.desk.form.load import getdoc from frappe.config import get_modules_from_all_apps + from frappe.desk.form.load import getdoc frappe.response.docs = [] getdoc("User", "Administrator") doc = frappe.response.docs[0] diff --git a/frappe/email/doctype/email_account/email_account.py b/frappe/email/doctype/email_account/email_account.py index a1ddbf7a68..fb7349adba 100755 --- a/frappe/email/doctype/email_account/email_account.py +++ b/frappe/email/doctype/email_account/email_account.py @@ -725,6 +725,7 @@ def get_max_email_uid(email_account): def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_outgoing): """ setup email inbox for user """ from frappe.core.doctype.user.user import ask_pass_update + def add_user_email(user): user = frappe.get_doc("User", user) row = user.append("user_emails", {}) @@ -736,11 +737,11 @@ def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_ou user.save(ignore_permissions=True) - udpate_user_email_settings = False + update_user_email_settings = False if not all([email_account, email_id]): return - user_names = frappe.db.get_values("User", { "email": email_id }, as_dict=True) + user_names = frappe.db.get_values("User", {"email": email_id}, as_dict=True) if not user_names: return @@ -757,9 +758,9 @@ def setup_user_email_inbox(email_account, awaiting_password, email_id, enable_ou add_user_email(user_name) else: # update awaiting password for email account - udpate_user_email_settings = True + update_user_email_settings = True - if udpate_user_email_settings: + if update_user_email_settings: frappe.db.sql("""UPDATE `tabUser Email` SET awaiting_password = %(awaiting_password)s, enable_outgoing = %(enable_outgoing)s WHERE email_account = %(email_account)s""", { "email_account": email_account, @@ -782,8 +783,8 @@ def remove_user_email_inbox(email_account): for user in users: doc = frappe.get_doc("User", user.get("name")) - to_remove = [ row for row in doc.user_emails if row.email_account == email_account ] - [ doc.remove(row) for row in to_remove ] + to_remove = [row for row in doc.user_emails if row.email_account == email_account] + [doc.remove(row) for row in to_remove] doc.save(ignore_permissions=True) From 399629da45ab664df8ae3c6c21e806962cc0a7d0 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 21 Aug 2021 13:47:42 +0530 Subject: [PATCH 61/74] fix(ux): Disable button while executing script - page.set_action will now pass the btn in the handler callback --- frappe/desk/doctype/system_console/system_console.js | 9 ++++++--- frappe/public/js/frappe/form/form.js | 4 ++-- frappe/public/js/frappe/ui/page.js | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/frappe/desk/doctype/system_console/system_console.js b/frappe/desk/doctype/system_console/system_console.js index c7eac39490..48dd2ba108 100644 --- a/frappe/desk/doctype/system_console/system_console.js +++ b/frappe/desk/doctype/system_console/system_console.js @@ -5,7 +5,7 @@ frappe.ui.form.on('System Console', { onload: function(frm) { frappe.ui.keys.add_shortcut({ shortcut: 'shift+enter', - action: () => frm.execute_action('Execute'), + action: () => frm.page.btn_primary.trigger('click'), page: frm.page, description: __('Execute Console script'), ignore_inputs: true, @@ -14,8 +14,11 @@ frappe.ui.form.on('System Console', { refresh: function(frm) { frm.disable_save(); - frm.page.set_primary_action(__("Execute"), () => { - frm.execute_action('Execute'); + frm.page.set_primary_action(__("Execute"), $btn => { + $btn.text(__('Executing...')); + return frm.execute_action("Execute").then(() => { + $btn.text(__('Execute')); + }); }); } }); diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index fd49df027c..3588923527 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -339,7 +339,7 @@ frappe.ui.form.Form = class FrappeForm { } } if (action.action_type==='Server Action') { - frappe.xcall(action.action, {'doc': this.doc}).then((doc) => { + return frappe.xcall(action.action, {'doc': this.doc}).then((doc) => { if (doc.doctype) { // document is returned by the method, // apply the changes locally and refresh @@ -354,7 +354,7 @@ frappe.ui.form.Form = class FrappeForm { }); }); } else if (action.action_type==='Route') { - frappe.set_route(action.action); + return frappe.set_route(action.action); } } diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js index 22fdf476b8..320227b258 100644 --- a/frappe/public/js/frappe/ui/page.js +++ b/frappe/public/js/frappe/ui/page.js @@ -251,7 +251,7 @@ frappe.ui.Page = class Page { .prop("disabled", false) .html(opts.label) .on("click", function() { - let response = opts.click.apply(this); + let response = opts.click.apply(this, [btn]); me.btn_disable_enable(btn, response); }); From 7c178ae18c41d21ac53d8b77aae0b179adeb8349 Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 23 Aug 2021 11:28:33 +0530 Subject: [PATCH 62/74] fix(ux): better message for removal of assignment (#14008) (cherry picked from commit 40352d9df6418e0c435e0ae9f9dd8f96095c70db) Co-authored-by: Ankush Menat --- frappe/desk/doctype/todo/todo.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frappe/desk/doctype/todo/todo.py b/frappe/desk/doctype/todo/todo.py index 09297b4e5e..754b94cdcb 100644 --- a/frappe/desk/doctype/todo/todo.py +++ b/frappe/desk/doctype/todo/todo.py @@ -29,8 +29,15 @@ class ToDo(Document): else: # NOTE the previous value is only available in validate method if self.get_db_value("status") != self.status: + if self.owner == frappe.session.user: + removal_message = frappe._("{0} removed their assignment.").format( + get_fullname(frappe.session.user)) + else: + removal_message = frappe._("Assignment of {0} removed by {1}").format( + get_fullname(self.owner), get_fullname(frappe.session.user)) + self._assignment = { - "text": frappe._("Assignment closed by {0}").format(get_fullname(frappe.session.user)), + "text": removal_message, "comment_type": "Assignment Completed" } From 30f9572122a4ef8c357799e50f763e49c21cac4c Mon Sep 17 00:00:00 2001 From: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:32:14 +0530 Subject: [PATCH 63/74] chore: Let maintainer raise a PR on stable branch --- .mergify.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 1a81a28594..8c7a7dc95d 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,9 +1,11 @@ pull_request_rules: - name: Auto-close PRs on stable branch conditions: - - or: - - base=version-13 - - base=version-12 + - and: + - author!=surajshetty3416 + - or: + - base=version-13 + - base=version-12 actions: close: comment: From 7e9b78bf7deb5dd03c01653e81ef810e7f2dd7bc Mon Sep 17 00:00:00 2001 From: shariquerik Date: Mon, 23 Aug 2021 13:45:14 +0530 Subject: [PATCH 64/74] test: Type on focused block fix --- cypress/integration/workspace.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/integration/workspace.js b/cypress/integration/workspace.js index 9701e54c5e..28930b5734 100644 --- a/cypress/integration/workspace.js +++ b/cypress/integration/workspace.js @@ -36,12 +36,12 @@ context('Workspace 2.0', () => { cy.get('.codex-editor__redactor .ce-block'); cy.get('.custom-actions .inner-group-button[data-label="Add%20Block"]').click(); cy.get('.custom-actions .inner-group-button .dropdown-menu .block-menu-item-label').contains('Heading').click(); - cy.get(".ce-block:last").find('h2').click({force: true}).type('Header'); + cy.get(":focus").type('Header'); cy.get(".ce-block:last").find('.ce-header').should('exist'); cy.get('.custom-actions .inner-group-button[data-label="Add%20Block"]').click(); cy.get('.custom-actions .inner-group-button .dropdown-menu .block-menu-item-label').contains('Text').click(); - cy.get(".ce-block:last").find('.ce-paragraph').click({force: true}).type('Paragraph text'); + cy.get(":focus").type('Paragraph text'); cy.get(".ce-block:last").find('.ce-paragraph').should('exist'); }); From 70899a7a959be3d7ba26bd6aa6783a7123434c24 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 23 Aug 2021 21:43:29 +0530 Subject: [PATCH 65/74] feat(minor): Added app_name and app_logo in Website Settings --- .../website_settings/website_settings.json | 23 +++++++++++++++---- frappe/www/login.py | 8 ++++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/frappe/website/doctype/website_settings/website_settings.json b/frappe/website/doctype/website_settings/website_settings.json index f4eee7231e..e7ae2a01e1 100644 --- a/frappe/website/doctype/website_settings/website_settings.json +++ b/frappe/website/doctype/website_settings/website_settings.json @@ -56,9 +56,11 @@ "google_analytics_id", "google_analytics_anonymize_ip", "misc_section", - "subdomain", + "app_name", + "app_logo", "disable_signup", "section_break_38", + "subdomain", "head_html", "robots_txt", "route_redirects", @@ -224,7 +226,7 @@ "collapsible": 1, "fieldname": "misc_section", "fieldtype": "Section Break", - "label": "Disable Signup" + "label": "Login Page" }, { "description": "An icon file with .ico extension. Should be 16 x 16 px. Generated using a favicon generator. [favicon-generator.org]", @@ -235,7 +237,7 @@ { "description": "Sub-domain provided by erpnext.com", "fieldname": "subdomain", - "fieldtype": "Text", + "fieldtype": "Small Text", "label": "Subdomain", "read_only": 1 }, @@ -425,6 +427,17 @@ "fieldname": "navbar_template_section", "fieldtype": "Section Break", "label": "Navbar Template" + }, + { + "default": "Frappe", + "fieldname": "app_name", + "fieldtype": "Data", + "label": "App Name" + }, + { + "fieldname": "app_logo", + "fieldtype": "Attach Image", + "label": "App Logo" } ], "icon": "fa fa-cog", @@ -433,7 +446,7 @@ "issingle": 1, "links": [], "max_attachments": 10, - "modified": "2021-07-15 17:39:56.609771", + "modified": "2021-08-23 21:39:51.702248", "modified_by": "Administrator", "module": "Website", "name": "Website Settings", @@ -457,4 +470,4 @@ "sort_field": "modified", "sort_order": "ASC", "track_changes": 1 -} +} \ No newline at end of file diff --git a/frappe/www/login.py b/frappe/www/login.py index 6542b29d42..f816b2f91e 100644 --- a/frappe/www/login.py +++ b/frappe/www/login.py @@ -34,9 +34,11 @@ def get_context(context): context.for_test = 'login.html' context["title"] = "Login" context["provider_logins"] = [] - context["disable_signup"] = frappe.utils.cint(frappe.db.get_value("Website Settings", "Website Settings", "disable_signup")) - context["logo"] = frappe.get_hooks("app_logo_url")[-1] - context["app_name"] = frappe.get_system_settings("app_name") or _("Frappe") + context["disable_signup"] = frappe.utils.cint(frappe.db.get_single_value("Website Settings", "disable_signup")) + context["logo"] = (frappe.db.get_single_value('Website Settings', 'app_logo') or + frappe.get_hooks("app_logo_url")[-1]) + context["app_name"] = (frappe.db.get_single_value('Website Settings', 'app_name') or + frappe.get_system_settings("app_name") or _("Frappe")) providers = [i.name for i in frappe.get_all("Social Login Key", filters={"enable_social_login":1}, order_by="name")] for provider in providers: client_id, base_url = frappe.get_value("Social Login Key", provider, ["client_id", "base_url"]) From 7caae74004b30cfcd6718c1a3b3f1d151efe9e1b Mon Sep 17 00:00:00 2001 From: Shariq Ansari <30859809+shariquerik@users.noreply.github.com> Date: Tue, 24 Aug 2021 10:15:37 +0530 Subject: [PATCH 66/74] build: Update datatable to 1.15.4 (#14016) Co-authored-by: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ddbec178e..2283a44533 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "express": "^4.17.1", "fast-deep-equal": "^2.0.1", "frappe-charts": "^2.0.0-rc13", - "frappe-datatable": "^1.15.3", + "frappe-datatable": "^1.15.4", "frappe-gantt": "^0.5.0", "fuse.js": "^3.4.6", "highlight.js": "^10.4.1", diff --git a/yarn.lock b/yarn.lock index e8f527b7f1..ee530d747b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2721,10 +2721,10 @@ frappe-charts@^2.0.0-rc13: resolved "https://registry.yarnpkg.com/frappe-charts/-/frappe-charts-2.0.0-rc13.tgz#fdb251d7ae311c41e38f90a3ae108070ec6b9072" integrity sha512-Bv7IfllIrjRbKWHn5b769dOSenqdBixAr6m5kurf8ZUOJSLOgK4HOXItJ7BA8n9PvviH9/k5DaloisjLM2Bm1w== -frappe-datatable@^1.15.3: - version "1.15.3" - resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.15.3.tgz#1737e9aebfd363ffadffced71a3534c40e350223" - integrity sha512-tUE3pNbxCMX0HPKvwurLBPRAOAdS0gNo1+MpoyFSqXI7b7sp6/TCBRht6qu1Luw+VyIzBtXkJdnnqU+Uoy8iow== +frappe-datatable@^1.15.4: + version "1.15.4" + resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.15.4.tgz#dc2e5e5d8a0a7cb8ee658f2d39966af1d4405401" + integrity sha512-eW3upPvverm1GNBL4+IcPDvjm5xbJc5ZXW8TYEUZt/QQ2W75K/T6736pSzi9D6mX9sn3BtZ7Ige7MS45SGrgzQ== dependencies: hyperlist "^1.0.0-beta" lodash "^4.17.5" From 14783a1ba19ed381c132c0cd9c13cce1cb4b5174 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 24 Aug 2021 10:25:33 +0530 Subject: [PATCH 67/74] fix: Remove unnecessary raise after throw --- frappe/core/doctype/file/file.py | 1 - 1 file changed, 1 deletion(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index fcc8a860f3..5b88418675 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -258,7 +258,6 @@ class File(Document): self.content_hash = get_content_hash(f.read()) except IOError: frappe.throw(_("File {0} does not exist").format(self.file_url)) - raise def on_trash(self): if self.is_home_folder or self.is_attachments_folder: From 850939ed1374b9d145a2258b1be3155c955006bb Mon Sep 17 00:00:00 2001 From: gavin Date: Tue, 24 Aug 2021 13:26:03 +0530 Subject: [PATCH 68/74] Revert "ci: ignore js only changes while running unittests (#13932)" This reverts commit ead26527b7c0df4b4b011bd0962e751f15aa01b1. --- .github/workflows/patch-mariadb-tests.yml | 7 +------ .github/workflows/server-mariadb-tests.yml | 6 ------ .github/workflows/server-postgres-tests.yml | 3 --- .github/workflows/ui-tests.yml | 2 -- 4 files changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/workflows/patch-mariadb-tests.yml b/.github/workflows/patch-mariadb-tests.yml index 82be4d06b5..e8627a01fb 100644 --- a/.github/workflows/patch-mariadb-tests.yml +++ b/.github/workflows/patch-mariadb-tests.yml @@ -1,11 +1,6 @@ name: Patch -on: - pull_request: - paths-ignore: - - '**.js' - - '**.md' - workflow_dispatch: +on: [pull_request, workflow_dispatch] jobs: test: diff --git a/.github/workflows/server-mariadb-tests.yml b/.github/workflows/server-mariadb-tests.yml index 8d5bd690a1..2476102e3d 100644 --- a/.github/workflows/server-mariadb-tests.yml +++ b/.github/workflows/server-mariadb-tests.yml @@ -2,15 +2,9 @@ name: Server on: pull_request: - paths-ignore: - - '**.js' - - '**.md' workflow_dispatch: push: branches: [ develop ] - paths-ignore: - - '**.js' - - '**.md' jobs: test: diff --git a/.github/workflows/server-postgres-tests.yml b/.github/workflows/server-postgres-tests.yml index 8c97c7f84b..4325eebaad 100644 --- a/.github/workflows/server-postgres-tests.yml +++ b/.github/workflows/server-postgres-tests.yml @@ -2,9 +2,6 @@ name: Server on: pull_request: - paths-ignore: - - '**.js' - - '**.md' workflow_dispatch: jobs: diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index d76e5e77ea..f342c0709e 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -2,8 +2,6 @@ name: UI on: pull_request: - paths-ignore: - - '**.md' workflow_dispatch: push: branches: [ develop ] From af93d35471535522eeda9f72e95fd884b5a1ddfe Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 24 Aug 2021 14:33:53 +0530 Subject: [PATCH 69/74] fix: Use remove_all in file_manager.py --- frappe/core/doctype/file/file.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 5b88418675..b8ea134db5 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -729,6 +729,7 @@ def remove_file_by_url(file_url, doctype=None, name=None): fid = frappe.db.get_value("File", {"file_url": file_url}) if fid: + from frappe.utils.file_manager import remove_file return remove_file(fid=fid) From c07298648ac6ea6b1613309e68f3c7a5d6bde419 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 25 Aug 2021 10:49:37 +0530 Subject: [PATCH 70/74] test: Blur the phone_nos field to enable validation for the field --- cypress/integration/form_tour.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cypress/integration/form_tour.js b/cypress/integration/form_tour.js index d2d39679a8..ab7ada9034 100644 --- a/cypress/integration/form_tour.js +++ b/cypress/integration/form_tour.js @@ -20,10 +20,10 @@ context('Form Tour', () => { it('navigates a form tour', () => { open_test_form_tour(); - cy.get('#driver-popover-item').should('be.visible'); + cy.get('.frappe-driver').should('be.visible'); cy.get('.frappe-control[data-fieldname="first_name"]').as('first_name'); cy.get('@first_name').should('have.class', 'driver-highlighted-element'); - cy.get('#driver-popover-item').findByRole('button', {name: 'Next'}).as('next_btn'); + cy.get('.frappe-driver').findByRole('button', {name: 'Next'}).as('next_btn'); // next btn shouldn't move to next step, if first name is not entered cy.get('@next_btn').click(); @@ -68,13 +68,13 @@ context('Form Tour', () => { cy.get('.grid-row-open .frappe-control[data-fieldname="phone"]').as('phone'); cy.get('@phone').should('have.class', 'driver-highlighted-element'); // enter value in a table field - cy.fill_table_field('phone_nos', '1', 'phone', '1234567890'); + let field = cy.fill_table_field('phone_nos', '1', 'phone', '1234567890'); + field.blur(); // move to collapse row step cy.wait(500); - cy.get('@next_btn').click(); + cy.get('.driver-popover-title').contains('Test Title 4').siblings().get('@next_btn').click(); cy.wait(500); - // collapse row cy.get('.grid-row-open .grid-collapse-row').click(); cy.wait(500); @@ -82,7 +82,7 @@ context('Form Tour', () => { // assert save btn is highlighted cy.get('.primary-action').should('have.class', 'driver-highlighted-element'); cy.wait(500); - cy.get('#driver-popover-item').findByRole('button', {name: 'Save'}).should('be.visible'); + cy.get('.frappe-driver').findByRole('button', {name: 'Save'}).should('be.visible'); }); }); From 004891237e77fb95b64a7f8b535774b30b3b1b02 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 25 Aug 2021 12:34:48 +0530 Subject: [PATCH 71/74] test: Fix flaky timeline_email tests --- cypress/integration/timeline_email.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cypress/integration/timeline_email.js b/cypress/integration/timeline_email.js index e5b3ebeb7c..82af24e822 100644 --- a/cypress/integration/timeline_email.js +++ b/cypress/integration/timeline_email.js @@ -8,14 +8,13 @@ context('Timeline Email', () => { it('Adding new ToDo, adding email and verifying timeline content for email attachment, deleting attachment and ToDo', () => { //Adding new ToDo cy.click_listview_primary_button('Add ToDo'); - cy.get('.custom-actions > .btn').trigger('click', {delay: 500}); - cy.get('.row > .section-body > .form-column > form > .frappe-control > .form-group > .control-input-wrapper > .control-input > .ql-container > .ql-editor').eq(0).type('Test ToDo', {force: true}); + cy.get('.custom-actions:visible > .btn').contains("Edit in full page").click({delay: 500}); + cy.fill_field("description", "Test ToDo", "Text Editor"); cy.wait(500); - //cy.click_listview_primary_button('Save'); cy.get('.primary-action').contains('Save').click({force: true}); cy.wait(700); cy.visit('/app/todo'); - cy.get('.list-row > .level-left > .list-subject > .level-item.ellipsis > .ellipsis').eq(0).click(); + cy.get('.list-row > .level-left > .list-subject').eq(0).click(); //Creating a new email cy.get('.timeline-actions > .btn').click(); @@ -47,7 +46,7 @@ context('Timeline Email', () => { //Removing the added attachment cy.get('.attachment-row > .data-pill > .remove-btn > .icon').click(); - cy.get('.modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary').contains('Yes').click(); + cy.get('.modal-footer:visible > .standard-actions > .btn-primary').contains('Yes').click(); //To check if the removed attachment is shown in the timeline content cy.get('.timeline-content').should('contain', 'Removed 72402.jpg'); @@ -55,17 +54,17 @@ context('Timeline Email', () => { //To check if the discard button functionality in email is working correctly cy.get('.timeline-actions > .btn').click(); - cy.fill_field('recipients', 'test@example.com', 'MultiSelect'); + cy.fill_field('recipients', 'test@example.com', 'MultiSelect'); cy.get('.modal-footer > .standard-actions > .btn-secondary').contains('Discard').click(); cy.wait(500); cy.get('.timeline-actions > .btn').click(); cy.wait(500); cy.get_field('recipients', 'MultiSelect').should('have.text', ''); - cy.get('.modal.show > .modal-dialog > .modal-content > .modal-header > .modal-actions > .btn-modal-close > .icon').click(); + cy.get('.modal-header:visible > .modal-actions > .btn-modal-close > .icon').click(); //Deleting the added ToDo - cy.get('#page-ToDo > .page-head > .container > .row > .col > .standard-actions > .menu-btn-group > .btn').click(); - cy.get('.menu-btn-group > .dropdown-menu > li > .grey-link').eq(17).click(); - cy.get('.modal.show > .modal-dialog > .modal-content > .modal-footer > .standard-actions > .btn-primary').click(); + cy.get('.menu-btn-group:visible > .btn').click(); + cy.get('.menu-btn-group:visible > .dropdown-menu > li > .dropdown-item').contains('Delete').click(); + cy.get('.modal-footer:visible > .standard-actions > .btn-primary').click(); }); }); From 2865b35673a3bc3158ceed3c784f19e7cae2b9f8 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Wed, 25 Aug 2021 12:43:03 +0530 Subject: [PATCH 72/74] patch: set title as label if extends is empty --- frappe/patches/v14_0/update_workspace2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/patches/v14_0/update_workspace2.py b/frappe/patches/v14_0/update_workspace2.py index 2d7eb4cc76..1a56310a6c 100644 --- a/frappe/patches/v14_0/update_workspace2.py +++ b/frappe/patches/v14_0/update_workspace2.py @@ -54,7 +54,7 @@ def update_wspace(doc, seq, content): doc.sequence_id = seq + 1 doc.content = json.dumps(content) doc.public = 0 - doc.title = doc.extends + doc.title = doc.extends or doc.label doc.extends = '' doc.category = '' doc.onboarding = '' From 4a468c14d3eacba8274842a8cfa99a7c316a479b Mon Sep 17 00:00:00 2001 From: shariquerik Date: Wed, 25 Aug 2021 13:02:27 +0530 Subject: [PATCH 73/74] fix: updated pah --- frappe/patches.txt | 2 +- frappe/patches/v14_0/update_workspace2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/patches.txt b/frappe/patches.txt index 87919b0247..41ca1a1724 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -182,4 +182,4 @@ frappe.patches.v13_0.jinja_hook frappe.patches.v13_0.update_notification_channel_if_empty frappe.patches.v14_0.drop_data_import_legacy frappe.patches.v14_0.rename_cancelled_documents -frappe.patches.v14_0.update_workspace2 +frappe.patches.v14_0.update_workspace2 # 25.08.2021 diff --git a/frappe/patches/v14_0/update_workspace2.py b/frappe/patches/v14_0/update_workspace2.py index 1a56310a6c..4974919049 100644 --- a/frappe/patches/v14_0/update_workspace2.py +++ b/frappe/patches/v14_0/update_workspace2.py @@ -50,7 +50,7 @@ def create_content(doc): return content def update_wspace(doc, seq, content): - if not doc.is_standard and not doc.public: + if not doc.title and not content and not doc.is_standard and not doc.public: doc.sequence_id = seq + 1 doc.content = json.dumps(content) doc.public = 0 From 82c354e9187140eaf81b722086edb00cea946ec4 Mon Sep 17 00:00:00 2001 From: shariquerik Date: Wed, 25 Aug 2021 13:03:40 +0530 Subject: [PATCH 74/74] fix: updated patch --- frappe/patches/v14_0/update_workspace2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/patches/v14_0/update_workspace2.py b/frappe/patches/v14_0/update_workspace2.py index 4974919049..c212faee76 100644 --- a/frappe/patches/v14_0/update_workspace2.py +++ b/frappe/patches/v14_0/update_workspace2.py @@ -50,7 +50,7 @@ def create_content(doc): return content def update_wspace(doc, seq, content): - if not doc.title and not content and not doc.is_standard and not doc.public: + if not doc.title and not doc.content and not doc.is_standard and not doc.public: doc.sequence_id = seq + 1 doc.content = json.dumps(content) doc.public = 0