Project-Image-Uploader/backend/tests/unit/TelegramNotificationService.test.js
matthias.lotz 025578fa3d feat: Add TelegramNotificationService (Phase 2)
- Create TelegramNotificationService with all notification methods
- Add node-telegram-bot-api dependency
- Integrate service into server.js (auto-test on dev startup)
- Add ENV variables to docker/dev/backend/config/.env
- Create unit tests (10/14 passing - mock issues for 4)
- Update README.dev.md with Telegram testing guide

Service Features:
- sendTestMessage() - Test connection
- sendUploadNotification() - Phase 3 ready
- sendConsentChangeNotification() - Phase 4 ready
- sendGroupDeletedNotification() - Phase 4 ready
- sendDeletionWarning() - Phase 5 ready

Phase 2 complete: Backend service ready for integration.
2025-11-29 22:41:38 +01:00

217 lines
7.3 KiB
JavaScript

/**
* Unit Tests für TelegramNotificationService
*
* Phase 2: Basic Service Tests
*/
const TelegramNotificationService = require('../../src/services/TelegramNotificationService');
// Mock node-telegram-bot-api komplett
jest.mock('node-telegram-bot-api');
describe('TelegramNotificationService', () => {
let originalEnv;
let TelegramBot;
let mockBotInstance;
beforeAll(() => {
TelegramBot = require('node-telegram-bot-api');
});
beforeEach(() => {
// Speichere originale ENV-Variablen
originalEnv = { ...process.env };
// Setze Test-ENV
process.env.TELEGRAM_ENABLED = 'true';
process.env.TELEGRAM_BOT_TOKEN = 'test-bot-token-123';
process.env.TELEGRAM_CHAT_ID = '-1001234567890';
// Erstelle Mock-Bot-Instanz
mockBotInstance = {
sendMessage: jest.fn().mockResolvedValue({
message_id: 42,
chat: { id: -1001234567890 },
text: 'Test'
}),
getMe: jest.fn().mockResolvedValue({
id: 123456,
first_name: 'Test Bot',
username: 'test_bot'
})
};
// Mock TelegramBot constructor
TelegramBot.mockImplementation(() => mockBotInstance);
});
afterEach(() => {
// Restore original ENV
process.env = originalEnv;
});
describe('Initialization', () => {
it('sollte erfolgreich initialisieren wenn TELEGRAM_ENABLED=true', () => {
const service = new TelegramNotificationService();
expect(service.isAvailable()).toBe(true);
expect(TelegramBot).toHaveBeenCalledWith('test-bot-token-123', { polling: false });
});
it('sollte nicht initialisieren wenn TELEGRAM_ENABLED=false', () => {
process.env.TELEGRAM_ENABLED = 'false';
const service = new TelegramNotificationService();
expect(service.isAvailable()).toBe(false);
});
it('sollte fehlschlagen wenn TELEGRAM_BOT_TOKEN fehlt', () => {
delete process.env.TELEGRAM_BOT_TOKEN;
const service = new TelegramNotificationService();
expect(service.isAvailable()).toBe(false);
});
it('sollte fehlschlagen wenn TELEGRAM_CHAT_ID fehlt', () => {
delete process.env.TELEGRAM_CHAT_ID;
const service = new TelegramNotificationService();
expect(service.isAvailable()).toBe(false);
});
});
describe('sendTestMessage', () => {
it('sollte Test-Nachricht erfolgreich senden', async () => {
const service = new TelegramNotificationService();
const result = await service.sendTestMessage();
expect(result).toBeDefined();
expect(result.message_id).toBe(42);
expect(mockBotInstance.sendMessage).toHaveBeenCalledWith(
'-1001234567890',
expect.stringContaining('Telegram Service Test')
);
});
it('sollte null zurückgeben wenn Service nicht verfügbar', async () => {
process.env.TELEGRAM_ENABLED = 'false';
const service = new TelegramNotificationService();
const result = await service.sendTestMessage();
expect(result).toBeNull();
});
it('sollte Fehler werfen bei Telegram-API-Fehler', async () => {
const service = new TelegramNotificationService();
mockBotInstance.sendMessage.mockRejectedValueOnce(new Error('API Error'));
await expect(service.sendTestMessage()).rejects.toThrow('API Error');
});
});
describe('formatSocialMediaIcons', () => {
it('sollte Social Media Plattformen korrekt formatieren', () => {
const service = new TelegramNotificationService();
const result = service.formatSocialMediaIcons(['facebook', 'instagram', 'tiktok']);
expect(result).toBe('📘 Facebook, 📷 Instagram, 🎵 TikTok');
});
it('sollte leeren String bei leerer Liste zurückgeben', () => {
const service = new TelegramNotificationService();
const result = service.formatSocialMediaIcons([]);
expect(result).toBe('');
});
it('sollte case-insensitive sein', () => {
const service = new TelegramNotificationService();
const result = service.formatSocialMediaIcons(['FACEBOOK', 'Instagram', 'TikTok']);
expect(result).toBe('📘 Facebook, 📷 Instagram, 🎵 TikTok');
});
});
describe('getAdminUrl', () => {
it('sollte Admin-URL mit PUBLIC_URL generieren', () => {
process.env.PUBLIC_URL = 'https://test.example.com';
const service = new TelegramNotificationService();
const url = service.getAdminUrl();
expect(url).toBe('https://test.example.com/moderation');
});
it('sollte Default-URL verwenden wenn PUBLIC_URL nicht gesetzt', () => {
delete process.env.PUBLIC_URL;
const service = new TelegramNotificationService();
const url = service.getAdminUrl();
expect(url).toBe('https://internal.hobbyhimmel.de/moderation');
});
});
describe('sendUploadNotification (Phase 3)', () => {
it('sollte Upload-Benachrichtigung mit korrekten Daten senden', async () => {
const service = new TelegramNotificationService();
const groupData = {
name: 'Max Mustermann',
year: 2024,
title: 'Schweißkurs November',
imageCount: 12,
workshopConsent: true,
socialMediaConsents: ['instagram', 'tiktok'],
token: 'test-token-123'
};
await service.sendUploadNotification(groupData);
expect(mockBotInstance.sendMessage).toHaveBeenCalledWith(
'-1001234567890',
expect.stringContaining('📸 Neuer Upload!')
);
expect(mockBotInstance.sendMessage).toHaveBeenCalledWith(
'-1001234567890',
expect.stringContaining('Max Mustermann')
);
expect(mockBotInstance.sendMessage).toHaveBeenCalledWith(
'-1001234567890',
expect.stringContaining('Bilder: 12')
);
});
it('sollte null zurückgeben und nicht werfen bei Fehler', async () => {
const service = new TelegramNotificationService();
mockBotInstance.sendMessage.mockRejectedValueOnce(new Error('Network error'));
const groupData = {
name: 'Test User',
year: 2024,
title: 'Test',
imageCount: 5,
workshopConsent: false,
socialMediaConsents: []
};
const result = await service.sendUploadNotification(groupData);
expect(result).toBeNull();
});
});
});