import { render, screen, fireEvent } from "@testing-library/react"
import "@testing-library/jest-dom"
import ApiConfigManager from "../ApiConfigManager"
// Mock VSCode components
jest.mock("@vscode/webview-ui-toolkit/react", () => ({
VSCodeButton: ({ children, onClick, title, disabled }: any) => (
),
VSCodeTextField: ({ value, onInput, placeholder }: any) => (
onInput(e)}
placeholder={placeholder}
ref={undefined} // Explicitly set ref to undefined to avoid warning
/>
),
}))
jest.mock("vscrui", () => ({
Dropdown: ({ id, value, onChange, options, role }: any) => (
),
}))
describe("ApiConfigManager", () => {
const mockOnSelectConfig = jest.fn()
const mockOnDeleteConfig = jest.fn()
const mockOnRenameConfig = jest.fn()
const mockOnUpsertConfig = jest.fn()
const defaultProps = {
currentApiConfigName: "Default Config",
listApiConfigMeta: [{ name: "Default Config" }, { name: "Another Config" }],
onSelectConfig: mockOnSelectConfig,
onDeleteConfig: mockOnDeleteConfig,
onRenameConfig: mockOnRenameConfig,
onUpsertConfig: mockOnUpsertConfig,
}
beforeEach(() => {
jest.clearAllMocks()
})
it("immediately creates a copy when clicking add button", () => {
render()
// Find and click the add button
const addButton = screen.getByTitle("Add profile")
fireEvent.click(addButton)
// Verify that onUpsertConfig was called with the correct name
expect(mockOnUpsertConfig).toHaveBeenCalledTimes(1)
expect(mockOnUpsertConfig).toHaveBeenCalledWith("Default Config (copy)")
})
it("creates copy with correct name when current config has spaces", () => {
render()
const addButton = screen.getByTitle("Add profile")
fireEvent.click(addButton)
expect(mockOnUpsertConfig).toHaveBeenCalledWith("My Test Config (copy)")
})
it("handles empty current config name gracefully", () => {
render()
const addButton = screen.getByTitle("Add profile")
fireEvent.click(addButton)
expect(mockOnUpsertConfig).toHaveBeenCalledWith(" (copy)")
})
it("allows renaming the current config", () => {
render()
// Start rename
const renameButton = screen.getByTitle("Rename profile")
fireEvent.click(renameButton)
// Find input and enter new name
const input = screen.getByDisplayValue("Default Config")
fireEvent.input(input, { target: { value: "New Name" } })
// Save
const saveButton = screen.getByTitle("Save")
fireEvent.click(saveButton)
expect(mockOnRenameConfig).toHaveBeenCalledWith("Default Config", "New Name")
})
it("allows selecting a different config", () => {
render()
const select = screen.getByRole("combobox")
fireEvent.change(select, { target: { value: "Another Config" } })
expect(mockOnSelectConfig).toHaveBeenCalledWith("Another Config")
})
it("allows deleting the current config when not the only one", () => {
render()
const deleteButton = screen.getByTitle("Delete profile")
expect(deleteButton).not.toBeDisabled()
fireEvent.click(deleteButton)
expect(mockOnDeleteConfig).toHaveBeenCalledWith("Default Config")
})
it("disables delete button when only one config exists", () => {
render()
const deleteButton = screen.getByTitle("Cannot delete the only profile")
expect(deleteButton).toHaveAttribute("disabled")
})
it("cancels rename operation when clicking cancel", () => {
render()
// Start rename
const renameButton = screen.getByTitle("Rename profile")
fireEvent.click(renameButton)
// Find input and enter new name
const input = screen.getByDisplayValue("Default Config")
fireEvent.input(input, { target: { value: "New Name" } })
// Cancel
const cancelButton = screen.getByTitle("Cancel")
fireEvent.click(cancelButton)
// Verify rename was not called
expect(mockOnRenameConfig).not.toHaveBeenCalled()
// Verify we're back to normal view
expect(screen.queryByDisplayValue("New Name")).not.toBeInTheDocument()
})
})