Skip to content

Commit

Permalink
[TECH] Migration de la route /api/admin/users/{id}/organizations (PIX…
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Feb 3, 2025
2 parents 87eba47 + 5497a45 commit b97cdcd
Show file tree
Hide file tree
Showing 16 changed files with 131 additions and 135 deletions.
28 changes: 0 additions & 28 deletions api/lib/application/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,6 @@ import { userController } from './user-controller.js';

const register = async function (server) {
const adminRoutes = [
{
method: 'GET',
path: '/api/admin/users/{id}/organizations',
config: {
pre: [
{
method: (request, h) =>
securityPreHandlers.hasAtLeastOneAccessOf([
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
securityPreHandlers.checkAdminMemberHasRoleCertif,
securityPreHandlers.checkAdminMemberHasRoleSupport,
securityPreHandlers.checkAdminMemberHasRoleMetier,
])(request, h),
},
],
validate: {
params: Joi.object({
id: identifiersType.userId,
}),
},
handler: userController.findUserOrganizationsForAdmin,
notes: [
"- **Cette route est restreinte aux utilisateurs authentifiés ayant les droits d'accès**\n" +
'- Elle permet à un administrateur de lister les organisations auxquelles appartient l´utilisateur',
],
tags: ['api', 'admin', 'user', 'organizations'],
},
},
{
method: 'GET',
path: '/api/admin/users/{id}/certification-center-memberships',
Expand Down
14 changes: 0 additions & 14 deletions api/lib/application/users/user-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as trainingSerializer from '../../../src/devcomp/infrastructure/seriali
import * as certificationCenterMembershipSerializer from '../../../src/shared/infrastructure/serializers/jsonapi/certification-center-membership.serializer.js';
import * as requestResponseUtils from '../../../src/shared/infrastructure/utils/request-response-utils.js';
import { usecases } from '../../domain/usecases/index.js';
import * as userOrganizationForAdminSerializer from '../../infrastructure/serializers/jsonapi/user-organization-for-admin-serializer.js';

const findPaginatedUserRecommendedTrainings = async function (
request,
Expand All @@ -25,18 +24,6 @@ const findPaginatedUserRecommendedTrainings = async function (
return dependencies.trainingSerializer.serialize(userRecommendedTrainings, meta);
};

const findUserOrganizationsForAdmin = async function (
request,
h,
dependencies = { userOrganizationForAdminSerializer },
) {
const userId = request.params.id;
const organizations = await usecases.findUserOrganizationsForAdmin({
userId,
});
return h.response(dependencies.userOrganizationForAdminSerializer.serialize(organizations));
};

const findCertificationCenterMembershipsByUser = async function (
request,
h,
Expand All @@ -54,7 +41,6 @@ const findCertificationCenterMembershipsByUser = async function (
const userController = {
findCertificationCenterMembershipsByUser,
findPaginatedUserRecommendedTrainings,
findUserOrganizationsForAdmin,
};

export { userController };
2 changes: 0 additions & 2 deletions api/lib/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ import * as targetProfileTrainingRepository from '../../infrastructure/repositor
import * as thematicRepository from '../../infrastructure/repositories/thematic-repository.js';
// Not used in lib
import * as stageCollectionRepository from '../../infrastructure/repositories/user-campaign-results/stage-collection-repository.js';
import * as userOrganizationsForAdminRepository from '../../infrastructure/repositories/user-organizations-for-admin-repository.js';
import * as learningContentConversionService from '../services/learning-content/learning-content-conversion-service.js';
import * as userReconciliationService from '../services/user-reconciliation-service.js';
import * as organizationCreationValidator from '../validators/organization-creation-validator.js';
Expand Down Expand Up @@ -336,7 +335,6 @@ const dependencies = {
userAnonymizedEventLoggingJobRepository,
userEmailRepository,
userLoginRepository,
userOrganizationsForAdminRepository,
userOrgaSettingsRepository,
userRecommendedTrainingRepository: repositories.userRecommendedTrainingRepository,
userReconciliationService,
Expand Down
17 changes: 14 additions & 3 deletions api/src/team/application/membership/membership.admin.controller.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as membershipSerializer from '../../../shared/infrastructure/serializers/jsonapi/membership.serializer.js';
import { usecases } from '../../domain/usecases/index.js';
import * as userOrganizationForAdminSerializer from '../../infrastructure/serializers/jsonapi/user-organization-for-admin-serializer.js';

const findPaginatedFilteredMembershipsForAdmin = async function (request) {
const organizationId = request.params.id;
Expand All @@ -13,8 +14,18 @@ const findPaginatedFilteredMembershipsForAdmin = async function (request) {
return membershipSerializer.serializeForAdmin(memberships, pagination);
};

const membershipAdminController = {
findPaginatedFilteredMembershipsForAdmin,
const findUserOrganizationsForAdmin = async function (
request,
h,
dependencies = { userOrganizationForAdminSerializer },
) {
const userId = request.params.id;
const organizations = await usecases.findUserOrganizationsForAdmin({ userId });

return h.response(dependencies.userOrganizationForAdminSerializer.serialize(organizations));
};

export { membershipAdminController };
export const membershipAdminController = {
findPaginatedFilteredMembershipsForAdmin,
findUserOrganizationsForAdmin,
};
28 changes: 28 additions & 0 deletions api/src/team/application/membership/membership.admin.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,34 @@ import { membershipAdminController } from './membership.admin.controller.js';
import { membershipController } from './membership.controller.js';

export const membershipAdminRoutes = [
{
method: 'GET',
path: '/api/admin/users/{id}/organizations',
config: {
pre: [
{
method: (request, h) =>
securityPreHandlers.hasAtLeastOneAccessOf([
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
securityPreHandlers.checkAdminMemberHasRoleCertif,
securityPreHandlers.checkAdminMemberHasRoleSupport,
securityPreHandlers.checkAdminMemberHasRoleMetier,
])(request, h),
},
],
validate: {
params: Joi.object({
id: identifiersType.userId,
}),
},
handler: membershipAdminController.findUserOrganizationsForAdmin,
notes: [
"- **Cette route est restreinte aux utilisateurs authentifiés ayant les droits d'accès**\n" +
'- Elle permet à un administrateur de lister les organisations auxquelles appartient l´utilisateur',
],
tags: ['api', 'admin', 'user', 'organizations'],
},
},
{
method: 'POST',
path: '/api/admin/memberships',
Expand Down
2 changes: 2 additions & 0 deletions api/src/team/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as membershipRepository from '../../infrastructure/repositories/members
import { organizationInvitationRepository } from '../../infrastructure/repositories/organization-invitation.repository.js';
import { organizationInvitedUserRepository } from '../../infrastructure/repositories/organization-invited-user.repository.js';
import { userOrgaSettingsRepository } from '../../infrastructure/repositories/user-orga-settings-repository.js';
import { userOrganizationsForAdminRepository } from '../../infrastructure/repositories/user-organizations-for-admin.repository.js';
import * as certificationCenterInvitationService from '../services/certification-center-invitation-service.js';
import { organizationInvitationService } from '../services/organization-invitation.service.js';

Expand All @@ -40,6 +41,7 @@ const dependencies = {
organizationRepository,
refreshTokenRepository,
sharedMembershipRepository,
userOrganizationsForAdminRepository,
userRepository,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { knex } from '../../../db/knex-database-connection.js';
import { UserOrganizationForAdmin } from '../../../src/shared/domain/read-models/UserOrganizationForAdmin.js';
import { knex } from '../../../../db/knex-database-connection.js';
import { UserOrganizationForAdmin } from '../../../shared/domain/read-models/UserOrganizationForAdmin.js';

const findByUserId = async function (userId) {
const organizations = await knex('memberships')
Expand All @@ -18,4 +18,4 @@ const findByUserId = async function (userId) {
return organizations.map((attributes) => new UserOrganizationForAdmin(attributes));
};

export { findByUserId };
export const userOrganizationsForAdminRepository = { findByUserId };

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,40 @@ describe('Acceptance | Team | Admin | Route | membership', function () {
server = await createServer();
});

describe('GET /api/admin/users/{id}/organizations', function () {
it('returns 200 HTTP status code', async function () {
// given
const server = await createServer();
const userId = databaseBuilder.factory.buildUser().id;

const organization1 = databaseBuilder.factory.buildOrganization({
name: 'Organization 1',
});

databaseBuilder.factory.buildMembership({
organizationId: organization1.id,
userId,
organizationRole: 'MEMBER',
});

const admin = databaseBuilder.factory.buildUser.withRole();

await databaseBuilder.commit();

const options = {
method: 'GET',
url: `/api/admin/users/${userId}/organizations`,
headers: generateAuthenticatedUserRequestHeaders({ userId: admin.id }),
};

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

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

describe('POST /api/admin/memberships', function () {
let options;
let userId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as userOrganizationsForAdminRepository from '../../../../lib/infrastructure/repositories/user-organizations-for-admin-repository.js';
import { UserOrganizationForAdmin } from '../../../../src/shared/domain/read-models/UserOrganizationForAdmin.js';
import { databaseBuilder, expect } from '../../../test-helper.js';
import { UserOrganizationForAdmin } from '../../../../../src/shared/domain/read-models/UserOrganizationForAdmin.js';
import { userOrganizationsForAdminRepository } from '../../../../../src/team/infrastructure/repositories/user-organizations-for-admin.repository.js';
import { databaseBuilder, expect } from '../../../../test-helper.js';

describe('Integration | Repository | user-organizations-for-admin', function () {
describe('Integration | Team | Infrastructure | Repository | user-organizations-for-admin', function () {
context('#findByUserId', function () {
context('When user doesn’t exist', function () {
it('should return an empty list', async function () {
it('returns an empty list', async function () {
// given
const userId = databaseBuilder.factory.buildUser({ id: 1 }).id;

Expand All @@ -30,7 +30,7 @@ describe('Integration | Repository | user-organizations-for-admin', function ()
});

context('When user isn’t member of any organization', function () {
it('should return an empty list', async function () {
it('returns an empty list', async function () {
// given
const userId = databaseBuilder.factory.buildUser({ id: 1 }).id;

Expand All @@ -56,7 +56,7 @@ describe('Integration | Repository | user-organizations-for-admin', function ()
});

context('When user is member of some organizations', function () {
it('should return a list with the organizations the user is member of', async function () {
it('returns a list with the organizations the user is member of', async function () {
// given
const user = databaseBuilder.factory.buildUser({ firstName: 'Otto', lastName: 'KARR' });
const anotherUser = databaseBuilder.factory.buildUser({ firstName: 'Corinne', lastName: 'TITEGOUTTE' });
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { UserOrganizationForAdmin } from '../../../../../src/shared/domain/read-models/UserOrganizationForAdmin.js';
import { membershipAdminController } from '../../../../../src/team/application/membership/membership.admin.controller.js';
import { usecases } from '../../../../../src/team/domain/usecases/index.js';
import { expect, hFake, sinon } from '../../../../test-helper.js';

describe('Unit | Team | Application | Controller | Membership Admin', function () {
describe('#findUserOrganizationsForAdmin', function () {
it('returns user’s organization memberships', async function () {
// given
const organizationMemberships = [new UserOrganizationForAdmin()];
const organizationMembershipsSerialized = Symbol('an array of user’s organization memberships serialized');

const userOrganizationForAdminSerializer = { serialize: sinon.stub() };
userOrganizationForAdminSerializer.serialize
.withArgs(organizationMemberships)
.returns(organizationMembershipsSerialized);

sinon.stub(usecases, 'findUserOrganizationsForAdmin').resolves(organizationMemberships);

// when
const request = {
params: {
id: 1,
},
};
await membershipAdminController.findUserOrganizationsForAdmin(request, hFake, {
userOrganizationForAdminSerializer,
});

// then
expect(usecases.findUserOrganizationsForAdmin).to.have.been.calledWithExactly({ userId: 1 });
});
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { findUserOrganizationsForAdmin } from '../../../../lib/domain/usecases/find-user-organizations-for-admin.js';
import { expect, sinon } from '../../../test-helper.js';
import { findUserOrganizationsForAdmin } from '../../../../../src/team/domain/usecases/find-user-organizations-for-admin.usecase.js';
import { expect, sinon } from '../../../../test-helper.js';

describe('Unit | UseCase | findUserOrganizationsForAdmin', function () {
it('should fetch user’s organization memberships', async function () {
describe('Unit | Team | Domain | UseCase | findUserOrganizationsForAdmin', function () {
it('fetches user’s organization memberships', async function () {
const userId = 1;

const userOrganizationsForAdminRepository = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as serializer from '../../../../../lib/infrastructure/serializers/jsonapi/user-organization-for-admin-serializer.js';
import { UserOrganizationForAdmin } from '../../../../../src/shared/domain/read-models/UserOrganizationForAdmin.js';
import { expect } from '../../../../test-helper.js';
import { UserOrganizationForAdmin } from '../../../../../../src/shared/domain/read-models/UserOrganizationForAdmin.js';
import * as serializer from '../../../../../../src/team/infrastructure/serializers/jsonapi/user-organization-for-admin-serializer.js';
import { expect } from '../../../../../test-helper.js';

describe('Unit | Serializer | JSONAPI | user-organization-for-admin-serializer', function () {
describe('Unit | Team | Serializer | JSONAPI | user-organization-for-admin-serializer', function () {
describe('#serialize', function () {
it('should serialize a user’s organization memberships', function () {
it('serializes a user’s organization memberships', function () {
// given
const userOrganizationForAdmin1 = new UserOrganizationForAdmin({
id: 42,
Expand Down
Loading

0 comments on commit b97cdcd

Please sign in to comment.