diff --git a/apps/server-nestjs/src/modules/events/app-events.service.spec.ts b/apps/server-nestjs/src/modules/events/app-events.service.spec.ts index 35fa8759c4..d09c44c09b 100644 --- a/apps/server-nestjs/src/modules/events/app-events.service.spec.ts +++ b/apps/server-nestjs/src/modules/events/app-events.service.spec.ts @@ -175,4 +175,13 @@ describe('appEventsService', () => { data: expect.objectContaining({ args: payload }), })) }) + + describe('emit surface (migration parity)', () => { + const expectedEmitMethods = ['emitProjectEvent', 'emitProjectMemberEvent', 'emitRepositoryEvent'] as const + + it.each(expectedEmitMethods)('exposes %s as a public emit entrypoint', (method) => { + expect(typeof service[method]).toBe('function') + }) + + }) }) diff --git a/apps/server-nestjs/src/modules/keycloak/keycloak.service.spec.ts b/apps/server-nestjs/src/modules/keycloak/keycloak.service.spec.ts index b557a04ccd..c0a82d8dcf 100644 --- a/apps/server-nestjs/src/modules/keycloak/keycloak.service.spec.ts +++ b/apps/server-nestjs/src/modules/keycloak/keycloak.service.spec.ts @@ -526,4 +526,28 @@ describe('keycloakService', () => { expect(keycloak.removeUserFromGroup).toHaveBeenCalledWith('user-2', 'system-managed-id') }) }) + + describe('migration parity: admin-role event path (legacy hook.adminRole.*)', () => { + const adminRoles: AdminRoleWithDetails[] = [ + { id: 'admin-role-1', name: 'admin', permissions: 0n, position: 0, oidcGroup: '/admin-group', type: 'managed' }, + ] + const users: UserWithAdminRoles[] = [ + { id: 'user-1', adminRoleIds: ['admin-role-1'] }, + ] + + it('syncs admin-role OIDC groups via cron reconcile ONLY (no event path exists)', async () => { + datastore.getAllProjects.mockResolvedValue([]) + datastore.getAllAdminRoles.mockResolvedValue(adminRoles) + datastore.getAllUsersWithAdminRoleIds.mockResolvedValue(users) + + const adminGroup = makeGroupRepresentation({ id: 'kc-parity-group-id', name: 'admin', path: '/console/parity-admin' }) + keycloak.getOrCreateGroupByPath.mockResolvedValue(adminGroup) + keycloak.getGroupMembers.mockResolvedValue([]) + + await service.handleCron() + + expect(keycloak.getOrCreateGroupByPath).toHaveBeenCalledWith('/admin-group') + expect(keycloak.addUserToGroup).toHaveBeenCalledWith('user-1', 'kc-parity-group-id') + }) + }) })