fix(settings): preserve OpenAI form input on validation failure (#1862)

* fix(settings): preserve OpenAI form input on validation failure

Fixes #1824.

The OpenAI settings form auto-submits on blur, so typing the URI base
before the model triggers cross-field validation. The rescue re-renders
the page with values read from Setting.openai_*, which is still blank
because the failed save was rejected — so the user's input disappears
and they see 'OpenAI model is required' with no value to fix.

Stash the submitted uri_base and model on rescue and prefer them over
the saved Setting when rendering, so the user can finish typing the
missing field and re-submit.

* test(settings): cover openai_model preservation on validation fail (#1862)

jjmata asked for symmetric coverage of the model field. Add a test where
the user changes the URI base and clears the model in the same submit:
the cross-field validation fails and the re-rendered model input must
reflect the submitted (cleared) value rather than reverting to the saved
model. Complements the existing uri_base preservation test.
This commit is contained in:
dripsmvcp
2026-05-25 18:23:52 +09:00
committed by GitHub
parent 89f42497a9
commit 8f5454ad29
3 changed files with 57 additions and 2 deletions

View File

@@ -95,6 +95,55 @@ class Settings::HostingsControllerTest < ActionDispatch::IntegrationTest
end
end
# Regression: issue #1824. The OpenAI form auto-submits on blur, so entering
# the URI base before the model fires a partial submit that fails validation.
# The re-rendered form must show the user's submitted URI base — not the
# still-blank saved value — so they can finish typing the model.
test "preserves submitted openai uri base in form when validation fails" do
with_self_hosting do
Setting.openai_uri_base = nil
Setting.openai_model = ""
patch settings_hosting_url, params: { setting: { openai_uri_base: "https://api.example.com/v1" } }
assert_response :unprocessable_entity
assert_select "input[name=?]", "setting[openai_uri_base]" do |inputs|
assert_equal "https://api.example.com/v1", inputs.first["value"]
end
end
ensure
Setting.openai_uri_base = nil
Setting.openai_model = nil
end
# PR #1862 review (jjmata): symmetric coverage for the model field. When the
# user changes the URI base and clears the model in the same auto-submit, the
# cross-field validation fails — the re-rendered model input must reflect the
# user's submitted (cleared) value, not silently revert to the saved model.
test "preserves submitted openai model in form when validation fails" do
with_self_hosting do
Setting.openai_uri_base = "https://saved.example.com/v1"
Setting.openai_model = "saved-model"
patch settings_hosting_url, params: { setting: {
openai_uri_base: "https://new.example.com/v1",
openai_model: ""
} }
assert_response :unprocessable_entity
assert_select "input[name=?]", "setting[openai_uri_base]" do |inputs|
assert_equal "https://new.example.com/v1", inputs.first["value"]
end
assert_select "input[name=?]", "setting[openai_model]" do |inputs|
assert_not_equal "saved-model", inputs.first["value"].to_s,
"model field must reflect the submitted (cleared) value, not the saved model"
end
end
ensure
Setting.openai_uri_base = nil
Setting.openai_model = nil
end
test "can update openai model alone when self hosting is enabled" do
with_self_hosting do
patch settings_hosting_url, params: { setting: { openai_model: "gpt-4" } }