Fix scouthub-home-be
This commit is contained in:
@@ -18,6 +18,8 @@ const getUserGroupsInOrganization = jest.fn();
|
||||
const assignRealmRoleToUser = jest.fn();
|
||||
const removeRealmRoleFromUser = jest.fn();
|
||||
const getUserRealmRoles = jest.fn();
|
||||
const addMemberToOrganization = jest.fn();
|
||||
const findUserByEmail = jest.fn();
|
||||
|
||||
jest.mock('../../src/keycloak-admin', () => ({
|
||||
listOrganizationMembers: (...args: unknown[]) => listOrganizationMembers(...args),
|
||||
@@ -28,6 +30,8 @@ jest.mock('../../src/keycloak-admin', () => ({
|
||||
assignRealmRoleToUser: (...args: unknown[]) => assignRealmRoleToUser(...args),
|
||||
removeRealmRoleFromUser: (...args: unknown[]) => removeRealmRoleFromUser(...args),
|
||||
getUserRealmRoles: (...args: unknown[]) => getUserRealmRoles(...args),
|
||||
addMemberToOrganization: (...args: unknown[]) => addMemberToOrganization(...args),
|
||||
findUserByEmail: (...args: unknown[]) => findUserByEmail(...args),
|
||||
}));
|
||||
|
||||
import { app } from '../../src/app';
|
||||
@@ -62,6 +66,14 @@ function nonCapoToken(orgId: string): string {
|
||||
});
|
||||
}
|
||||
|
||||
function adminCentraleToken(): string {
|
||||
return signToken({
|
||||
sub: 'user-admin',
|
||||
email: 'admin@example.com',
|
||||
realm_access: { roles: ['admin'] },
|
||||
});
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
nock(KEYCLOAK_HOST).persist().get(CERTS_PATH).reply(200, {
|
||||
keys: [{ ...jwk, kid: KID, alg: 'RS256', use: 'sig' }],
|
||||
@@ -76,6 +88,68 @@ beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('POST /gruppi/:orgId/membri', () => {
|
||||
test('aggiunge un utente già registrato con successo e risponde 201', async () => {
|
||||
findUserByEmail.mockResolvedValueOnce({ id: 'user-1' });
|
||||
addMemberToOrganization.mockResolvedValueOnce(undefined);
|
||||
assignUserToGroup.mockResolvedValueOnce(undefined);
|
||||
assignRealmRoleToUser.mockResolvedValueOnce(undefined);
|
||||
|
||||
const response = await request(app)
|
||||
.post('/gruppi/org-1/membri')
|
||||
.set('Authorization', `Bearer ${adminCentraleToken()}`)
|
||||
.send({ email: 'gia-registrato@example.com', ruolo: 'Capi' });
|
||||
|
||||
expect(response.status).toBe(201);
|
||||
expect(response.body).toEqual({ userId: 'user-1', email: 'gia-registrato@example.com', ruolo: 'Capi' });
|
||||
|
||||
expect(findUserByEmail).toHaveBeenCalledWith('gia-registrato@example.com');
|
||||
expect(addMemberToOrganization).toHaveBeenCalledWith('org-1', 'user-1');
|
||||
expect(assignUserToGroup).toHaveBeenCalledWith('user-1', 'Capi');
|
||||
expect(assignRealmRoleToUser).toHaveBeenCalledWith('user-1', 'Capi');
|
||||
});
|
||||
|
||||
test("risponde 404 se non esiste un utente registrato con quell'email", async () => {
|
||||
findUserByEmail.mockResolvedValueOnce(null);
|
||||
|
||||
const response = await request(app)
|
||||
.post('/gruppi/org-1/membri')
|
||||
.set('Authorization', `Bearer ${adminCentraleToken()}`)
|
||||
.send({ email: 'sconosciuto@example.com', ruolo: 'Capi' });
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
expect(addMemberToOrganization).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('risponde 502 se una chiamata Keycloak fallisce a metà sequenza', async () => {
|
||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
||||
findUserByEmail.mockResolvedValueOnce({ id: 'user-1' });
|
||||
addMemberToOrganization.mockResolvedValueOnce(undefined);
|
||||
assignUserToGroup.mockRejectedValueOnce(new Error('Keycloak non raggiungibile'));
|
||||
|
||||
const response = await request(app)
|
||||
.post('/gruppi/org-1/membri')
|
||||
.set('Authorization', `Bearer ${adminCentraleToken()}`)
|
||||
.send({ email: 'gia-registrato@example.com', ruolo: 'Capi' });
|
||||
|
||||
expect(response.status).toBe(502);
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith(expect.stringContaining('STEP 2'), expect.anything());
|
||||
expect(assignRealmRoleToUser).not.toHaveBeenCalled();
|
||||
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
test('risponde 403 se chiamato da capo-gruppo, anche sulla propria organizzazione', async () => {
|
||||
const response = await request(app)
|
||||
.post('/gruppi/org-1/membri')
|
||||
.set('Authorization', `Bearer ${capoGruppoToken('org-1')}`)
|
||||
.send({ email: 'gia-registrato@example.com', ruolo: 'Capi' });
|
||||
|
||||
expect(response.status).toBe(403);
|
||||
expect(findUserByEmail).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /gruppi/:orgId/membri', () => {
|
||||
test('restituisce la lista membri con ruolo e gruppo interno', async () => {
|
||||
listOrganizationMembers.mockResolvedValueOnce([
|
||||
@@ -116,6 +190,19 @@ describe('GET /gruppi/:orgId/membri', () => {
|
||||
expect(response.status).toBe(403);
|
||||
expect(listOrganizationMembers).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("admin accede con successo anche a un'organizzazione che non è la propria", async () => {
|
||||
listOrganizationMembers.mockResolvedValueOnce([{ userId: 'user-1', email: 'uno@example.com' }]);
|
||||
getUserGroupsInOrganization.mockResolvedValueOnce([]);
|
||||
getUserRealmRoles.mockResolvedValueOnce([]);
|
||||
|
||||
const response = await request(app)
|
||||
.get('/gruppi/org-altrui/membri')
|
||||
.set('Authorization', `Bearer ${adminCentraleToken()}`);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(listOrganizationMembers).toHaveBeenCalledWith('org-altrui');
|
||||
});
|
||||
});
|
||||
|
||||
describe('PUT /gruppi/:orgId/membri/:userId/ruolo', () => {
|
||||
@@ -173,6 +260,19 @@ describe('PUT /gruppi/:orgId/membri/:userId/ruolo', () => {
|
||||
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
test("admin può cambiare ruolo anche in un'organizzazione che non è la propria", async () => {
|
||||
getUserGroupsInOrganization.mockResolvedValueOnce([]);
|
||||
getUserRealmRoles.mockResolvedValueOnce([]);
|
||||
|
||||
const response = await request(app)
|
||||
.put('/gruppi/org-altrui/membri/user-1/ruolo')
|
||||
.set('Authorization', `Bearer ${adminCentraleToken()}`)
|
||||
.send({ ruolo: 'Aiuto capi' });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(assignUserToGroup).toHaveBeenCalledWith('user-1', 'Aiuto capi');
|
||||
});
|
||||
});
|
||||
|
||||
describe('DELETE /gruppi/:orgId/membri/:userId', () => {
|
||||
@@ -209,4 +309,15 @@ describe('DELETE /gruppi/:orgId/membri/:userId', () => {
|
||||
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
test("admin può rimuovere un membro anche in un'organizzazione che non è la propria", async () => {
|
||||
removeMemberFromOrganization.mockResolvedValueOnce(undefined);
|
||||
|
||||
const response = await request(app)
|
||||
.delete('/gruppi/org-altrui/membri/user-1')
|
||||
.set('Authorization', `Bearer ${adminCentraleToken()}`);
|
||||
|
||||
expect(response.status).toBe(204);
|
||||
expect(removeMemberFromOrganization).toHaveBeenCalledWith('org-altrui', 'user-1');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user