feat(astrolabe): add dynamic MCP server configuration for testing
Replace static post-installation configuration with dynamic test-time configuration to support testing multiple MCP server deployments. Changes: - Remove static MCP server URL and OAuth client setup from post-installation - Add configure_astrolabe_for_mcp_server fixture (session-scoped) - Fixture dynamically configures: * Nextcloud system config (mcp_server_url, mcp_server_public_url) * OAuth client creation via occ oidc:create * Client credential storage (astrolabe_client_id, astrolabe_client_secret) - Update existing OAuth tests to use dynamic configuration - Add test_astrolabe_multi_server_integration.py with parametrized tests Benefits: - Test Astrolabe with mcp-oauth, mcp-keycloak, mcp-multi-user-basic - Each test configures for its specific MCP server - No static configuration conflicts between deployments - Cleaner post-installation (37 lines, down from 85) Test Results: - test_astrolabe_configuration_for_different_servers: PASSED (mcp-oauth, mcp-keycloak) - test_astrolabe_reconfiguration: PASSED 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
"""Test Astrolabe integration with multiple MCP server deployments.
|
||||
|
||||
This test suite verifies that the Astrolabe app can be dynamically configured
|
||||
to connect to different MCP server deployments (mcp-oauth, mcp-keycloak, etc.).
|
||||
|
||||
The configuration is managed dynamically during tests using the
|
||||
configure_astrolabe_for_mcp_server fixture, which allows testing multiple
|
||||
deployment scenarios without requiring static post-installation configuration.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
pytestmark = [pytest.mark.integration, pytest.mark.oauth]
|
||||
|
||||
|
||||
class TestAstrolabeMultiServerIntegration:
|
||||
"""Test suite for Astrolabe integration with multiple MCP servers."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mcp_server_config",
|
||||
[
|
||||
{
|
||||
"name": "mcp-oauth",
|
||||
"internal_url": "http://mcp-oauth:8001",
|
||||
"public_url": "http://localhost:8001",
|
||||
},
|
||||
{
|
||||
"name": "mcp-keycloak",
|
||||
"internal_url": "http://mcp-keycloak:8002",
|
||||
"public_url": "http://localhost:8002",
|
||||
},
|
||||
# Add more MCP server configurations as needed:
|
||||
# {
|
||||
# "name": "mcp-multi-user-basic",
|
||||
# "internal_url": "http://mcp-multi-user-basic:8000",
|
||||
# "public_url": "http://localhost:8003",
|
||||
# },
|
||||
],
|
||||
)
|
||||
async def test_astrolabe_configuration_for_different_servers(
|
||||
self, configure_astrolabe_for_mcp_server, mcp_server_config
|
||||
):
|
||||
"""Test that Astrolabe can be configured for different MCP servers.
|
||||
|
||||
This test verifies that:
|
||||
1. The configure_astrolabe_for_mcp_server fixture successfully configures
|
||||
the Astrolabe app for different MCP server endpoints
|
||||
2. OAuth client credentials are properly generated and stored
|
||||
3. The configuration can be dynamically changed between tests
|
||||
"""
|
||||
logger.info(f"Configuring Astrolabe for {mcp_server_config['name']}...")
|
||||
|
||||
# Configure Astrolabe for the specific MCP server
|
||||
credentials = await configure_astrolabe_for_mcp_server(
|
||||
mcp_server_internal_url=mcp_server_config["internal_url"],
|
||||
mcp_server_public_url=mcp_server_config["public_url"],
|
||||
)
|
||||
|
||||
# Verify credentials were returned
|
||||
assert "client_id" in credentials
|
||||
assert "client_secret" in credentials
|
||||
assert credentials["client_id"] == "nextcloudMcpServerUIPublicClient"
|
||||
assert len(credentials["client_secret"]) > 0
|
||||
|
||||
logger.info(
|
||||
f"✓ Astrolabe successfully configured for {mcp_server_config['name']}"
|
||||
)
|
||||
logger.info(f" Internal URL: {mcp_server_config['internal_url']}")
|
||||
logger.info(f" Public URL: {mcp_server_config['public_url']}")
|
||||
logger.info(f" Client ID: {credentials['client_id']}")
|
||||
logger.info(f" Client Secret: {credentials['client_secret'][:8]}...")
|
||||
|
||||
async def test_astrolabe_reconfiguration(self, configure_astrolabe_for_mcp_server):
|
||||
"""Test that Astrolabe can be reconfigured multiple times in the same session.
|
||||
|
||||
This verifies that the OAuth client can be recreated with different
|
||||
settings without conflicts.
|
||||
"""
|
||||
# First configuration: mcp-oauth
|
||||
logger.info("First configuration: mcp-oauth")
|
||||
credentials1 = await configure_astrolabe_for_mcp_server(
|
||||
mcp_server_internal_url="http://mcp-oauth:8001",
|
||||
mcp_server_public_url="http://localhost:8001",
|
||||
)
|
||||
|
||||
assert credentials1["client_id"] == "nextcloudMcpServerUIPublicClient"
|
||||
|
||||
# Second configuration: mcp-keycloak (reconfiguration)
|
||||
logger.info("Second configuration: mcp-keycloak (reconfiguration)")
|
||||
credentials2 = await configure_astrolabe_for_mcp_server(
|
||||
mcp_server_internal_url="http://mcp-keycloak:8002",
|
||||
mcp_server_public_url="http://localhost:8002",
|
||||
)
|
||||
|
||||
assert credentials2["client_id"] == "nextcloudMcpServerUIPublicClient"
|
||||
|
||||
# Client secrets should be different (new client created)
|
||||
assert credentials1["client_secret"] != credentials2["client_secret"]
|
||||
|
||||
logger.info("✓ Astrolabe successfully reconfigured without conflicts")
|
||||
@@ -10,8 +10,14 @@ logger = logging.getLogger(__name__)
|
||||
pytestmark = [pytest.mark.integration, pytest.mark.oauth]
|
||||
|
||||
|
||||
async def test_capture_settings_page(browser):
|
||||
async def test_capture_settings_page(browser, configure_astrolabe_for_mcp_server):
|
||||
"""Capture what's actually rendered on the personal settings page."""
|
||||
# Configure Astrolabe for mcp-oauth server
|
||||
await configure_astrolabe_for_mcp_server(
|
||||
mcp_server_internal_url="http://mcp-oauth:8001",
|
||||
mcp_server_public_url="http://localhost:8001",
|
||||
)
|
||||
|
||||
nextcloud_host = os.getenv("NEXTCLOUD_HOST", "http://localhost:8080")
|
||||
username = os.getenv("NEXTCLOUD_USERNAME", "admin")
|
||||
password = os.getenv("NEXTCLOUD_PASSWORD", "admin")
|
||||
|
||||
@@ -44,14 +44,32 @@ async def nc_admin_http_client(nextcloud_credentials):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
async def authorized_nc_session(browser, nextcloud_credentials):
|
||||
async def configure_astrolabe_for_tests(configure_astrolabe_for_mcp_server):
|
||||
"""Configure Astrolabe to connect to mcp-oauth server before running tests.
|
||||
|
||||
This module-scoped fixture ensures Astrolabe is properly configured
|
||||
for the mcp-oauth server (http://localhost:8001) before any tests run.
|
||||
"""
|
||||
logger.info("Configuring Astrolabe for mcp-oauth server...")
|
||||
await configure_astrolabe_for_mcp_server(
|
||||
mcp_server_internal_url="http://mcp-oauth:8001",
|
||||
mcp_server_public_url="http://localhost:8001",
|
||||
)
|
||||
logger.info("✓ Astrolabe configured for mcp-oauth server")
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
async def authorized_nc_session(
|
||||
browser, nextcloud_credentials, configure_astrolabe_for_tests
|
||||
):
|
||||
"""Module-scoped fixture that logs in and authorizes the NC PHP app once.
|
||||
|
||||
This fixture:
|
||||
1. Creates a browser context
|
||||
2. Logs in to Nextcloud
|
||||
3. Authorizes the MCP Server UI app (if not already authorized)
|
||||
4. Returns the page for use in all tests
|
||||
1. Configures Astrolabe for mcp-oauth server (via configure_astrolabe_for_tests)
|
||||
2. Creates a browser context
|
||||
3. Logs in to Nextcloud
|
||||
4. Authorizes the MCP Server UI app (if not already authorized)
|
||||
5. Returns the page for use in all tests
|
||||
|
||||
The authorization is done once and reused for all tests in this module.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user