import { describe, expect, it } from "vitest"; import { readFileSync } from "node:fs"; import { resolve } from "node:path"; const readAttachmentList = () => readFileSync(resolve(__dirname, "./AttachmentList.vue"), "utf8"); describe("AttachmentList permissions", () => { it("does not require project member list permission to render uploaders", () => { const source = readAttachmentList(); expect(source).not.toContain("listMembers"); }); it("matches the contract-fee attachment table layout", () => { const source = readAttachmentList(); expect(source).toContain('prop="filename" :label="TEXT.common.labels.filename" min-width="360" show-overflow-tooltip'); expect(source).toContain(':label="TEXT.common.labels.size" min-width="180"'); expect(source).toContain(':label="TEXT.common.labels.uploader" min-width="180"'); expect(source).toContain('prop="uploaded_at" :label="TEXT.common.labels.uploadedAt" min-width="180" show-overflow-tooltip'); expect(source).toContain(':label="TEXT.common.labels.actions" min-width="180"'); expect(source).not.toContain('width="160"'); expect(source).toContain('class="attachment-actions"'); expect(source).toContain("flex-wrap: nowrap;"); expect(source).toContain("gap: 4px;"); }); it("can aggregate multiple attachment entity types into one table with an attachment type column", () => { const source = readAttachmentList(); expect(source).toContain("entityGroups?: AttachmentEntityGroup[]"); expect(source).toContain('v-if="hasEntityGroups"'); expect(source).toContain('label="附件类型"'); expect(source).toContain("scope.row.attachment_type_label"); expect(source).toContain("fetchAttachments(props.studyId, group.entityType, props.entityId)"); expect(source).toContain("attachment_type_label: group.label"); expect(source).toContain("attachment_entity_type: group.entityType"); }); it("can reload attachments when the parent refresh key changes", () => { const source = readAttachmentList(); expect(source).toContain("refreshKey?: number"); expect(source).toContain("() => props.refreshKey"); expect(source).toContain("load();"); }); it("can hide the uploader while keeping the attachment table visible", () => { const source = readAttachmentList(); expect(source).toContain("hideUploader?: boolean"); expect(source).toContain("canShowUploader"); expect(source).toContain("!props.hideUploader && canCreate.value"); }); it("hides the default attachment title row when uploader is hidden and no explicit title is provided", () => { const source = readAttachmentList(); expect(source).toContain("const showHeader = computed(() => !!props.title || canShowUploader.value)"); expect(source).toContain('