Astrolabe was refactored to mint session-derived JWTs (TokenGenerationRequest Event) and a one-click background-indexing opt-in, dropping the OAuth authorize/callback/refresh surface. Bump the submodule and bring the test suite in line: - New test_astrolabe_session_jwt_search.py: a logged-in user searches via the minted JWT with no provisioning (replaces the obsolete login_flow_provisioning OAuth-authorize test; token_refresh test deleted — refresh flow is gone). - settings_buttons: assert the new revoke endpoint + that oauth/disconnect is gone (404). - multi_user_background_sync / plotly / chunk_context: drop the OAuth authorize step; provision via the one-click "Enable background indexing" button (#mcp-enable-background-button -> #mcp-revoke-background-button) instead of generating + pasting an app password. - docker-compose.yml: mount the astrolabe submodule into the app container. - third_party/astrolabe: bump to the one-click opt-in commit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
64 lines
2.5 KiB
Python
64 lines
2.5 KiB
Python
"""Integration tests for Astrolabe personal-settings background-sync endpoints.
|
|
|
|
Cross-system interface test. The astrolabe app (installed by
|
|
app-hooks/post-installation/20-install-astrolabe-app.sh; source in
|
|
./third_party/astrolabe) was refactored to session-minted JWTs — the old
|
|
per-user OAuth flow and its ``/apps/astrolabe/oauth/disconnect`` route are
|
|
gone. Background indexing is now an app-password opt-in with a single revoke
|
|
endpoint.
|
|
|
|
These tests assert the *current* HTTP surface of the settings page:
|
|
- the revoke endpoint exists and is auth-gated
|
|
(POST /apps/astrolabe/api/v1/background-sync/credentials/revoke)
|
|
- the obsolete OAuth disconnect route is gone (404)
|
|
- the personal settings page route resolves
|
|
"""
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
pytestmark = pytest.mark.integration
|
|
|
|
NEXTCLOUD_URL = "http://localhost:8080"
|
|
ASTROLABE = f"{NEXTCLOUD_URL}/apps/astrolabe"
|
|
|
|
# Auth failures (no session) surface as 401 or a login redirect.
|
|
_UNAUTH = {401, 302, 303, 307, 308}
|
|
|
|
|
|
async def test_revoke_endpoint_requires_auth():
|
|
"""The background-sync revoke endpoint exists and rejects anonymous calls."""
|
|
async with httpx.AsyncClient(follow_redirects=False) as client:
|
|
resp = await client.post(
|
|
f"{ASTROLABE}/api/v1/background-sync/credentials/revoke",
|
|
headers={"OCS-APIRequest": "true"},
|
|
)
|
|
# Must NOT be 404 — the route must exist — and must be auth-gated.
|
|
assert resp.status_code != 404, "revoke route missing"
|
|
assert resp.status_code in _UNAUTH, (
|
|
f"expected auth rejection, got {resp.status_code}"
|
|
)
|
|
|
|
|
|
async def test_obsolete_oauth_disconnect_route_removed():
|
|
"""The pre-refactor OAuth disconnect route must no longer exist.
|
|
|
|
Regression guard for the auth refactor: ``/apps/astrolabe/oauth/disconnect``
|
|
(and the rest of the OAuth authorize/callback/disconnect surface) was
|
|
removed in favour of session-minted JWTs.
|
|
"""
|
|
async with httpx.AsyncClient(follow_redirects=False) as client:
|
|
resp = await client.post(f"{ASTROLABE}/oauth/disconnect")
|
|
assert resp.status_code == 404, (
|
|
f"obsolete oauth/disconnect route still resolves ({resp.status_code})"
|
|
)
|
|
|
|
|
|
async def test_settings_page_route_resolves():
|
|
"""The personal settings page route exists (auth-gated when no session)."""
|
|
async with httpx.AsyncClient(follow_redirects=False) as client:
|
|
resp = await client.get(f"{NEXTCLOUD_URL}/settings/user/astrolabe")
|
|
assert resp.status_code in ({200} | _UNAUTH), (
|
|
f"unexpected status for settings page: {resp.status_code}"
|
|
)
|