feat(15-05): getWidgets filters via ModuleAccessService (D-22, PERM-07)
- DashboardModule imports ModuleRegistryModule to inject ModuleAccessService - getWidgets(userId, tenantId, role) runs the existing findMany unchanged first, then calls getAccessibleModuleIds exactly once — only if a loaded widget's type is in WIDGET_MODULE_MAP (currently always empty, so no lookup runs today); unresolved module slugs fail closed - DashboardController.getWidgets forwards tenantId + role from the JWT - dashboard.service.spec.ts (8 tests, TDD-GREEN): covers every <behavior> case incl. D-03 ADMIN bypass, adjacency/empty/ordering/idempotency, and fail-closed on an unresolved Module slug - pnpm --filter @tessera/api test: 457/457 green; type-check clean - manual e2e against local API + DB container: empty WIDGET_MODULE_MAP leaves an existing user's widget count unchanged (2/2 clock+search survived the filter), throwaway verification user/rows removed after
This commit is contained in:
@@ -5,9 +5,12 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
* Objektreferenz (`mockMap`) gesteuert: `getModuleSlugForWidgetType`
|
||||
* liest `mockMap` erst zur Aufrufzeit, deshalb genügt eine Mutation vor
|
||||
* jedem Test statt eines dynamischen Imports mit `vi.resetModules()` je
|
||||
* Testfall (vi.mock wird von Vitest ohnehin an den Dateianfang gehoben).
|
||||
* Testfall. `vi.mock` selbst wird von Vitest an den Dateianfang gehoben —
|
||||
* `mockMap` muss deshalb über `vi.hoisted` deklariert werden, sonst
|
||||
* schlägt der Zugriff im Factory-Callback mit einem
|
||||
* Initialisierungsfehler fehl.
|
||||
*/
|
||||
const mockMap: Record<string, string> = {};
|
||||
const mockMap = vi.hoisted(() => ({}) as Record<string, string>);
|
||||
|
||||
vi.mock('./widget-module-map', () => ({
|
||||
WIDGET_MODULE_MAP: mockMap,
|
||||
@@ -125,7 +128,7 @@ describe('DashboardService.getWidgets — Modulfilter (D-22, PERM-07)', () => {
|
||||
|
||||
it('D-03: ein ADMIN sieht ein modulgebundenes Widget eines aktiven Moduls auch ohne eigenen Grant', async () => {
|
||||
mockMap['tender-radar'] = 'tender-radar';
|
||||
const widget = makeWidget({ id: 'w1', widgetType: 'tender-radar' });
|
||||
const widget = makeWidget({ id: 'w1', userId: 'admin-1', widgetType: 'tender-radar' });
|
||||
const prisma = makeFakePrisma({
|
||||
widgets: [widget],
|
||||
modules: [{ id: 'mod-1', slug: 'tender-radar' }],
|
||||
|
||||
Reference in New Issue
Block a user