167 lines
7.4 KiB
TypeScript
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();
|
|
});
|
|
});
|