tyt-api-nest/test/e2e/specs/dictionaries.e2e-spec.ts
EL 73082225f6 "1. 新增系统字典与全局植入目录相关表结构及迁移
2. 扩展患者手术与材料模型,更新种子数据
3. 新增字典模块,增强设备植入目录管理能力
4. 重构患者后台服务与表单链路,统一权限与参数校验
5. 管理台新增字典页面并改造患者/设备页面与路由权限
6. 补充字典及相关领域 e2e 测试并更新文档"
2026-03-19 20:42:17 +08:00

134 lines
4.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import request from 'supertest';
import { Role } from '../../../src/generated/prisma/enums.js';
import {
closeE2EContext,
createE2EContext,
type E2EContext,
} from '../helpers/e2e-context.helper.js';
import {
expectSuccessEnvelope,
uniqueSeedValue,
} from '../helpers/e2e-http.helper.js';
import { assertRoleMatrix } from '../helpers/e2e-matrix.helper.js';
describe('BDictionariesController (e2e)', () => {
let ctx: E2EContext;
beforeAll(async () => {
ctx = await createE2EContext();
});
afterAll(async () => {
await closeE2EContext(ctx);
});
describe('GET /b/dictionaries', () => {
it('成功DOCTOR 可查询启用中的系统字典', async () => {
const response = await request(ctx.app.getHttpServer())
.get('/b/dictionaries')
.query({ type: 'PRIMARY_DISEASE' })
.set('Authorization', `Bearer ${ctx.tokens[Role.DOCTOR]}`);
expectSuccessEnvelope(response, 200);
expect(
(response.body.data as Array<{ label: string; enabled: boolean }>).some(
(item) => item.label === '先天性脑积水' && item.enabled === true,
),
).toBe(true);
});
});
describe('字典维护流程', () => {
it('成功SYSTEM_ADMIN 可新增、更新、删除字典项,非管理员读取不到停用项', async () => {
const createLabel = uniqueSeedValue('字典项');
const updateLabel = `${createLabel}-启用`;
const createResponse = await request(ctx.app.getHttpServer())
.post('/b/dictionaries')
.set('Authorization', `Bearer ${ctx.tokens[Role.SYSTEM_ADMIN]}`)
.send({
type: 'SHUNT_MODE',
label: createLabel,
sortOrder: 999,
enabled: false,
});
expectSuccessEnvelope(createResponse, 201);
const createdId = createResponse.body.data.id as number;
const doctorReadResponse = await request(ctx.app.getHttpServer())
.get('/b/dictionaries')
.query({ type: 'SHUNT_MODE' })
.set('Authorization', `Bearer ${ctx.tokens[Role.DOCTOR]}`);
expectSuccessEnvelope(doctorReadResponse, 200);
expect(
(doctorReadResponse.body.data as Array<{ label: string }>).some(
(item) => item.label === createLabel,
),
).toBe(false);
const adminReadResponse = await request(ctx.app.getHttpServer())
.get('/b/dictionaries')
.query({ type: 'SHUNT_MODE', includeDisabled: true })
.set('Authorization', `Bearer ${ctx.tokens[Role.SYSTEM_ADMIN]}`);
expectSuccessEnvelope(adminReadResponse, 200);
expect(
(adminReadResponse.body.data as Array<{ label: string }>).some(
(item) => item.label === createLabel,
),
).toBe(true);
const updateResponse = await request(ctx.app.getHttpServer())
.patch(`/b/dictionaries/${createdId}`)
.set('Authorization', `Bearer ${ctx.tokens[Role.SYSTEM_ADMIN]}`)
.send({
label: updateLabel,
enabled: true,
});
expectSuccessEnvelope(updateResponse, 200);
expect(updateResponse.body.data.label).toBe(updateLabel);
expect(updateResponse.body.data.enabled).toBe(true);
const deleteResponse = await request(ctx.app.getHttpServer())
.delete(`/b/dictionaries/${createdId}`)
.set('Authorization', `Bearer ${ctx.tokens[Role.SYSTEM_ADMIN]}`);
expectSuccessEnvelope(deleteResponse, 200);
expect(deleteResponse.body.data.id).toBe(createdId);
});
it('角色矩阵:仅 SYSTEM_ADMIN 可维护字典,其他角色 403未登录 401', async () => {
await assertRoleMatrix({
name: 'POST /b/dictionaries role matrix',
tokens: ctx.tokens,
expectedStatusByRole: {
[Role.SYSTEM_ADMIN]: 201,
[Role.HOSPITAL_ADMIN]: 403,
[Role.DIRECTOR]: 403,
[Role.LEADER]: 403,
[Role.DOCTOR]: 403,
[Role.ENGINEER]: 403,
},
sendAsRole: async (_role, token) =>
request(ctx.app.getHttpServer())
.post('/b/dictionaries')
.set('Authorization', `Bearer ${token}`)
.send({
type: 'DISTAL_SHUNT_DIRECTION',
label: uniqueSeedValue('矩阵字典项'),
}),
sendWithoutToken: async () =>
request(ctx.app.getHttpServer())
.post('/b/dictionaries')
.send({
type: 'DISTAL_SHUNT_DIRECTION',
label: uniqueSeedValue('匿名字典项'),
}),
});
});
});
});