import { beforeEach, describe, expect, it, vi } from 'vitest' import type { Request, Response } from 'express' import { cambiarPasswordEndpoint } from './auth.controller.js' import { AppError } from '../utils/errors.js' // ---------- Servicio mockeado (la lógica se prueba en auth.service.test) ---------- const servicioMock = vi.hoisted(() => ({ cambiarPassword: vi.fn() })) vi.mock('../services/auth.service.js', () => ({ cambiarPassword: servicioMock.cambiarPassword, })) function reqFake(overrides: Partial = {}): Request { return { body: { actual: 'Frasa2026', nueva: 'NuevaPass2026' }, usuarioToken: { sub: 'u-1', username: 'asesor uno', rol: 'vendedor' }, ...overrides, } as Request } function resFake() { const json = vi.fn() const end = vi.fn() const status = vi.fn().mockReturnValue({ json, end }) return { res: { json, status } as unknown as Response, status, json, end } } beforeEach(() => { vi.clearAllMocks() }) describe('cambiarPasswordEndpoint', () => { it('204 sin cuerpo cuando el servicio cambia la contraseña', async () => { servicioMock.cambiarPassword.mockResolvedValue(undefined) const { res, status, end } = resFake() await cambiarPasswordEndpoint(reqFake(), res) expect(servicioMock.cambiarPassword).toHaveBeenCalledWith( { sub: 'u-1', username: 'asesor uno', rol: 'vendedor' }, 'Frasa2026', 'NuevaPass2026', ) expect(status).toHaveBeenCalledWith(204) expect(end).toHaveBeenCalled() }) it('sin token verificado: 400', async () => { const { res } = resFake() await expect(cambiarPasswordEndpoint(reqFake({ usuarioToken: undefined }), res)).rejects.toThrow( 'Falta el token verificado', ) expect(servicioMock.cambiarPassword).not.toHaveBeenCalled() }) it('body inválido: ZodError (el error handler lo traduce a 400)', async () => { const { res } = resFake() await expect( cambiarPasswordEndpoint(reqFake({ body: { actual: '' } }), res), ).rejects.toThrow() expect(servicioMock.cambiarPassword).not.toHaveBeenCalled() }) it('propaga el AppError del servicio (actual incorrecta → 400)', async () => { servicioMock.cambiarPassword.mockRejectedValue( new AppError(400, 'La contraseña actual no es correcta'), ) const { res } = resFake() const error = await cambiarPasswordEndpoint(reqFake(), res).catch((e: unknown) => e) expect(error).toMatchObject({ status: 400 }) }) })