build / build (push) Successful in 1m31s
在 c93313c 之上增量落地原型与前端规范,保留既有流程图入口/失败提示/指派预览/线级停发:
- 审批/抄送抽屉按原型重构(422→1026 / 239→742 行):科室树+成员多选、SYSTEM/CUSTOM 分支、
CUSTOM 分类导航自动定位、跨节点导航重置、保存后重开回显
- 新增授权管理页 /admin/usage-grants(UsageGrants.vue,417 行):校域清单、按流程线筛选、
授予/撤销后回读,失败不宣称成功
- 路由与 API:新增 usage-grant(schoolList/summary/grant/revoke)、department(groups/options/resolve/members)、
instance/resubmit;TaskHandle 增加「退回待修改」入口(仅 status=50 显示)
- 错误处理沿用 flowError 统一出口,不透出后端原文
- 组件/契约测试:flow-error、flow2-contract、department-roundtrip、task-result
不含构建产物(dist-verify)与依赖目录
28 lines
2.0 KiB
TypeScript
28 lines
2.0 KiB
TypeScript
import { it, expect, vi, afterEach } from 'vitest';
|
|
import { mount, flushPromises, enableAutoUnmount } from '@vue/test-utils';
|
|
import ViewUIPlus from 'view-ui-plus';
|
|
import TaskHandle from '@/views/flow/TaskHandle.vue';
|
|
const { api } = vi.hoisted(() => ({ api: { taskDetail: vi.fn(), approve: vi.fn() } }));
|
|
vi.mock('@/api/module/flow', () => ({ flowApi: api, INSTANCE_STATUS: { 10: '审批中' } }));
|
|
vi.mock('vue-router', () => ({ useRoute: () => ({ params: { taskId: '1' }, path: '/task/1', query: { embed: '1' } }), useRouter: () => ({ push: vi.fn() }) }));
|
|
vi.mock('@/utils/taskEmbed', () => ({ isBareTaskRoute: () => true, postToParent: vi.fn() }));
|
|
enableAutoUnmount(afterEach);
|
|
const detail = { instanceId: 9, status: 10, myPendingTaskIds: [1], trace: [{ taskId: 1, status: 0 }], outlets: [] };
|
|
async function click(text: string) {
|
|
const b = Array.from(document.querySelectorAll('button')).find(x => x.textContent?.trim() === text);
|
|
expect(b).toBeTruthy(); b!.click(); await flushPromises();
|
|
}
|
|
for (const lost of [true, false]) it(lost ? 'POST 丢响应不声称未生效' : 'POST 成功但刷新失败保留成功并关闭办理入口', async () => {
|
|
document.body.innerHTML = '';
|
|
let reads = 0;
|
|
api.taskDetail.mockImplementation(() => ({ send: async () => { if (++reads > 1) throw new Error('refresh failed'); return detail; } }));
|
|
api.approve.mockImplementation(() => ({ send: async () => { if (lost) throw new TypeError('Failed to fetch'); return {}; } }));
|
|
mount(TaskHandle, { global: { plugins: [ViewUIPlus], stubs: { TraceTimeline: true } }, attachTo: document.body });
|
|
await flushPromises(); await click('同意'); await click('确定');
|
|
const text = document.body.textContent || '';
|
|
expect(text).not.toContain('本次办理未生效');
|
|
expect(text).not.toContain('任务仍是你的待办');
|
|
if (lost) expect(text).toContain('结果待确认');
|
|
else { expect(text).toContain('已提交成功'); expect(document.querySelector('.actions')).toBeNull(); }
|
|
});
|