Skip to content

Commit

Permalink
feat(api): create route and deleteCampaigns controller method
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandre-Monney committed Jul 4, 2024
1 parent 09afcca commit a7aeb54
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,34 @@ const register = async function (server) {
],
},
},
{
method: 'DELETE',
path: '/api/organizations/{organizationId}/campaigns',
config: {
pre: [
{
method: securityPreHandlers.checkUserBelongsToOrganization,
},
],
validate: {
params: Joi.object({
organizationId: identifiersType.organizationId,
}),
payload: Joi.object({
data: Joi.array()
.required()
.items(Joi.object({ type: Joi.string().required(), id: identifiersType.campaignId })),
}),
},
handler: campaignAdministrationController.deleteCampaigns,
notes: [
'- **Cette route est restreinte aux utilisateurs authentifiés**\n' +
"- Suppression d'une ou plusieurs campagne(s)\n" +
'- L‘utilisateur doit appartenir à l‘organisation',
],
tags: ['api', 'orga', 'campaign'],
},
},
]);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as csvSerializer from '../../../../lib/infrastructure/serializers/csv/c
import { usecases } from '../../../../src/prescription/campaign/domain/usecases/index.js';
import * as queryParamsUtils from '../../../shared/infrastructure/utils/query-params-utils.js';
import * as requestResponseUtils from '../../../shared/infrastructure/utils/request-response-utils.js';
import { extractUserIdFromRequest } from '../../../shared/infrastructure/utils/request-response-utils.js';
import * as csvCampaignsIdsParser from '../infrastructure/serializers/csv/csv-campaigns-ids-parser.js';
import * as campaignManagementSerializer from '../infrastructure/serializers/jsonapi/campaign-management-serializer.js';
import * as campaignReportSerializer from '../infrastructure/serializers/jsonapi/campaign-report-serializer.js';
Expand Down Expand Up @@ -133,6 +134,16 @@ const findPaginatedCampaignManagements = async function (
return dependencies.campaignManagementSerializer.serialize(campaigns, meta);
};

const deleteCampaigns = async function (request, h) {
const userId = extractUserIdFromRequest(request);
const { organizationId } = request.params;
const campaignIds = request.deserializedPayload.map(({ id }) => id);

await usecases.deleteCampaigns({ userId, organizationId, campaignIds });

return h.response(null).code(204);
};

const campaignAdministrationController = {
save,
update,
Expand All @@ -144,6 +155,7 @@ const campaignAdministrationController = {
archiveCampaign,
archiveCampaigns,
unarchiveCampaign,
deleteCampaigns,
};

export { campaignAdministrationController };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { ObjectValidationError } from '../../../../../lib/domain/errors.js';
import * as moduleUnderTest from '../../../../../src/prescription/campaign/application/campaign-administration-route.js';
import { campaignAdministrationController } from '../../../../../src/prescription/campaign/application/campaign-adminstration-controller.js';
import { DeletedCampaignError } from '../../../../../src/prescription/campaign/domain/errors.js';
import { usecases } from '../../../../../src/prescription/campaign/domain/usecases/index.js';
import { securityPreHandlers } from '../../../../../src/shared/application/security-pre-handlers.js';
import {
databaseBuilder,
expect,
Expand Down Expand Up @@ -83,4 +87,75 @@ describe('Integration | Application | Route | campaign administration router', f
expect(response.statusCode).to.equal(403);
});
});

describe('DELETE /api/organizations/{organizationId}/campaigns', function () {
it('return a 204 status code in success case', async function () {
const userId = 1;
const organizationId = 2;
const campaignIds = [1];
sinon.stub(usecases, 'deleteCampaigns');
sinon.stub(securityPreHandlers, 'checkUserBelongsToOrganization').callsFake((request, h) => h.response(true));

// given
const method = 'DELETE';
const url = '/api/organizations/2/campaigns';
const payload = {
data: [{ type: 'campaigns', id: campaignIds[0] }],
};
httpTestServer = new HttpTestServer();
httpTestServer.setupDeserialization();
await httpTestServer.register(moduleUnderTest);

const headers = {
authorization: generateValidRequestAuthorizationHeader(userId),
};

// when
const response = await httpTestServer.request(method, url, payload, null, headers);
// then
expect(securityPreHandlers.checkUserBelongsToOrganization).to.have.been.calledOnce;
expect(usecases.deleteCampaigns).to.have.been.calledWithExactly({ userId, organizationId, campaignIds });
expect(response.statusCode).to.equal(204);
});

it('return a 422 status code if an ObjectValidationError is thrown', async function () {
sinon.stub(usecases, 'deleteCampaigns');
sinon.stub(securityPreHandlers, 'checkUserBelongsToOrganization').callsFake((request, h) => h.response(true));
usecases.deleteCampaigns.rejects(new ObjectValidationError());
// given
const method = 'DELETE';
const url = '/api/organizations/2/campaigns';
const payload = {
data: [],
};
httpTestServer = new HttpTestServer();
httpTestServer.setupDeserialization();
await httpTestServer.register(moduleUnderTest);

// when
const response = await httpTestServer.request(method, url, payload);
// then
expect(response.statusCode).to.equal(422);
});

it('return a 412 status code if an DeletedCampaignError is thrown', async function () {
sinon.stub(usecases, 'deleteCampaigns');
sinon.stub(securityPreHandlers, 'checkUserBelongsToOrganization').callsFake((request, h) => h.response(true));
usecases.deleteCampaigns.rejects(new DeletedCampaignError());
// given
const method = 'DELETE';
const url = '/api/organizations/2/campaigns';
const payload = {
data: [],
};
httpTestServer = new HttpTestServer();
httpTestServer.setupDeserialization();
await httpTestServer.register(moduleUnderTest);

// when
const response = await httpTestServer.request(method, url, payload);
// then
expect(response.statusCode).to.equal(412);
});
});
});

0 comments on commit a7aeb54

Please sign in to comment.