Files
FRASA-CAS/api-gateway/src/services/push.service.test.ts
Consult AS Technology c77b4c0628 feat(mejoras): 14 mejoras al CRM Frasa
Fase 1 - UI: dark mode, skeletons, toasts
Fase 2 - Filtros: avanzados Mi día, búsqueda global Ctrl+K
Fase 3 - Datos: export Excel, notas apartados, auditoría
Fase 4 - Dashboard: gráficas vendedor + métricas uso
Fase 5 - Responsive: tablets optimizadas
Fase 6 - PWA: IndexedDB offline, push notifications

Backend: 3 tablas nuevas, 6 services, 6 endpoints nuevos
721 API tests + fronts verdes.
2026-09-07 06:04:49 +00:00

141 lines
4.4 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
// ---------- Prisma mockeado ----------
const prismaMock = vi.hoisted(() => ({
pushSubscription: {
upsert: vi.fn(),
deleteMany: vi.fn(),
findUnique: vi.fn(),
},
usuario: {
findFirst: vi.fn(),
},
}))
vi.mock('./prisma.js', () => ({ prisma: prismaMock }))
// ---------- web-push mockeado ----------
const webPushMock = vi.hoisted(() => ({
setVapidDetails: vi.fn(),
sendNotification: vi.fn(),
}))
vi.mock('web-push', () => ({ default: webPushMock }))
// ---------- config mockeado ----------
vi.mock('../config/index.js', () => ({
config: {
push: {
vapidPublicKey: 'test-public-key',
vapidPrivateKey: 'test-private-key',
vapidEmail: 'mailto:test@frasa.com',
},
},
}))
import {
registrarSuscripcion,
eliminarSuscripcion,
enviarPush,
usuarioIdPorMondayUserId,
obtenerVapidPublicKey,
} from './push.service.js'
beforeEach(() => {
vi.clearAllMocks()
})
describe('push.service', () => {
describe('registrarSuscripcion', () => {
it('hace upsert con los datos de la suscripción', async () => {
prismaMock.pushSubscription.upsert.mockResolvedValue({})
await registrarSuscripcion('user-1', {
endpoint: 'https://fcm.googleapis.com/fcm/send/abc',
p256dh: 'key123',
auth: 'auth456',
})
expect(prismaMock.pushSubscription.upsert).toHaveBeenCalledWith({
where: { usuarioId: 'user-1' },
update: {
endpoint: 'https://fcm.googleapis.com/fcm/send/abc',
p256dh: 'key123',
auth: 'auth456',
},
create: {
usuarioId: 'user-1',
endpoint: 'https://fcm.googleapis.com/fcm/send/abc',
p256dh: 'key123',
auth: 'auth456',
},
})
})
})
describe('eliminarSuscripcion', () => {
it('elimina todas las suscripciones del usuario', async () => {
prismaMock.pushSubscription.deleteMany.mockResolvedValue({ count: 1 })
await eliminarSuscripcion('user-1')
expect(prismaMock.pushSubscription.deleteMany).toHaveBeenCalledWith({ where: { usuarioId: 'user-1' } })
})
})
describe('enviarPush', () => {
it('envía push si el usuario tiene suscripción', async () => {
prismaMock.pushSubscription.findUnique.mockResolvedValue({
endpoint: 'https://fcm.googleapis.com/fcm/send/abc',
p256dh: 'key123',
auth: 'auth456',
})
webPushMock.sendNotification.mockResolvedValue({ statusCode: 201 })
const result = await enviarPush('user-1', 'Test', 'Cuerpo del mensaje')
expect(result).toBe(true)
expect(webPushMock.sendNotification).toHaveBeenCalledWith(
{ endpoint: 'https://fcm.googleapis.com/fcm/send/abc', keys: { p256dh: 'key123', auth: 'auth456' } },
expect.stringContaining('"titulo":"Test"'),
)
})
it('devuelve false si el usuario no tiene suscripción', async () => {
prismaMock.pushSubscription.findUnique.mockResolvedValue(null)
const result = await enviarPush('user-1', 'Test', 'Cuerpo')
expect(result).toBe(false)
expect(webPushMock.sendNotification).not.toHaveBeenCalled()
})
it('elimina suscripción inválida (404) y devuelve false', async () => {
prismaMock.pushSubscription.findUnique.mockResolvedValue({
endpoint: 'https://expired',
p256dh: 'key',
auth: 'auth',
})
webPushMock.sendNotification.mockRejectedValue({ statusCode: 404 })
prismaMock.pushSubscription.deleteMany.mockResolvedValue({ count: 1 })
const result = await enviarPush('user-1', 'Test', 'Cuerpo')
expect(result).toBe(false)
expect(prismaMock.pushSubscription.deleteMany).toHaveBeenCalledWith({ where: { usuarioId: 'user-1' } })
})
})
describe('usuarioIdPorMondayUserId', () => {
it('devuelve el usuarioId si encuentra el usuario', async () => {
prismaMock.usuario.findFirst.mockResolvedValue({ id: 'local-user-1' })
const result = await usuarioIdPorMondayUserId(12345)
expect(result).toBe('local-user-1')
})
it('devuelve null si no encuentra el usuario', async () => {
prismaMock.usuario.findFirst.mockResolvedValue(null)
const result = await usuarioIdPorMondayUserId(99999)
expect(result).toBeNull()
})
})
describe('obtenerVapidPublicKey', () => {
it('devuelve la VAPID public key del config', () => {
expect(obtenerVapidPublicKey()).toBe('test-public-key')
})
})
})