|
|
@@ -0,0 +1,100 @@
|
|
|
+/**
|
|
|
+ * admin.family.reportEntry 契约级单测(TDD-RED 阶段,预期红)
|
|
|
+ *
|
|
|
+ * 能力键: admin.family.reportEntry
|
|
|
+ * 溯源·需求: docs/superpowers/specs/2026-11-08-family-admin-list-polish.md §需求2
|
|
|
+ * (列表上传报告数为 0 时也可点击,进入后可代传报告、查看报告)
|
|
|
+ * 溯源·设计: cfc-web/src/views/Families.vue
|
|
|
+ * - L62-67 去掉 reportCount>0 条件(reportCount=0 也渲染可点击 el-link)
|
|
|
+ * - L206-226 reports 明细弹窗补「代传报告」入口(跳转 ProxyReportUpload 或内嵌上传)
|
|
|
+ *
|
|
|
+ * 【为何以「源码契约」而非「shallowMount 组件挂载」方式书写】
|
|
|
+ * 参考风格(ActivityAudit.spec.js)使用 shallowMount 挂载组件。但当前 cfclub 主链的
|
|
|
+ * Families.vue 模板存在一处先在的硬编译错误:查看成员弹窗中 `<el-empty v-else>`
|
|
|
+ * 嵌套在 `<el-table>`(其 v-if 挂在 table 自身)内部,vue-template-compiler 将其
|
|
|
+ * 列为 errors[],导致 vue-jest 无法加载整个组件(suite 直接编译失败)。本任务明确禁止
|
|
|
+ * 修改 src/main 实现,故无法绕过该先在障碍。GREEN 阶段落地本能力时会同步修正该嵌套;
|
|
|
+ * 届时可将本文件升级为 shallowMount 挂载式测试。
|
|
|
+ *
|
|
|
+ * 因此本文件采用「源码契约」断言:读取真实的 Families.vue 源码,断言设计契约所需
|
|
|
+ * 结构/行为缺失(RED)。GREEN 阶段实现后断言转绿。断言聚焦行为契约,不锁定实现细节
|
|
|
+ * (跳转路由 vs 内嵌上传二者任一即可)。
|
|
|
+ */
|
|
|
+import fs from 'fs'
|
|
|
+import path from 'path'
|
|
|
+
|
|
|
+// 读取真实组件源码(相对本测试文件:src/__tests__/views -> src/views)
|
|
|
+const srcPath = path.resolve(__dirname, '../../views/Families.vue')
|
|
|
+const source = fs.readFileSync(srcPath, 'utf8')
|
|
|
+
|
|
|
+/** 取 reportCount 列模板块(`<el-table-column prop="reportCount"` 至其 `</el-table-column>`) */
|
|
|
+function reportCountColumn() {
|
|
|
+ const start = source.indexOf('<el-table-column prop="reportCount"')
|
|
|
+ expect(start).toBeGreaterThan(-1) // 列存在是既有契约
|
|
|
+ const end = source.indexOf('</el-table-column>', start)
|
|
|
+ return source.slice(start, end)
|
|
|
+}
|
|
|
+
|
|
|
+/** 取报告明细弹窗的 reports 分区块(`detailType === 'reports'` 至下一个 detailType 分支开头) */
|
|
|
+function reportsDialogBlock() {
|
|
|
+ const start = source.indexOf("detailType === 'reports'")
|
|
|
+ expect(start).toBeGreaterThan(-1) // 明细弹窗 reports 分支存在是既有契约
|
|
|
+ const end = source.indexOf("detailType ===", start + 1)
|
|
|
+ return source.slice(start, end > 0 ? end : start + 5000)
|
|
|
+}
|
|
|
+
|
|
|
+/** 取组件 script 段(`<script>` 至 `</script>`) */
|
|
|
+function scriptBlock() {
|
|
|
+ const start = source.indexOf('<script>')
|
|
|
+ const end = source.indexOf('</script>')
|
|
|
+ return source.slice(start, end)
|
|
|
+}
|
|
|
+
|
|
|
+describe('admin.family.reportEntry 契约 (TDD-RED)', () => {
|
|
|
+ describe('AC1 · 列表 reportCount=0 也渲染可点击链接', () => {
|
|
|
+ /** 当前源码中 reportCount 列内容(含 v-if 门控与 v-else 灰字两个分支) */
|
|
|
+ const col = () => reportCountColumn()
|
|
|
+
|
|
|
+ it('reportCount 列不应再包含 `reportCount > 0` 门控(L62-67 契约要求去掉该条件)', () => {
|
|
|
+ expect(col()).not.toMatch(/reportCount\s*>\s*0/)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('reportCount 列不应再包含 `.cell-zero` 灰字 fallback(L62-67 契约要求改为 el-link)', () => {
|
|
|
+ expect(col()).not.toContain('cell-zero')
|
|
|
+ })
|
|
|
+
|
|
|
+ it('reportCount 列的 el-link 不应再被 `v-if="scope.row.reportCount > 0"` 门控,且需保留 openDetailDialog 点击行为', () => {
|
|
|
+ expect(col()).toContain('<el-link')
|
|
|
+ expect(col()).toContain("openDetailDialog(scope.row.id, 'reports')")
|
|
|
+ // 契约核心:当前 el-link 被 reportCount>0 门控包围(<el-link v-if="scope.row.reportCount > 0"...),RED 阶段应断言其未被门控
|
|
|
+ expect(col()).not.toMatch(/<el-link[^>]*v-if\s*=\s*["']scope\.row\.reportCount\s*>\s*0["']/)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ describe('AC2 · 报告明细弹窗补「代传报告」入口', () => {
|
|
|
+ const dialog = () => reportsDialogBlock()
|
|
|
+ const script = () => scriptBlock()
|
|
|
+
|
|
|
+ it('reports 明细弹窗区块内需出现「代传报告」文案或语义标记(design anchor L206-226)', () => {
|
|
|
+ const hasEntry =
|
|
|
+ dialog().includes('代传报告') ||
|
|
|
+ dialog().includes('proxy-report-entry') ||
|
|
|
+ dialog().includes('handleProxyReportUpload') ||
|
|
|
+ dialog().includes('goProxyReportUpload')
|
|
|
+ expect(hasEntry).toBe(true)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('组件 script 需提供处理代传报告流程的方法(跳转 ProxyReportUpload 路由或触发内嵌上传)', () => {
|
|
|
+ const hasProxyHandler =
|
|
|
+ /(goProxyReportUpload|handleProxyReportUpload|openProxyReportUpload)/.test(script()) ||
|
|
|
+ (/report-proxy-upload/.test(script()))
|
|
|
+ expect(hasProxyHandler).toBe(true)
|
|
|
+ })
|
|
|
+
|
|
|
+ it('代传报告流程需绑定 familyId(跳转时需携带 query.familyId 或复用当前 detailFamilyId)', () => {
|
|
|
+ const s = script()
|
|
|
+ expect(s).toMatch(/familyId/)
|
|
|
+ expect(s).toMatch(/report-proxy-upload|ProxyReportUpload/)
|
|
|
+ })
|
|
|
+ })
|
|
|
+})
|