| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "os" |
| 6 | "reasonix/internal/config" |
| 7 | "testing" |
| 8 | ) |
| 9 | |
| 10 | func TestSavedCredentialAllowsAdmissionThroughPendingMetadata(t *testing.T) { |
| 11 | isolateDesktopUserDirs(t) |
| 12 | if err := os.MkdirAll(config.ReasonixHomeDir(), 0700); err != nil { |
| 13 | t.Fatal(err) |
| 14 | } |
| 15 | body := "default_model='relay/chat'\n[[providers]]\nname='relay'\nkind='openai'\nbase_url='https://relay.invalid/v1'\nmodel='chat'\napi_key_env='MISSING_REVIEW_KEY'\n[desktop]\nprovider_access=['relay']\n" |
| 16 | if err := os.WriteFile(config.UserConfigPath(), []byte(body), 0600); err != nil { |
| 17 | t.Fatal(err) |
| 18 | } |
| 19 | app := NewApp() |
| 20 | app.ctx = context.Background() |
| 21 | app.readyHook = func() {} |
| 22 | t.Cleanup(app.closeSessionServices) |
| 23 | tab := modelSettingsBootTab(t, app, "review", t.TempDir(), "relay/chat") |
| 24 | original := tab.Ctrl |
| 25 | t.Cleanup(original.Close) |
| 26 | app.activeTabID = tab.ID |
| 27 | before := app.tabMeta(tab, true) |
| 28 | if before.Authentication == nil || before.Authentication.Ready() { |
| 29 | t.Fatal("expected missing-key fixture") |
| 30 | } |
| 31 | result, err := config.CommitConnectionCredential(config.ConnectionCredentialRequest{RequestID: "review-save", ConfigPath: config.UserConfigPath(), ProviderNames: []string{"relay"}, Key: "fixture-key"}) |
| 32 | if err != nil || !result.Persisted { |
| 33 | t.Fatalf("save: %+v %v", result, err) |
| 34 | } |
| 35 | app.refreshTabMetaExtras(tab) |
| 36 | application := app.GetModelSettingsApplication() |
| 37 | meta := app.tabMeta(tab, true) |
| 38 | if application.Application != "pending" || meta.Authentication == nil || meta.Authentication.Ready() { |
| 39 | t.Fatalf("unexpected state: application=%s auth=%+v", application.Application, meta.Authentication) |
| 40 | } |
| 41 | if !meta.ModelSettingsPending { |
| 42 | t.Fatal("saved settings did not expose pending admission") |
| 43 | } |
| 44 | if len(tab.Ctrl.History()) != len(original.History()) { |
| 45 | t.Fatal("metadata refresh created a turn") |
| 46 | } |
| 47 | admission, _, err := app.beginTabTurn(tab.ID, false) |
| 48 | if err != nil { |
| 49 | t.Fatal(err) |
| 50 | } |
| 51 | admission.abort() |
| 52 | if fresh := app.tabMeta(tab, true); fresh.Authentication == nil || !fresh.Authentication.Ready() { |
| 53 | t.Fatalf("backend admission did not recover: %+v", fresh.Authentication) |
| 54 | } |
| 55 | if fresh := app.tabMeta(tab, true); fresh.ModelSettingsPending { |
| 56 | t.Fatal("replacement inherited stale pending metadata") |
| 57 | } |
| 58 | } |
| 59 |