Merge pull request #19780 from ankush/hooks_audit
feat: Audit hooks report
This commit is contained in:
commit
87008e3930
6 changed files with 121 additions and 0 deletions
0
frappe/custom/report/__init__.py
Normal file
0
frappe/custom/report/__init__.py
Normal file
0
frappe/custom/report/audit_system_hooks/__init__.py
Normal file
0
frappe/custom/report/audit_system_hooks/__init__.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) 2023, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
/* eslint-disable */
|
||||
|
||||
frappe.query_reports["Audit System Hooks"] = {
|
||||
filters: [],
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"add_total_row": 0,
|
||||
"columns": [],
|
||||
"creation": "2023-01-25 15:02:21.896117",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"filters": [],
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "",
|
||||
"modified": "2023-01-25 15:03:31.263337",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Custom",
|
||||
"name": "Audit System Hooks",
|
||||
"owner": "Administrator",
|
||||
"prepared_report": 0,
|
||||
"query": "",
|
||||
"ref_doctype": "System Settings",
|
||||
"report_name": "Audit System Hooks",
|
||||
"report_type": "Script Report",
|
||||
"roles": [
|
||||
{
|
||||
"role": "System Manager"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
# Copyright (c) 2023, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
return get_columns(), get_data()
|
||||
|
||||
|
||||
def get_columns():
|
||||
values_field_type = "Data" # TODO: better text wrapping in reportview
|
||||
columns = [
|
||||
{"label": "Hook name", "fieldname": "hook_name", "fieldtype": "Data", "width": 200},
|
||||
{"label": "Hook key (optional)", "fieldname": "hook_key", "fieldtype": "Data", "width": 200},
|
||||
{"label": "Hook Values (resolved)", "fieldname": "hook_values", "fieldtype": values_field_type},
|
||||
]
|
||||
|
||||
# Each app is shown in order as a column
|
||||
installed_apps = frappe.get_installed_apps(_ensure_on_bench=True)
|
||||
columns += [
|
||||
{"label": app, "fieldname": app, "fieldtype": values_field_type} for app in installed_apps
|
||||
]
|
||||
|
||||
return columns
|
||||
|
||||
|
||||
def get_data():
|
||||
hooks = frappe.get_hooks()
|
||||
installed_apps = frappe.get_installed_apps(_ensure_on_bench=True)
|
||||
|
||||
def fmt_hook_values(v):
|
||||
"""Improve readability by discarding falsy values and removing containers when only 1
|
||||
value is in container"""
|
||||
if not v:
|
||||
return ""
|
||||
|
||||
v = delist(v)
|
||||
|
||||
if isinstance(v, (dict, list)):
|
||||
try:
|
||||
return frappe.as_json(v)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return str(v)
|
||||
|
||||
data = []
|
||||
for hook, values in hooks.items():
|
||||
if isinstance(values, dict):
|
||||
for k, v in values.items():
|
||||
row = {"hook_name": hook, "hook_key": fmt_hook_values(k), "hook_values": fmt_hook_values(v)}
|
||||
for app in installed_apps:
|
||||
if app_hooks := delist(frappe.get_hooks(hook, app_name=app)):
|
||||
row[app] = fmt_hook_values(app_hooks.get(k))
|
||||
data.append(row)
|
||||
else:
|
||||
row = {"hook_name": hook, "hook_values": fmt_hook_values(values)}
|
||||
for app in installed_apps:
|
||||
row[app] = fmt_hook_values(frappe.get_hooks(hook, app_name=app))
|
||||
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def delist(val):
|
||||
if isinstance(val, list) and len(val) == 1:
|
||||
return val[0]
|
||||
return val
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) 2022, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from frappe.custom.report.audit_system_hooks.audit_system_hooks import execute
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestAuditSystemHooksReport(FrappeTestCase):
|
||||
def test_basic_query(self):
|
||||
_, data = execute()
|
||||
for row in data:
|
||||
if row.get("hook_name") == "app_name":
|
||||
self.assertEqual(row.get("hook_values"), "frappe")
|
||||
break
|
||||
else:
|
||||
self.fail("Failed to generate hooks report")
|
||||
Loading…
Add table
Reference in a new issue