66 lines
2.5 KiB
TypeScript
66 lines
2.5 KiB
TypeScript
import { BadRequestException } from '@nestjs/common';
|
|
import { ClientBatchTaskDto, ClientDeleteResourceDto, ClientDrainageInfoDto, ClientImportConfirmDto } from './client-write.dto';
|
|
import { strictValidationPipe } from './strict-validation.pipe';
|
|
|
|
function validate<T>(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',
|
|
'example.com/path?source=sms',
|
|
'www.example.com',
|
|
'192.0.2.10:8080/landing',
|
|
'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);
|
|
});
|
|
});
|