Files
IPSExtractor/services/desktop_app/src/renderer/App.test.tsx
T

167 lines
7.4 KiB
TypeScript

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
import App from "./App";
async function advanceToDiscover(user: ReturnType<typeof userEvent.setup>) {
await user.click(screen.getByRole("button", { name: /explorar/i }));
await user.click(screen.getByRole("button", { name: /siguiente/i }));
}
async function discoverFields(user: ReturnType<typeof userEvent.setup>) {
await advanceToDiscover(user);
await user.click(screen.getByRole("button", { name: /descubrir campos/i }));
}
describe("App", () => {
it("renders the extraction wizard", () => {
render(<App />);
expect(screen.getByText("IPSExtractor")).toBeInTheDocument();
expect(screen.getByRole("button", { name: /^extraccion$/i })).toBeInTheDocument();
expect(screen.getByRole("button", { name: /tareas/i })).toBeInTheDocument();
expect(screen.getByRole("button", { name: /configuracion/i })).toBeInTheDocument();
expect(screen.getByText("Origen de los documentos")).toBeInTheDocument();
expect(screen.queryByText("IPS_DOCUMENT_ROOT_LOCAL")).not.toBeInTheDocument();
expect(screen.queryByText("IPS_DOCUMENT_ROOT_CONTAINER")).not.toBeInTheDocument();
expect(screen.queryByText("Ruta enviada a Docker/API")).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: /siguiente/i })).toBeDisabled();
});
it("shows API URL settings in the configuration page", async () => {
const user = userEvent.setup();
render(<App />);
await user.click(screen.getByRole("button", { name: /configuracion/i }));
expect(screen.getByText("Conexion API")).toBeInTheDocument();
const input = screen.getByLabelText("URL del API Gateway");
await user.clear(input);
await user.type(input, "http://localhost:9000");
expect(input).toHaveValue("http://localhost:9000");
});
it("adds and removes document types", async () => {
const user = userEvent.setup();
render(<App />);
await user.click(screen.getByRole("button", { name: /agregar tipo/i }));
expect(screen.getByLabelText("Nombre tipo 2")).toBeInTheDocument();
const removeButtons = screen.getAllByLabelText("Eliminar tipo");
await user.click(removeButtons[1]);
expect(screen.queryByLabelText("Nombre tipo 2")).not.toBeInTheDocument();
});
it("does not show keywords in general folder mode", async () => {
const user = userEvent.setup();
render(<App />);
await user.click(screen.getByRole("button", { name: /carpeta general/i }));
expect(screen.queryByLabelText(/keywords/i)).not.toBeInTheDocument();
expect(screen.queryByText(/^Keywords$/)).not.toBeInTheDocument();
expect(screen.getByText(/se procesaran todos los pdf y tiff/i)).toBeInTheDocument();
});
it("shows schema fields from a mocked API response", async () => {
const user = userEvent.setup();
vi.spyOn(window.desktopApi!, "selectDirectory").mockResolvedValue("C:\\docs\\lote");
vi.spyOn(globalThis, "fetch").mockResolvedValue({
ok: true,
text: async () => JSON.stringify({ schema_by_type: { Factura: { numero: "str" } }, sample_by_type: { Factura: { numero: "A1" } } }),
} as Response);
render(<App />);
await discoverFields(user);
await user.click(screen.getByRole("button", { name: /siguiente/i }));
expect(await screen.findByRole("checkbox", { name: "Seleccionar numero" })).toBeInTheDocument();
});
it("blocks advancing while no fields are selected", async () => {
const user = userEvent.setup();
vi.spyOn(window.desktopApi!, "selectDirectory").mockResolvedValue("C:\\docs\\lote");
vi.spyOn(globalThis, "fetch").mockResolvedValue({
ok: true,
text: async () => JSON.stringify({ schema_by_type: { Factura: { numero: "str" } }, sample_by_type: { Factura: { numero: "A1" } } }),
} as Response);
render(<App />);
await discoverFields(user);
await user.click(screen.getByRole("button", { name: /siguiente/i }));
expect(screen.getByRole("button", { name: /siguiente/i })).toBeDisabled();
});
it("creates an extraction task with mocked API responses", async () => {
const user = userEvent.setup();
vi.spyOn(window.desktopApi!, "selectDirectory").mockResolvedValue("C:\\docs\\lote");
vi.spyOn(globalThis, "fetch").mockImplementation(async (input) => {
const url = String(input);
if (url.includes("/extraction/schemas/upload")) {
return {
ok: true,
text: async () => JSON.stringify({ schema_by_type: { Factura: { numero: "str" } }, sample_by_type: { Factura: { numero: "A1" } } }),
} as Response;
}
if (url.includes("/tasks/extraction")) {
return {
ok: true,
text: async () => JSON.stringify({
id: "task-1",
type: "extraction",
status: "running",
title: "Extraccion desktop",
request: { source: "desktop" },
result: { extraction_batch_id: "batch-1", processed: 0, total: 1 },
error: null,
owner_id: null,
created_at: "now",
updated_at: "now",
started_at: "now",
finished_at: null,
}),
} as Response;
}
if (url.includes("/tasks/task-1/ingest")) {
return {
ok: true,
text: async () => JSON.stringify({ processed: 1, total: 1, task: { id: "task-1", status: "completed", result: { extraction_batch_id: "batch-1" } } }),
} as Response;
}
if (url.includes("/tasks/task-1") && !url.includes("/rows") && !url.includes("/ingest")) {
return {
ok: true,
text: async () => JSON.stringify({
id: "task-1",
type: "extraction",
status: "completed",
title: "Extraccion desktop",
request: { source: "desktop" },
result: { extraction_batch_id: "batch-1", processed: 1, total: 1 },
error: null,
owner_id: null,
created_at: "now",
updated_at: "now",
started_at: "now",
finished_at: "now",
}),
} as Response;
}
if (url.includes("/tasks?")) {
return {
ok: true,
text: async () => JSON.stringify([{ id: "task-1", type: "extraction", status: "completed", title: "Extraccion desktop", request: {}, result: { extraction_batch_id: "batch-1" }, error: null, owner_id: null, created_at: "now", updated_at: "now", started_at: "now", finished_at: "now" }]),
} as Response;
}
if (url.includes("/tasks/task-1/rows")) {
return {
ok: true,
text: async () => JSON.stringify({ task_id: "task-1", batch_id: "batch-1", rows: [{ radicado: "R1", numero: "A1" }], limit: 500, offset: 0 }),
} as Response;
}
return { ok: true, text: async () => "{}" } as Response;
});
render(<App />);
await discoverFields(user);
await user.click(screen.getByRole("button", { name: /siguiente/i }));
await user.click(await screen.findByRole("checkbox", { name: "Seleccionar numero" }));
await user.click(screen.getByRole("button", { name: /siguiente/i }));
await user.click(screen.getByRole("button", { name: /ejecutar extraccion/i }));
expect(await screen.findByText("Tareas y resultados")).toBeInTheDocument();
expect((await screen.findAllByText("completed")).length).toBeGreaterThan(0);
expect(await screen.findByText("A1")).toBeInTheDocument();
});
});