diff --git a/apps/web/src/app/(portal)/admin/groups/groups-page.test.tsx b/apps/web/src/app/(portal)/admin/groups/groups-page.test.tsx index d78d111..fdea52d 100644 --- a/apps/web/src/app/(portal)/admin/groups/groups-page.test.tsx +++ b/apps/web/src/app/(portal)/admin/groups/groups-page.test.tsx @@ -96,6 +96,7 @@ interface Group { tenantId: string; name: string; ldapDn: string | null; + internalName: string | null; isDefault: boolean; createdAt: string; updatedAt: string; @@ -108,6 +109,7 @@ const mockGroups: Group[] = [ tenantId: 't1', name: 'Alle Benutzer', ldapDn: null, + internalName: null, isDefault: true, createdAt: '2026-01-01T00:00:00.000Z', updatedAt: '2026-01-01T00:00:00.000Z', @@ -118,6 +120,32 @@ const mockGroups: Group[] = [ tenantId: 't1', name: 'Buchhaltung', ldapDn: 'CN=Buchhaltung,OU=Gruppen,DC=ctl,DC=local', + internalName: null, + isDefault: false, + createdAt: '2026-01-01T00:00:00.000Z', + updatedAt: '2026-01-01T00:00:00.000Z', + memberCount: 1, + }, +]; + +const mockGroupsWithInternalName: Group[] = [ + { + id: 'g3', + tenantId: 't1', + name: 'AD-Vertrieb', + ldapDn: 'CN=AD-Vertrieb,OU=Gruppen,DC=ctl,DC=local', + internalName: 'Vertrieb', + isDefault: false, + createdAt: '2026-01-01T00:00:00.000Z', + updatedAt: '2026-01-01T00:00:00.000Z', + memberCount: 2, + }, + { + id: 'g4', + tenantId: 't1', + name: 'AD-Support', + ldapDn: 'CN=AD-Support,OU=Gruppen,DC=ctl,DC=local', + internalName: null, isDefault: false, createdAt: '2026-01-01T00:00:00.000Z', updatedAt: '2026-01-01T00:00:00.000Z', @@ -178,6 +206,35 @@ describe('AdminGroupsPage', () => { expect(screen.getByText('1')).toBeInTheDocument(); }); + it('shows the internal name in the name column and the AD name as title when internalName is set (D-04)', async () => { + vi.stubGlobal( + 'fetch', + vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve(mockGroupsWithInternalName) })), + ); + + render(); + + await waitFor(() => { + expect(screen.getByText('Vertrieb')).toBeInTheDocument(); + }); + expect(screen.queryByText('AD-Vertrieb')).not.toBeInTheDocument(); + expect(screen.getByText('Vertrieb').closest('span')).toHaveAttribute('title', 'AD-Vertrieb'); + }); + + it('falls back to the stored name in the name column when internalName is not set (D-04)', async () => { + vi.stubGlobal( + 'fetch', + vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve(mockGroupsWithInternalName) })), + ); + + render(); + + await waitFor(() => { + expect(screen.getByText('AD-Support')).toBeInTheDocument(); + }); + expect(screen.getByText('AD-Support').closest('span')).toHaveAttribute('title', 'AD-Support'); + }); + it('toggles the default-group star optimistically and persists via PATCH', async () => { const fetchMock = vi.fn((url: string, init?: RequestInit) => { if (typeof url === 'string' && url.endsWith('/groups') && (!init || init.method === undefined)) { diff --git a/apps/web/src/app/(portal)/admin/groups/page.tsx b/apps/web/src/app/(portal)/admin/groups/page.tsx index 572e579..5335e51 100644 --- a/apps/web/src/app/(portal)/admin/groups/page.tsx +++ b/apps/web/src/app/(portal)/admin/groups/page.tsx @@ -177,7 +177,9 @@ export default function AdminGroupsPage() { {groups.map((group) => ( - {group.name} + + {group.internalName ?? group.name} +