diff --git a/packages/strapi-hook-mongoose/lib/mount-models.js b/packages/strapi-hook-mongoose/lib/mount-models.js index 02c61982c7..4a57c82162 100644 --- a/packages/strapi-hook-mongoose/lib/mount-models.js +++ b/packages/strapi-hook-mongoose/lib/mount-models.js @@ -348,10 +348,10 @@ const createOnFetchPopulateFn = ({ ) { this._mongooseOptions.populate[name].path = `${name}.ref`; } else { - this._mongooseOptions.populate[name] = { + _.set(this._mongooseOptions, ['populate', name], { path: `${name}.ref`, _docs: {}, - }; + }); } }); diff --git a/packages/strapi-hook-mongoose/lib/queries.js b/packages/strapi-hook-mongoose/lib/queries.js index d07a828d2d..9279fac51b 100644 --- a/packages/strapi-hook-mongoose/lib/queries.js +++ b/packages/strapi-hook-mongoose/lib/queries.js @@ -267,9 +267,10 @@ module.exports = ({ model, modelKey, strapi }) => { const relations = pickRelations(values); const data = omitExernalValues(values); + // update groups first in case it fails don't update the entity + await updateGroups(entry, values); // Update entry with no-relational data. await entry.updateOne(data); - await updateGroups(entry, values); // Update relational data and return the entry. return model.updateRelations(Object.assign(params, { values: relations })); diff --git a/packages/strapi-plugin-content-manager/test/groups.test.e2e.js b/packages/strapi-plugin-content-manager/test/groups.test.e2e.js deleted file mode 100644 index bb9dd49d38..0000000000 --- a/packages/strapi-plugin-content-manager/test/groups.test.e2e.js +++ /dev/null @@ -1,145 +0,0 @@ -const { registerAndLogin } = require('../../../test/helpers/auth'); -const createModelsUtils = require('../../../test/helpers/models'); -const { createAuthRequest } = require('../../../test/helpers/request'); - -let modelsUtils; -let rq; - -describe('Test type groups', () => { - beforeAll(async () => { - const token = await registerAndLogin(); - rq = createAuthRequest(token); - - modelsUtils = createModelsUtils({ rq }); - - await modelsUtils.createGroup({ - name: 'somegroup', - attributes: { - name: { - type: 'string', - }, - }, - }); - }, 60000); - - afterAll(async () => { - await modelsUtils.deleteGroup('somegroup'); - }); - - describe('Non repeatable and Non required group', () => { - beforeAll(async () => { - await modelsUtils.createModelWithType('withgroup', 'group', { - group: 'somegroup', - repeatable: false, - required: false, - }); - }, 60000); - - afterAll(async () => { - await modelsUtils.deleteModel('withgroup'); - }, 60000); - - describe('POST new entry', () => { - test('Creating entry with JSON works', async () => { - const res = await rq.post('/content-manager/explorer/withgroup', { - body: { - field: { - name: 'someString', - }, - }, - }); - - expect(res.statusCode).toBe(200); - expect(res.body.field).toEqual( - expect.objectContaining({ - id: expect.anything(), - name: 'someString', - }) - ); - }); - - test('Creating entry with formdata works', async () => { - const res = await rq.post('/content-manager/explorer/withgroup', { - formData: { - data: JSON.stringify({ - field: { - name: 'someValue', - }, - }), - }, - }); - - expect(res.statusCode).toBe(200); - expect(res.body.field).toEqual( - expect.objectContaining({ - id: expect.anything(), - name: 'someValue', - }) - ); - }); - - test.each([[], 'someString', 128219, false])( - 'Throws if the field is not an object %p', - async value => { - const res = await rq.post('/content-manager/explorer/withgroup', { - body: { - field: value, - }, - }); - - expect(res.statusCode).toBe(400); - } - ); - - test('Can send a null value', async () => { - const res = await rq.post('/content-manager/explorer/withgroup', { - body: { - field: null, - }, - }); - - expect(res.statusCode).toBe(200); - expect(res.body.field).toBe(null); - }); - - test('Can send input without the group field', async () => { - const res = await rq.post('/content-manager/explorer/withgroup', { - body: {}, - }); - - expect(res.statusCode).toBe(200); - expect(res.body.field).toBe(null); - }); - }); - - describe('GET entries', () => { - test('Should return entries with their nested groups', async () => { - const res = await rq.get('/content-manager/explorer/withgroup'); - - expect(res.statusCode).toBe(200); - expect(Array.isArray(res.body)).toBe(true); - res.body.forEach(entry => { - if (entry.field === null) return; - - expect(entry.field).toMatchObject({ - name: expect.any(String), - }); - }); - }); - }); - - describe('PUT entry', () => { - test.todo('Keeps the previous value if group not sent'); - test.todo('Removes previous group if null sent'); - test.todo('Replaces the previous group if sent without id'); - test.todo('Throws on invalid id in sent group'); - test.todo('Updates group if previsous group id is sent'); - }); - }); - - describe('Non repeatable required group', () => {}); - describe('Repeatable non required group', () => {}); - describe('Repeatable non required group with min and max', () => {}); - describe('Repeatable required group', () => {}); - describe('Repeatable required group with min and max', () => {}); -}); diff --git a/packages/strapi-plugin-content-manager/test/groups/repeatable-min-max.test.e2e.js b/packages/strapi-plugin-content-manager/test/groups/repeatable-min-max.test.e2e.js new file mode 100644 index 0000000000..5483e6bc3c --- /dev/null +++ b/packages/strapi-plugin-content-manager/test/groups/repeatable-min-max.test.e2e.js @@ -0,0 +1,567 @@ +const { registerAndLogin } = require('../../../../test/helpers/auth'); +const createModelsUtils = require('../../../../test/helpers/models'); +const { createAuthRequest } = require('../../../../test/helpers/request'); + +let modelsUtils; +let rq; + +describe.each([ + ['CONTENT MANAGER', '/content-manager/explorer/withgroup'], + ['GENERATED API', '/withgroups'], +])('[%s] => Non repeatable and Not required group', (_, path) => { + beforeAll(async () => { + const token = await registerAndLogin(); + const authRq = createAuthRequest(token); + + modelsUtils = createModelsUtils({ rq: authRq }); + + await modelsUtils.createGroup({ + name: 'somegroup', + attributes: { + name: { + type: 'string', + }, + }, + }); + + await modelsUtils.createModelWithType('withgroup', 'group', { + group: 'somegroup', + repeatable: true, + required: false, + min: 1, + max: 5, + }); + + rq = authRq.defaults({ + baseUrl: `http://localhost:1337${path}`, + }); + }, 60000); + + afterAll(async () => { + await modelsUtils.deleteGroup('somegroup'); + await modelsUtils.deleteModel('withgroup'); + }, 60000); + + describe('POST new entry', () => { + test('Creating entry with JSON works', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body.field)).toBe(true); + expect(res.body.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.anything(), + name: 'someString', + }), + ]) + ); + }); + + test('Creating entry with formdata works', async () => { + const res = await rq.post('/', { + formData: { + data: JSON.stringify({ + field: [ + { + name: 'someValue', + }, + ], + }), + }, + }); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body.field)).toBe(true); + expect(res.body.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.anything(), + name: 'someValue', + }), + ]) + ); + }); + + test.each(['someString', 128219, false, {}, null])( + 'Throws if the field is not an object %p', + async value => { + const res = await rq.post('/', { + body: { + field: value, + }, + }); + + expect(res.statusCode).toBe(400); + } + ); + + test('Throws when sending an empty array or an array with less then the min', async () => { + const res = await rq.post('/', { + body: { + field: [], + }, + }); + + expect(res.statusCode).toBe(400); + }); + + test('Throws when sending too many items', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'one', + }, + { + name: 'one', + }, + { + name: 'one', + }, + { + name: 'one', + }, + { + name: 'one', + }, + { + name: 'one', + }, + ], + }, + }); + + expect(res.statusCode).toBe(400); + }); + + test('Can send input without the group field', async () => { + const res = await rq.post('/', { + body: {}, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual([]); + }); + }); + + describe('GET entries', () => { + test('Data is orderd in the order sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'firstString', + }, + { + name: 'someString', + }, + ], + }, + }); + + const getRes = await rq.get(`/${res.body.id}`); + expect(getRes.statusCode).toBe(200); + expect(Array.isArray(getRes.body.field)).toBe(true); + + expect(getRes.body.field[0]).toMatchObject({ + name: 'firstString', + }); + expect(getRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + }); + + test('Should return entries with their nested groups', async () => { + const res = await rq.get('/'); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body)).toBe(true); + res.body.forEach(entry => { + expect(Array.isArray(entry.field)).toBe(true); + + if (entry.field.length === 0) return; + + expect(entry.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: expect.any(String), + }), + ]) + ); + }); + }); + }); + + describe('PUT entry', () => { + test.each(['someString', 128219, false, {}, null])( + 'Throws when sending invalid updated field %p', + async value => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: value, + }, + }); + + expect(updateRes.statusCode).toBe(400); + + // shouldn't have been updated + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + } + ); + + test('Updates order at each request', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'otherString', + }, + ], + }, + }); + + expect(res.body.field[0]).toMatchObject({ + name: 'someString', + }); + expect(res.body.field[1]).toMatchObject({ + name: 'otherString', + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'otherString', + }, + { + name: 'someString', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(200); + expect(Array.isArray(updateRes.body.field)).toBe(true); + + expect(updateRes.body.field[0]).toMatchObject({ + name: 'otherString', + }); + expect(updateRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(Array.isArray(getRes.body.field)).toBe(true); + + expect(getRes.body.field[0]).toMatchObject({ + name: 'otherString', + }); + expect(getRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + }); + + test('Keeps the previous value if group not sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'otherString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: {}, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + }); + + test('Throws when not enough items', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [], + }, + }); + + expect(updateRes.statusCode).toBe(400); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(res.body); + }); + + test('Throws when too many items', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'someString', + }, + { + name: 'someString', + }, + { + name: 'someString', + }, + { + name: 'someString', + }, + { + name: 'someString', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(400); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(res.body); + }); + + test('Replaces the previous groups if sent without id', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'new String', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(200); + + const oldIds = res.body.field.map(val => val.id); + updateRes.body.field.forEach(val => { + expect(oldIds.includes(val.id)).toBe(false); + }); + + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: [ + { + name: 'new String', + }, + ], + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: [ + { + name: 'new String', + }, + ], + }); + }); + + test('Throws on invalid id in group', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + id: 'invalid_id', + name: 'new String', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(400); + }); + + test('Updates group with ids, create new ones and removes old ones', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'one', + }, + { + name: 'two', + }, + { + name: 'three', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + id: res.body.field[0].id, // send old id to update the previous group + name: 'newOne', + }, + { + name: 'newTwo', + }, + { + id: res.body.field[2].id, + name: 'three', + }, + { + name: 'four', + }, + ], + }, + }); + + const expectedResult = { + id: res.body.id, + field: [ + { + id: res.body.field[0].id, + name: 'newOne', + }, + { + name: 'newTwo', + }, + { + id: res.body.field[2].id, + name: 'three', + }, + { + name: 'four', + }, + ], + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectedResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectedResult); + }); + }); + + describe('DELETE entry', () => { + test('Returns entry with groups', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'someOtherString', + }, + { + name: 'otherSomeString', + }, + ], + }, + }); + + const deleteRes = await rq.delete(`/${res.body.id}`); + + expect(deleteRes.statusCode).toBe(200); + expect(deleteRes.body).toMatchObject(res.body); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(404); + }); + }); +}); diff --git a/packages/strapi-plugin-content-manager/test/groups/repeatable-not-required.test.e2e.js b/packages/strapi-plugin-content-manager/test/groups/repeatable-not-required.test.e2e.js new file mode 100644 index 0000000000..32a8b94a51 --- /dev/null +++ b/packages/strapi-plugin-content-manager/test/groups/repeatable-not-required.test.e2e.js @@ -0,0 +1,499 @@ +const { registerAndLogin } = require('../../../../test/helpers/auth'); +const createModelsUtils = require('../../../../test/helpers/models'); +const { createAuthRequest } = require('../../../../test/helpers/request'); + +let modelsUtils; +let rq; + +describe.each([ + ['CONTENT MANAGER', '/content-manager/explorer/withgroup'], + ['GENERATED API', '/withgroups'], +])('[%s] => Non repeatable and Not required group', (_, path) => { + beforeAll(async () => { + const token = await registerAndLogin(); + const authRq = createAuthRequest(token); + + modelsUtils = createModelsUtils({ rq: authRq }); + + await modelsUtils.createGroup({ + name: 'somegroup', + attributes: { + name: { + type: 'string', + }, + }, + }); + + await modelsUtils.createModelWithType('withgroup', 'group', { + group: 'somegroup', + repeatable: true, + required: false, + }); + + rq = authRq.defaults({ + baseUrl: `http://localhost:1337${path}`, + }); + }, 60000); + + afterAll(async () => { + await modelsUtils.deleteGroup('somegroup'); + await modelsUtils.deleteModel('withgroup'); + }, 60000); + + describe('POST new entry', () => { + test('Creating entry with JSON works', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body.field)).toBe(true); + expect(res.body.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.anything(), + name: 'someString', + }), + ]) + ); + }); + + test('Creating entry with formdata works', async () => { + const res = await rq.post('/', { + formData: { + data: JSON.stringify({ + field: [ + { + name: 'someValue', + }, + ], + }), + }, + }); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body.field)).toBe(true); + expect(res.body.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.anything(), + name: 'someValue', + }), + ]) + ); + }); + + test.each(['someString', 128219, false, {}, null])( + 'Throws if the field is not an object %p', + async value => { + const res = await rq.post('/', { + body: { + field: value, + }, + }); + + expect(res.statusCode).toBe(400); + } + ); + + test('Can send an empty array', async () => { + const res = await rq.post('/', { + body: { + field: [], + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual([]); + }); + + test('Can send input without the group field', async () => { + const res = await rq.post('/', { + body: {}, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual([]); + }); + }); + + describe('GET entries', () => { + test('Data is orderd in the order sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'firstString', + }, + { + name: 'someString', + }, + ], + }, + }); + + const getRes = await rq.get(`/${res.body.id}`); + expect(getRes.statusCode).toBe(200); + expect(Array.isArray(getRes.body.field)).toBe(true); + + expect(getRes.body.field[0]).toMatchObject({ + name: 'firstString', + }); + expect(getRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + }); + + test('Should return entries with their nested groups', async () => { + const res = await rq.get('/'); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body)).toBe(true); + res.body.forEach(entry => { + expect(Array.isArray(entry.field)).toBe(true); + + if (entry.field.length === 0) return; + + expect(entry.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: expect.any(String), + }), + ]) + ); + }); + }); + }); + + describe('PUT entry', () => { + test.each(['someString', 128219, false, {}, null])( + 'Throws when sending invalid updated field %p', + async value => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: value, + }, + }); + + expect(updateRes.statusCode).toBe(400); + + // shouldn't have been updated + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + } + ); + + test('Updates order at each request', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'otherString', + }, + ], + }, + }); + + expect(res.body.field[0]).toMatchObject({ + name: 'someString', + }); + expect(res.body.field[1]).toMatchObject({ + name: 'otherString', + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'otherString', + }, + { + name: 'someString', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(200); + expect(Array.isArray(updateRes.body.field)).toBe(true); + + expect(updateRes.body.field[0]).toMatchObject({ + name: 'otherString', + }); + expect(updateRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(Array.isArray(getRes.body.field)).toBe(true); + + expect(getRes.body.field[0]).toMatchObject({ + name: 'otherString', + }); + expect(getRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + }); + + test('Keeps the previous value if group not sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'otherString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: {}, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + }); + + test('Removes previous groups if empty array sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [], + }, + }); + + const expectResult = { + id: res.body.id, + field: [], + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectResult); + }); + + test('Replaces the previous groups if sent without id', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'new String', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(200); + + const oldIds = res.body.field.map(val => val.id); + updateRes.body.field.forEach(val => { + expect(oldIds.includes(val.id)).toBe(false); + }); + + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: [ + { + name: 'new String', + }, + ], + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: [ + { + name: 'new String', + }, + ], + }); + }); + + test('Throws on invalid id in group', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + id: 'invalid_id', + name: 'new String', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(400); + }); + + test('Updates group with ids, create new ones and removes old ones', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'one', + }, + { + name: 'two', + }, + { + name: 'three', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + id: res.body.field[0].id, // send old id to update the previous group + name: 'newOne', + }, + { + name: 'newTwo', + }, + { + id: res.body.field[2].id, + name: 'three', + }, + { + name: 'four', + }, + ], + }, + }); + + const expectedResult = { + id: res.body.id, + field: [ + { + id: res.body.field[0].id, + name: 'newOne', + }, + { + name: 'newTwo', + }, + { + id: res.body.field[2].id, + name: 'three', + }, + { + name: 'four', + }, + ], + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectedResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectedResult); + }); + }); + + describe('DELETE entry', () => { + test('Returns entry with groups', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'someOtherString', + }, + { + name: 'otherSomeString', + }, + ], + }, + }); + + const deleteRes = await rq.delete(`/${res.body.id}`); + + expect(deleteRes.statusCode).toBe(200); + expect(deleteRes.body).toMatchObject(res.body); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(404); + }); + }); +}); diff --git a/packages/strapi-plugin-content-manager/test/groups/repeatable-required.test.e2e.js b/packages/strapi-plugin-content-manager/test/groups/repeatable-required.test.e2e.js new file mode 100644 index 0000000000..c9922f9759 --- /dev/null +++ b/packages/strapi-plugin-content-manager/test/groups/repeatable-required.test.e2e.js @@ -0,0 +1,498 @@ +const { registerAndLogin } = require('../../../../test/helpers/auth'); +const createModelsUtils = require('../../../../test/helpers/models'); +const { createAuthRequest } = require('../../../../test/helpers/request'); + +let modelsUtils; +let rq; + +describe.each([ + ['CONTENT MANAGER', '/content-manager/explorer/withgroup'], + ['GENERATED API', '/withgroups'], +])('[%s] => Non repeatable and Not required group', (_, path) => { + beforeAll(async () => { + const token = await registerAndLogin(); + const authRq = createAuthRequest(token); + + modelsUtils = createModelsUtils({ rq: authRq }); + + await modelsUtils.createGroup({ + name: 'somegroup', + attributes: { + name: { + type: 'string', + }, + }, + }); + + await modelsUtils.createModelWithType('withgroup', 'group', { + group: 'somegroup', + repeatable: true, + required: true, + }); + + rq = authRq.defaults({ + baseUrl: `http://localhost:1337${path}`, + }); + }, 60000); + + afterAll(async () => { + await modelsUtils.deleteGroup('somegroup'); + await modelsUtils.deleteModel('withgroup'); + }, 60000); + + describe('POST new entry', () => { + test('Creating entry with JSON works', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body.field)).toBe(true); + expect(res.body.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.anything(), + name: 'someString', + }), + ]) + ); + }); + + test('Creating entry with formdata works', async () => { + const res = await rq.post('/', { + formData: { + data: JSON.stringify({ + field: [ + { + name: 'someValue', + }, + ], + }), + }, + }); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body.field)).toBe(true); + expect(res.body.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: expect.anything(), + name: 'someValue', + }), + ]) + ); + }); + + test.each(['someString', 128219, false, {}, null])( + 'Throws if the field is not an object %p', + async value => { + const res = await rq.post('/', { + body: { + field: value, + }, + }); + + expect(res.statusCode).toBe(400); + } + ); + + test('Can send an empty array', async () => { + const res = await rq.post('/', { + body: { + field: [], + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual([]); + }); + + test('Throws when group is not provided', async () => { + const res = await rq.post('/', { + body: {}, + }); + + expect(res.statusCode).toBe(400); + }); + }); + + describe('GET entries', () => { + test('Data is orderd in the order sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'firstString', + }, + { + name: 'someString', + }, + ], + }, + }); + + const getRes = await rq.get(`/${res.body.id}`); + expect(getRes.statusCode).toBe(200); + expect(Array.isArray(getRes.body.field)).toBe(true); + + expect(getRes.body.field[0]).toMatchObject({ + name: 'firstString', + }); + expect(getRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + }); + + test('Should return entries with their nested groups', async () => { + const res = await rq.get('/'); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body)).toBe(true); + res.body.forEach(entry => { + expect(Array.isArray(entry.field)).toBe(true); + + if (entry.field.length === 0) return; + + expect(entry.field).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: expect.any(String), + }), + ]) + ); + }); + }); + }); + + describe('PUT entry', () => { + test.each(['someString', 128219, false, {}, null])( + 'Throws when sending invalid updated field %p', + async value => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: value, + }, + }); + + expect(updateRes.statusCode).toBe(400); + + // shouldn't have been updated + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + } + ); + + test('Updates order at each request', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'otherString', + }, + ], + }, + }); + + expect(res.body.field[0]).toMatchObject({ + name: 'someString', + }); + expect(res.body.field[1]).toMatchObject({ + name: 'otherString', + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'otherString', + }, + { + name: 'someString', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(200); + expect(Array.isArray(updateRes.body.field)).toBe(true); + + expect(updateRes.body.field[0]).toMatchObject({ + name: 'otherString', + }); + expect(updateRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(Array.isArray(getRes.body.field)).toBe(true); + + expect(getRes.body.field[0]).toMatchObject({ + name: 'otherString', + }); + expect(getRes.body.field[1]).toMatchObject({ + name: 'someString', + }); + }); + + test('Keeps the previous value if group not sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'otherString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: {}, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + }); + + test('Removes previous groups if empty array sent', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [], + }, + }); + + const expectResult = { + id: res.body.id, + field: [], + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectResult); + }); + + test('Replaces the previous groups if sent without id', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + name: 'new String', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(200); + + const oldIds = res.body.field.map(val => val.id); + updateRes.body.field.forEach(val => { + expect(oldIds.includes(val.id)).toBe(false); + }); + + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: [ + { + name: 'new String', + }, + ], + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: [ + { + name: 'new String', + }, + ], + }); + }); + + test('Throws on invalid id in group', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + id: 'invalid_id', + name: 'new String', + }, + ], + }, + }); + + expect(updateRes.statusCode).toBe(400); + }); + + test('Updates group with ids, create new ones and removes old ones', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'one', + }, + { + name: 'two', + }, + { + name: 'three', + }, + ], + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: [ + { + id: res.body.field[0].id, // send old id to update the previous group + name: 'newOne', + }, + { + name: 'newTwo', + }, + { + id: res.body.field[2].id, + name: 'three', + }, + { + name: 'four', + }, + ], + }, + }); + + const expectedResult = { + id: res.body.id, + field: [ + { + id: res.body.field[0].id, + name: 'newOne', + }, + { + name: 'newTwo', + }, + { + id: res.body.field[2].id, + name: 'three', + }, + { + name: 'four', + }, + ], + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectedResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectedResult); + }); + }); + + describe('DELETE entry', () => { + test('Returns entry with groups', async () => { + const res = await rq.post('/', { + body: { + field: [ + { + name: 'someString', + }, + { + name: 'someOtherString', + }, + { + name: 'otherSomeString', + }, + ], + }, + }); + + const deleteRes = await rq.delete(`/${res.body.id}`); + + expect(deleteRes.statusCode).toBe(200); + expect(deleteRes.body).toMatchObject(res.body); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(404); + }); + }); +}); diff --git a/packages/strapi-plugin-content-manager/test/groups/single-not-required.test.e2e.js b/packages/strapi-plugin-content-manager/test/groups/single-not-required.test.e2e.js new file mode 100644 index 0000000000..b9465bb799 --- /dev/null +++ b/packages/strapi-plugin-content-manager/test/groups/single-not-required.test.e2e.js @@ -0,0 +1,334 @@ +const { registerAndLogin } = require('../../../../test/helpers/auth'); +const createModelsUtils = require('../../../../test/helpers/models'); +const { createAuthRequest } = require('../../../../test/helpers/request'); + +let modelsUtils; +let rq; + +describe.each([ + ['CONTENT MANAGER', '/content-manager/explorer/withgroup'], + ['GENERATED API', '/withgroups'], +])('[%s] => Non repeatable and Not required group', (_, path) => { + beforeAll(async () => { + const token = await registerAndLogin(); + const authRq = createAuthRequest(token); + + modelsUtils = createModelsUtils({ rq: authRq }); + + await modelsUtils.createGroup({ + name: 'somegroup', + attributes: { + name: { + type: 'string', + }, + }, + }); + + await modelsUtils.createModelWithType('withgroup', 'group', { + group: 'somegroup', + repeatable: false, + required: false, + }); + + rq = authRq.defaults({ + baseUrl: `http://localhost:1337${path}`, + }); + }, 60000); + + afterAll(async () => { + await modelsUtils.deleteGroup('somegroup'); + await modelsUtils.deleteModel('withgroup'); + }, 60000); + + describe('POST new entry', () => { + test('Creating entry with JSON works', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual( + expect.objectContaining({ + id: expect.anything(), + name: 'someString', + }) + ); + }); + + test('Creating entry with formdata works', async () => { + const res = await rq.post('/', { + formData: { + data: JSON.stringify({ + field: { + name: 'someValue', + }, + }), + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual( + expect.objectContaining({ + id: expect.anything(), + name: 'someValue', + }) + ); + }); + + test.each([[], 'someString', 128219, false])( + 'Throws if the field is not an object %p', + async value => { + const res = await rq.post('/', { + body: { + field: value, + }, + }); + + expect(res.statusCode).toBe(400); + } + ); + + test('Can send a null value', async () => { + const res = await rq.post('/', { + body: { + field: null, + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toBe(null); + }); + + test('Can send input without the group field', async () => { + const res = await rq.post('/', { + body: {}, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toBe(null); + }); + }); + + describe('GET entries', () => { + test('Should return entries with their nested groups', async () => { + const res = await rq.get('/'); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body)).toBe(true); + res.body.forEach(entry => { + if (entry.field === null) return; + + expect(entry.field).toMatchObject({ + name: expect.any(String), + }); + }); + }); + }); + + describe('PUT entry', () => { + test.each([[], 'someString', 128219, false])( + 'Throws when sending invalid updated field %p', + async value => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: value, + }, + }); + + expect(updateRes.statusCode).toBe(400); + + // shouldn't have been updated + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + } + ); + + test('Keeps the previous value if group not sent', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: {}, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + }); + + test('Removes previous group if null sent', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: null, + }, + }); + + const expectResult = { + id: res.body.id, + field: null, + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectResult); + }); + + test('Replaces the previous group if sent without id', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: { + name: 'new String', + }, + }, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body.field.id).not.toBe(res.body.field.id); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: { + name: 'new String', + }, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: { + name: 'new String', + }, + }); + }); + + test('Throws on invalid id in group', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: { + id: 'invalid_id', + name: 'new String', + }, + }, + }); + + expect(updateRes.statusCode).toBe(400); + }); + + test('Updates group if previsous group id is sent', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: { + id: res.body.field.id, // send old id to update the previous group + name: 'new String', + }, + }, + }); + + const expectedResult = { + id: res.body.id, + field: { + id: res.body.field.id, + name: 'new String', + }, + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectedResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectedResult); + }); + }); + + describe('DELETE entry', () => { + test('Returns entry with groups', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const deleteRes = await rq.delete(`/${res.body.id}`); + + expect(deleteRes.statusCode).toBe(200); + expect(deleteRes.body).toMatchObject(res.body); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(404); + }); + }); +}); diff --git a/packages/strapi-plugin-content-manager/test/groups/single-required.test.e2e.js b/packages/strapi-plugin-content-manager/test/groups/single-required.test.e2e.js new file mode 100644 index 0000000000..27003624dd --- /dev/null +++ b/packages/strapi-plugin-content-manager/test/groups/single-required.test.e2e.js @@ -0,0 +1,326 @@ +const { registerAndLogin } = require('../../../../test/helpers/auth'); +const createModelsUtils = require('../../../../test/helpers/models'); +const { createAuthRequest } = require('../../../../test/helpers/request'); + +let modelsUtils; +let rq; + +describe.each([ + ['CONTENT MANAGER', '/content-manager/explorer/withgroup'], + ['GENERATED API', '/withgroups'], +])('[%s] => Non repeatable and required group', (_, path) => { + beforeAll(async () => { + const token = await registerAndLogin(); + const authRq = createAuthRequest(token); + + modelsUtils = createModelsUtils({ rq: authRq }); + + await modelsUtils.createGroup({ + name: 'somegroup', + attributes: { + name: { + type: 'string', + }, + }, + }); + + await modelsUtils.createModelWithType('withgroup', 'group', { + group: 'somegroup', + repeatable: false, + required: true, + }); + + rq = authRq.defaults({ + baseUrl: `http://localhost:1337${path}`, + }); + }, 60000); + + afterAll(async () => { + await modelsUtils.deleteGroup('somegroup'); + await modelsUtils.deleteModel('withgroup'); + }, 60000); + + describe('POST new entry', () => { + test('Creating entry with JSON works', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual( + expect.objectContaining({ + id: expect.anything(), + name: 'someString', + }) + ); + }); + + test('Creating entry with formdata works', async () => { + const res = await rq.post('/', { + formData: { + data: JSON.stringify({ + field: { + name: 'someValue', + }, + }), + }, + }); + + expect(res.statusCode).toBe(200); + expect(res.body.field).toEqual( + expect.objectContaining({ + id: expect.anything(), + name: 'someValue', + }) + ); + }); + + test.each([[], 'someString', 128219, false])( + 'Throws if the field is not an object %p', + async value => { + const res = await rq.post('/', { + body: { + field: value, + }, + }); + + expect(res.statusCode).toBe(400); + } + ); + + test('Throws when sending a null value', async () => { + const res = await rq.post('/', { + body: { + field: null, + }, + }); + + expect(res.statusCode).toBe(400); + }); + + test('Throws when the group is not provided', async () => { + const res = await rq.post('/', { + body: {}, + }); + + expect(res.statusCode).toBe(400); + }); + }); + + describe('GET entries', () => { + test('Should return entries with their nested groups', async () => { + const res = await rq.get('/'); + + expect(res.statusCode).toBe(200); + expect(Array.isArray(res.body)).toBe(true); + res.body.forEach(entry => { + if (entry.field === null) return; + + expect(entry.field).toMatchObject({ + name: expect.any(String), + }); + }); + }); + }); + + describe('PUT entry', () => { + test.each([[], 'someString', 128219, false])( + 'Throws when sending invalid updated field %p', + async value => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: value, + }, + }); + + expect(updateRes.statusCode).toBe(400); + + // shouldn't have been updated + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + } + ); + + test('Keeps the previous value if group not sent', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: {}, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: res.body.field, + }); + }); + + test('Throws if group is null', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: null, + }, + }); + + expect(updateRes.statusCode).toBe(400); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(res.body); + }); + + test('Replaces the previous group if sent without id', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: { + name: 'new String', + }, + }, + }); + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body.field.id).not.toBe(res.body.field.id); + expect(updateRes.body).toMatchObject({ + id: res.body.id, + field: { + name: 'new String', + }, + }); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject({ + id: res.body.id, + field: { + name: 'new String', + }, + }); + }); + + test('Throws on invalid id in group', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: { + id: 'invalid_id', + name: 'new String', + }, + }, + }); + + expect(updateRes.statusCode).toBe(400); + }); + + test('Updates group if previsous group id is sent', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const updateRes = await rq.put(`/${res.body.id}`, { + body: { + field: { + id: res.body.field.id, // send old id to update the previous group + name: 'new String', + }, + }, + }); + + const expectedResult = { + id: res.body.id, + field: { + id: res.body.field.id, + name: 'new String', + }, + }; + + expect(updateRes.statusCode).toBe(200); + expect(updateRes.body).toMatchObject(expectedResult); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(200); + expect(getRes.body).toMatchObject(expectedResult); + }); + }); + + describe('DELETE entry', () => { + test('Returns entry with groups', async () => { + const res = await rq.post('/', { + body: { + field: { + name: 'someString', + }, + }, + }); + + const deleteRes = await rq.delete(`/${res.body.id}`); + + expect(deleteRes.statusCode).toBe(200); + expect(deleteRes.body).toMatchObject(res.body); + + const getRes = await rq.get(`/${res.body.id}`); + + expect(getRes.statusCode).toBe(404); + }); + }); +});