63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
|
|
/**
|
||
|
|
* Phase 7 §14.10 critical mitigation: SMTP/IMAP credential validators.
|
||
|
|
*
|
||
|
|
* Validates the API surface of the sales-config update payload: that
|
||
|
|
* malformed addresses are rejected, that sensible bounds are enforced,
|
||
|
|
* and that the empty-string-means-unchanged convention is preserved by the
|
||
|
|
* validator (the service-layer assumption).
|
||
|
|
*/
|
||
|
|
import { describe, expect, it } from 'vitest';
|
||
|
|
|
||
|
|
import { updateSalesEmailConfigSchema } from '@/lib/validators/sales-email-config';
|
||
|
|
|
||
|
|
describe('updateSalesEmailConfigSchema', () => {
|
||
|
|
it('accepts a fully populated payload', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({
|
||
|
|
fromAddress: 'sales@example.com',
|
||
|
|
smtpHost: 'smtp.example.com',
|
||
|
|
smtpPort: 587,
|
||
|
|
smtpSecure: false,
|
||
|
|
smtpUser: 'sales',
|
||
|
|
smtpPass: 'secret',
|
||
|
|
noreplyFromAddress: 'noreply@example.com',
|
||
|
|
templateBerthPdfBody: 'Hi {{client.fullName}}',
|
||
|
|
templateBrochureBody: 'Hi {{client.fullName}}',
|
||
|
|
brochureMaxUploadMb: 50,
|
||
|
|
emailAttachThresholdMb: 15,
|
||
|
|
});
|
||
|
|
expect(r.success).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts empty-string smtpPass (means "leave unchanged")', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({ smtpPass: '' });
|
||
|
|
expect(r.success).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts explicit null smtpPass (means "clear")', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({ smtpPass: null });
|
||
|
|
expect(r.success).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects malformed from address', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({ fromAddress: 'not-an-email' });
|
||
|
|
expect(r.success).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects out-of-range smtp port', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({ smtpPort: 99999 });
|
||
|
|
expect(r.success).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects unknown auth method', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({ authMethod: 'oauth_apple' });
|
||
|
|
expect(r.success).toBe(false);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('caps body templates at 50KB', () => {
|
||
|
|
const r = updateSalesEmailConfigSchema.safeParse({
|
||
|
|
templateBrochureBody: 'x'.repeat(60_000),
|
||
|
|
});
|
||
|
|
expect(r.success).toBe(false);
|
||
|
|
});
|
||
|
|
});
|