feat(pendientes): cotizador (mensualidades, bloqueo de unidad, totales, numMensualidades), cobranza (recibos, atrasos, mora configurable, recordatorios), soporte (adjuntos, filtros, estados), clientes maestro (catalogos reales), contactos (ficha y duplicados) y permisos de captura por rol

This commit is contained in:
2026-09-21 08:34:53 +00:00
parent b5a20aed4e
commit 2fc80e7f9e
66 changed files with 3792 additions and 436 deletions

View File

@@ -1,5 +1,6 @@
import { describe, expect, it } from 'vitest'
import { resolverFiltroMios } from './planes.controller.js'
import { describe, expect, it, vi } from 'vitest'
import type { Request, Response } from 'express'
import { ROLES_EDITAN_PLAN, requireEditaPlan, resolverFiltroMios } from './planes.controller.js'
describe('resolverFiltroMios (?mios=1)', () => {
it('sin ?mios=1 no filtra nada', () => {
@@ -20,3 +21,35 @@ describe('resolverFiltroMios (?mios=1)', () => {
expect(resolverFiltroMios('1', undefined)).toBeUndefined()
})
})
const reqCon = (rol?: string): Request =>
({
body: {},
params: { id: 'plan-1' },
...(rol ? { usuarioToken: { sub: 'u-1', username: 'x', rol } } : {}),
}) as unknown as Request
describe('requireEditaPlan (PATCH /planes/:id)', () => {
it('admin, manager, dirección y sus roles legacy pasan', () => {
for (const rol of ROLES_EDITAN_PLAN) {
const next = vi.fn()
requireEditaPlan(reqCon(rol), {} as Response, next)
expect(next).toHaveBeenCalled()
}
expect(ROLES_EDITAN_PLAN).toEqual(
expect.arrayContaining(['admin', 'manager', 'direccion_general', 'director_ventas']),
)
})
it('los roles de cobranza que no son dirección quedan fuera', () => {
for (const rol of ['vendedor', 'administracion_venta', 'escrituracion']) {
expect(() => requireEditaPlan(reqCon(rol), {} as Response, vi.fn())).toThrow(
'Solo admin, manager o dirección pueden modificar el plan',
)
}
})
it('sin token también rechaza (403)', () => {
expect(() => requireEditaPlan(reqCon(), {} as Response, vi.fn())).toThrow()
})
})