mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-05-15 14:27:31 -04:00
add tests
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
import pytest
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from mealie.db.models.recipe.recipe import RecipeModel
|
||||||
|
from mealie.db.models.users.users import LongLiveToken, User
|
||||||
from mealie.services.query_filter.builder import (
|
from mealie.services.query_filter.builder import (
|
||||||
LogicalOperator,
|
LogicalOperator,
|
||||||
QueryFilterBuilder,
|
QueryFilterBuilder,
|
||||||
@@ -6,6 +11,7 @@ from mealie.services.query_filter.builder import (
|
|||||||
RelationalKeyword,
|
RelationalKeyword,
|
||||||
RelationalOperator,
|
RelationalOperator,
|
||||||
)
|
)
|
||||||
|
from mealie.services.query_filter.context import allow_filter_restricted
|
||||||
|
|
||||||
|
|
||||||
def test_query_filter_builder_json():
|
def test_query_filter_builder_json():
|
||||||
@@ -74,3 +80,76 @@ def test_query_filter_builder_json_uses_raw_value():
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# PrivateColumn tests
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_private_field_user_password_raises():
|
||||||
|
"""Filtering on User.password (PrivateColumn) should raise ValueError."""
|
||||||
|
with pytest.raises(ValueError, match="private field"):
|
||||||
|
QueryFilterBuilder.get_model_and_model_attr_from_attr_string("password", User)
|
||||||
|
|
||||||
|
|
||||||
|
def test_private_field_long_live_token_raises():
|
||||||
|
"""Filtering on LongLiveToken.token (PrivateColumn) should raise ValueError."""
|
||||||
|
with pytest.raises(ValueError, match="private field"):
|
||||||
|
QueryFilterBuilder.get_model_and_model_attr_from_attr_string("token", LongLiveToken)
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_private_field_does_not_raise():
|
||||||
|
"""Filtering on a normal field should not raise."""
|
||||||
|
model, attr, _ = QueryFilterBuilder.get_model_and_model_attr_from_attr_string("full_name", User)
|
||||||
|
assert model is User
|
||||||
|
assert attr is User.full_name
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# __filter_restricted__ traversal tests
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_restricted_traversal_blocked_when_disallowed():
|
||||||
|
"""Traversing into User (restricted) via RecipeModel.user should raise when allow_restricted=False."""
|
||||||
|
with pytest.raises(ValueError, match="restricted model"):
|
||||||
|
QueryFilterBuilder.get_model_and_model_attr_from_attr_string("user.email", RecipeModel, allow_restricted=False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_restricted_traversal_allowed_by_default():
|
||||||
|
"""Traversing into User via RecipeModel.user should succeed when allow_restricted=True (default)."""
|
||||||
|
model, attr, _ = QueryFilterBuilder.get_model_and_model_attr_from_attr_string("user.email", RecipeModel)
|
||||||
|
assert model is User
|
||||||
|
assert attr is User.email
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# ContextVar tests
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_allow_filter_restricted_default_is_true():
|
||||||
|
"""The ContextVar default must be True so authenticated requests are unrestricted."""
|
||||||
|
assert allow_filter_restricted.get() is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_filter_query_respects_context_var_false(monkeypatch):
|
||||||
|
"""filter_query should block restricted traversal when the ContextVar is False."""
|
||||||
|
allow_filter_restricted.set(False)
|
||||||
|
try:
|
||||||
|
query = sa.select(RecipeModel)
|
||||||
|
builder = QueryFilterBuilder("user.email = 'test@example.com'")
|
||||||
|
with pytest.raises(ValueError, match="restricted model"):
|
||||||
|
builder.filter_query(query, RecipeModel)
|
||||||
|
finally:
|
||||||
|
allow_filter_restricted.set(True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_filter_query_respects_context_var_true():
|
||||||
|
"""filter_query should allow restricted traversal when the ContextVar is True (default)."""
|
||||||
|
allow_filter_restricted.set(True)
|
||||||
|
query = sa.select(RecipeModel)
|
||||||
|
builder = QueryFilterBuilder("user.email = 'test@example.com'")
|
||||||
|
# Should not raise
|
||||||
|
builder.filter_query(query, RecipeModel)
|
||||||
|
|||||||
Reference in New Issue
Block a user