import { render, screen } from "@testing-library/react"
import { beforeEach, describe, expect, it, vi } from "vitest"
import { AppProvider, useApp } from "../../services/app-provider"
// Мокаем XState machine
const mockSend = vi.fn()
const mockState = {
context: {
isConnected: false,
error: null,
projectState: {
currentProject: {
path: null,
name: "Test Project",
isDirty: false,
},
},
},
matches: vi.fn((state) => state === "disconnected"), // Изначально disconnected
}
vi.mock("@xstate/react", () => ({
useMachine: vi.fn(() => [mockState, mockSend]),
}))
// Мокаем app-machine
vi.mock("../../services/app-machine", () => ({
appMachine: {
id: "app",
initial: "disconnected",
},
}))
// Компонент для тестирования хука useApp
const TestComponent = () => {
const context = useApp()
const { isConnected, isConnecting, connectionError, projectState, executeCommand } = context
return (
{isConnected ? "Connected" : "Disconnected"}
{isConnecting ? "Connecting" : "Not Connecting"}
{connectionError ?? "No Error"}
{projectState?.currentProject?.name ?? "No Project"}
)
}
describe("AppProvider", () => {
beforeEach(() => {
vi.clearAllMocks()
})
it("should render children and provide context", () => {
render(
Child Component
,
)
expect(screen.getByTestId("child")).toBeInTheDocument()
})
it("should provide app context to children", () => {
render(
,
)
expect(screen.getByTestId("connected")).toHaveTextContent("Disconnected")
expect(screen.getByTestId("connecting")).toHaveTextContent("Not Connecting")
expect(screen.getByTestId("error")).toHaveTextContent("No Error")
expect(screen.getByTestId("project-name")).toHaveTextContent("Test Project")
})
it("should handle executeCommand function", () => {
render(
,
)
const button = screen.getByTestId("execute-command")
button.click()
expect(mockSend).toHaveBeenCalledWith({
type: "EXECUTE_COMMAND",
command: { type: "TEST" },
})
})
it("should connect automatically on mount", () => {
render(
,
)
// Проверяем, что отправлено событие подключения
expect(mockSend).toHaveBeenCalledWith({ type: "CONNECT" })
})
it("should provide disconnect functionality", () => {
// Создаем тестовый компонент, который проверяет функции
const DisconnectTestComponent = () => {
const { disconnect } = useApp()
return (
)
}
render(
,
)
const button = screen.getByTestId("disconnect")
button.click()
expect(mockSend).toHaveBeenCalledWith({ type: "DISCONNECT" })
})
it("should provide retry connection functionality", () => {
// Создаем тестовый компонент, который проверяет функции
const RetryTestComponent = () => {
const { retryConnection } = useApp()
return (
)
}
render(
,
)
const button = screen.getByTestId("retry")
button.click()
expect(mockSend).toHaveBeenCalledWith({ type: "RETRY_CONNECTION" })
})
})