import { render, screen, fireEvent, waitFor } from "@testing-library/react" import userEvent from "@testing-library/user-event" import { useState } from "react" import { test, expect, vi } from "vitest" import { RecordEditor } from "./RecordEditor" import type { RecordDTO } from "@/api/types" function Harness({ initial, onChange, }: { initial: RecordDTO[] onChange: (records: RecordDTO[]) => void }) { const [value, setValue] = useState(initial) return ( { setValue(next) onChange(next) }} /> ) } test("добавление записи вызывает onChange с новой пустой записью типа A", async () => { const onChange = vi.fn() const user = userEvent.setup() render() await user.click(screen.getByRole("button", { name: /добавить запись/i })) expect(onChange).toHaveBeenCalledWith([{ type: "A", name: "", ttl: 3600, values: [""] }]) }) test("изменение полей записи вызывает onChange с корректным массивом", async () => { const onChange = vi.fn() render( , ) fireEvent.change(screen.getByLabelText(/имя записи 1/i), { target: { value: "www" } }) fireEvent.change(screen.getByLabelText(/ttl записи 1/i), { target: { value: "300" } }) fireEvent.change(screen.getByLabelText(/значения записи 1/i), { target: { value: "192.0.2.1" }, }) await waitFor(() => expect(onChange).toHaveBeenLastCalledWith([ { type: "A", name: "www", ttl: 300, values: ["192.0.2.1"] }, ]), ) }) test("несколько значений в textarea дают несколько элементов values", async () => { const onChange = vi.fn() render( , ) fireEvent.change(screen.getByLabelText(/значения записи 1/i), { target: { value: "ns1.example.com.\nns2.example.com." }, }) await waitFor(() => expect(onChange).toHaveBeenLastCalledWith([ { type: "NS", name: "@", ttl: 3600, values: ["ns1.example.com.", "ns2.example.com."], }, ]), ) }) test("выбор типа SRV и составное значение prio weight port target", async () => { const onChange = vi.fn() const user = userEvent.setup() render( , ) await user.click(screen.getByRole("combobox", { name: /тип записи 1/i })) await user.click(await screen.findByRole("option", { name: /^srv$/i })) fireEvent.change(screen.getByLabelText(/значения записи 1/i), { target: { value: "10 5 5060 sipserver.example.com." }, }) await waitFor(() => expect(onChange).toHaveBeenLastCalledWith([ { type: "SRV", name: "_sip._tcp", ttl: 3600, values: ["10 5 5060 sipserver.example.com."], }, ]), ) }) test("удаление записи вызывает onChange без удалённой записи", async () => { const onChange = vi.fn() const user = userEvent.setup() const initial: RecordDTO[] = [ { type: "A", name: "a", ttl: 3600, values: ["1.1.1.1"] }, { type: "A", name: "b", ttl: 3600, values: ["2.2.2.2"] }, ] render() await user.click(screen.getByRole("button", { name: /удалить запись 1/i })) expect(onChange).toHaveBeenLastCalledWith([ { type: "A", name: "b", ttl: 3600, values: ["2.2.2.2"] }, ]) }) test("mono-шрифт применён к полям name и values", () => { render( , ) expect(screen.getByLabelText(/имя записи 1/i)).toHaveClass("font-dns") expect(screen.getByLabelText(/значения записи 1/i)).toHaveClass("font-dns") })