Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/controllers/settings/hostings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ def update

redirect_to settings_hosting_path, notice: t(".success")
rescue Setting::ValidationError => error
# Preserve user-submitted OpenAI config so the form re-renders with their
# input intact (issue #1824). The form auto-submits on blur, so a partial
# entry (e.g. URI base before model) hits validation and would otherwise
# be wiped because the view reads from the unchanged Setting.* values.
@openai_uri_base_input = hosting_params[:openai_uri_base] if hosting_params.key?(:openai_uri_base)
@openai_model_input = hosting_params[:openai_model] if hosting_params.key?(:openai_model)
flash.now[:alert] = error.message
render :show, status: :unprocessable_entity
end
Expand Down
4 changes: 2 additions & 2 deletions app/views/settings/hostings/_openai_settings.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<%= form.text_field :openai_uri_base,
label: t(".uri_base_label"),
placeholder: t(".uri_base_placeholder"),
value: Setting.openai_uri_base,
value: @openai_uri_base_input || Setting.openai_uri_base,
autocomplete: "off",
autocapitalize: "none",
spellcheck: "false",
Expand All @@ -41,7 +41,7 @@
<%= form.text_field :openai_model,
label: t(".model_label"),
placeholder: t(".model_placeholder"),
value: Setting.openai_model,
value: @openai_model_input || Setting.openai_model,
autocomplete: "off",
autocapitalize: "none",
spellcheck: "false",
Expand Down
49 changes: 49 additions & 0 deletions test/controllers/settings/hostings_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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" } }
Expand Down