103 lines
4.7 KiB
TypeScript
103 lines
4.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { readFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
const readSource = () => readFileSync(resolve(__dirname, "./DocumentList.vue"), "utf8");
|
|
|
|
describe("DocumentList permissions", () => {
|
|
it("guards create edit and delete actions with document operation permissions", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain('can("documents.create")');
|
|
expect(source).toContain('can("documents.update")');
|
|
expect(source).toContain('can("documents.delete")');
|
|
expect(source).toContain('v-if="canCreate"');
|
|
expect(source).toContain('v-if="canUpdate"');
|
|
expect(source).toContain('v-if="canDelete"');
|
|
expect(source).toContain('@click.stop="openEdit(row)"');
|
|
expect(source).not.toContain(':disabled="!canCreate"');
|
|
});
|
|
|
|
it("uses a drawer for creating documents instead of a dialog", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("<el-drawer");
|
|
expect(source).toContain('class="document-editor-drawer"');
|
|
expect(source).toContain('class="editor-header"');
|
|
expect(source).toContain('class="drawer-footer"');
|
|
expect(source).not.toContain("<el-dialog");
|
|
expect(source).not.toContain('append-to=".layout-main .content-wrapper"');
|
|
});
|
|
|
|
it("guards dirty drawer closes while allowing mask close", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("useDrawerDirtyGuard");
|
|
expect(source).toContain('const editorDirtyGuard = useDrawerDirtyGuard(() => editorForm);');
|
|
expect(source).toContain(':close-on-click-modal="true"');
|
|
expect(source).toContain(':before-close="editorDirtyGuard.beforeClose"');
|
|
expect(source).toContain("editorDirtyGuard.syncBaseline()");
|
|
});
|
|
|
|
it("uses the shared datetime formatter and splits updated-at into two lines", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("displayDateTime");
|
|
expect(source).toContain("splitDateTime(row.updated_at).date");
|
|
expect(source).toContain("splitDateTime(row.updated_at).time");
|
|
expect(source).toContain("const displayValue = displayDateTime(value)");
|
|
expect(source).not.toContain('replace("T", " ").replace("Z", "")');
|
|
});
|
|
|
|
it("keeps desktop document browsing in a master detail workflow", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain("const isDesktop = isTauriRuntime();");
|
|
expect(source).toContain('class="document-workbench"');
|
|
expect(source).toContain('class="document-preview-pane"');
|
|
expect(source).toContain("selectedDocument");
|
|
expect(source).toContain('@row-click="handleDocumentRowClick"');
|
|
expect(source).toContain('@row-dblclick="openDocumentDetail"');
|
|
expect(source).toContain('@keydown.enter.prevent="openSelectedDocument"');
|
|
expect(source).toContain("selectDocument(row);");
|
|
expect(source).toContain("return;");
|
|
expect(source).toContain("goDetail(row.id);");
|
|
expect(source).not.toContain('@row-click="handleRowClick"');
|
|
});
|
|
|
|
it("stretches the desktop document workbench flush to the desktop content edges", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain(":global(.desktop-content:has(> .document-page--desktop))");
|
|
expect(source).toContain("padding: 0;");
|
|
expect(source).toContain(".document-page--desktop {");
|
|
expect(source).toContain("width: 100%;");
|
|
expect(source).toContain("height: 100%;");
|
|
expect(source).toContain("min-height: 100%;");
|
|
expect(source).toContain("margin: 0;");
|
|
expect(source).toContain("overflow-x: hidden;");
|
|
expect(source).toContain("border-radius: 0 !important;");
|
|
expect(source).toContain(".document-page--desktop .main-content-flat");
|
|
expect(source).toContain(".document-page--desktop .document-table-section");
|
|
expect(source).toContain(".document-page--desktop .document-workbench.is-desktop");
|
|
expect(source).toContain(".document-page--desktop .document-table-pane");
|
|
expect(source).toContain("flex: 1 1 auto;");
|
|
expect(source).toContain("min-height: 0;");
|
|
});
|
|
|
|
it("routes desktop document actions through context menu controls", () => {
|
|
const source = readSource();
|
|
|
|
expect(source).toContain('@row-contextmenu="openDocumentContextMenu"');
|
|
expect(source).toContain("documentContextMenu");
|
|
expect(source).toContain('class="document-context-menu"');
|
|
expect(source).not.toContain('class="preview-actions"');
|
|
expect(source).toContain("@click=\"openSelectedDocument\"");
|
|
expect(source).toContain("@click=\"openSelectedDocumentEditor\"");
|
|
expect(source).toContain("@click=\"deleteSelectedDocument\"");
|
|
expect(source).toContain(':disabled="isInactiveSite(selectedDocument.site_id)"');
|
|
expect(source).toContain('v-if="!isDesktop && (canUpdate || canDelete)"');
|
|
expect(source).toContain('"row-selected"');
|
|
});
|
|
});
|