From aecfb2c7e3cbceee24392a59190210203d94abc7 Mon Sep 17 00:00:00 2001 From: Carlos Narro Date: Sat, 30 May 2026 19:49:09 +0200 Subject: [PATCH] =?UTF-8?q?Add=20validaci=C3=B3n=20y=20slug=20del=20signup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- mvp/b2c/src/lib/validation/signup.ts | 21 +++++++++++++++++++++ mvp/b2c/tests/validation/signup.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 mvp/b2c/src/lib/validation/signup.ts create mode 100644 mvp/b2c/tests/validation/signup.test.ts diff --git a/mvp/b2c/src/lib/validation/signup.ts b/mvp/b2c/src/lib/validation/signup.ts new file mode 100644 index 0000000..c60488b --- /dev/null +++ b/mvp/b2c/src/lib/validation/signup.ts @@ -0,0 +1,21 @@ +import { z } from 'zod'; + +export const signupSchema = z.object({ + nombre: z.string().trim().min(1, 'Indica tu nombre.'), + email: z.string().trim().toLowerCase().email('Email no válido.'), + empresa: z.string().trim().min(1, 'Indica el nombre de tu empresa.'), + provincia: z.string().trim().min(1, 'Indica tu provincia.'), + password: z.string().min(8, 'La contraseña debe tener al menos 8 caracteres.'), + optInMarketing: z.union([z.literal('on'), z.literal('')]).optional(), +}); + +export type SignupInput = z.infer; + +export function slugify(value: string): string { + return value + .normalize('NFD') + .replace(/[̀-ͯ]/g, '') + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/^-+|-+$/g, ''); +} diff --git a/mvp/b2c/tests/validation/signup.test.ts b/mvp/b2c/tests/validation/signup.test.ts new file mode 100644 index 0000000..11480aa --- /dev/null +++ b/mvp/b2c/tests/validation/signup.test.ts @@ -0,0 +1,25 @@ +import { describe, it, expect } from 'vitest'; +import { signupSchema, slugify } from '@/lib/validation/signup'; + +describe('signupSchema', () => { + it('acepta un alta válida y normaliza email a minúsculas', () => { + const r = signupSchema.safeParse({ + nombre: 'Ana', email: 'Ana@X.com', empresa: 'Reformas Ana', + provincia: 'Madrid', password: 'Segura2026', optInMarketing: 'on', + }); + expect(r.success).toBe(true); + if (r.success) expect(r.data.email).toBe('ana@x.com'); + }); + + it('rechaza email inválido y contraseña corta', () => { + expect(signupSchema.safeParse({ + nombre: 'Ana', email: 'no-mail', empresa: 'X', provincia: 'Madrid', password: '123', + }).success).toBe(false); + }); +}); + +describe('slugify', () => { + it('genera slug url-safe sin acentos', () => { + expect(slugify('Reformas Ándalus, S.L.')).toBe('reformas-andalus-s-l'); + }); +});