diff --git a/src/api/structures/__tests__/identifiers.test.js b/src/api/structures/__tests__/identifiers.test.js index 33b51980..c76bfe13 100644 --- a/src/api/structures/__tests__/identifiers.test.js +++ b/src/api/structures/__tests__/identifiers.test.js @@ -1,7 +1,9 @@ -import { structures as resource, identifiers as subresource } from '../../resources'; +import { + structures as resource, + identifiers as subresource, +} from '../../resources'; let authorization; -let id; let resourceId; const payload = { @@ -25,20 +27,16 @@ beforeAll(async () => { resourceId = body.id; }); -beforeEach(async () => { +afterEach(async () => { + // Delete all structures identifiers const { body } = await global.superapp - .post(`/${resource}/${resourceId}/${subresource}`) - .set('Authorization', authorization) - .send(payload); - id = body.id; -}); + .get(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization); + const promises = body.data.map((identifier) => global.superapp + .delete(`/${resource}/${resourceId}/${subresource}/${identifier.id}`) + .set('Authorization', authorization)); -afterEach(async () => { - if (id) { - await global.superapp - .delete(`/${resource}/${resourceId}/${subresource}/${id}`) - .set('Authorization', authorization); - } + await Promise.all(promises); }); describe('API > structures > identifiers > create', () => { @@ -77,17 +75,38 @@ describe('API > structures > identifiers > create', () => { .send(rest) .expect(400); }); + + it('should return 204 if an identifier with same type and same value already exists', async () => { + const paylod = { type: 'siret', value: '12345678912346' }; + + await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(paylod) + .expect(201); + + await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(paylod) + .expect(204); + }); }); describe('API > structures > identifiers > update', () => { it('should update an existing identifier', async () => { + const { body: { id } } = await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(payload); + const type = 'wikidata'; - const { body } = await global.superapp + const { body: updatedBody } = await global.superapp .patch(`/${resource}/${resourceId}/${subresource}/${id}`) .set('Authorization', authorization) .send({ type }) .expect(200); - expect(body.type).toBe(type); + expect(updatedBody.type).toBe(type); }); it('should throw bad request if id too short', async () => { @@ -107,6 +126,11 @@ describe('API > structures > identifiers > update', () => { }); it('should throw bad request with badly formatted payload', async () => { + const { body: { id } } = await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(payload); + await global.superapp .patch(`/${resource}/${resourceId}/${subresource}/${id}`) .set('Authorization', authorization) @@ -115,6 +139,11 @@ describe('API > structures > identifiers > update', () => { }); it('should accept empty dates', async () => { + const { body: { id } } = await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(payload); + await global.superapp .patch(`/${resource}/${resourceId}/${subresource}/${id}`) .set('Authorization', authorization) @@ -126,13 +155,19 @@ describe('API > structures > identifiers > update', () => { describe('API > structures > identifiers > read', () => { it('should read existing identifier', async () => { const { body } = await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(payload); + const { id } = body; + + const { body: readBody } = await global.superapp .get(`/${resource}/${resourceId}/${subresource}/${id}`) .set('Authorization', authorization) .expect(200); - expect(body.type).toBe(payload.type); - expect(body.value).toBe(payload.value); - expect(body.active).toBeFalsy(); - expect(body.createdBy.lastName).toBe('user'); + expect(readBody.type).toBe(payload.type); + expect(readBody.value).toBe(payload.value); + expect(readBody.active).toBeFalsy(); + expect(readBody.createdBy.lastName).toBe('user'); }); it('should throw bad request if id too short', async () => { @@ -166,6 +201,11 @@ describe('API > structures > identifiers > delete', () => { }); it('should delete existing identifier', async () => { + const { body: { id } } = await global.superapp + .post(`/${resource}/${resourceId}/${subresource}`) + .set('Authorization', authorization) + .send(payload); + await global.superapp .delete(`/${resource}/${resourceId}/${subresource}/${id}`) .set('Authorization', authorization) @@ -207,14 +247,6 @@ describe('API > structures > identifiers > list', () => { }); }); - beforeEach(async () => { - if (id) { - await global.superapp - .delete(`/${resource}/${resourceId}/${subresource}/${id}`) - .set('Authorization', authorization); - } - }); - it('should list', async () => { const { body } = await global.superapp .get(`/${resource}/${resourceId}/${subresource}`) diff --git a/src/api/structures/identifiers/identifiers.middlewares.js b/src/api/structures/identifiers/identifiers.middlewares.js new file mode 100644 index 00000000..36728c47 --- /dev/null +++ b/src/api/structures/identifiers/identifiers.middlewares.js @@ -0,0 +1,8 @@ +import { identifiersRepository } from '../../commons/repositories'; + +export const validateStructureIdentifierCreatePayload = async (req, res, next) => { + const { type, value } = req.body; + const { resourceId } = req.params; + const check = await identifiersRepository.findOne({ resourceId, type, value }); + return check ? res.status(204).json() : next(); +}; diff --git a/src/api/structures/identifiers/identifiers.routes.js b/src/api/structures/identifiers/identifiers.routes.js index 967698f6..81730b6d 100644 --- a/src/api/structures/identifiers/identifiers.routes.js +++ b/src/api/structures/identifiers/identifiers.routes.js @@ -6,7 +6,8 @@ import { saveInElastic, saveInStore } from '../../commons/middlewares/event.midd import { readQuery, readQueryWithLookup } from '../../commons/queries/identifiers.query'; import elasticQuery from '../../commons/queries/structures.elastic'; import { identifiersRepository as repository, structuresRepository } from '../../commons/repositories'; -import { identifiers as subresource, structures as resource } from '../../resources'; +import { structures as resource, identifiers as subresource } from '../../resources'; +import { validateStructureIdentifierCreatePayload } from './identifiers.middlewares'; const router = new express.Router(); @@ -14,6 +15,7 @@ router.route(`/${resource}/:resourceId/${subresource}`) .get(controllers.list(repository, readQuery)) .post([ createContext, + validateStructureIdentifierCreatePayload, setGeneratedInternalIdInContext(subresource), controllers.create(repository, readQueryWithLookup), saveInStore(subresource), diff --git a/src/openapi/paths/structures/identifiers.yml b/src/openapi/paths/structures/identifiers.yml index 7849b1f4..8216cfcc 100644 --- a/src/openapi/paths/structures/identifiers.yml +++ b/src/openapi/paths/structures/identifiers.yml @@ -57,6 +57,8 @@ collectionMethods: application/json: schema: $ref: '../../api.yml#/components/schemas/StructureIdentifier' + '204': + description: 'No content' '400': $ref: '../../api.yml#/components/responses/BadRequest' '401':