feat: BreakPilot PWA - Full codebase (clean push without large binaries)
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
All services: admin-v2, studio-v2, website, ai-compliance-sdk, consent-service, klausur-service, voice-service, and infrastructure. Large PDFs and compiled binaries excluded via .gitignore.
This commit is contained in:
170
h5p-service/tests/README.md
Normal file
170
h5p-service/tests/README.md
Normal file
@@ -0,0 +1,170 @@
|
||||
# H5P Service Tests
|
||||
|
||||
## Overview
|
||||
|
||||
Dieser Ordner enthält Integration Tests für den BreakPilot H5P Service.
|
||||
|
||||
## Test-Struktur
|
||||
|
||||
```
|
||||
tests/
|
||||
├── README.md # Diese Datei
|
||||
├── setup.js # Jest Test Setup
|
||||
└── server.test.js # Integration Tests für Server Endpoints
|
||||
```
|
||||
|
||||
## Test-Coverage
|
||||
|
||||
Die Tests decken folgende Bereiche ab:
|
||||
|
||||
### 1. Health & Info Endpoints
|
||||
- `GET /` - Service Info Page
|
||||
- `GET /health` - Health Check
|
||||
|
||||
### 2. Editor Selection Page
|
||||
- `GET /h5p/editor/new` - Hauptseite mit allen 8 Content-Typen
|
||||
|
||||
### 3. Content Type Editors (8 Typen)
|
||||
- Quiz Editor
|
||||
- Interactive Video Editor
|
||||
- Course Presentation Editor
|
||||
- Flashcards Editor
|
||||
- Timeline Editor
|
||||
- Drag and Drop Editor
|
||||
- Fill in the Blanks Editor
|
||||
- Memory Game Editor
|
||||
|
||||
### 4. Content Type Players (8 Typen)
|
||||
- Quiz Player
|
||||
- Interactive Video Player
|
||||
- Course Presentation Player
|
||||
- Flashcards Player (coming soon)
|
||||
- Timeline Player
|
||||
- Drag and Drop Player
|
||||
- Fill in the Blanks Player
|
||||
- Memory Game Player
|
||||
|
||||
### 5. Static File Serving
|
||||
- `/h5p/core/*` - H5P Core Files
|
||||
- `/h5p/editors/*` - Editor HTML Files
|
||||
- `/h5p/players/*` - Player HTML Files
|
||||
|
||||
### 6. Error Handling
|
||||
- 404 für nicht existierende Routes
|
||||
- Invalid Editor/Player Routes
|
||||
|
||||
## Tests ausführen
|
||||
|
||||
### Lokale Entwicklung
|
||||
|
||||
```bash
|
||||
# Alle Tests ausführen
|
||||
npm test
|
||||
|
||||
# Tests mit Watch-Mode
|
||||
npm run test:watch
|
||||
|
||||
# Tests für CI/CD
|
||||
npm run test:ci
|
||||
```
|
||||
|
||||
### Docker Container Tests
|
||||
|
||||
```bash
|
||||
# Service starten
|
||||
docker compose -f docker-compose.content.yml up -d h5p-service
|
||||
|
||||
# Tests im Container ausführen
|
||||
docker compose -f docker-compose.content.yml exec h5p-service npm test
|
||||
```
|
||||
|
||||
## Test-Konfiguration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Beschreibung |
|
||||
|----------|---------|--------------|
|
||||
| `H5P_TEST_URL` | `http://localhost:8080` | Base URL für Tests |
|
||||
|
||||
### Jest Konfiguration
|
||||
|
||||
Siehe `jest.config.js` für Details:
|
||||
- Test Timeout: 10000ms
|
||||
- Coverage Reports: text, lcov, html
|
||||
- Test Match: `**/tests/**/*.test.js`
|
||||
|
||||
## Coverage
|
||||
|
||||
Coverage Reports werden generiert in:
|
||||
- `coverage/lcov-report/index.html` (HTML Report)
|
||||
- `coverage/lcov.info` (LCOV Format)
|
||||
- Terminal Output
|
||||
|
||||
Ziel: >80% Coverage
|
||||
|
||||
## Neue Tests hinzufügen
|
||||
|
||||
### Test-Template
|
||||
|
||||
```javascript
|
||||
describe('Feature Name', () => {
|
||||
test('should do something', async () => {
|
||||
const response = await request(BASE_URL).get('/endpoint');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Expected Content');
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Service nicht erreichbar
|
||||
|
||||
```bash
|
||||
# Service Status prüfen
|
||||
docker compose -f docker-compose.content.yml ps
|
||||
|
||||
# Logs ansehen
|
||||
docker compose -f docker-compose.content.yml logs h5p-service
|
||||
|
||||
# Service neu starten
|
||||
docker compose -f docker-compose.content.yml restart h5p-service
|
||||
```
|
||||
|
||||
### Tests schlagen fehl
|
||||
|
||||
1. Prüfe, ob Service läuft: `curl http://localhost:8003/health`
|
||||
2. Prüfe Logs: `docker compose -f docker-compose.content.yml logs h5p-service`
|
||||
3. Rebuilde Container: `docker compose -f docker-compose.content.yml up -d --build h5p-service`
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Isolierte Tests**: Jeder Test sollte unabhängig laufen
|
||||
2. **Cleanup**: Tests sollten keine persistenten Änderungen hinterlassen
|
||||
3. **Assertions**: Klare und aussagekräftige Expectations
|
||||
4. **Beschreibungen**: Aussagekräftige test/describe Namen
|
||||
5. **Speed**: Integration Tests sollten <10s dauern
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
Die Tests werden automatisch ausgeführt bei:
|
||||
- Pull Requests
|
||||
- Commits auf `main` branch
|
||||
- Release Builds
|
||||
|
||||
GitHub Actions Workflow:
|
||||
```yaml
|
||||
- name: Run H5P Service Tests
|
||||
run: |
|
||||
docker compose -f docker-compose.content.yml up -d h5p-service
|
||||
docker compose -f docker-compose.content.yml exec h5p-service npm run test:ci
|
||||
```
|
||||
|
||||
## Zukünftige Erweiterungen
|
||||
|
||||
- [ ] E2E Tests mit Playwright
|
||||
- [ ] Performance Tests
|
||||
- [ ] Content Validation Tests
|
||||
- [ ] Security Tests (XSS, CSRF)
|
||||
- [ ] Load Tests
|
||||
236
h5p-service/tests/server.test.js
Normal file
236
h5p-service/tests/server.test.js
Normal file
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* H5P Service Integration Tests (ESM)
|
||||
* Tests für alle H5P Service Endpoints
|
||||
*/
|
||||
|
||||
import request from 'supertest';
|
||||
import { describe, test, expect } from '@jest/globals';
|
||||
import { app } from '../server-simple.js';
|
||||
|
||||
describe('H5P Service - Health & Info', () => {
|
||||
test('GET / should return service info page', async () => {
|
||||
const response = await request(app).get('/');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('H5P Service');
|
||||
expect(response.text).toContain('Running');
|
||||
});
|
||||
|
||||
test('GET /health should return healthy status', async () => {
|
||||
const response = await request(app).get('/health');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.body).toMatchObject({
|
||||
status: 'healthy',
|
||||
service: 'h5p-service-simplified'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Editor Selection Page', () => {
|
||||
test('GET /h5p/editor/new should return editor selection page', async () => {
|
||||
const response = await request(app).get('/h5p/editor/new');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('H5P Content Creator');
|
||||
expect(response.text).toContain('Quiz');
|
||||
expect(response.text).toContain('Interactive Video');
|
||||
expect(response.text).toContain('Course Presentation');
|
||||
expect(response.text).toContain('Flashcards');
|
||||
expect(response.text).toContain('Timeline');
|
||||
expect(response.text).toContain('Drag and Drop');
|
||||
expect(response.text).toContain('Fill in the Blanks');
|
||||
expect(response.text).toContain('Memory Game');
|
||||
});
|
||||
|
||||
test('Editor page should contain all 8 content types', async () => {
|
||||
const response = await request(app).get('/h5p/editor/new');
|
||||
|
||||
const contentTypes = [
|
||||
'Quiz',
|
||||
'Interactive Video',
|
||||
'Course Presentation',
|
||||
'Flashcards',
|
||||
'Timeline',
|
||||
'Drag and Drop',
|
||||
'Fill in the Blanks',
|
||||
'Memory Game'
|
||||
];
|
||||
|
||||
contentTypes.forEach(type => {
|
||||
expect(response.text).toContain(type);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Quiz Editor & Player', () => {
|
||||
test('GET /h5p/editor/quiz should return quiz editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/quiz');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Quiz Editor');
|
||||
expect(response.text).toContain('Frage hinzufügen');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/quiz should return quiz player', async () => {
|
||||
const response = await request(app).get('/h5p/player/quiz');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Quiz');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Interactive Video Editor & Player', () => {
|
||||
test('GET /h5p/editor/interactive-video should return video editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/interactive-video');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Interactive Video Editor');
|
||||
expect(response.text).toContain('Video-URL');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/interactive-video should return video player', async () => {
|
||||
const response = await request(app).get('/h5p/player/interactive-video');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Interactive Video');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Course Presentation Editor & Player', () => {
|
||||
test('GET /h5p/editor/course-presentation should return presentation editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/course-presentation');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Course Presentation Editor');
|
||||
expect(response.text).toContain('Folien');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/course-presentation should return presentation player', async () => {
|
||||
const response = await request(app).get('/h5p/player/course-presentation');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Course Presentation');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Flashcards Editor', () => {
|
||||
test('GET /h5p/editor/flashcards should return flashcards editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/flashcards');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Flashcards Editor');
|
||||
expect(response.text).toContain('Karte hinzufügen');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Timeline Editor & Player', () => {
|
||||
test('GET /h5p/editor/timeline should return timeline editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/timeline');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Timeline Editor');
|
||||
expect(response.text).toContain('Ereignis');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/timeline should return timeline player', async () => {
|
||||
const response = await request(app).get('/h5p/player/timeline');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Timeline');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Drag and Drop Editor & Player', () => {
|
||||
test('GET /h5p/editor/drag-drop should return drag drop editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/drag-drop');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Drag and Drop Editor');
|
||||
expect(response.text).toContain('Drop Zones');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/drag-drop should return drag drop player', async () => {
|
||||
const response = await request(app).get('/h5p/player/drag-drop');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Drag and Drop');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Fill in the Blanks Editor & Player', () => {
|
||||
test('GET /h5p/editor/fill-blanks should return fill blanks editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/fill-blanks');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Fill in the Blanks Editor');
|
||||
expect(response.text).toContain('Lückentext');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/fill-blanks should return fill blanks player', async () => {
|
||||
const response = await request(app).get('/h5p/player/fill-blanks');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Fill in the Blanks');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Memory Game Editor & Player', () => {
|
||||
test('GET /h5p/editor/memory should return memory editor', async () => {
|
||||
const response = await request(app).get('/h5p/editor/memory');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Memory Game Editor');
|
||||
expect(response.text).toContain('Paar');
|
||||
});
|
||||
|
||||
test('GET /h5p/player/memory should return memory player', async () => {
|
||||
const response = await request(app).get('/h5p/player/memory');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Memory');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Static Files', () => {
|
||||
test('Static core files should be accessible', async () => {
|
||||
const response = await request(app).get('/h5p/core/h5p.css');
|
||||
|
||||
// May or may not exist, but should not 500
|
||||
expect([200, 404]).toContain(response.status);
|
||||
});
|
||||
|
||||
test('Editors directory should be accessible', async () => {
|
||||
const response = await request(app).get('/h5p/editors/quiz-editor.html');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Quiz Editor');
|
||||
});
|
||||
|
||||
test('Players directory should be accessible', async () => {
|
||||
const response = await request(app).get('/h5p/players/quiz-player.html');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.text).toContain('Quiz');
|
||||
});
|
||||
});
|
||||
|
||||
describe('H5P Service - Error Handling', () => {
|
||||
test('GET /nonexistent should return 404', async () => {
|
||||
const response = await request(app).get('/nonexistent');
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
|
||||
test('Invalid editor route should return 404', async () => {
|
||||
const response = await request(app).get('/h5p/editor/nonexistent');
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
|
||||
test('Invalid player route should return 404', async () => {
|
||||
const response = await request(app).get('/h5p/player/nonexistent');
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
});
|
||||
22
h5p-service/tests/setup.js
Normal file
22
h5p-service/tests/setup.js
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Jest Test Setup
|
||||
* Konfiguriert Testumgebung für H5P Service Tests
|
||||
*
|
||||
* Note: Uses global Jest functions to avoid ESM import issues
|
||||
* with setupFilesAfterEnv in some Jest versions.
|
||||
*/
|
||||
|
||||
// Timeout für alle Tests erhöhen (global.jest is available in Jest environment)
|
||||
if (typeof jest !== 'undefined') {
|
||||
jest.setTimeout(10000);
|
||||
}
|
||||
|
||||
// Before all tests
|
||||
beforeAll(() => {
|
||||
console.log('Starting H5P Service Tests...');
|
||||
});
|
||||
|
||||
// After all tests
|
||||
afterAll(() => {
|
||||
console.log('H5P Service Tests Completed');
|
||||
});
|
||||
Reference in New Issue
Block a user