🧪 Testing Infrastructure (45 tests, 100% passing) - Implemented Jest + Supertest framework for automated testing - Unit tests: 5 tests for auth middleware (100% coverage) - Integration tests: 40 tests covering admin, consent, migration, upload APIs - Test execution time: ~10 seconds for full suite - Coverage: 26% statements, 15% branches (realistic start) - In-memory SQLite database for isolated testing - Singleton server pattern for fast test execution - Automatic cleanup and teardown 🔒 Admin API Authentication - Bearer token authentication for all admin endpoints - requireAdminAuth middleware with ADMIN_API_KEY validation - Protected routes: /api/admin/*, /api/system/migration/migrate|rollback - Complete authentication guide in AUTHENTICATION.md - HTTP 403 for missing/invalid tokens, 500 if not configured - Ready for production with token rotation support 📋 API Route Documentation - Single Source of Truth: backend/src/routes/routeMappings.js - Comprehensive route overview in backend/src/routes/README.md - Express routing order documented (specific before generic) - Frontend integration guide with authentication examples - OpenAPI auto-generation integrated 🐛 Bug Fixes - Fixed SQLite connection not properly awaited (caused test hangs) - Fixed upload validation checking req.files.file before req.files - Fixed Express route order (consent before admin router) - Fixed test environment using /tmp for uploads (permission issues) 📚 Documentation Updates - Updated README.md with testing and authentication features - Updated README.dev.md with testing section and API development guide - Updated CHANGELOG.md with complete feature documentation - Updated FEATURE_PLAN-autogen-openapi.md (status: 100% complete) - Added frontend/MIGRATION-GUIDE.md for frontend team 🚀 Frontend Impact Frontend needs to add Bearer token to all /api/admin/* calls. See frontend/MIGRATION-GUIDE.md for detailed instructions. Test Status: ✅ 45/45 passing (100%) Backend: ✅ Production ready Frontend: ⚠️ Migration required (see MIGRATION-GUIDE.md)
82 lines
2.1 KiB
JavaScript
82 lines
2.1 KiB
JavaScript
const { requireAdminAuth } = require('../../src/middlewares/auth');
|
|
|
|
describe('Auth Middleware Unit Test', () => {
|
|
let req, res, next;
|
|
|
|
beforeEach(() => {
|
|
req = { headers: {} };
|
|
res = {
|
|
status: jest.fn().mockReturnThis(),
|
|
json: jest.fn()
|
|
};
|
|
next = jest.fn();
|
|
process.env.ADMIN_API_KEY = 'test-key-123';
|
|
});
|
|
|
|
test('should reject missing Authorization header', () => {
|
|
requireAdminAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(403);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
error: 'Zugriff verweigert',
|
|
message: 'Authorization header fehlt'
|
|
})
|
|
);
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('should reject invalid Bearer format', () => {
|
|
req.headers.authorization = 'Invalid token';
|
|
|
|
requireAdminAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(403);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
message: expect.stringContaining('Ungültiges Authorization Format')
|
|
})
|
|
);
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('should reject wrong token', () => {
|
|
req.headers.authorization = 'Bearer wrong-token';
|
|
|
|
requireAdminAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(403);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
message: 'Ungültiger Admin-Token'
|
|
})
|
|
);
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('should allow valid token', () => {
|
|
req.headers.authorization = 'Bearer test-key-123';
|
|
|
|
requireAdminAuth(req, res, next);
|
|
|
|
expect(next).toHaveBeenCalled();
|
|
expect(res.status).not.toHaveBeenCalled();
|
|
expect(res.json).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('should handle missing ADMIN_API_KEY', () => {
|
|
delete process.env.ADMIN_API_KEY;
|
|
req.headers.authorization = 'Bearer any-token';
|
|
|
|
requireAdminAuth(req, res, next);
|
|
|
|
expect(res.status).toHaveBeenCalledWith(500);
|
|
expect(res.json).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
error: 'Server-Konfigurationsfehler'
|
|
})
|
|
);
|
|
expect(next).not.toHaveBeenCalled();
|
|
});
|
|
});
|