Files
freeplanet_serverside/src/modules/InvioNotifiche.test.js
2025-11-21 20:47:30 +01:00

542 lines
15 KiB
JavaScript

/**
* TEST UNITARI PER LA CLASSE InvioNotifiche
*
* Framework: Jest
* Installazione: npm install --save-dev jest
* Esecuzione: npm test
*/
const InvioNotifiche = require('./InvioNotifiche');
// Mock dei servizi esterni
const mockEmailService = {
sendMail: jest.fn().mockResolvedValue({ messageId: 'mock-email-id' })
};
const mockTelegramBot = {
sendMessage: jest.fn().mockResolvedValue({ message_id: 123 })
};
const mockLogger = {
info: jest.fn(),
warn: jest.fn(),
error: jest.fn()
};
describe('InvioNotifiche', () => {
let notifiche;
beforeEach(() => {
// Reset dei mock prima di ogni test
jest.clearAllMocks();
// Inizializza classe con mock
notifiche = new InvioNotifiche({
emailService: mockEmailService,
telegramBot: mockTelegramBot,
adminTelegramId: '999999999',
adminEmail: 'paolo@riso.app',
baseUrl: 'https://riso.app',
nomeApp: 'RISO',
emailTemplates: {
verificaEmail: './templates/verifica.pug',
richiestaAmmissione: './templates/ammissione.pug',
benvenuto: './templates/benvenuto.pug',
profiloCompletato: './templates/profilo.pug'
},
logger: mockLogger
});
// Mock del metodo _getInvitante
notifiche._getInvitante = jest.fn().mockResolvedValue({
id: 5,
username: 'invitante',
email: 'invitante@example.com',
name: 'Marco Invitante',
teleg_id: 111111111
});
});
// ============================================
// TEST: notificaRegistrazione
// ============================================
describe('notificaRegistrazione', () => {
test('Invia email di verifica quando verified_email = false', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
verified_email: false,
invitante_id: 5
};
const result = await notifiche.notificaRegistrazione(utente, 'token123');
// Verifica che l'email sia stata inviata
expect(mockEmailService.sendMail).toHaveBeenCalledTimes(2); // utente + admin
expect(result.emailVerificaInviata).toBe(true);
expect(result.success).toBe(true);
// Verifica logging
expect(mockLogger.info).toHaveBeenCalledWith(
expect.stringContaining('Notifica registrazione')
);
});
test('Salta verifica email quando verified_email = true', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
verified_email: true,
invitante_id: 5
};
const result = await notifiche.notificaRegistrazione(utente, null);
// Verifica che NON sia stata inviata email di verifica
expect(result.emailVerificaInviata).toBe(false);
expect(result.success).toBe(true);
// Verifica che sia stata chiamata notificaRichiestaAmmissione
expect(notifiche._getInvitante).toHaveBeenCalledWith(5);
});
test('Gestisce errori correttamente', async () => {
mockEmailService.sendMail.mockRejectedValueOnce(new Error('SMTP Error'));
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
verified_email: false,
invitante_id: 5
};
await expect(
notifiche.notificaRegistrazione(utente, 'token123')
).rejects.toThrow();
expect(mockLogger.error).toHaveBeenCalled();
});
});
// ============================================
// TEST: notificaRichiestaAmmissione
// ============================================
describe('notificaRichiestaAmmissione', () => {
test('Invia notifica email e telegram all\'invitante', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
invitante_id: 5,
created_at: new Date()
};
const result = await notifiche.notificaRichiestaAmmissione(utente);
// Verifica chiamate
expect(notifiche._getInvitante).toHaveBeenCalledWith(5);
expect(mockEmailService.sendMail).toHaveBeenCalled();
expect(mockTelegramBot.sendMessage).toHaveBeenCalled();
expect(result.success).toBe(true);
});
test('Gestisce invitante non trovato', async () => {
notifiche._getInvitante.mockResolvedValueOnce(null);
const utente = {
id: 1,
username: 'mario.rossi',
invitante_id: 999
};
await expect(
notifiche.notificaRichiestaAmmissione(utente)
).rejects.toThrow('Invitante non trovato');
});
test('Invia notifica anche se Telegram fallisce', async () => {
mockTelegramBot.sendMessage.mockRejectedValueOnce(new Error('Telegram Error'));
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
invitante_id: 5,
created_at: new Date()
};
const result = await notifiche.notificaRichiestaAmmissione(utente);
// Email dovrebbe essere comunque inviata
expect(mockEmailService.sendMail).toHaveBeenCalled();
expect(mockLogger.error).toHaveBeenCalledWith(
expect.stringContaining('Errore invio Telegram'),
expect.any(Error)
);
});
});
// ============================================
// TEST: notificaUtenteAmmesso
// ============================================
describe('notificaUtenteAmmesso', () => {
test('Invia email di benvenuto all\'utente', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
teleg_id: 0
};
const result = await notifiche.notificaUtenteAmmesso(utente);
expect(mockEmailService.sendMail).toHaveBeenCalled();
expect(result.success).toBe(true);
// Verifica oggetto email
const emailCall = mockEmailService.sendMail.mock.calls[0][0];
expect(emailCall.subject).toContain('Benvenuto');
});
test('Invia anche Telegram se utente ha teleg_id', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
teleg_id: 123456789
};
await notifiche.notificaUtenteAmmesso(utente);
expect(mockTelegramBot.sendMessage).toHaveBeenCalledWith(
123456789,
expect.stringContaining('Benvenuto'),
expect.any(Object)
);
});
test('Salta Telegram se teleg_id = 0', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
teleg_id: 0
};
await notifiche.notificaUtenteAmmesso(utente);
// Solo email, no Telegram
expect(mockTelegramBot.sendMessage).not.toHaveBeenCalled();
});
});
// ============================================
// TEST: notificaProfiloCompletato
// ============================================
describe('notificaProfiloCompletato', () => {
test('Invia notifica se Telegram è verificato', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
teleg_id: 123456789,
invitante_id: 5
};
const result = await notifiche.notificaProfiloCompletato(utente);
expect(notifiche._getInvitante).toHaveBeenCalledWith(5);
expect(mockEmailService.sendMail).toHaveBeenCalled();
expect(mockTelegramBot.sendMessage).toHaveBeenCalled();
expect(result.success).toBe(true);
});
test('Non invia se Telegram non verificato', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
teleg_id: 0,
invitante_id: 5
};
const result = await notifiche.notificaProfiloCompletato(utente);
expect(result.success).toBe(false);
expect(result.message).toContain('Telegram non ancora verificato');
expect(mockEmailService.sendMail).not.toHaveBeenCalled();
});
});
// ============================================
// TEST: gestisciEvento
// ============================================
describe('gestisciEvento', () => {
test('Gestisce evento REGISTRAZIONE', async () => {
const spy = jest.spyOn(notifiche, 'notificaRegistrazione');
await notifiche.gestisciEvento('REGISTRAZIONE', {
utente: { username: 'test' },
tokenVerifica: 'token123'
});
expect(spy).toHaveBeenCalled();
});
test('Gestisce evento EMAIL_VERIFICATA', async () => {
const spy = jest.spyOn(notifiche, 'notificaRichiestaAmmissione');
await notifiche.gestisciEvento('EMAIL_VERIFICATA', {
utente: { username: 'test', invitante_id: 5 }
});
expect(spy).toHaveBeenCalled();
});
test('Gestisce evento UTENTE_AMMESSO', async () => {
const spy = jest.spyOn(notifiche, 'notificaUtenteAmmesso');
await notifiche.gestisciEvento('UTENTE_AMMESSO', {
utente: { username: 'test' }
});
expect(spy).toHaveBeenCalled();
});
test('Gestisce evento PROFILO_COMPLETATO solo se Telegram verificato', async () => {
const spy = jest.spyOn(notifiche, 'notificaProfiloCompletato');
// Con Telegram verificato
await notifiche.gestisciEvento('PROFILO_COMPLETATO', {
utente: { username: 'test', teleg_id: 123, invitante_id: 5 }
});
expect(spy).toHaveBeenCalled();
spy.mockClear();
// Senza Telegram
const result = await notifiche.gestisciEvento('PROFILO_COMPLETATO', {
utente: { username: 'test', teleg_id: 0 }
});
expect(spy).not.toHaveBeenCalled();
expect(result.success).toBe(false);
});
test('Lancia errore per evento non riconosciuto', async () => {
await expect(
notifiche.gestisciEvento('EVENTO_INESISTENTE', {})
).rejects.toThrow('Evento non riconosciuto');
});
});
// ============================================
// TEST: isProfiloCompleto
// ============================================
describe('isProfiloCompleto', () => {
test('Ritorna true se profilo completo', () => {
const utente = {
name: 'Mario Rossi',
email: 'mario@example.com',
teleg_id: 123456789
};
expect(notifiche.isProfiloCompleto(utente)).toBe(true);
});
test('Ritorna false se manca name', () => {
const utente = {
email: 'mario@example.com',
teleg_id: 123456789
};
expect(notifiche.isProfiloCompleto(utente)).toBe(false);
});
test('Ritorna false se manca email', () => {
const utente = {
name: 'Mario Rossi',
teleg_id: 123456789
};
expect(notifiche.isProfiloCompleto(utente)).toBe(false);
});
test('Ritorna false se Telegram non verificato', () => {
const utente = {
name: 'Mario Rossi',
email: 'mario@example.com',
teleg_id: 0
};
expect(notifiche.isProfiloCompleto(utente)).toBe(false);
});
});
// ============================================
// TEST: Metodi Privati
// ============================================
describe('Metodi privati', () => {
test('_inviaEmail invia email correttamente', async () => {
const result = await notifiche._inviaEmail(
'test@example.com',
'Test Subject',
'<p>Test HTML</p>'
);
expect(result.success).toBe(true);
expect(mockEmailService.sendMail).toHaveBeenCalledWith(
expect.objectContaining({
to: 'test@example.com',
subject: 'Test Subject',
html: '<p>Test HTML</p>'
})
);
});
test('_inviaTelegram invia messaggio correttamente', async () => {
const result = await notifiche._inviaTelegram(
123456789,
'Test message'
);
expect(result.success).toBe(true);
expect(mockTelegramBot.sendMessage).toHaveBeenCalledWith(
123456789,
'Test message',
expect.any(Object)
);
});
test('_inviaTelegram gestisce ID non valido', async () => {
const result = await notifiche._inviaTelegram(0, 'Test');
expect(result.success).toBe(false);
expect(result.error).toContain('non valido');
expect(mockLogger.warn).toHaveBeenCalled();
});
test('_inviaCopiaCopiaAdmin invia a email e telegram admin', async () => {
await notifiche._inviaCopiaCopiaAdmin('Test', 'Message');
expect(mockEmailService.sendMail).toHaveBeenCalledWith(
expect.objectContaining({
to: 'admin@riso.app',
subject: '[ADMIN] Test'
})
);
expect(mockTelegramBot.sendMessage).toHaveBeenCalledWith(
'999999999',
expect.stringContaining('NOTIFICA ADMIN'),
expect.any(Object)
);
});
});
});
// ============================================
// TEST: Integrazione
// ============================================
describe('Test di Integrazione', () => {
let notifiche;
beforeEach(() => {
notifiche = new InvioNotifiche({
emailService: mockEmailService,
telegramBot: mockTelegramBot,
adminTelegramId: '999999999',
adminEmail: 'admin@riso.app',
baseUrl: 'https://riso.app',
nomeApp: 'RISO',
emailTemplates: {},
logger: mockLogger
});
notifiche._getInvitante = jest.fn().mockResolvedValue({
id: 5,
username: 'invitante',
email: 'invitante@example.com',
teleg_id: 111111111
});
});
test('Flusso completo: Registrazione → Verifica → Ammissione → Profilo', async () => {
const utente = {
id: 1,
username: 'mario.rossi',
email: 'mario@example.com',
name: 'Mario Rossi',
verified_email: false,
invitante_id: 5,
teleg_id: 0,
created_at: new Date()
};
// 1. Registrazione
await notifiche.notificaRegistrazione(utente, 'token123');
expect(mockEmailService.sendMail).toHaveBeenCalled();
// 2. Verifica email
utente.verified_email = true;
await notifiche.notificaRichiestaAmmissione(utente);
expect(notifiche._getInvitante).toHaveBeenCalled();
// 3. Ammissione
await notifiche.notificaUtenteAmmesso(utente);
expect(mockEmailService.sendMail).toHaveBeenCalled();
// 4. Profilo completato
utente.teleg_id = 123456789;
await notifiche.notificaProfiloCompletato(utente);
expect(mockTelegramBot.sendMessage).toHaveBeenCalled();
// Verifica che tutte le notifiche admin siano state inviate
const adminCalls = mockEmailService.sendMail.mock.calls.filter(
call => call[0].subject.includes('[ADMIN]')
);
expect(adminCalls.length).toBeGreaterThan(0);
});
});
// Configurazione package.json per Jest
/*
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
"jest": {
"testEnvironment": "node",
"coveragePathIgnorePatterns": ["/node_modules/"],
"testMatch": ["**/__tests__/**/*.js", "**/?(*.)+(spec|test).js"]
}
}
*/