From d0a5a9a7ba7bbff9edadb6a306d468d14420983d Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Thu, 14 Nov 2019 00:06:53 +0100 Subject: [PATCH 01/31] :white_check_mark: Add JUnit XML reports to Travis Signed-off-by: mathieu.brunot --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index df66db88a7..0288c01f7e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,12 +21,12 @@ matrix: - name: "Python 3.6 MariaDB" python: 3.6 env: DB=mariadb TYPE=server - script: bench --site test_site run-tests --coverage + script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml - name: "Python 3.6 PostgreSQL" python: 3.6 env: DB=postgres TYPE=server - script: bench --site test_site run-tests --coverage + script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml - name: "Cypress" python: 3.6 @@ -37,7 +37,7 @@ matrix: - name: "Python 2.7 MariaDB" python: 2.7 env: DB=mariadb TYPE=server - script: bench --site test_site run-tests --coverage + script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml install: - cd ~ From 0054206e431d6418447e3a117223aeeba6e80833 Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Mon, 25 Nov 2019 23:23:49 +0100 Subject: [PATCH 02/31] :construction: Testing without TimeLogging Signed-off-by: mathieu.brunot --- frappe/test_runner.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 76140e442c..4e5010ed38 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -131,7 +131,8 @@ def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfa pr = cProfile.Profile() pr.enable() - out = unittest_runner(resultclass=TimeLoggingTestResult, verbosity=1+(verbose and 1 or 0), failfast=failfast).run(test_suite) + # resultclass=TimeLoggingTestResult, + out = unittest_runner(verbosity=1+(verbose and 1 or 0), failfast=failfast).run(test_suite) if profile: pr.disable() From f3717bd7a69f2ab9088e87e481ddd5f64b1c2aaa Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Tue, 26 Nov 2019 03:11:14 +0100 Subject: [PATCH 03/31] :white_check_mark: Test XML reports Signed-off-by: mathieu.brunot --- .travis.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0288c01f7e..a5c81f9631 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,11 +19,21 @@ cache: matrix: include: - name: "Python 3.6 MariaDB" + python: 3.6 + env: DB=mariadb TYPE=server + script: bench --site test_site run-tests --coverage + + - name: "Python 3.6 MariaDB XML Report" python: 3.6 env: DB=mariadb TYPE=server script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml - name: "Python 3.6 PostgreSQL" + python: 3.6 + env: DB=postgres TYPE=server + script: bench --site test_site run-tests --coverage + + - name: "Python 3.6 PostgreSQL XML Report" python: 3.6 env: DB=postgres TYPE=server script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml @@ -35,6 +45,11 @@ matrix: script: bench --site test_site run-ui-tests frappe --headless - name: "Python 2.7 MariaDB" + python: 2.7 + env: DB=mariadb TYPE=server + script: bench --site test_site run-tests --coverage + + - name: "Python 2.7 MariaDB XML Report" python: 2.7 env: DB=mariadb TYPE=server script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml From 3073515b1c2c40c14aeda5a2e4cb4a3a1b363c12 Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Tue, 26 Nov 2019 03:11:40 +0100 Subject: [PATCH 04/31] :construction: Split runner init from test run Signed-off-by: mathieu.brunot --- frappe/test_runner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 4e5010ed38..23ba00789d 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -131,8 +131,8 @@ def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfa pr = cProfile.Profile() pr.enable() - # resultclass=TimeLoggingTestResult, - out = unittest_runner(verbosity=1+(verbose and 1 or 0), failfast=failfast).run(test_suite) + runner = unittest_runner(resultclass=TimeLoggingTestResult, verbosity=1+(verbose and 1 or 0), failfast=failfast) + out = runner.run(test_suite) if profile: pr.disable() From cf50b52df7b2bf33044a619dbdbf0cb8d2b2c255 Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Tue, 26 Nov 2019 03:21:23 +0100 Subject: [PATCH 05/31] :bug: Allow Unit Test XML to write binary Signed-off-by: mathieu.brunot --- frappe/test_runner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 23ba00789d..86aa1b730e 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -38,7 +38,7 @@ def main(app=None, module=None, doctype=None, verbose=False, tests=(), xmloutput_fh = None if junit_xml_output: - xmloutput_fh = open(junit_xml_output, 'w') + xmloutput_fh = open(junit_xml_output, 'wb') unittest_runner = xmlrunner_wrapper(xmloutput_fh) else: unittest_runner = unittest.TextTestRunner From 469944d2738fd9de1d468c2a9b357c6f65003001 Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Tue, 26 Nov 2019 04:00:14 +0100 Subject: [PATCH 06/31] :bug: Change runner init if XML report on Signed-off-by: mathieu.brunot --- frappe/test_runner.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 86aa1b730e..e7ec13afe6 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -65,11 +65,11 @@ def main(app=None, module=None, doctype=None, verbose=False, tests=(), frappe.get_attr(fn)() if doctype: - ret = run_tests_for_doctype(doctype, verbose, tests, force, profile) + ret = run_tests_for_doctype(doctype, verbose, tests, force, profile, junit_xml_output=junit_xml_output) elif module: - ret = run_tests_for_module(module, verbose, tests, profile) + ret = run_tests_for_module(module, verbose, tests, profile, junit_xml_output=junit_xml_output) else: - ret = run_all_tests(app, verbose, profile, ui_tests, failfast=failfast) + ret = run_all_tests(app, verbose, profile, ui_tests, failfast=failfast, junit_xml_output=junit_xml_output) frappe.db.commit() @@ -106,7 +106,7 @@ class TimeLoggingTestResult(unittest.TextTestResult): super(TimeLoggingTestResult, self).addSuccess(test) -def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfast=False): +def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfast=False, junit_xml_output=False): import os apps = [app] if app else frappe.get_installed_apps() @@ -127,11 +127,15 @@ def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfa _add_test(app, path, filename, verbose, test_suite, ui_tests) + if junit_xml_output: + runner = unittest_runner(verbosity=1+(verbose and 1 or 0), failfast=failfast) + else: + runner = unittest_runner(resultclass=TimeLoggingTestResult, verbosity=1+(verbose and 1 or 0), failfast=failfast) + if profile: pr = cProfile.Profile() pr.enable() - runner = unittest_runner(resultclass=TimeLoggingTestResult, verbosity=1+(verbose and 1 or 0), failfast=failfast) out = runner.run(test_suite) if profile: @@ -143,7 +147,7 @@ def run_all_tests(app=None, verbose=False, profile=False, ui_tests=False, failfa return out -def run_tests_for_doctype(doctypes, verbose=False, tests=(), force=False, profile=False): +def run_tests_for_doctype(doctypes, verbose=False, tests=(), force=False, profile=False, junit_xml_output=False): modules = [] if not isinstance(doctypes, (list, tuple)): doctypes = [doctypes] @@ -161,15 +165,15 @@ def run_tests_for_doctype(doctypes, verbose=False, tests=(), force=False, profil make_test_records(doctype, verbose=verbose, force=force) modules.append(importlib.import_module(test_module)) - return _run_unittest(modules, verbose=verbose, tests=tests, profile=profile) + return _run_unittest(modules, verbose=verbose, tests=tests, profile=profile, junit_xml_output=junit_xml_output) -def run_tests_for_module(module, verbose=False, tests=(), profile=False): +def run_tests_for_module(module, verbose=False, tests=(), profile=False, junit_xml_output=False): module = importlib.import_module(module) if hasattr(module, "test_dependencies"): for doctype in module.test_dependencies: make_test_records(doctype, verbose=verbose) - return _run_unittest(module, verbose=verbose, tests=tests, profile=profile) + return _run_unittest(module, verbose=verbose, tests=tests, profile=profile, junit_xml_output=junit_xml_output) def run_setup_wizard_ui_test(app=None, verbose=False, profile=False): '''Run setup wizard UI test using test_test_runner''' @@ -186,7 +190,7 @@ def run_ui_tests(app=None, test=None, test_list=None, verbose=False, profile=Fal frappe.flags.ui_test_path = test return _run_unittest(module, verbose=verbose, tests=(), profile=profile) -def _run_unittest(modules, verbose=False, tests=(), profile=False): +def _run_unittest(modules, verbose=False, tests=(), profile=False, junit_xml_output=False): test_suite = unittest.TestSuite() if not isinstance(modules, (list, tuple)): @@ -202,13 +206,18 @@ def _run_unittest(modules, verbose=False, tests=(), profile=False): else: test_suite.addTest(module_test_cases) + if junit_xml_output: + runner = unittest_runner(verbosity=1+(verbose and 1 or 0)) + else: + runner = unittest_runner(resultclass=TimeLoggingTestResult, verbosity=1+(verbose and 1 or 0)) + if profile: pr = cProfile.Profile() pr.enable() frappe.flags.tests_verbose = verbose - out = unittest_runner(verbosity=1+(verbose and 1 or 0)).run(test_suite) + out = runner.run(test_suite) if profile: From 598a0d1a45e4cd61258f740f0e367469b9c83a6b Mon Sep 17 00:00:00 2001 From: Mathieu Brunot Date: Tue, 31 Dec 2019 02:40:06 +0100 Subject: [PATCH 07/31] ci(coverage): Pin converage to 4.5.4 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 6990a0df8a..4962caf788 100644 --- a/.travis.yml +++ b/.travis.yml @@ -91,5 +91,6 @@ install: - bench build --app frappe after_script: + - pip install coverage==4.5.4 - pip install python-coveralls - coveralls -b apps/frappe -d ../../sites/.coverage From fbf2e8812192e71e3478598425003e27b2d4cf73 Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 13 Jan 2020 13:30:18 +0530 Subject: [PATCH 08/31] style(web-form): change delete button to an icon --- frappe/public/js/frappe/web_form/web_form.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/web_form/web_form.js b/frappe/public/js/frappe/web_form/web_form.js index f1d1d5076e..17c284db4a 100644 --- a/frappe/public/js/frappe/web_form/web_form.js +++ b/frappe/public/js/frappe/web_form/web_form.js @@ -86,7 +86,11 @@ export default class WebForm extends frappe.ui.FieldGroup { } setup_delete_button() { - this.add_button_to_header("Delete", "danger", () => this.delete()); + this.add_button_to_header( + '', + "light", + () => this.delete() + ); } setup_print_button() { From 0aa9b024c12cc8a898e3c06398d568fed62867d6 Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 13 Jan 2020 09:35:12 +0100 Subject: [PATCH 09/31] allow again fairlogin as ID provider See discussion https://github.com/frappe/frappe/pull/8720#issuecomment-571486691 --- frappe/integrations/oauth2_logins.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/integrations/oauth2_logins.py b/frappe/integrations/oauth2_logins.py index a3ee98ad4e..14a6bcc417 100644 --- a/frappe/integrations/oauth2_logins.py +++ b/frappe/integrations/oauth2_logins.py @@ -31,6 +31,10 @@ def login_via_office365(code, state): def login_via_salesforce(code, state): login_via_oauth2("salesforce", code, state, decoder=decoder_compat) +@frappe.whitelist(allow_guest=True) +def login_via_fairlogin(code, state): + login_via_oauth2("fairlogin", code, state, decoder=decoder_compat) + @frappe.whitelist(allow_guest=True) def custom(code, state): """ From c234336ddcc89a3c1ec464d074d23536abc83a11 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 13 Jan 2020 15:02:43 +0530 Subject: [PATCH 10/31] feat: add security headers to webhook --- .../integrations/doctype/webhook/webhook.js | 10 ++++++- .../integrations/doctype/webhook/webhook.json | 29 ++++++++++++++++++- .../integrations/doctype/webhook/webhook.py | 10 +++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/frappe/integrations/doctype/webhook/webhook.js b/frappe/integrations/doctype/webhook/webhook.js index 90b5b12dc6..8154cf82a0 100644 --- a/frappe/integrations/doctype/webhook/webhook.js +++ b/frappe/integrations/doctype/webhook/webhook.js @@ -66,7 +66,15 @@ frappe.ui.form.on('Webhook', { webhook_doctype: (frm) => { frappe.webhook.set_fieldname_select(frm); - } + }, + + enable_security: (frm) => { + frm.toggle_reqd('webhook_secret', frm.doc.enable_security); + }, + + generate_secret: (frm) => { + frm.call("generate_secret"); + }, }); frappe.ui.form.on("Webhook Data", { diff --git a/frappe/integrations/doctype/webhook/webhook.json b/frappe/integrations/doctype/webhook/webhook.json index 8aa96e6859..4c02a4403e 100644 --- a/frappe/integrations/doctype/webhook/webhook.json +++ b/frappe/integrations/doctype/webhook/webhook.json @@ -19,6 +19,10 @@ "request_url", "cb_webhook", "request_structure", + "sb_security", + "enable_security", + "webhook_secret", + "generate_secret", "sb_webhook_headers", "webhook_headers", "sb_webhook_data", @@ -127,10 +131,33 @@ "fieldtype": "Select", "label": "Naming Series", "options": "\nHOOK-.####" + }, + { + "fieldname": "sb_security", + "fieldtype": "Section Break", + "label": "Webhook Security" + }, + { + "default": "0", + "fieldname": "enable_security", + "fieldtype": "Check", + "label": "Enable Security" + }, + { + "depends_on": "eval:doc.enable_security == 1", + "fieldname": "webhook_secret", + "fieldtype": "Password", + "label": "Webhook Secret" + }, + { + "depends_on": "eval:doc.enable_security == 1", + "fieldname": "generate_secret", + "fieldtype": "Button", + "label": "Generate Secret" } ], "links": [], - "modified": "2020-01-06 02:51:07.997566", + "modified": "2020-01-13 01:11:29.392078", "modified_by": "Administrator", "module": "Integrations", "name": "Webhook", diff --git a/frappe/integrations/doctype/webhook/webhook.py b/frappe/integrations/doctype/webhook/webhook.py index 0a97022f66..070d0177b9 100644 --- a/frappe/integrations/doctype/webhook/webhook.py +++ b/frappe/integrations/doctype/webhook/webhook.py @@ -16,6 +16,8 @@ from frappe import _ from frappe.model.document import Document from frappe.utils.jinja import validate_template +WEBHOOK_SECRET_HEADER = "X-Frappe-Webhook-Key" + class Webhook(Document): def validate(self): @@ -67,6 +69,9 @@ class Webhook(Document): if len(webhook_data) != len(set(webhook_data)): frappe.throw(_("Same Field is entered more than once")) + def generate_secret(self): + self.webhook_secret = frappe.generate_hash(length=32) + def get_context(doc): return {"doc": doc, "utils": frappe.utils} @@ -94,10 +99,15 @@ def enqueue_webhook(doc, webhook): def get_webhook_headers(doc, webhook): headers = {} + + if webhook.enable_security: + headers[WEBHOOK_SECRET_HEADER] = webhook.get_password("webhook_secret") + if webhook.webhook_headers: for h in webhook.webhook_headers: if h.get("key") and h.get("value"): headers[h.get("key")] = h.get("value") + return headers From ed71b275a26c895009ac7a97009e7b279e5da2a3 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 13 Jan 2020 15:24:11 +0530 Subject: [PATCH 11/31] fix: remove auto-generation of secret --- frappe/integrations/doctype/webhook/webhook.js | 6 +----- frappe/integrations/doctype/webhook/webhook.json | 9 +-------- frappe/integrations/doctype/webhook/webhook.py | 3 --- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/frappe/integrations/doctype/webhook/webhook.js b/frappe/integrations/doctype/webhook/webhook.js index 8154cf82a0..09c296113a 100644 --- a/frappe/integrations/doctype/webhook/webhook.js +++ b/frappe/integrations/doctype/webhook/webhook.js @@ -70,11 +70,7 @@ frappe.ui.form.on('Webhook', { enable_security: (frm) => { frm.toggle_reqd('webhook_secret', frm.doc.enable_security); - }, - - generate_secret: (frm) => { - frm.call("generate_secret"); - }, + } }); frappe.ui.form.on("Webhook Data", { diff --git a/frappe/integrations/doctype/webhook/webhook.json b/frappe/integrations/doctype/webhook/webhook.json index 4c02a4403e..9f979099c9 100644 --- a/frappe/integrations/doctype/webhook/webhook.json +++ b/frappe/integrations/doctype/webhook/webhook.json @@ -22,7 +22,6 @@ "sb_security", "enable_security", "webhook_secret", - "generate_secret", "sb_webhook_headers", "webhook_headers", "sb_webhook_data", @@ -148,16 +147,10 @@ "fieldname": "webhook_secret", "fieldtype": "Password", "label": "Webhook Secret" - }, - { - "depends_on": "eval:doc.enable_security == 1", - "fieldname": "generate_secret", - "fieldtype": "Button", - "label": "Generate Secret" } ], "links": [], - "modified": "2020-01-13 01:11:29.392078", + "modified": "2020-01-13 01:53:04.459968", "modified_by": "Administrator", "module": "Integrations", "name": "Webhook", diff --git a/frappe/integrations/doctype/webhook/webhook.py b/frappe/integrations/doctype/webhook/webhook.py index 070d0177b9..152ffada97 100644 --- a/frappe/integrations/doctype/webhook/webhook.py +++ b/frappe/integrations/doctype/webhook/webhook.py @@ -69,9 +69,6 @@ class Webhook(Document): if len(webhook_data) != len(set(webhook_data)): frappe.throw(_("Same Field is entered more than once")) - def generate_secret(self): - self.webhook_secret = frappe.generate_hash(length=32) - def get_context(doc): return {"doc": doc, "utils": frappe.utils} From 43ccae0327cf8d9b81ee527778a5d86793592722 Mon Sep 17 00:00:00 2001 From: Rohan Bansal Date: Mon, 13 Jan 2020 15:35:15 +0530 Subject: [PATCH 12/31] fix: hash secret before assigning to header --- frappe/integrations/doctype/webhook/webhook.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/frappe/integrations/doctype/webhook/webhook.py b/frappe/integrations/doctype/webhook/webhook.py index 152ffada97..5cbe7c0a02 100644 --- a/frappe/integrations/doctype/webhook/webhook.py +++ b/frappe/integrations/doctype/webhook/webhook.py @@ -4,7 +4,10 @@ from __future__ import unicode_literals +import base64 import datetime +import hashlib +import hmac import json from time import sleep @@ -16,7 +19,7 @@ from frappe import _ from frappe.model.document import Document from frappe.utils.jinja import validate_template -WEBHOOK_SECRET_HEADER = "X-Frappe-Webhook-Key" +WEBHOOK_SECRET_HEADER = "X-Frappe-Webhook-Signature" class Webhook(Document): @@ -98,7 +101,15 @@ def get_webhook_headers(doc, webhook): headers = {} if webhook.enable_security: - headers[WEBHOOK_SECRET_HEADER] = webhook.get_password("webhook_secret") + data = get_webhook_data(doc, webhook) + signature = base64.b64encode( + hmac.new( + webhook.get_password("webhook_secret").encode("utf8"), + json.dumps(data).encode("utf8"), + hashlib.sha256 + ).digest() + ) + headers[WEBHOOK_SECRET_HEADER] = signature if webhook.webhook_headers: for h in webhook.webhook_headers: From 2a3601ade87bdc525021f78aae31b1973ea45e79 Mon Sep 17 00:00:00 2001 From: prssanna Date: Mon, 13 Jan 2020 16:25:43 +0530 Subject: [PATCH 13/31] fix: set doctype in timeline item --- frappe/public/js/frappe/form/footer/timeline.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js index 6dbb7904c2..747e59b410 100644 --- a/frappe/public/js/frappe/form/footer/timeline.js +++ b/frappe/public/js/frappe/form/footer/timeline.js @@ -371,6 +371,10 @@ frappe.ui.form.Timeline = class Timeline { c.sender = c.sender.split("<")[1].split(">")[0]; } + if (!c.doctype && c.communication_type == 'Comment' || c.communication_type == 'Communication') { + c.doctype = c.communication_type; + } + c.user_info = frappe.user_info(c.sender); c["delete"] = ""; From 4f7c46e140df8ec4d96ec21dc075244d93018675 Mon Sep 17 00:00:00 2001 From: "mathieu.brunot" Date: Mon, 13 Jan 2020 11:57:12 +0100 Subject: [PATCH 14/31] :ok_hand: Remove XML reports from CI Signed-off-by: mathieu.brunot --- .travis.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4e35a97208..6990a0df8a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,21 +22,11 @@ matrix: env: DB=mariadb TYPE=server script: bench --site test_site run-tests --coverage - - name: "Python 3.6 MariaDB XML Report" - python: 3.6 - env: DB=mariadb TYPE=server - script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml - - name: "Python 3.6 PostgreSQL" python: 3.6 env: DB=postgres TYPE=server script: bench --site test_site run-tests --coverage - - name: "Python 3.6 PostgreSQL XML Report" - python: 3.6 - env: DB=postgres TYPE=server - script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml - - name: "Cypress" python: 3.6 env: DB=mariadb TYPE=ui @@ -48,11 +38,6 @@ matrix: env: DB=mariadb TYPE=server script: bench --site test_site run-tests --coverage - - name: "Python 2.7 MariaDB XML Report" - python: 2.7 - env: DB=mariadb TYPE=server - script: bench --site test_site run-tests --coverage --junit-xml-output frappe_unit_tests.xml - before_install: # install wkhtmltopdf - wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz From dfa9bf463dc724bf56f498ee76b49a8468790cfb Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Mon, 13 Jan 2020 17:22:23 +0530 Subject: [PATCH 15/31] fix: stripe api payment receipt email --- frappe/integrations/doctype/stripe_settings/stripe_settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/integrations/doctype/stripe_settings/stripe_settings.py b/frappe/integrations/doctype/stripe_settings/stripe_settings.py index 35beef7faa..70ca6002e4 100644 --- a/frappe/integrations/doctype/stripe_settings/stripe_settings.py +++ b/frappe/integrations/doctype/stripe_settings/stripe_settings.py @@ -76,7 +76,7 @@ class StripeSettings(Document): def create_charge_on_stripe(self): import stripe try: - charge = stripe.Charge.create(amount=cint(flt(self.data.amount)*100), currency=self.data.currency, source=self.data.stripe_token_id, description=self.data.description) + charge = stripe.Charge.create(amount=cint(flt(self.data.amount)*100), currency=self.data.currency, source=self.data.stripe_token_id, description=self.data.description, receipt_email=self.data.payer_email) if charge.captured == True: self.integration_request.db_set('status', 'Completed', update_modified=False) From b9ac4a409436ab0b8a84e23309698cab7472ca66 Mon Sep 17 00:00:00 2001 From: prssanna Date: Tue, 14 Jan 2020 11:06:33 +0530 Subject: [PATCH 16/31] fix: code formatting --- frappe/public/js/frappe/form/footer/timeline.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/footer/timeline.js b/frappe/public/js/frappe/form/footer/timeline.js index 747e59b410..8294c3f7b8 100644 --- a/frappe/public/js/frappe/form/footer/timeline.js +++ b/frappe/public/js/frappe/form/footer/timeline.js @@ -371,7 +371,7 @@ frappe.ui.form.Timeline = class Timeline { c.sender = c.sender.split("<")[1].split(">")[0]; } - if (!c.doctype && c.communication_type == 'Comment' || c.communication_type == 'Communication') { + if (!c.doctype && ['Comment', 'Communication'].includes(c.communication_type)) { c.doctype = c.communication_type; } From e28ae2f4ab3b61820ae00c5c13ba771380ff856f Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Tue, 14 Jan 2020 11:32:00 +0530 Subject: [PATCH 17/31] fix: update message --- frappe/public/js/frappe/desk.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 23d7bffec2..5e642f907b 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -481,7 +481,7 @@ frappe.Application = Class.extend({ // Iterate over changelog var change_log_dialog = frappe.msgprint({ message: frappe.render_template("change_log", {"change_log": change_log}), - title: __("Updated To New Version 🎉"), + title: __("Updated To A New Version 🎉"), wide: true, scroll: true }); From f056f63ee106c249e20add924b9042075598447e Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 14 Jan 2020 13:01:43 +0530 Subject: [PATCH 18/31] fix: Set correct doctype on clicking Customize button --- frappe/public/js/frappe/form/toolbar.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js index f6bc6f7cc8..b760e8682c 100644 --- a/frappe/public/js/frappe/form/toolbar.js +++ b/frappe/public/js/frappe/form/toolbar.js @@ -267,14 +267,21 @@ frappe.ui.form.Toolbar = Class.extend({ }); } - if(frappe.user_roles.includes("System Manager") && me.frm.meta.issingle === 0) { + if (frappe.user_roles.includes("System Manager") && me.frm.meta.issingle === 0) { + let doctype = me.frm.doctype; + if (me.frm.doctype == 'DocType') { + if (me.frm.docname == 'DocType') return; + else { + doctype = me.frm.docname; + } + } this.page.add_menu_item(__("Customize"), function() { if (me.frm.meta && me.frm.meta.custom) { - frappe.set_route('Form', 'DocType', me.frm.doctype); + frappe.set_route('Form', 'DocType', doctype); } else { frappe.set_route('Form', 'Customize Form', { - doc_type: me.frm.doctype + doc_type: doctype }); } }, true); From 2004e2e4cf6cdf9630fe6c2a1fa8de7f227958e5 Mon Sep 17 00:00:00 2001 From: prssanna Date: Tue, 14 Jan 2020 13:22:10 +0530 Subject: [PATCH 19/31] fix(Report): group by reports not being saved --- frappe/public/js/frappe/ui/group_by/group_by.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/group_by/group_by.js b/frappe/public/js/frappe/ui/group_by/group_by.js index 6a1c877635..fa2e2552c2 100644 --- a/frappe/public/js/frappe/ui/group_by/group_by.js +++ b/frappe/public/js/frappe/ui/group_by/group_by.js @@ -81,7 +81,11 @@ frappe.ui.GroupBy = class { } apply_settings(settings) { - this.groupby_select.val(settings.group_by); + + // Extract fieldname from `tabdoctype`.`fieldname` + let group_by_fieldname = settings.group_by.split('.')[1].slice(1, -1); + + this.groupby_select.val(group_by_fieldname); this.aggregate_function_select.val(settings.aggregate_function); this.show_hide_aggregate_on(); this.aggregate_on_select.val(settings.aggregate_on); From 26e426d7042ea8aa6746db8886ba6c7962449712 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 14 Jan 2020 13:32:50 +0530 Subject: [PATCH 20/31] fix: Do not show customize button for custom doctype --- frappe/public/js/frappe/form/toolbar.js | 30 ++++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js index b760e8682c..f772d453e4 100644 --- a/frappe/public/js/frappe/form/toolbar.js +++ b/frappe/public/js/frappe/form/toolbar.js @@ -268,23 +268,21 @@ frappe.ui.form.Toolbar = Class.extend({ } if (frappe.user_roles.includes("System Manager") && me.frm.meta.issingle === 0) { - let doctype = me.frm.doctype; - if (me.frm.doctype == 'DocType') { - if (me.frm.docname == 'DocType') return; - else { - doctype = me.frm.docname; - } - } - this.page.add_menu_item(__("Customize"), function() { + let is_doctype_form = me.frm.doctype === 'DocType'; + let doctype = is_doctype_form ? me.frm.docname : me.frm.doctype; + let is_doctype_custom = is_doctype_form ? me.frm.doc.custom : false; - if (me.frm.meta && me.frm.meta.custom) { - frappe.set_route('Form', 'DocType', doctype); - } else { - frappe.set_route('Form', 'Customize Form', { - doc_type: doctype - }); - } - }, true); + if (doctype != 'DocType' && !is_doctype_custom) { + this.page.add_menu_item(__("Customize"), function() { + if (me.frm.meta && me.frm.meta.custom) { + frappe.set_route('Form', 'DocType', doctype); + } else { + frappe.set_route('Form', 'Customize Form', { + doc_type: doctype + }); + } + }, true); + } if (frappe.boot.developer_mode===1) { // edit doctype From c29cd3a335c76a7f1ede0953f0bf7b8c2aaa2d3a Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 14 Jan 2020 13:36:59 +0530 Subject: [PATCH 21/31] fix: Do not show Edit DocType button in DocType form --- frappe/public/js/frappe/form/toolbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/toolbar.js b/frappe/public/js/frappe/form/toolbar.js index f772d453e4..528c874935 100644 --- a/frappe/public/js/frappe/form/toolbar.js +++ b/frappe/public/js/frappe/form/toolbar.js @@ -284,7 +284,7 @@ frappe.ui.form.Toolbar = Class.extend({ }, true); } - if (frappe.boot.developer_mode===1) { + if (frappe.boot.developer_mode===1 && !is_doctype_form) { // edit doctype this.page.add_menu_item(__("Edit DocType"), function() { frappe.set_route('Form', 'DocType', me.frm.doctype); From 273a64ff44a30577f623ff59cc70b6bf435c9bed Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Tue, 14 Jan 2020 17:25:01 +0530 Subject: [PATCH 22/31] fix(background_job): use status as get_status is not accessible in html --- frappe/core/page/background_jobs/background_jobs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/page/background_jobs/background_jobs.html b/frappe/core/page/background_jobs/background_jobs.html index 08177ecf8a..c5d598ccd3 100644 --- a/frappe/core/page/background_jobs/background_jobs.html +++ b/frappe/core/page/background_jobs/background_jobs.html @@ -11,7 +11,7 @@ {% for j in jobs %} - {{ j.queue.split(".").slice(-1)[0] }} + {{ j.queue.split(".").slice(-1)[0] }}
{{ frappe.utils.encode_tags(j.job_name) }} From b83452022a9e203619a855268933a04e9e5bce8c Mon Sep 17 00:00:00 2001 From: thefalconx33 Date: Wed, 15 Jan 2020 12:43:40 +0530 Subject: [PATCH 23/31] fix: report doesn't have attribute custom report --- frappe/desk/query_report.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index 7dc561193f..48c1123d75 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -229,8 +229,9 @@ def get_prepared_report_result(report, filters, dn="", user=None): "status": "Completed", "filters": json.dumps(filters), "owner": user, - "report_name": report.report_name - } + "report_name": report.get('custom_report') or report.get('report_name') + }, + order_by = 'creation desc' ) if doc_list: From 34d23575264664a2c8c4ffbbb382db55854c33bb Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Wed, 15 Jan 2020 13:15:31 +0530 Subject: [PATCH 24/31] fix(patch): reload Prepared Report doctype --- frappe/patches/v11_0/delete_all_prepared_reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/patches/v11_0/delete_all_prepared_reports.py b/frappe/patches/v11_0/delete_all_prepared_reports.py index de36db66af..1d722da7e6 100644 --- a/frappe/patches/v11_0/delete_all_prepared_reports.py +++ b/frappe/patches/v11_0/delete_all_prepared_reports.py @@ -3,7 +3,7 @@ import frappe def execute(): if frappe.db.table_exists('Prepared Report'): - frappe.reload_doc("core", "doctype", "prepared_doctype") + frappe.reload_doc("core", "doctype", "prepared_report") prepared_reports = frappe.get_all("Prepared Report") for report in prepared_reports: frappe.delete_doc("Prepared Report", report.name) From 09548a881b345029a2e7d7fc785fca738acbb799 Mon Sep 17 00:00:00 2001 From: Prssanna Desai Date: Wed, 15 Jan 2020 14:31:45 +0530 Subject: [PATCH 25/31] fix: use replace instead of slice Co-Authored-By: Suraj Shetty <13928957+surajshetty3416@users.noreply.github.com> --- frappe/public/js/frappe/ui/group_by/group_by.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/group_by/group_by.js b/frappe/public/js/frappe/ui/group_by/group_by.js index fa2e2552c2..3aebeae12f 100644 --- a/frappe/public/js/frappe/ui/group_by/group_by.js +++ b/frappe/public/js/frappe/ui/group_by/group_by.js @@ -83,7 +83,7 @@ frappe.ui.GroupBy = class { apply_settings(settings) { // Extract fieldname from `tabdoctype`.`fieldname` - let group_by_fieldname = settings.group_by.split('.')[1].slice(1, -1); + let group_by_fieldname = settings.group_by.split('.')[1].replace('`', ''); this.groupby_select.val(group_by_fieldname); this.aggregate_function_select.val(settings.aggregate_function); From ee5004acaf8031a431504620feb6d45bf9d7a918 Mon Sep 17 00:00:00 2001 From: Revant Nandgaonkar Date: Wed, 15 Jan 2020 15:35:37 +0530 Subject: [PATCH 26/31] fix: Geolocation field Field inherits from ControlData instead of ControlCode fixes https://github.com/frappe/erpnext/issues/20221 --- frappe/public/js/frappe/form/controls/geolocation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/geolocation.js b/frappe/public/js/frappe/form/controls/geolocation.js index d68f6254b9..a193973c8a 100644 --- a/frappe/public/js/frappe/form/controls/geolocation.js +++ b/frappe/public/js/frappe/form/controls/geolocation.js @@ -1,4 +1,4 @@ -frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlCode.extend({ +frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({ make_wrapper() { // Create the elements for map area this._super(); From 31a27a73b54b8953f0fc09176550dfc1218af10f Mon Sep 17 00:00:00 2001 From: prssanna Date: Wed, 15 Jan 2020 15:49:29 +0530 Subject: [PATCH 27/31] fix: remove type=reset for grid buttons --- frappe/public/js/frappe/form/grid.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index 6c66362426..3960833028 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -65,26 +65,22 @@ export default class Grid {