test: add permissions tests for qb.get_query

This commit is contained in:
Faris Ansari 2025-03-03 12:22:04 +05:30
parent f707cf5722
commit ccca6bffab

View file

@ -5,9 +5,17 @@ from frappe.core.doctype.doctype.test_doctype import new_doctype
from frappe.query_builder import Field
from frappe.query_builder.functions import Abs, Count, Ifnull, Max, Now, Timestamp
from frappe.tests import IntegrationTestCase
from frappe.tests.test_db_query import (
create_nested_doctype,
create_nested_doctype_records,
setup_patched_blog_post,
setup_test_user,
)
from frappe.tests.test_query_builder import db_type_is, run_only_if
from frappe.utils.nestedset import get_ancestors_of, get_descendants_of
EXTRA_TEST_RECORD_DEPENDENCIES = ["User", "Blog Post", "Blog Category", "Blogger"]
def create_tree_docs():
records = [
@ -252,7 +260,7 @@ class TestQuery(IntegrationTestCase):
)
self.assertRaisesRegex(
frappe.ValidationError,
frappe.PermissionError,
"Invalid filter",
lambda: frappe.qb.get_query(
"DocType",
@ -455,3 +463,135 @@ class TestQuery(IntegrationTestCase):
note1.delete()
note2.delete()
def test_build_match_conditions(self):
from frappe.permissions import add_user_permission, clear_user_permissions_for_doctype
clear_user_permissions_for_doctype("Blog Post", "test2@example.com")
test2user = frappe.get_doc("User", "test2@example.com")
test2user.add_roles("Blogger")
frappe.set_user("test2@example.com")
# Before any user permission is applied, there should be no conditions
query = frappe.qb.get_query("Blog Post", ignore_permissions=False)
self.assertNotIn("(`tabBlog Post`.`name` in (", str(query))
# Add user permissions
add_user_permission("Blog Post", "-test-blog-post", "test2@example.com", True)
add_user_permission("Blog Post", "-test-blog-post-1", "test2@example.com", True)
# After applying user permission, condition should be in query
query = str(frappe.qb.get_query("Blog Post", ignore_permissions=False))
# Check for user permission condition in the query string
if frappe.db.db_type == "mariadb":
self.assertIn("`name` IS NULL OR `name` IN ('-test-blog-post-1','-test-blog-post')", query)
elif frappe.db.db_type == "postgres":
self.assertIn("\"name\" IS NULL OR \"name\" IN ('-test-blog-post-1','-test-blog-post')", query)
frappe.set_user("Administrator")
clear_user_permissions_for_doctype("Blog Post", "test2@example.com")
test2user.remove_roles("Blogger")
def test_ignore_permissions_for_query(self):
frappe.set_user("test2@example.com")
with self.assertRaises(frappe.PermissionError):
frappe.qb.get_query("DocType", filters={"istable": 1}, ignore_permissions=False)
result = frappe.qb.get_query("DocType", filters={"istable": 1}, ignore_permissions=True).run()
self.assertTrue(len(result) > 0)
frappe.set_user("Administrator")
def test_permlevel_fields(self):
"""Test permission level check when querying fields"""
with setup_patched_blog_post(), setup_test_user(set_user=True):
# Create a test blog post
test_post = frappe.get_doc(
{
"doctype": "Blog Post",
"title": "Test Permission Post",
"content": "Test Content",
"published": 1,
}
).insert(ignore_permissions=True)
# Without proper permission, published field should be filtered out
data = frappe.qb.get_query(
"Blog Post",
filters={"name": test_post.name},
fields=["name", "published", "title"],
ignore_permissions=False,
).run(as_dict=1)
field_list = [field for d in data for field in d.keys()]
self.assertIn("title", field_list)
self.assertIn("name", field_list)
self.assertNotIn("published", field_list)
# With Administrator, all fields should be accessible
frappe.set_user("Administrator")
data = frappe.qb.get_query(
"Blog Post",
filters={"name": test_post.name},
fields=["name", "published", "title"],
ignore_permissions=False,
).run(as_dict=1)
field_list = [field for d in data for field in d.keys()]
self.assertIn("published", field_list)
test_post.delete()
def test_nested_permission(self):
"""Test permission on nested doctypes"""
frappe.set_user("Administrator")
create_nested_doctype()
create_nested_doctype_records()
from frappe.permissions import add_user_permission, clear_user_permissions_for_doctype
clear_user_permissions_for_doctype("Nested DocType")
# Add user permission for only one root folder
add_user_permission("Nested DocType", "Level 1 A", "test2@example.com")
from frappe.core.page.permission_manager.permission_manager import update
# To avoid if_owner filter
update("Nested DocType", "All", 0, "if_owner", 0)
test2user = frappe.get_doc("User", "test2@example.com")
test2user.add_roles("Blogger")
frappe.set_user("test2@example.com")
data = frappe.qb.get_query("Nested DocType", ignore_permissions=False).run(as_dict=1)
# Children of the permitted node should be accessible
self.assertTrue(any(d.name == "Level 2 A" for d in data))
# Other nodes should not be accessible
self.assertFalse(any(d.name == "Level 1 B" for d in data))
self.assertFalse(any(d.name == "Level 2 B" for d in data))
update("Nested DocType", "All", 0, "if_owner", 1) # Reset to default
frappe.set_user("Administrator")
def test_is_set_is_not_set(self):
"""Test is set and is not set filters"""
result = frappe.qb.get_query("DocType", filters={"autoname": ["is", "not set"]}).run(as_dict=1)
self.assertTrue({"name": "Integration Request"} in result)
self.assertTrue({"name": "User"} in result)
self.assertFalse({"name": "Blogger"} in result)
result = frappe.qb.get_query("DocType", filters={"autoname": ["is", "set"]}).run(as_dict=1)
self.assertTrue({"name": "DocField"} in result)
self.assertTrue({"name": "Prepared Report"} in result)
self.assertFalse({"name": "Property Setter"} in result)
# Test with updating value to NULL
frappe.db.set_value("DocType", "Property Setter", "autoname", None, update_modified=False)
result = frappe.qb.get_query("DocType", filters={"autoname": ["is", "set"]}).run(as_dict=1)
self.assertFalse(any(d.name == "Property Setter" for d in result))