fix: ai preferences crashed and deleted stuff in preferences

This commit is contained in:
2026-07-07 22:43:05 +02:00
parent 4a03fc0ba2
commit dc35518bad
21 changed files with 1883 additions and 261 deletions

View File

@@ -385,6 +385,28 @@ defmodule BDS.AITest do
assert Repo.get(Setting, "__encrypted_ai.online.api_key") == nil
end
test "put_endpoint clears fields on nil instead of crashing" do
assert {:ok, _endpoint} =
BDS.AI.put_endpoint(
:online,
%{url: "https://api.example.test/v1", api_key: "secret", model: "gpt-4o-mini"},
secret_backend: FakeSecretBackend
)
# A partial config (blank URL/model) must not raise — it clears those keys.
assert {:ok, endpoint} =
BDS.AI.put_endpoint(
:online,
%{url: nil, api_key: nil, model: nil},
secret_backend: FakeSecretBackend
)
assert endpoint.url == nil
assert Repo.get(Setting, "ai.online.url") == nil
assert Repo.get(Setting, "ai.online.model") == nil
assert Repo.get(Setting, "__encrypted_ai.online.api_key") == nil
end
test "airplane_endpoint_configured? reflects the airplane endpoint url and model" do
refute BDS.AI.airplane_endpoint_configured?()

View File

@@ -2085,6 +2085,50 @@ defmodule BDS.Desktop.ShellLiveTest do
BDS.AI.Catalog.model_capabilities("llama3.3")
end
test "saving ai settings without editing preserves stored endpoints" do
assert {:ok, _online} =
AI.put_endpoint(:online, %{
url: "https://api.example.test/v1",
api_key: "keep-me",
model: "gpt-4.1"
})
assert {:ok, _airplane} =
AI.put_endpoint(:airplane, %{
url: "http://localhost:11434/v1",
api_key: nil,
model: "llama3.3"
})
{:ok, view, _html} = live_isolated(build_conn(), BDS.Desktop.ShellLive)
_html =
view
|> element("[data-testid='activity-button'][data-view='settings']")
|> render_click()
_html =
view
|> element("[data-testid='sidebar-open-item'][data-item-id='settings-project']")
|> render_click()
# Save with an untouched form (no change_settings_ai). The endpoints must
# survive instead of being wiped by an empty draft.
_html =
view
|> element("#settings-editor-shell button[phx-click='save_settings_ai']")
|> render_click()
assert {:ok, online} = AI.get_endpoint(:online)
assert online.url == "https://api.example.test/v1"
assert online.api_key == "keep-me"
assert online.model == "gpt-4.1"
assert {:ok, airplane} = AI.get_endpoint(:airplane)
assert airplane.url == "http://localhost:11434/v1"
assert airplane.model == "llama3.3"
end
test "ai settings refresh models from the configured endpoints" do
Application.put_env(:bds, :ai_http_client, FakeEndpointModelHttpClient)