fix(cli): support Codex OAuth in quick start
This commit is contained in:
@@ -978,7 +978,14 @@ class TestMainMenuUpdate:
|
||||
expected_provider_names = set()
|
||||
seen_display_names: set[str] = set()
|
||||
for spec in PROVIDERS:
|
||||
if spec.name == "custom" or spec.is_oauth or spec.is_transcription_only:
|
||||
if (
|
||||
spec.name == "custom"
|
||||
or spec.is_transcription_only
|
||||
or (
|
||||
spec.is_oauth
|
||||
and spec.name not in onboard_wizard._QUICK_START_OAUTH_PROVIDERS
|
||||
)
|
||||
):
|
||||
continue
|
||||
if spec.display_name in seen_display_names:
|
||||
continue
|
||||
@@ -988,9 +995,118 @@ class TestMainMenuUpdate:
|
||||
|
||||
assert selected_provider_names == expected_provider_names
|
||||
assert "assemblyai" not in selected_provider_names
|
||||
assert choices["OpenAI Codex"] == "openai_codex"
|
||||
assert "github_copilot" not in selected_provider_names
|
||||
assert choices["OpenCode Zen"] == "opencode"
|
||||
assert choices[onboard_wizard._QUICK_START_CUSTOM_PROVIDER_CHOICE] == "custom"
|
||||
|
||||
def test_quick_start_openai_codex_uses_oauth_and_default_model(self, monkeypatch):
|
||||
"""Codex should authenticate without asking for an API key."""
|
||||
config = Config()
|
||||
oauth_calls: list[tuple[Config, str]] = []
|
||||
model_prompts: list[tuple[str, str, str]] = []
|
||||
|
||||
monkeypatch.setattr(onboard_wizard, "_show_quick_start_progress", lambda *_args: None)
|
||||
monkeypatch.setattr(
|
||||
onboard_wizard,
|
||||
"_select_with_back",
|
||||
lambda *args, **kwargs: "OpenAI Codex",
|
||||
)
|
||||
|
||||
def fail_api_key_prompt(*_args, **_kwargs):
|
||||
raise AssertionError("OpenAI Codex Quick Start should not ask for an API key")
|
||||
|
||||
def fake_model_input(prompt, current, provider):
|
||||
model_prompts.append((prompt, current, provider))
|
||||
return current
|
||||
|
||||
monkeypatch.setattr(onboard_wizard, "_input_text", fail_api_key_prompt)
|
||||
monkeypatch.setattr(onboard_wizard, "_input_model_with_autocomplete", fake_model_input)
|
||||
monkeypatch.setattr(
|
||||
onboard_wizard,
|
||||
"_quick_start_oauth_login",
|
||||
lambda selected_config, provider: oauth_calls.append(
|
||||
(selected_config, provider)
|
||||
)
|
||||
or True,
|
||||
)
|
||||
|
||||
assert onboard_wizard._configure_quick_start_provider(config) is True
|
||||
|
||||
assert oauth_calls == [(config, "openai_codex")]
|
||||
assert model_prompts == [
|
||||
("Model ID", "openai-codex/gpt-5.6-sol", "openai_codex")
|
||||
]
|
||||
assert config.providers.openai_codex.api_key is None
|
||||
assert config.model_presets["primary"].provider == "openai_codex"
|
||||
assert config.model_presets["primary"].model == "openai-codex/gpt-5.6-sol"
|
||||
|
||||
def test_quick_start_openai_codex_login_failure_does_not_create_preset(self, monkeypatch):
|
||||
"""A failed Codex login must not leave a ready-looking model preset."""
|
||||
config = Config()
|
||||
|
||||
monkeypatch.setattr(onboard_wizard, "_show_quick_start_progress", lambda *_args: None)
|
||||
monkeypatch.setattr(
|
||||
onboard_wizard,
|
||||
"_select_with_back",
|
||||
lambda *args, **kwargs: "OpenAI Codex",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
onboard_wizard,
|
||||
"_input_model_with_autocomplete",
|
||||
lambda *args, **kwargs: "openai-codex/gpt-5.6-sol",
|
||||
)
|
||||
monkeypatch.setattr(onboard_wizard, "_quick_start_oauth_login", lambda *args: False)
|
||||
|
||||
assert onboard_wizard._configure_quick_start_provider(config) is False
|
||||
assert "primary" not in config.model_presets
|
||||
|
||||
def test_quick_start_openai_codex_login_reuses_existing_token(self, monkeypatch):
|
||||
"""Quick Start should not open a new login flow when Codex is already authenticated."""
|
||||
import oauth_cli_kit
|
||||
|
||||
config = Config()
|
||||
token = SimpleNamespace(access="existing-token", account_id="account-123")
|
||||
login_calls: list[object] = []
|
||||
|
||||
monkeypatch.setattr(oauth_cli_kit, "get_token", lambda **kwargs: token)
|
||||
monkeypatch.setattr(
|
||||
oauth_cli_kit,
|
||||
"login_oauth_interactive",
|
||||
lambda **kwargs: login_calls.append(kwargs),
|
||||
)
|
||||
monkeypatch.setattr(onboard_wizard.console, "print", lambda *args, **kwargs: None)
|
||||
|
||||
assert onboard_wizard._quick_start_oauth_login(config, "openai_codex") is True
|
||||
assert login_calls == []
|
||||
|
||||
def test_quick_start_summary_reports_missing_codex_oauth(self, monkeypatch):
|
||||
"""The review step should distinguish OAuth from an API-key setup."""
|
||||
config = Config()
|
||||
config.model_presets["primary"] = ModelPresetConfig(
|
||||
model="openai-codex/gpt-5.6-sol",
|
||||
provider="openai_codex",
|
||||
)
|
||||
captured: dict[str, list[tuple[str, str]]] = {}
|
||||
|
||||
monkeypatch.setattr(onboard_wizard, "_show_quick_start_progress", lambda *_args: None)
|
||||
monkeypatch.setattr(
|
||||
onboard_wizard,
|
||||
"_quick_start_oauth_is_authenticated",
|
||||
lambda *args: False,
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
onboard_wizard,
|
||||
"_print_summary_panel",
|
||||
lambda rows, _title: captured.setdefault("rows", rows),
|
||||
)
|
||||
|
||||
onboard_wizard._show_quick_start_summary(config)
|
||||
|
||||
rows = dict(captured["rows"])
|
||||
assert rows["Status"] == "OpenAI Codex OAuth login missing"
|
||||
assert rows["WebSocket channel"] == "enabled"
|
||||
|
||||
def test_quick_start_provider_choice_skips_advanced_prompts(self, monkeypatch):
|
||||
"""The beginner path should ask for provider credentials and model."""
|
||||
config = Config()
|
||||
|
||||
Reference in New Issue
Block a user