import { BadRequestException } from '@nestjs/common'; import { ClientBatchTaskDto, ClientDeleteResourceDto, ClientDrainageInfoDto, ClientImportConfirmDto } from './client-write.dto'; import { strictValidationPipe } from './strict-validation.pipe'; function validate(metatype: new () => T, value: unknown) { return strictValidationPipe.transform(value, { type: 'body', metatype, data: undefined }); } describe('strict client write DTOs', () => { it('accepts an import confirmation without a client-supplied phones array', async () => { await expect( validate(ClientImportConfirmDto, { content: '【测试】验证码 ${code}', importContent: 'phone,code\n13800000001,1234', }), ).resolves.toEqual(expect.objectContaining({ importContent: expect.any(String) })); }); it('rejects a direct batch task without validated phone numbers', async () => { await expect(validate(ClientBatchTaskDto, { content: '【测试】通知' })).rejects.toBeInstanceOf(BadRequestException); }); it('rejects a client-supplied operator identity', async () => { await expect( validate(ClientDeleteResourceDto, { status: 'deleted', operatorId: 'another-user' }), ).rejects.toBeInstanceOf(BadRequestException); }); it('rejects a client-supplied tenant identity', async () => { await expect( validate(ClientBatchTaskDto, { tenantId: 'other-tenant', content: '【测试】通知', phones: ['13800000001'], }), ).rejects.toBeInstanceOf(BadRequestException); }); it('rejects deeply nested or prototype-like dynamic values', async () => { await expect( validate(ClientBatchTaskDto, { content: '【测试】通知', phones: ['13800000001'], variables: { safe: { nested: { too: { deep: { value: 'x' } } } } }, }), ).rejects.toBeInstanceOf(BadRequestException); }); it.each([ 'https://example.com/path', '13800138000', '+86 138-0013-8000', '0755-12345678', '(010) 12345678-123', ])('accepts a drainage URL or phone number without a separate name: %s', async (url) => { await expect(validate(ClientDrainageInfoDto, { url })).resolves.toEqual(expect.objectContaining({ url })); }); it('rejects arbitrary drainage text that is neither a URL nor a phone number', async () => { await expect(validate(ClientDrainageInfoDto, { url: '品牌官网' })).rejects.toBeInstanceOf(BadRequestException); }); });