diff --git a/frontend/__tests__/components/shared/modals/settings/settings-form.test.tsx b/frontend/__tests__/components/shared/modals/settings/settings-form.test.tsx index e373fdfb3e4f..06d1628e1f74 100644 --- a/frontend/__tests__/components/shared/modals/settings/settings-form.test.tsx +++ b/frontend/__tests__/components/shared/modals/settings/settings-form.test.tsx @@ -1,13 +1,22 @@ import { screen, fireEvent } from "@testing-library/react"; -import { describe, it, expect, vi } from "vitest"; +import { describe, it, expect, vi, afterEach } from "vitest"; import { renderWithProviders } from "test-utils"; import { createRoutesStub } from "react-router"; +import userEvent from "@testing-library/user-event"; import { DEFAULT_SETTINGS } from "#/services/settings"; import { SettingsForm } from "#/components/shared/modals/settings/settings-form"; import OpenHands from "#/api/open-hands"; describe("SettingsForm", () => { const getConfigSpy = vi.spyOn(OpenHands, "getConfig"); + const saveSettingsSpy = vi.spyOn(OpenHands, "saveSettings"); + + const onCloseMock = vi.fn(); + + afterEach(() => { + vi.clearAllMocks(); + }); + getConfigSpy.mockResolvedValue({ APP_MODE: "saas", GITHUB_CLIENT_ID: "123", @@ -19,10 +28,10 @@ describe("SettingsForm", () => { Component: () => ( {}} + models={["anthropic/claude-3-5-sonnet-20241022", "model2"]} + agents={["CodeActAgent", "agent2"]} + securityAnalyzers={["analyzer1", "analyzer2"]} + onClose={onCloseMock} /> ), path: "/", @@ -35,11 +44,33 @@ describe("SettingsForm", () => { }); it("should show runtime size selector when advanced options are enabled", async () => { + const user = userEvent.setup(); renderWithProviders(); - const advancedSwitch = screen.getByRole("switch", { - name: "SETTINGS_FORM$ADVANCED_OPTIONS_LABEL", - }); - fireEvent.click(advancedSwitch); - await screen.findByText("SETTINGS_FORM$RUNTIME_SIZE_LABEL"); + + const toggleAdvancedMode = screen.getByTestId("advanced-option-switch"); + await user.click(toggleAdvancedMode); + + await screen.findByTestId("runtime-size"); + }); + + it("should not submit the form if required fields are empty", async () => { + const user = userEvent.setup(); + renderWithProviders(); + + expect(screen.queryByTestId("custom-model-input")).not.toBeInTheDocument(); + + const toggleAdvancedMode = screen.getByTestId("advanced-option-switch"); + await user.click(toggleAdvancedMode); + + const customModelInput = screen.getByTestId("custom-model-input"); + expect(customModelInput).toBeInTheDocument(); + + await user.clear(customModelInput); + + const saveButton = screen.getByTestId("save-settings-button"); + await user.click(saveButton); + + expect(saveSettingsSpy).not.toHaveBeenCalled(); + expect(onCloseMock).not.toHaveBeenCalled(); }); }); diff --git a/frontend/src/components/shared/inputs/advanced-option-switch.tsx b/frontend/src/components/shared/inputs/advanced-option-switch.tsx index 50709f9de3ac..958dc9f1bf46 100644 --- a/frontend/src/components/shared/inputs/advanced-option-switch.tsx +++ b/frontend/src/components/shared/inputs/advanced-option-switch.tsx @@ -18,6 +18,7 @@ export function AdvancedOptionSwitch({ return (