- sistemazioni Email : registrazione, invio invito, email di benvenuto
- fix circuito - profilo
This commit is contained in:
541
src/modules/InvioNotifiche.test.js
Normal file
541
src/modules/InvioNotifiche.test.js
Normal file
@@ -0,0 +1,541 @@
|
||||
/**
|
||||
* 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"]
|
||||
}
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user