feat(web): расписание, каналы уведомлений, история проверок, drift-badge
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { MemoryRouter } from "react-router-dom"
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
||||
import { SchedulePage } from "./SchedulePage"
|
||||
import { AuthProvider } from "@/auth/AuthContext"
|
||||
import { api } from "@/api/client"
|
||||
import { vi, beforeEach, test, expect } from "vitest"
|
||||
|
||||
const PROJECT_ID = "p1"
|
||||
|
||||
function renderPage() {
|
||||
const qc = new QueryClient()
|
||||
return render(
|
||||
<QueryClientProvider client={qc}>
|
||||
<AuthProvider>
|
||||
<MemoryRouter initialEntries={["/schedule"]}>
|
||||
<SchedulePage />
|
||||
</MemoryRouter>
|
||||
</AuthProvider>
|
||||
</QueryClientProvider>,
|
||||
)
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
vi.spyOn(api.auth, "me").mockResolvedValue({
|
||||
user: { id: "u1", email: "a@b.com" },
|
||||
project: { id: PROJECT_ID, name: "Default" },
|
||||
})
|
||||
vi.spyOn(api, "getSchedule").mockResolvedValue({ intervalSeconds: 120, enabled: true })
|
||||
})
|
||||
|
||||
test("показывает текущий интервал и enabled", async () => {
|
||||
renderPage()
|
||||
|
||||
const intervalInput = await screen.findByLabelText(/интервал/i)
|
||||
expect(intervalInput).toHaveValue(120)
|
||||
expect(screen.getByRole("checkbox", { name: /включ/i })).toBeChecked()
|
||||
})
|
||||
|
||||
test("сохранение вызывает updateSchedule с новыми значениями", async () => {
|
||||
const updateSpy = vi.spyOn(api, "putSchedule").mockResolvedValue({ intervalSeconds: 300, enabled: false })
|
||||
const user = userEvent.setup()
|
||||
renderPage()
|
||||
|
||||
const intervalInput = await screen.findByLabelText(/интервал/i)
|
||||
await user.clear(intervalInput)
|
||||
await user.type(intervalInput, "300")
|
||||
await user.click(screen.getByRole("checkbox", { name: /включ/i }))
|
||||
await user.click(screen.getByRole("button", { name: /сохранить/i }))
|
||||
|
||||
await waitFor(() =>
|
||||
expect(updateSpy).toHaveBeenCalledWith(PROJECT_ID, { intervalSeconds: 300, enabled: false }),
|
||||
)
|
||||
})
|
||||
|
||||
test("валидация: интервал меньше 60 блокирует сохранение", async () => {
|
||||
const updateSpy = vi.spyOn(api, "putSchedule").mockResolvedValue({ intervalSeconds: 120, enabled: true })
|
||||
const user = userEvent.setup()
|
||||
renderPage()
|
||||
|
||||
const intervalInput = await screen.findByLabelText(/интервал/i)
|
||||
await user.clear(intervalInput)
|
||||
await user.type(intervalInput, "30")
|
||||
await user.click(screen.getByRole("button", { name: /сохранить/i }))
|
||||
|
||||
expect(await screen.findByRole("alert")).toHaveTextContent(/60/)
|
||||
expect(updateSpy).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("ошибка сохранения отображается пользователю", async () => {
|
||||
vi.spyOn(api, "putSchedule").mockRejectedValue(new Error("Не удалось сохранить расписание"))
|
||||
const user = userEvent.setup()
|
||||
renderPage()
|
||||
|
||||
const intervalInput = await screen.findByLabelText(/интервал/i)
|
||||
await user.clear(intervalInput)
|
||||
await user.type(intervalInput, "180")
|
||||
await user.click(screen.getByRole("button", { name: /сохранить/i }))
|
||||
|
||||
expect(await screen.findByRole("alert")).toHaveTextContent("Не удалось сохранить расписание")
|
||||
})
|
||||
Reference in New Issue
Block a user