Files
PRA-only-demo/src/main/capabilities/office-file-extended.test.ts
T

127 lines
6.5 KiB
TypeScript

import ExcelJS from "exceljs";
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { PDFDocument } from "pdf-lib";
import { afterEach, describe, expect, it } from "vitest";
import type { CatalogComponent, FlowNode } from "../../shared/types";
import { getHandler } from "../engine/registry";
import type { RunContext } from "../engine/types";
import "./office-file-extended";
const directories: string[] = [];
const context = {} as RunContext;
const component = {} as CatalogComponent;
const node = (componentId: string): FlowNode => ({
id: `office_file_extended_${componentId}`,
componentId,
position: { x: 0, y: 0 },
values: {},
options: {}
});
async function temporaryDirectory(): Promise<string> {
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-office-file-extended-"));
directories.push(directory);
return directory;
}
async function run(componentId: string, args: Record<string, unknown>): Promise<unknown> {
const handler = getHandler(componentId);
expect(handler, `${componentId} should be registered`).toBeTruthy();
return handler!(context, node(componentId), args, component);
}
afterEach(async () => {
await Promise.all(directories.splice(0).map((directory) => rm(directory, { recursive: true, force: true })));
});
describe("extended Office and file capabilities", () => {
it("registers audited catalog component ids", async () => {
const catalog = JSON.parse(await readFile(path.resolve("resources/catalog.json"), "utf8")) as { components: Array<{ id: string }> };
const catalogIds = new Set(catalog.components.map((item) => item.id));
for (const id of [
"Excel_Cs_ReadRowCount", "Excel_Cs_ReadCellFormula", "Excel_Cs_GetPath", "Excel_GetPath",
"Excel_Cs_ConvertColumn", "Excel_Cs_GetEmptyCell", "Excel_Cs_ReadColumn", "Excel_GetColDataNew",
"Excel_Cs_DeleteRow", "Excel_Cs_DeleteColumn", "Excel_Cs_ClearRangeV4", "Excel_Cs_MergeCells",
"Excel_Cs_SetHeight", "Excel_Cs_SetWidth", "Excel_Cs_CopyV2", "PDF_CreateNewPdf", "PDF_GetPdfInformation"
]) {
expect(catalogIds.has(id), `${id} should exist in catalog.json`).toBe(true);
expect(getHandler(id), `${id} should be registered`).toBeTruthy();
}
});
it("reads formulas, rows, columns, paths, and empty cells from a real workbook", async () => {
const directory = await temporaryDirectory();
const filePath = path.join(directory, "read.xlsx");
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet("Data");
sheet.getCell("A1").value = "name";
sheet.getCell("A2").value = "alpha";
sheet.getCell("A3").value = "beta";
sheet.getCell("B1").value = 2;
sheet.getCell("B2").value = 3;
sheet.getCell("B3").value = { formula: "SUM(B1:B2)", result: 5 };
await workbook.xlsx.writeFile(filePath);
await expect(run("Excel_Cs_ReadRowCount", { workbook: filePath, sheet: "Data", range: "all" })).resolves.toBe(3);
await expect(run("Excel_Cs_ReadCellFormula", { workbook: filePath, sheet: "Data", column: "B", row: 3 })).resolves.toBe("SUM(B1:B2)");
await expect(run("Excel_Cs_GetEmptyCell", { workbook: filePath, sheet: "Data", column: "A", row: 1 })).resolves.toBe("A4");
await expect(run("Excel_Cs_ReadColumn", { workbook: filePath, sheet: "Data", columnName: "A" })).resolves.toEqual(["name", "alpha", "beta"]);
await expect(run("Excel_GetColDataNew", { objExcel: filePath, sheet: "Data", column: "B" })).resolves.toEqual([2, 3, 5]);
await expect(run("Excel_Cs_GetPath", { workbook: { path: filePath } })).resolves.toBe(filePath);
await expect(run("Excel_GetPath", { objExcel: filePath })).resolves.toBe(filePath);
await expect(run("Excel_Cs_ConvertColumn", { convertInput: 28, convertType: "0" })).resolves.toBe("AB");
await expect(run("Excel_Cs_ConvertColumn", { convertInput: "AB", convertType: "1" })).resolves.toBe(28);
});
it("mutates rows, columns, ranges, dimensions, merged cells, and sheets on disk", async () => {
const directory = await temporaryDirectory();
const filePath = path.join(directory, "mutate.xlsx");
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet("Data");
sheet.addRows([["a", "b", "c"], [1, 2, 3], [4, 5, 6]]);
await workbook.xlsx.writeFile(filePath);
await run("Excel_Cs_SetHeight", { workbook: filePath, sheet: "Data", rows: "1-2", height: 25, save: "1" });
await run("Excel_Cs_SetWidth", { workbook: filePath, sheet: "Data", columns: "A,B", width: 18, save: "1" });
await run("Excel_Cs_ClearRangeV4", { workbook: filePath, sheet: "Data", excelRng: "B2:B2", save: "1" });
await run("Excel_Cs_MergeCells", { workbook: filePath, sheet: "Data", range: "A4:B4", merge: "0", save: "1" });
await run("Excel_Cs_CopyV2", { workbook: filePath, sheet: "Data", newSheet: "Copy", save: "1" });
await run("Excel_Cs_DeleteRow", { workbook: filePath, sheet: "Copy", row: 2, mode: "single", save: "1" });
await run("Excel_Cs_DeleteColumn", { workbook: filePath, sheet: "Copy", column: "C", mode: "single", save: "1" });
const saved = new ExcelJS.Workbook();
await saved.xlsx.readFile(filePath);
const data = saved.getWorksheet("Data")!;
const copy = saved.getWorksheet("Copy")!;
expect(data.getRow(1).height).toBe(25);
expect(data.getColumn("A").width).toBe(18);
expect(data.getCell("B2").value).toBeNull();
expect(data.getCell("A4").isMerged).toBe(true);
expect(copy.getCell("A2").value).toBe(4);
expect(copy.getCell("C1").value).toBeNull();
});
it("extracts selected pages and returns metadata from real PDF files", async () => {
const directory = await temporaryDirectory();
const sourcePath = path.join(directory, "source.pdf");
const document = await PDFDocument.create();
document.setTitle("RPA Test");
document.setAuthor("Codex");
document.addPage([100, 100]);
document.addPage([200, 200]);
document.addPage([300, 300]);
await writeFile(sourcePath, await document.save());
const output = await run("PDF_CreateNewPdf", { fileInPath: sourcePath, pdfRange: "pages", pdfNum: "1,3", newPdfPath: directory }) as string;
const extracted = await PDFDocument.load(await readFile(output));
expect(extracted.getPageCount()).toBe(2);
expect(extracted.getPage(0).getWidth()).toBe(100);
expect(extracted.getPage(1).getWidth()).toBe(300);
await expect(run("PDF_GetPdfInformation", { fileInPath: sourcePath })).resolves.toMatchObject({
path: sourcePath, fileName: "source.pdf", pageCount: 3, title: "RPA Test", author: "Codex"
});
});
});