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('匿名字典项'), }), }); }); }); });