format-validation-error.test.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /// <reference types="vite/client" />
  2. import { describe, expect, it } from 'vitest';
  3. import { z } from 'zod';
  4. import type { TFunction } from 'i18next';
  5. import { formatInboundIssue, formatInboundValidation } from '@/pages/inbounds/form/formatValidationError';
  6. const templates: Record<string, string> = {
  7. 'pages.inbounds.toasts.invalidClientField': 'Client {client}: {field} — {reason}',
  8. 'pages.inbounds.toasts.invalidField': '{field} — {reason}',
  9. 'pages.inbounds.toasts.moreIssues': '{message} (+{count} more)',
  10. clients: 'clients',
  11. };
  12. const t = ((key: string, opts?: Record<string, unknown>) => {
  13. let out = templates[key] ?? (opts?.defaultValue as string | undefined) ?? key;
  14. if (opts) {
  15. for (const [k, v] of Object.entries(opts)) {
  16. out = out.split(`{${k}}`).join(String(v));
  17. }
  18. }
  19. return out;
  20. }) as unknown as TFunction;
  21. describe('formatInboundValidation', () => {
  22. it('resolves a real client array index back to the client email', () => {
  23. const schema = z.object({
  24. settings: z.object({
  25. clients: z.array(z.object({ email: z.string(), tgId: z.number() })),
  26. }),
  27. });
  28. const values = {
  29. settings: {
  30. clients: [
  31. { email: '[email protected]', tgId: 1 },
  32. { email: '[email protected]', tgId: 'oops' },
  33. ],
  34. },
  35. };
  36. const parsed = schema.safeParse(values);
  37. expect(parsed.success).toBe(false);
  38. if (parsed.success) return;
  39. expect(formatInboundIssue(parsed.error.issues[0], values, t)).toContain('Client "[email protected]": tgId — ');
  40. });
  41. it('falls back to the index when the client has no email', () => {
  42. const issue = { path: ['settings', 'clients', 7, 'tgId'], message: 'Invalid input' };
  43. const values = { settings: { clients: [] } };
  44. expect(formatInboundIssue(issue, values, t)).toBe('Client #7: tgId — Invalid input');
  45. });
  46. it('formats non-client paths plainly', () => {
  47. const issue = { path: ['port'], message: 'Invalid input' };
  48. expect(formatInboundIssue(issue, {}, t)).toBe('port — Invalid input');
  49. });
  50. it('appends a count when several fields fail', () => {
  51. const issues = [
  52. { path: ['settings', 'clients', 0, 'tgId'], message: 'Invalid input' },
  53. { path: ['port'], message: 'Invalid input' },
  54. ];
  55. const values = { settings: { clients: [{ email: '[email protected]' }] } };
  56. expect(formatInboundValidation(issues, values, t)).toBe('Client "[email protected]": tgId — Invalid input (+1 more)');
  57. });
  58. });