feat: toast for settings save

This commit is contained in:
Leon
2025-07-16 18:20:45 +02:00
parent 0e19af170d
commit d47e975574
2 changed files with 137 additions and 27 deletions

View File

@@ -4,6 +4,7 @@ import "@testing-library/jest-dom"
import { SettingsDialog } from "../SettingsDialog"
import { Settings } from "@/lib/api"
import * as api from "@/lib/api"
import { toast } from "sonner"
// Mock the API module
jest.mock("@/lib/api", () => ({
@@ -12,6 +13,14 @@ jest.mock("@/lib/api", () => ({
testImapConnection: jest.fn(),
}))
// Mock the toast module
jest.mock("sonner", () => ({
toast: {
success: jest.fn(),
error: jest.fn(),
},
}))
const mockedApi = api as jest.Mocked<typeof api>
const mockSettings: Settings = {
@@ -31,9 +40,15 @@ const mockFolderOptions = ["INBOX", "Sent", "Archive", "Spam"]
describe("SettingsDialog", () => {
const handleOpenChange = jest.fn()
const handleSuccess = jest.fn()
const consoleError = jest.spyOn(console, "error").mockImplementation(() => {})
beforeEach(() => {
jest.clearAllMocks()
consoleError.mockClear()
})
afterAll(() => {
consoleError.mockRestore()
})
it("renders settings and respects locked fields", () => {
@@ -53,11 +68,13 @@ describe("SettingsDialog", () => {
expect(screen.getByLabelText(/IMAP Username/i)).toBeEnabled()
// Check that values are set correctly
expect(screen.getByLabelText(/IMAP Username/i)).toHaveValue(mockSettings.imap_username)
expect(screen.getByLabelText(/IMAP Username/i)).toHaveValue(
mockSettings.imap_username
)
expect(screen.getByLabelText(/Mark emails as read/i)).toBeChecked()
})
it("allows updating and saving settings", async () => {
it("allows updating and saving settings, showing success toast", async () => {
mockedApi.updateSettings.mockResolvedValueOnce(mockSettings)
render(
@@ -71,7 +88,9 @@ describe("SettingsDialog", () => {
)
// Change a setting
fireEvent.change(screen.getByLabelText(/IMAP Username/i), { target: { value: "new.user@example.com" } })
fireEvent.change(screen.getByLabelText(/IMAP Username/i), {
target: { value: "new.user@example.com" },
})
// Save
fireEvent.click(screen.getByRole("button", { name: /Save Settings/i }))
@@ -82,13 +101,37 @@ describe("SettingsDialog", () => {
imap_username: "new.user@example.com",
})
)
expect(toast.success).toHaveBeenCalledWith("Settings saved successfully!")
expect(handleSuccess).toHaveBeenCalledTimes(1)
expect(handleOpenChange).toHaveBeenCalledWith(false)
})
})
it("shows an error toast if saving settings fails", async () => {
mockedApi.updateSettings.mockRejectedValueOnce(new Error("Failed to save"))
render(
<SettingsDialog
settings={mockSettings}
folderOptions={mockFolderOptions}
isOpen={true}
onOpenChange={handleOpenChange}
onSuccess={handleSuccess}
/>
)
fireEvent.click(screen.getByRole("button", { name: /Save Settings/i }))
await waitFor(() => {
expect(toast.error).toHaveBeenCalledWith("Failed to save settings.")
expect(handleSuccess).not.toHaveBeenCalled()
})
})
it("handles successful connection test", async () => {
mockedApi.testImapConnection.mockResolvedValueOnce({ message: "Connection successful!" })
mockedApi.testImapConnection.mockResolvedValueOnce({
message: "Connection successful!",
})
render(
<SettingsDialog
@@ -104,12 +147,16 @@ describe("SettingsDialog", () => {
await waitFor(() => {
expect(screen.getByText("Connection successful!")).toBeInTheDocument()
expect(screen.getByTestId("connection-status")).toHaveClass("text-green-600")
expect(screen.getByTestId("connection-status")).toHaveClass(
"text-green-600"
)
})
})
it("handles failed connection test", async () => {
mockedApi.testImapConnection.mockRejectedValueOnce(new Error("Authentication failed"))
mockedApi.testImapConnection.mockRejectedValueOnce(
new Error("Authentication failed")
)
render(
<SettingsDialog