diff --git a/api-tests/core/content-type-builder/collection-type.test.api.js b/api-tests/core/content-type-builder/collection-type.test.api.js index 124df1a074..ac0087a9ac 100644 --- a/api-tests/core/content-type-builder/collection-type.test.api.js +++ b/api-tests/core/content-type-builder/collection-type.test.api.js @@ -7,6 +7,7 @@ const { createStrapiInstance } = require('api-tests/strapi'); const { createAuthRequest } = require('api-tests/request'); const modelsUtils = require('api-tests/models'); +const { createTestBuilder } = require('api-tests/builder'); let strapi; let rq; @@ -17,8 +18,28 @@ const restart = async () => { rq = await createAuthRequest({ strapi }); }; +const builder = createTestBuilder(); + +const localTestData = { + models: { + dog: { + singularName: 'dog', + pluralName: 'dogs', + collectionName: 'dogs-collection', + displayName: 'Dog Display', + kind: 'collectionType', + attributes: { + name: { + type: 'string', + }, + }, + }, + }, +}; + describe('Content Type Builder - Content types', () => { beforeAll(async () => { + await builder.addContentType(localTestData.models.dog).build(); strapi = await createStrapiInstance(); rq = await createAuthRequest({ strapi }); }); @@ -129,6 +150,54 @@ describe('Content Type Builder - Content types', () => { expect(res.body).toMatchSnapshot(); }); + test.each([ + ['singularName', 'singularName'], + ['singularName', 'pluralName'], + ['pluralName', 'singularName'], + ['pluralName', 'pluralName'], + ['pluralName', 'collectionName'], + ])(`Cannot use %p that exists as another type's %p`, async (sourceField, matchField) => { + const body = { + contentType: { + displayName: 'Dog2', + pluralName: 'safe-plural-name', + singularName: 'safe-singular-name', + collectionName: 'safe-collection-name', + attributes: { + name: { + type: 'string', + }, + }, + }, + }; + + // set the conflicting name in the given field + body.contentType[sourceField] = localTestData.models.dog[matchField]; + + const res = await rq({ + method: 'POST', + url: '/content-type-builder/content-types', + body, + }); + + expect(res.statusCode).toBe(400); + expect(res.body).toEqual({ + error: { + details: { + errors: [ + { + message: `contentType: name \`${body.contentType[sourceField]}\` is already being used by another content type.`, + name: 'ValidationError', + path: ['contentType', sourceField], + }, + ], + }, + message: `contentType: name \`${body.contentType[sourceField]}\` is already being used by another content type.`, + name: 'ValidationError', + }, + }); + }); + test('Cannot use same string for singularName and pluralName', async () => { const res = await rq({ method: 'POST', diff --git a/packages/core/content-type-builder/server/controllers/validation/content-type.js b/packages/core/content-type-builder/server/controllers/validation/content-type.js index 1062f6fb2f..e879979e7e 100644 --- a/packages/core/content-type-builder/server/controllers/validation/content-type.js +++ b/packages/core/content-type-builder/server/controllers/validation/content-type.js @@ -138,7 +138,7 @@ const nameIsAvailable = (isEdition) => { return { name: 'nameAlreadyUsed', - message: 'Content Type name `${value}` is already being used.', + message: 'contentType: name `${value}` is already being used by another content type.', test(value) { // don't check on edition if (isEdition) return true; @@ -158,7 +158,7 @@ const nameIsNotExistingCollectionName = (isEdition) => { return { name: 'nameAlreadyUsed', - message: 'Content Type name `${value}` is already being used by another content type.', + message: 'contentType: name `${value}` is already being used by another content type.', test(value) { // don't check on edition if (isEdition) return true; diff --git a/packages/core/content-type-builder/server/services/schema-builder/content-type-builder.js b/packages/core/content-type-builder/server/services/schema-builder/content-type-builder.js index c65d162396..3aeea6345b 100644 --- a/packages/core/content-type-builder/server/services/schema-builder/content-type-builder.js +++ b/packages/core/content-type-builder/server/services/schema-builder/content-type-builder.js @@ -101,7 +101,7 @@ module.exports = function createComponentBuilder() { contentType .setUID(uid) .set('kind', infos.kind || typeKinds.COLLECTION_TYPE) - .set('collectionName', nameToCollectionName(infos.pluralName)) + .set('collectionName', infos.collectionName || nameToCollectionName(infos.pluralName)) .set('info', { singularName: infos.singularName, pluralName: infos.pluralName,