Files
odysseus/tests/test_setup_device_auth_static.py
T
stocky789 1e0d9b92af feat: add ChatGPT Subscription provider (#2876)
* feat: Add ChatGPT Subscription support and related features

- Introduced a new provider option for ChatGPT Subscription in the endpoint selection UI.
- Implemented OAuth flow for ChatGPT Subscription sign-in, including polling for authorization status.
- Updated admin interface to handle ChatGPT Subscription, including disabling API key input and providing user guidance.
- Enhanced cost tracking logic to differentiate between subscription and non-subscription endpoints.
- Added new slash commands for managing skills, including listing, searching, and invoking skills.
- Implemented caching for skill catalog to optimize performance.
- Updated tests to cover new ChatGPT Subscription functionality and ensure proper endpoint probing.
- Refactored existing code to accommodate new features and improve maintainability.

* refactor: share provider device-flow setup

- reuse one device-flow backend for Copilot and ChatGPT Subscription
- add one frontend device-flow helper for Settings and /setup
- put GitHub Copilot back into Add Models, now as a dropdown option
- make provider selection just select; clicking Add starts sign-in
- stop ChatGPT Subscription setup from opening auth tabs automatically
- make /setup copilot and /setup chatgpt-subscription work from chat
- show ChatGPT Subscription in the /setup suggestions
- show the real error message when setup fails
- add focused tests for the shared flow and setup UI

* feat(chatgpt-subscription): harden credential lifecycle and streamline auth UX

Backend:
- Resolve runtime bearer for provider-auth endpoints at probe time via a
  shared _resolve_probe_key() that delegates to resolve_endpoint_runtime,
  applied across all probe/refresh call sites.
- Skip live completion probes and health pings for discovery-only providers
  (centralized behind _is_discovery_only_provider) — the Codex/Responses API
  has no such endpoints, so status is derived from cached models.
- Never persist the short lived ChatGPT bearer to the plaintext sessions
  table; proactively clear any stale bearer left by an earlier code path.
- Revoke orphaned ProviderAuthSession credentials when the last endpoint
  backing them is deleted (_delete_orphaned_provider_auth), surfaced via
  cleared_provider_auth in the delete response.

Frontend (admin.js):
- Auto-start the device-auth flow on provider selection so the authorization
  panel (code + Authorize) shows immediately instead of behind a "Sign in" click.
- Remove the redundant top button for device auth providers, move retry
  into the panel via an inline "Try again".
- Drop the self-evident hint text and add an execCommand clipboard fallback so
  Copy works in non-secure (HTTP/LAN) contexts.

* fix: harden chatgpt subscription provider

* chore: remove PR media from branch

* Fix chatgpt subscription recovery and token handling

---------

Co-authored-by: 5p00kyy <admin@5p00ky.dev>
2026-06-08 10:19:18 +02:00

43 lines
1.6 KiB
Python

"""Static regressions for `/setup` account sign-in providers."""
from pathlib import Path
_REPO = Path(__file__).resolve().parent.parent
_SLASH = (_REPO / "static" / "js" / "slashCommands.js").read_text(encoding="utf-8")
def _between(src: str, start: str, end: str) -> str:
start_idx = src.index(start)
end_idx = src.index(end, start_idx)
return src[start_idx:end_idx]
def test_setup_guide_lists_account_sign_in_providers():
guide_block = _between(_SLASH, "function _showSetupEndpointChoices", "async function _hasConfiguredModels")
assert 'data-setup-provider="' in _SLASH
assert "provider.key" in _SLASH
assert "'copilot'" in _SLASH
assert "'chatgpt-subscription'" in _SLASH
assert "/setup copilot" in _SLASH
assert "/setup chatgpt-subscription" in _SLASH
def test_clicking_account_sign_in_provider_prefills_setup_command_not_api_key():
click_block = _between(_SLASH, "const providerEl = e.target.closest('.setup-clickable-provider')", "// 3. Check")
assert "providerEl.dataset.setupProvider" in click_block
assert "providerEl.dataset.setupKind === 'device-auth'" in click_block
assert "'/setup ' + providerKey" in click_block
def test_setup_chatgpt_subscription_prints_auth_url_without_auto_opening_tab():
flow_block = _between(_SLASH, "async function _setupProviderDeviceFlow", "async function _cmdSetup")
assert "providerKey === 'chatgpt-subscription'" in flow_block
assert "Open this URL" in flow_block
assert "authUrl" in flow_block
assert 'href="\' + uiModule.esc(authUrl || \'\') + \'"' in flow_block
assert "if (providerKey === 'chatgpt-subscription') return;" in flow_block