169 lines
5.9 KiB
TypeScript
169 lines
5.9 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import { describe, it } from "node:test"
|
|
import { normalizeImportedTables } from "@/lib/drive/docs-table-import"
|
|
import { docsDefaultTableBorder } from "@/lib/drive/docs-table-actions"
|
|
import {
|
|
normalizeTableBorderForExport,
|
|
prepareTablesForDocxExport,
|
|
} from "@/lib/drive/docs-table-export"
|
|
import { buildDocsTableCellStyle, docsTableBorderToCss } from "@/lib/drive/docs-table-styles"
|
|
|
|
describe("docs-table", () => {
|
|
it("converts DOCX border objects to CSS", () => {
|
|
const css = docsTableBorderToCss({ size: 8, style: "single", color: "#000000" })
|
|
assert.equal(css, "1pt solid #000000")
|
|
})
|
|
|
|
it("builds cell style from imported DOCX attrs", () => {
|
|
const style = buildDocsTableCellStyle({
|
|
backgroundColor: "#c9daf8",
|
|
verticalAlign: "middle",
|
|
borderTop: { size: 8, style: "single", color: "#000000" },
|
|
})
|
|
assert.match(style ?? "", /background-color: #c9daf8/)
|
|
assert.match(style ?? "", /vertical-align: middle/)
|
|
assert.match(style ?? "", /border-top: 1pt solid #000000/)
|
|
})
|
|
|
|
it("normalizeTableBorderForExport converts CSS border strings", () => {
|
|
const border = normalizeTableBorderForExport("1pt solid #1a73e8")
|
|
assert.equal(border?.style, "single")
|
|
assert.equal(border?.color, "#1a73e8")
|
|
assert.equal(border?.size, 8)
|
|
})
|
|
|
|
it("prepareTablesForDocxExport normalizes table attrs for export", () => {
|
|
const prepared = prepareTablesForDocxExport({
|
|
type: "doc",
|
|
content: [
|
|
{
|
|
type: "table",
|
|
attrs: { alignment: "center", layout: "fixed" },
|
|
content: [
|
|
{
|
|
type: "tableRow",
|
|
attrs: { rowHeight: "48px" },
|
|
content: [
|
|
{
|
|
type: "tableCell",
|
|
attrs: {
|
|
colwidth: [120],
|
|
backgroundColor: "#c9daf8",
|
|
borderTop: { size: 8, style: "solid", color: "#000000" },
|
|
},
|
|
content: [{ type: "paragraph", content: [{ type: "text", text: "A" }] }],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
})
|
|
|
|
const table = (prepared.content as Array<Record<string, unknown>>)[0]
|
|
const row = (table.content as Array<Record<string, unknown>>)[0]
|
|
const cell = ((row.content as Array<Record<string, unknown>>)[0].attrs ??
|
|
{}) as Record<string, unknown>
|
|
const borderTop = cell.borderTop as { style?: string }
|
|
|
|
assert.equal(borderTop.style, "single")
|
|
assert.deepEqual(cell.colwidth, [120])
|
|
assert.equal(cell.backgroundColor, "#c9daf8")
|
|
})
|
|
|
|
it("docsDefaultTableBorder uses DOCX single style", () => {
|
|
const border = docsDefaultTableBorder("#1a73e8")
|
|
assert.equal(border.size, 8)
|
|
assert.equal(border.style, "single")
|
|
assert.equal(border.color, "#1a73e8")
|
|
})
|
|
|
|
it("DOCX export round-trips table borders and colors", async () => {
|
|
const content = prepareTablesForDocxExport({
|
|
type: "doc",
|
|
content: [
|
|
{
|
|
type: "table",
|
|
attrs: { alignment: "center", layout: "fixed" },
|
|
content: [
|
|
{
|
|
type: "tableRow",
|
|
content: [
|
|
{
|
|
type: "tableHeader",
|
|
attrs: {
|
|
colwidth: [140],
|
|
backgroundColor: "#f3f3f3",
|
|
borderTop: docsDefaultTableBorder("#000000"),
|
|
borderBottom: docsDefaultTableBorder("#000000"),
|
|
borderLeft: docsDefaultTableBorder("#000000"),
|
|
borderRight: docsDefaultTableBorder("#000000"),
|
|
},
|
|
content: [{ type: "paragraph", content: [{ type: "text", text: "Titre" }] }],
|
|
},
|
|
{
|
|
type: "tableCell",
|
|
attrs: {
|
|
colwidth: [180],
|
|
backgroundColor: "#c9daf8",
|
|
verticalAlign: "middle",
|
|
},
|
|
content: [{ type: "paragraph", content: [{ type: "text", text: "Cellule" }] }],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
})
|
|
|
|
const { generateDOCX } = await import("@docen/export-docx")
|
|
const blob = await generateDOCX(content, { outputType: "blob" })
|
|
assert.ok(blob instanceof Blob)
|
|
|
|
const { parseDOCX } = await import("@docen/import-docx")
|
|
const imported = await parseDOCX(await blob.arrayBuffer())
|
|
const table = ((imported as { content?: unknown[] }).content ?? [])[0] as {
|
|
type?: string
|
|
attrs?: { alignment?: string }
|
|
content?: Array<{ content?: Array<{ type?: string; attrs?: Record<string, unknown> }> }>
|
|
}
|
|
|
|
assert.equal(table.type, "table")
|
|
assert.equal(table.attrs?.alignment, "center")
|
|
|
|
const cells = table.content?.[0]?.content ?? []
|
|
assert.equal(cells[0]?.type, "tableHeader")
|
|
assert.equal(cells[0]?.attrs?.backgroundColor, "#f3f3f3")
|
|
assert.ok(cells[0]?.attrs?.borderTop)
|
|
assert.equal(cells[1]?.attrs?.backgroundColor, "#c9daf8")
|
|
assert.equal(cells[1]?.attrs?.verticalAlign, "middle")
|
|
})
|
|
|
|
it("normalizeImportedTables drops rowspan 0 placeholder cells", () => {
|
|
const normalized = normalizeImportedTables({
|
|
type: "doc",
|
|
content: [
|
|
{
|
|
type: "table",
|
|
content: [
|
|
{
|
|
type: "tableRow",
|
|
content: [
|
|
{ type: "tableCell", attrs: { rowspan: 2 }, content: [{ type: "paragraph" }] },
|
|
{ type: "tableCell", attrs: { rowspan: 0 }, content: [{ type: "paragraph" }] },
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
})
|
|
|
|
const table = (normalized.content as Array<Record<string, unknown>>)[0]
|
|
const row = ((table.content as Array<Record<string, unknown>>)[0].content ??
|
|
[]) as Array<Record<string, unknown>>
|
|
assert.equal(row.length, 1)
|
|
assert.equal((row[0].attrs as { rowspan?: number }).rowspan, 2)
|
|
})
|
|
})
|