- Integrate TelegramNotificationService into batchUpload route - Send notification on successful upload with group details - Add metadata parsing for year/title/name from form fields - Create integration tests for upload notifications - Fix getAdminUrl() to use INTERNAL_HOST with dev port - Update jest.config.js to transform uuid ESM module - Non-blocking async notification (won't fail upload on error) Phase 3 complete: Upload notifications working in Docker dev environment Tested successfully with real Telegram bot in test group
184 lines
7.4 KiB
JavaScript
184 lines
7.4 KiB
JavaScript
/**
|
|
* Integration Tests für Telegram Upload-Benachrichtigungen
|
|
*
|
|
* Phase 3: Upload-Benachrichtigungen
|
|
*
|
|
* Diese Tests prüfen die Integration zwischen Upload-Route und Telegram-Service
|
|
*/
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const { getRequest } = require('../testServer');
|
|
|
|
describe('Telegram Upload Notifications (Integration)', () => {
|
|
let TelegramNotificationService;
|
|
let sendUploadNotificationSpy;
|
|
|
|
beforeAll(() => {
|
|
// Spy auf TelegramNotificationService
|
|
TelegramNotificationService = require('../../src/services/TelegramNotificationService');
|
|
});
|
|
|
|
beforeEach(() => {
|
|
// Spy auf sendUploadNotification erstellen
|
|
sendUploadNotificationSpy = jest.spyOn(TelegramNotificationService.prototype, 'sendUploadNotification')
|
|
.mockResolvedValue({ message_id: 42 });
|
|
|
|
// isAvailable() immer true zurückgeben für Tests
|
|
jest.spyOn(TelegramNotificationService.prototype, 'isAvailable')
|
|
.mockReturnValue(true);
|
|
});
|
|
|
|
afterEach(() => {
|
|
// Restore alle Spys
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
describe('POST /api/upload/batch', () => {
|
|
const testImagePath = path.join(__dirname, '../utils/test-image.jpg');
|
|
|
|
// Erstelle Test-Bild falls nicht vorhanden
|
|
beforeAll(() => {
|
|
if (!fs.existsSync(testImagePath)) {
|
|
// Erstelle 1x1 px JPEG
|
|
const buffer = Buffer.from([
|
|
0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46,
|
|
0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01,
|
|
0x00, 0x01, 0x00, 0x00, 0xFF, 0xDB, 0x00, 0x43,
|
|
0x00, 0x08, 0x06, 0x06, 0x07, 0x06, 0x05, 0x08,
|
|
0x07, 0x07, 0x07, 0x09, 0x09, 0x08, 0x0A, 0x0C,
|
|
0x14, 0x0D, 0x0C, 0x0B, 0x0B, 0x0C, 0x19, 0x12,
|
|
0x13, 0x0F, 0x14, 0x1D, 0x1A, 0x1F, 0x1E, 0x1D,
|
|
0x1A, 0x1C, 0x1C, 0x20, 0x24, 0x2E, 0x27, 0x20,
|
|
0x22, 0x2C, 0x23, 0x1C, 0x1C, 0x28, 0x37, 0x29,
|
|
0x2C, 0x30, 0x31, 0x34, 0x34, 0x34, 0x1F, 0x27,
|
|
0x39, 0x3D, 0x38, 0x32, 0x3C, 0x2E, 0x33, 0x34,
|
|
0x32, 0xFF, 0xC0, 0x00, 0x0B, 0x08, 0x00, 0x01,
|
|
0x00, 0x01, 0x01, 0x01, 0x11, 0x00, 0xFF, 0xC4,
|
|
0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x03, 0xFF, 0xC4, 0x00, 0x14,
|
|
0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0xFF, 0xDA, 0x00, 0x08, 0x01, 0x01,
|
|
0x00, 0x00, 0x3F, 0x00, 0x37, 0xFF, 0xD9
|
|
]);
|
|
fs.writeFileSync(testImagePath, buffer);
|
|
}
|
|
});
|
|
|
|
it('sollte Telegram-Benachrichtigung bei erfolgreichem Upload senden', async () => {
|
|
const response = await getRequest()
|
|
.post('/api/upload/batch')
|
|
.field('year', '2024')
|
|
.field('title', 'Test Upload')
|
|
.field('name', 'Test User')
|
|
.field('consents', JSON.stringify({
|
|
workshopConsent: true,
|
|
socialMediaConsents: ['instagram', 'tiktok']
|
|
}))
|
|
.attach('images', testImagePath);
|
|
|
|
// Upload sollte erfolgreich sein
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.message).toBe('Batch upload successful');
|
|
|
|
// Warte kurz auf async Telegram-Call
|
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
|
|
// Telegram-Service sollte aufgerufen worden sein
|
|
expect(sendUploadNotificationSpy).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
name: 'Test User',
|
|
year: 2024,
|
|
title: 'Test Upload',
|
|
imageCount: 1,
|
|
workshopConsent: true,
|
|
socialMediaConsents: ['instagram', 'tiktok']
|
|
})
|
|
);
|
|
});
|
|
|
|
it('sollte Upload nicht fehlschlagen wenn Telegram-Service nicht verfügbar', async () => {
|
|
// Restore mock und setze isAvailable auf false
|
|
jest.restoreAllMocks();
|
|
jest.spyOn(TelegramNotificationService.prototype, 'isAvailable')
|
|
.mockReturnValue(false);
|
|
sendUploadNotificationSpy = jest.spyOn(TelegramNotificationService.prototype, 'sendUploadNotification');
|
|
|
|
const response = await getRequest()
|
|
.post('/api/upload/batch')
|
|
.field('year', '2024')
|
|
.field('title', 'Test Upload')
|
|
.field('name', 'Test User')
|
|
.field('consents', JSON.stringify({
|
|
workshopConsent: false,
|
|
socialMediaConsents: []
|
|
}))
|
|
.attach('images', testImagePath);
|
|
|
|
// Upload sollte trotzdem erfolgreich sein
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.message).toBe('Batch upload successful');
|
|
|
|
// Telegram sollte nicht aufgerufen worden sein
|
|
expect(sendUploadNotificationSpy).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('sollte Upload nicht fehlschlagen wenn Telegram-Benachrichtigung fehlschlägt', async () => {
|
|
sendUploadNotificationSpy.mockRejectedValueOnce(
|
|
new Error('Telegram API Error')
|
|
);
|
|
|
|
const response = await getRequest()
|
|
.post('/api/upload/batch')
|
|
.field('year', '2024')
|
|
.field('title', 'Test Upload')
|
|
.field('name', 'Test User')
|
|
.field('consents', JSON.stringify({
|
|
workshopConsent: true,
|
|
socialMediaConsents: []
|
|
}))
|
|
.attach('images', testImagePath);
|
|
|
|
// Upload sollte trotzdem erfolgreich sein
|
|
expect(response.status).toBe(200);
|
|
expect(response.body.message).toBe('Batch upload successful');
|
|
|
|
// Warte auf async error handling
|
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
|
|
// Telegram wurde versucht aufzurufen
|
|
expect(sendUploadNotificationSpy).toHaveBeenCalled();
|
|
});
|
|
|
|
it('sollte korrekte Daten an Telegram-Service übergeben', async () => {
|
|
const response = await getRequest()
|
|
.post('/api/upload/batch')
|
|
.field('year', '2025')
|
|
.field('title', 'Schweißkurs November')
|
|
.field('name', 'Max Mustermann')
|
|
.field('consents', JSON.stringify({
|
|
workshopConsent: true,
|
|
socialMediaConsents: ['facebook', 'instagram']
|
|
}))
|
|
.attach('images', testImagePath)
|
|
.attach('images', testImagePath);
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
|
|
expect(sendUploadNotificationSpy).toHaveBeenCalledWith({
|
|
name: 'Max Mustermann',
|
|
year: 2025,
|
|
title: 'Schweißkurs November',
|
|
imageCount: 2,
|
|
workshopConsent: true,
|
|
socialMediaConsents: ['facebook', 'instagram'],
|
|
token: expect.any(String)
|
|
});
|
|
});
|
|
});
|
|
});
|