From 425e4bf1b3dea2fd1daac6e07172850174f8ae08 Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Tue, 15 Nov 2022 10:49:02 +0000 Subject: [PATCH 1/3] fix(File): validate `attached_to_*` when saving (#18880) --- frappe/core/doctype/file/file.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/frappe/core/doctype/file/file.py b/frappe/core/doctype/file/file.py index 1518c72f95..0e28145c9a 100755 --- a/frappe/core/doctype/file/file.py +++ b/frappe/core/doctype/file/file.py @@ -78,21 +78,38 @@ class File(Document): self.validate_duplicate_entry() def validate(self): + if self.is_folder: + return + # Ensure correct formatting and type self.file_url = unquote(self.file_url) if self.file_url else "" + self.validate_attachment_references() + # when dict is passed to get_doc for creation of new_doc, is_new returns None # this case is handled inside handle_is_private_changed if not self.is_new() and self.has_value_changed("is_private"): self.handle_is_private_changed() - if not self.is_folder: - self.validate_file_path() - self.validate_file_url() - self.validate_file_on_disk() + self.validate_file_path() + self.validate_file_url() + self.validate_file_on_disk() self.file_size = frappe.form_dict.file_size or self.file_size + def validate_attachment_references(self): + if not self.attached_to_doctype: + return + + if self.attached_to_name and not isinstance(self.attached_to_name, str): + frappe.throw(_("Attached To Name must be a string"), TypeError) + + if not self.attached_to_field: + return + + if not frappe.get_meta(self.attached_to_doctype).has_field(self.attached_to_field): + frappe.throw(_("The fieldname you've specified in Attached To Field is invalid")) + def after_rename(self, *args, **kwargs): for successor in self.get_successors(): setup_folder_path(successor, self.name) From 9b90e620bcac12fdd271de32d6f948aaf89a7443 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 15 Nov 2022 17:16:30 +0530 Subject: [PATCH 2/3] chore: disable flaky test This is - flaky - difficult to find source of flake because of crazy tests - adds little value tbh [skip ci] --- frappe/tests/test_zbg_job_sanity_test.py | 27 ------------------------ 1 file changed, 27 deletions(-) delete mode 100644 frappe/tests/test_zbg_job_sanity_test.py diff --git a/frappe/tests/test_zbg_job_sanity_test.py b/frappe/tests/test_zbg_job_sanity_test.py deleted file mode 100644 index 19dc168c04..0000000000 --- a/frappe/tests/test_zbg_job_sanity_test.py +++ /dev/null @@ -1,27 +0,0 @@ -""" smoak tests to check that all registered background jobs execute without error. - -Note: Filename is intentional to run this test roughly at end. Don't change.""" - -import time - -import frappe -from frappe.core.doctype.rq_job.rq_job import RQJob, remove_failed_jobs -from frappe.tests.utils import FrappeTestCase, timeout - - -class TestScheduledJobSanity(FrappeTestCase): - def setUp(self): - remove_failed_jobs() - - @timeout(90) - def test_bg_jobs_run(self): - """Enqueue all scheduled jobs, wait for finish and verify that none failed.""" - for scheduled_job_type in frappe.get_all("Scheduled Job Type", pluck="name"): - frappe.get_doc("Scheduled Job Type", scheduled_job_type).enqueue(force=True) - - while RQJob.get_list({"filters": [["RQ Job", "status", "in", ("queued", "started")]]}): - time.sleep(0.5) - - # Check no failed, if failed print full details - failed_jobs = RQJob.get_list({"filters": [["RQ Job", "status", "=", "failed"]]}) - self.assertEqual(len(failed_jobs), 0, "Jobs failed: " + str(failed_jobs)) From 9fc330ea6c702515f4862e49cab0fae796420ef6 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 15 Nov 2022 18:45:51 +0530 Subject: [PATCH 3/3] Revert "fix: remove middleware to clear `frappe.local` (#18874)" (#18886) This reverts commit 2971abe517b2d98f35a75544db3ff3953da651a0. --- frappe/app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/app.py b/frappe/app.py index 8f40fcfa82..0d7fdc1fe1 100644 --- a/frappe/app.py +++ b/frappe/app.py @@ -5,6 +5,7 @@ import logging import os from werkzeug.exceptions import HTTPException, NotFound +from werkzeug.local import LocalManager from werkzeug.middleware.profiler import ProfilerMiddleware from werkzeug.middleware.shared_data import SharedDataMiddleware from werkzeug.wrappers import Request, Response @@ -24,10 +25,13 @@ from frappe.utils import get_site_name, sanitize_html from frappe.utils.error import make_error_snapshot from frappe.website.serve import get_response +local_manager = LocalManager(frappe.local) + _site = None _sites_path = os.environ.get("SITES_PATH", ".") +@local_manager.middleware @Request.application def application(request: Request): response = None