feat(quick-261003-387): Kategorien-API - Anlegen, Sortieren, Zuordnen, Loeschen mit Verschieben, Ueberlagerung in allen Modullisten
- Verwaltungs-Endpunkte nur fuer Administratoren, statische Routen vor :key - Loeschen verschiebt alle Eintraege inkl. persoenlicher eigener Module in einer Transaktion, ohne Ziel 409 - /modules, /modules/catalog und /module-grants/matrix liefern wirksame Kategorie und Reihenfolge - eigene Module pruefen die Kategorie gegen die Organisation (400 bei unbekannter) - Zugriffsinventar nachgezogen Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ForbiddenException, NotFoundException } from '@nestjs/common';
|
||||
import { BadRequestException, ForbiddenException, NotFoundException } from '@nestjs/common';
|
||||
import { Role } from '@prisma/client';
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
@@ -51,9 +51,18 @@ const admin = { id: 'admin1', role: Role.ADMIN };
|
||||
const userA = { id: 'ua', role: Role.USER };
|
||||
const userB = { id: 'ub', role: Role.USER };
|
||||
|
||||
// Kategorien-Dienst (quick-261003-387): die Organisation fuehrt eine feste
|
||||
// Menge von Kennungen; eine andere lehnt assertCategoryKey mit 400 ab.
|
||||
const KNOWN_CATEGORIES = new Set(['fleet', 'infrastructure', 'custom-modules', 'neu-angelegt']);
|
||||
|
||||
function setup() {
|
||||
const prisma = makeFakePrisma();
|
||||
return { prisma, service: new CustomModulesService(prisma as any) };
|
||||
const categories = {
|
||||
assertCategoryKey: vi.fn(async (_tenantId: string, key: string) => {
|
||||
if (!KNOWN_CATEGORIES.has(key)) throw new BadRequestException('Unbekannte Kategorie');
|
||||
}),
|
||||
};
|
||||
return { prisma, categories, service: new CustomModulesService(prisma as any, categories as any) };
|
||||
}
|
||||
|
||||
describe('CustomModulesService — anlegen', () => {
|
||||
@@ -106,6 +115,40 @@ describe('CustomModulesService — anlegen', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('CustomModulesService — Kategorie gegen die Organisation pruefen', () => {
|
||||
it('create: eine vorhandene Kennung (auch eine neu angelegte) ist erlaubt', async () => {
|
||||
const { categories, service } = setup();
|
||||
const res: any = await service.create('t1', userA, { ...dto, category: 'neu-angelegt' });
|
||||
expect(res.category).toBe('neu-angelegt');
|
||||
expect(categories.assertCategoryKey).toHaveBeenCalledWith('t1', 'neu-angelegt');
|
||||
});
|
||||
|
||||
it('create: eine unbekannte Kategorie -> 400, nichts gespeichert', async () => {
|
||||
const { prisma, service } = setup();
|
||||
await expect(
|
||||
service.create('t1', userA, { ...dto, category: 'gibtsnicht' }),
|
||||
).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(prisma.customModule.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('update: eine unbekannte Kategorie -> 400, der Eintrag bleibt unveraendert', async () => {
|
||||
const { prisma, service } = setup();
|
||||
const created: any = await service.create('t1', userA, dto);
|
||||
await expect(
|
||||
service.update('t1', userA, created.id, { category: 'gibtsnicht' }),
|
||||
).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(prisma.customModule.update).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('update ohne Kategorie prueft nichts', async () => {
|
||||
const { categories, service } = setup();
|
||||
const created: any = await service.create('t1', userA, dto);
|
||||
categories.assertCategoryKey.mockClear();
|
||||
await service.update('t1', userA, created.id, { name: 'Neuer Name' });
|
||||
expect(categories.assertCategoryKey).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('CustomModulesService — lesen', () => {
|
||||
it('list liefert gemeinsame plus eigene Eintraege, nie die eines anderen Benutzers', async () => {
|
||||
const { service } = setup();
|
||||
|
||||
Reference in New Issue
Block a user