feat: Phase 6 – Modul-API-Vertrag mit platform-module-sdk
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
roots: ['<rootDir>/src'],
|
||||
roots: ['<rootDir>/src', '<rootDir>/test'],
|
||||
testRegex: '.*\\.spec\\.ts$',
|
||||
moduleFileExtensions: ['ts', 'js', 'json'],
|
||||
collectCoverageFrom: ['src/**/*.ts', '!src/main.ts', '!src/**/*.module.ts'],
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ConfigModule } from '../config/config.module';
|
||||
import { DatabaseModule } from '../database/database.module';
|
||||
import { AuditModule } from '../audit/audit.module';
|
||||
import { SessionService } from '../auth/session.service';
|
||||
import { ModulePermissionRepository } from '../modules/module-permission.repository';
|
||||
import { ModulePermissionsService } from '../modules/module-permissions.service';
|
||||
import { ModuleRepository } from '../modules/module.repository';
|
||||
import { PasswordHasher } from './password-hasher';
|
||||
@@ -25,6 +26,7 @@ import { UsersService } from './users.service';
|
||||
ProfileService,
|
||||
SessionService,
|
||||
ModuleRepository,
|
||||
ModulePermissionRepository,
|
||||
ModulePermissionsService,
|
||||
],
|
||||
exports: [UserRepository, PasswordHasher],
|
||||
|
||||
106
apps/platform-backend/test/platform-module-sdk.spec.ts
Normal file
106
apps/platform-backend/test/platform-module-sdk.spec.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* SDK-Tests (Phase 6): Vertrags-Helper des Modul-SDKs.
|
||||
* Das SDK ist CommonJS und wird direkt mit Node getestet.
|
||||
*/
|
||||
const {
|
||||
GATEWAY_HEADERS,
|
||||
extractIdentity,
|
||||
healthResponse,
|
||||
meResponse,
|
||||
} = require('../../../modules/demo/backend/platform-module-sdk');
|
||||
|
||||
describe('platform-module-sdk', () => {
|
||||
describe('extractIdentity', () => {
|
||||
it('extrahiert die Identität aus korrekten Gateway-Headern', () => {
|
||||
const identity = extractIdentity({
|
||||
[GATEWAY_HEADERS.userId]: 'user-123',
|
||||
[GATEWAY_HEADERS.username]: 'max',
|
||||
[GATEWAY_HEADERS.displayName]: 'Max Mustermann',
|
||||
[GATEWAY_HEADERS.role]: 'USER',
|
||||
});
|
||||
|
||||
expect(identity).toEqual({
|
||||
userId: 'user-123',
|
||||
username: 'max',
|
||||
displayName: 'Max Mustermann',
|
||||
role: 'USER',
|
||||
});
|
||||
});
|
||||
|
||||
it('ist case-insensitive bei Header-Namen', () => {
|
||||
const identity = extractIdentity({
|
||||
'X-User-Id': 'user-123',
|
||||
'X-User-Username': 'max',
|
||||
'X-User-Role': 'ADMIN',
|
||||
});
|
||||
|
||||
expect(identity).not.toBeNull();
|
||||
expect(identity?.role).toBe('ADMIN');
|
||||
});
|
||||
|
||||
it('gibt null zurück, wenn Header fehlen (kein Gateway-Request)', () => {
|
||||
expect(extractIdentity({})).toBeNull();
|
||||
expect(extractIdentity({ 'x-user-id': 'user-123' })).toBeNull();
|
||||
});
|
||||
|
||||
it('gibt null bei ungültiger Rolle zurück', () => {
|
||||
const identity = extractIdentity({
|
||||
[GATEWAY_HEADERS.userId]: 'user-123',
|
||||
[GATEWAY_HEADERS.username]: 'max',
|
||||
[GATEWAY_HEADERS.role]: 'SUPERADMIN',
|
||||
});
|
||||
expect(identity).toBeNull();
|
||||
});
|
||||
|
||||
it('verwendet den Benutzernamen als Fallback für den Anzeigenamen', () => {
|
||||
const identity = extractIdentity({
|
||||
[GATEWAY_HEADERS.userId]: 'user-123',
|
||||
[GATEWAY_HEADERS.username]: 'max',
|
||||
[GATEWAY_HEADERS.role]: 'USER',
|
||||
});
|
||||
expect(identity?.displayName).toBe('max');
|
||||
});
|
||||
});
|
||||
|
||||
describe('healthResponse', () => {
|
||||
it('erzeugt eine vertragskonforme /health-Antwort', () => {
|
||||
expect(healthResponse('demo', '1.0.0')).toEqual({
|
||||
moduleId: 'demo',
|
||||
version: '1.0.0',
|
||||
status: 'healthy',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('meResponse', () => {
|
||||
it('erzeugt eine vertragskonforme /api/me-Antwort', () => {
|
||||
const identity = {
|
||||
userId: 'user-123',
|
||||
username: 'max',
|
||||
displayName: 'Max Mustermann',
|
||||
role: 'USER' as const,
|
||||
};
|
||||
|
||||
expect(meResponse(identity, 'demo', ['demo.read'])).toEqual({
|
||||
user: {
|
||||
id: 'user-123',
|
||||
username: 'max',
|
||||
displayName: 'Max Mustermann',
|
||||
platformRole: 'USER',
|
||||
},
|
||||
module: { id: 'demo' },
|
||||
permissions: ['demo.read'],
|
||||
});
|
||||
});
|
||||
|
||||
it('verwendet leere Permissions als Default', () => {
|
||||
const identity = {
|
||||
userId: 'user-123',
|
||||
username: 'max',
|
||||
displayName: 'Max',
|
||||
role: 'ADMIN' as const,
|
||||
};
|
||||
expect(meResponse(identity, 'demo').permissions).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user