542 lines
15 KiB
JavaScript
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"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
*/
|