Files
mcp-nextcloud/tests/server/login_flow/test_management_api.py
T
Chris Coutinho 079188e16a test: mark management-api integration test with login_flow
`tests/server/login_flow/test_management_api.py` had
`[pytest.mark.integration, pytest.mark.oauth]` while every other test in
`tests/server/login_flow/` uses `[pytest.mark.integration,
pytest.mark.login_flow]`. The single-user CI matrix filter is
`(integration and not keycloak and not login_flow and not
multi_user_basic)`, so the missing `login_flow` mark let this test
collect and run under single-user mode against `localhost:8004` (which
isn't up there, hitting the bug being reported), even though it's
specifically driving the login-flow MCP server.

Also `oauth` isn't a registered marker (see `[tool.pytest.ini_options]`
in pyproject.toml), so it was emitting an unregistered-marker warning.

Replacing the marker aligns this file with its siblings: single-user /
multi-user-basic / keycloak filters all deselect it now, and the
login-flow filter still picks it up.

Verified: `pytest --collect-only -m "<single-user filter>"` reports 2
deselected; `-m login_flow` collects both tests.
2026-05-03 22:44:58 +02:00

53 lines
2.0 KiB
Python

"""Integration tests for the management API on the login-flow MCP server.
These tests drive a real OAuth flow against Nextcloud's `oidc` app using the
static `nextcloudMcpServerUIPublicClient` client (which is allowlisted on the
`mcp-login-flow` container via `ALLOWED_MGMT_CLIENT`), then hit the
management API endpoints with the resulting bearer token.
Regression coverage for the bug where /api/v1/apps proxied to OCS v1
/cloud/apps and always 401'd. The handler now uses /ocs/v2.php/cloud/capabilities,
which is reachable for OAuth bearer tokens.
"""
import httpx
import pytest
LOGIN_FLOW_API_BASE_URL = "http://localhost:8004"
pytestmark = [pytest.mark.integration, pytest.mark.login_flow]
async def test_get_installed_apps_returns_capability_keys(
login_flow_static_client_token: str,
):
"""GET /api/v1/apps returns 200 with a list of enabled-app capability keys."""
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(
f"{LOGIN_FLOW_API_BASE_URL}/api/v1/apps",
headers={"Authorization": f"Bearer {login_flow_static_client_token}"},
)
assert response.status_code == 200, (
f"/api/v1/apps returned {response.status_code}: {response.text}"
)
data = response.json()
assert "apps" in data
assert isinstance(data["apps"], list)
# Anonymous capabilities always exposes core; authenticated also exposes
# files. Both should be present whether or not the oidc app's
# BearerAuthMiddleware ran for this OCS route.
apps = data["apps"]
assert "core" in apps, f"expected 'core' in apps, got {apps}"
assert "files" in apps, f"expected 'files' in apps, got {apps}"
async def test_get_installed_apps_requires_bearer_token():
"""No Authorization header → 401 (handler's token validator rejects it)."""
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(f"{LOGIN_FLOW_API_BASE_URL}/api/v1/apps")
assert response.status_code == 401