Skip to content

Commit

Permalink
[TECH] Migration de la route POST /api/memberships/{id}/disable dans …
Browse files Browse the repository at this point in the history
…/src/team

 #11554
  • Loading branch information
pix-service-auto-merge authored Mar 4, 2025
2 parents 4a9cd5c + 413bc2f commit fae6ecb
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 212 deletions.
36 changes: 0 additions & 36 deletions api/lib/application/memberships/index.js

This file was deleted.

2 changes: 0 additions & 2 deletions api/lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as campaignParticipations from './application/campaign-participations/i
import * as certificationCenterMemberships from './application/certification-center-memberships/index.js';
import * as certificationCenters from './application/certification-centers/index.js';
import * as frameworks from './application/frameworks/index.js';
import * as memberships from './application/memberships/index.js';
import * as organizations from './application/organizations/index.js';
import * as scoOrganizationLearners from './application/sco-organization-learners/index.js';
import * as users from './application/users/index.js';
Expand All @@ -15,7 +14,6 @@ const routes = [
certificationCenters,
certificationCenterMemberships,
healthcheck,
memberships,
organizations,
scoOrganizationLearners,
frameworks,
Expand Down
23 changes: 23 additions & 0 deletions api/src/team/application/membership/membership.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ export const membershipRoutes = [
],
},
},
{
method: 'POST',
path: '/api/memberships/{id}/disable',
config: {
pre: [
{
method: (request, h) => securityPreHandlers.checkUserIsAdminInOrganization(request, h),
assign: 'isAdminInOrganization',
},
],
validate: {
params: Joi.object({
id: identifiersType.membershipId,
}),
},
handler: (request, h) => membershipController.disable(request, h),
tags: ['api'],
notes: [
"- **Cette route est restreinte aux utilisateurs authentifiés en tant qu'administrateur de l'organisation\n" +
"- Elle permet la désactivation d'un membre",
],
},
},
{
method: 'GET',
path: '/api/organizations/{id}/memberships',
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -315,4 +315,95 @@ describe('Acceptance | Team | Application | Route | membership', function () {
});
});
});

describe('POST /api/memberships/{id}/disable', function () {
let options;
let membershipId;
let organizationId;

beforeEach(async function () {
organizationId = databaseBuilder.factory.buildOrganization().id;
const userId = databaseBuilder.factory.buildUser().id;
membershipId = databaseBuilder.factory.buildMembership({ organizationId, userId }).id;
const organizationAdminUserId = databaseBuilder.factory.buildUser().id;
databaseBuilder.factory.buildMembership({
userId: organizationAdminUserId,
organizationId,
organizationRole: Membership.roles.ADMIN,
});

await databaseBuilder.commit();

options = {
method: 'POST',
url: `/api/memberships/${membershipId}/disable`,
payload: {
data: {
id: membershipId.toString(),
type: 'memberships',
relationships: {
user: {
data: {
type: 'users',
id: userId,
},
},
organization: {
data: {
type: 'organizations',
id: organizationId,
},
},
},
},
},
headers: generateAuthenticatedUserRequestHeaders({ userId: organizationAdminUserId }),
};
});

context('Success cases', function () {
context('When user is admin of the organization', function () {
it('should return a 204', async function () {
// when
const response = await server.inject(options);

// then
expect(response.statusCode).to.equal(204);
});
});
});

context('Error cases', function () {
it('should respond with a 403 if user does not have the role Admin in organization', async function () {
// given
const notOrganizationAdminUserId = databaseBuilder.factory.buildUser().id;
databaseBuilder.factory.buildMembership({
userId: notOrganizationAdminUserId,
organizationId,
organizationRole: Membership.roles.MEMBER,
});
await databaseBuilder.commit();

options.headers = generateAuthenticatedUserRequestHeaders({ userId: notOrganizationAdminUserId });

// when
const response = await server.inject(options);

// then
expect(response.statusCode).to.equal(403);
});

it('should respond with a 400 if membership does not exist', async function () {
// given
const unknownMembershipId = 9999;
options.url = `/api/memberships/${unknownMembershipId}/disable`;

// when
const response = await server.inject(options);

// then
expect(response.statusCode).to.equal(400);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,42 @@ describe('Unit | Team | Application | Route | Membership', function () {
expect(membershipController.update).to.have.not.been.called;
});
});

describe('POST /api/memberships/{id}/disable', function () {
it('should return 204 if user is admin in organization', async function () {
// given
sinon.stub(securityPreHandlers, 'checkUserIsAdminInOrganization').callsFake((request, h) => h.response(true));
sinon.stub(membershipController, 'disable').callsFake((request, h) => h.response().code(204));

const httpTestServer = new HttpTestServer();
await httpTestServer.register(teamRoutes);
const membershipId = 123;

// when
const response = await httpTestServer.request('POST', `/api/memberships/${membershipId}/disable`);

// then
expect(response.statusCode).to.equal(204);
expect(membershipController.disable).to.have.been.called;
});

it('should return 403 if user is not admin in organization', async function () {
// given
sinon
.stub(securityPreHandlers, 'checkUserIsAdminInOrganization')
.callsFake((request, h) => h.response().code(403).takeover());
sinon.stub(membershipController, 'disable');

const httpTestServer = new HttpTestServer();
await httpTestServer.register(teamRoutes);
const membershipId = 123;

// when
const response = await httpTestServer.request('POST', `/api/memberships/${membershipId}/disable`);

// then
expect(response.statusCode).to.equal(403);
expect(membershipController.disable).to.have.not.been.called;
});
});
});
44 changes: 0 additions & 44 deletions api/tests/unit/application/memberships/index_test.js

This file was deleted.

0 comments on commit fae6ecb

Please sign in to comment.