|
| 1 | +"""Reusable pytest fixtures for unit-testing TestGen. |
| 2 | +
|
| 3 | +Importable by the core test suite and any plugin test suite. To use, import the fixtures |
| 4 | +you need into a ``conftest.py`` — pytest registers fixtures that are imported into a |
| 5 | +conftest, preserving their ``autouse`` flag for that subtree:: |
| 6 | +
|
| 7 | + from testgen.testing.fixtures import db_session_mock, mcp_user # noqa: F401 |
| 8 | +""" |
| 9 | + |
| 10 | +from unittest.mock import MagicMock, patch |
| 11 | +from uuid import uuid4 |
| 12 | + |
| 13 | +import pytest |
| 14 | + |
| 15 | +from testgen.mcp.permissions import set_mcp_token, set_mcp_username |
| 16 | + |
| 17 | +# Fictional role matrix for tests. role_a has full access (but NOT view_pii — several |
| 18 | +# tests rely on that to exercise the no-view_pii path), role_c is restricted, and |
| 19 | +# role_d holds edit + view_pii so deny/allow pairs can be distinguished against a real |
| 20 | +# ProjectPermissions without role_a accidentally granting view_pii. |
| 21 | +TEST_PERM_MATRIX = { |
| 22 | + "view": ["role_a", "role_b"], |
| 23 | + "catalog": ["role_a", "role_b", "role_c"], |
| 24 | + "edit": ["role_a", "role_d"], |
| 25 | + "administer": ["role_a"], |
| 26 | + "view_pii": ["role_d"], |
| 27 | +} |
| 28 | + |
| 29 | + |
| 30 | +def _test_roles_with_permission(permission): |
| 31 | + return TEST_PERM_MATRIX.get(permission, []) |
| 32 | + |
| 33 | + |
| 34 | +@pytest.fixture(autouse=True) |
| 35 | +def patched_settings(): |
| 36 | + with patch("testgen.settings.UI_BASE_URL", "http://tg-base-url"): |
| 37 | + yield |
| 38 | + |
| 39 | + |
| 40 | +@pytest.fixture |
| 41 | +def db_session_mock(): |
| 42 | + with patch("testgen.common.models.Session") as factory_mock: |
| 43 | + yield factory_mock().__enter__() |
| 44 | + |
| 45 | + |
| 46 | +@pytest.fixture(autouse=True) |
| 47 | +def mcp_user(): |
| 48 | + """Set up an authenticated MCP user for all tool tests. |
| 49 | +
|
| 50 | + Default: user has 'role_a' on 'demo' project (full access). |
| 51 | + The @mcp_permission decorator passes for any permission. |
| 52 | +
|
| 53 | + Tests needing scoped access patch _compute_project_permissions directly. |
| 54 | + """ |
| 55 | + set_mcp_username("test_user") |
| 56 | + set_mcp_token("test_bearer_token") |
| 57 | + user = MagicMock() |
| 58 | + user.id = uuid4() |
| 59 | + |
| 60 | + membership = MagicMock() |
| 61 | + membership.project_code = "demo" |
| 62 | + membership.role = "role_a" |
| 63 | + |
| 64 | + with ( |
| 65 | + patch("testgen.common.auth.authorize_token", return_value=user), |
| 66 | + patch("testgen.common.models.get_current_session", return_value=MagicMock()), |
| 67 | + patch("testgen.mcp.permissions.ProjectMembership") as mock_membership, |
| 68 | + patch("testgen.mcp.permissions.PluginHook") as mock_hook, |
| 69 | + ): |
| 70 | + mock_membership.get_memberships_for_user.return_value = [membership] |
| 71 | + mock_hook.instance.return_value.rbac.get_roles_with_permission.side_effect = ( |
| 72 | + _test_roles_with_permission |
| 73 | + ) |
| 74 | + yield user |
| 75 | + set_mcp_username(None) |
| 76 | + set_mcp_token(None) |
0 commit comments