From b37a92c60f6cc1e391dfb6720f558bc136f35df8 Mon Sep 17 00:00:00 2001 From: Alexandre Bodin Date: Tue, 27 Oct 2020 15:16:20 +0100 Subject: [PATCH] Refactored uid utils Signed-off-by: Alexandre Bodin --- .../config/routes.json | 6 +- .../controllers/ContentManager.js | 36 --------- .../controllers/uid.js | 41 ++++++++++ .../strapi-plugin-content-manager/oas.yml | 78 ++++++++++++++++++- .../services/content-types.js | 4 +- .../test/content-manager/uid.test.e2e.js | 34 ++++---- 6 files changed, 141 insertions(+), 58 deletions(-) create mode 100644 packages/strapi-plugin-content-manager/controllers/uid.js diff --git a/packages/strapi-plugin-content-manager/config/routes.json b/packages/strapi-plugin-content-manager/config/routes.json index 4d9c205aeb..21c907de84 100644 --- a/packages/strapi-plugin-content-manager/config/routes.json +++ b/packages/strapi-plugin-content-manager/config/routes.json @@ -53,7 +53,7 @@ { "method": "POST", "path": "/uid/generate", - "handler": "ContentManager.generateUID", + "handler": "uid.generateUID", "config": { "policies": [] } @@ -61,11 +61,13 @@ { "method": "POST", "path": "/uid/check-availability", - "handler": "ContentManager.checkUIDAvailability", + "handler": "uid.checkUIDAvailability", "config": { "policies": [] } }, + + { "method": "GET", "path": "/explorer/:model", diff --git a/packages/strapi-plugin-content-manager/controllers/ContentManager.js b/packages/strapi-plugin-content-manager/controllers/ContentManager.js index a212d29513..0d75b8b37d 100644 --- a/packages/strapi-plugin-content-manager/controllers/ContentManager.js +++ b/packages/strapi-plugin-content-manager/controllers/ContentManager.js @@ -4,11 +4,6 @@ const _ = require('lodash'); const { contentTypes: contentTypesUtils } = require('strapi-utils'); const parseMultipartBody = require('../utils/parse-multipart'); -const { - validateGenerateUIDInput, - validateCheckUIDAvailabilityInput, - validateUIDField, -} = require('./validation'); const { PUBLISHED_AT_ATTRIBUTE, @@ -47,37 +42,6 @@ const findEntityAndCheckPermissions = async (ability, action, model, id) => { }; module.exports = { - async generateUID(ctx) { - const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body); - - await validateUIDField(contentTypeUID, field); - - const uidService = strapi.plugins['content-manager'].services.uid; - - ctx.body = { - data: await uidService.generateUIDField({ contentTypeUID, field, data }), - }; - }, - - async checkUIDAvailability(ctx) { - const { contentTypeUID, field, value } = await validateCheckUIDAvailabilityInput( - ctx.request.body - ); - - await validateUIDField(contentTypeUID, field); - - const uidService = strapi.plugins['content-manager'].services.uid; - - const isAvailable = await uidService.checkUIDAvailability({ contentTypeUID, field, value }); - - ctx.body = { - isAvailable, - suggestion: !isAvailable - ? await uidService.findUniqueUID({ contentTypeUID, field, value }) - : null, - }; - }, - /** * Returns a list of entities of a content-type matching the query parameters */ diff --git a/packages/strapi-plugin-content-manager/controllers/uid.js b/packages/strapi-plugin-content-manager/controllers/uid.js new file mode 100644 index 0000000000..d1661a0f36 --- /dev/null +++ b/packages/strapi-plugin-content-manager/controllers/uid.js @@ -0,0 +1,41 @@ +'use strict'; + +const { getService } = require('../utils'); +const { + validateGenerateUIDInput, + validateCheckUIDAvailabilityInput, + validateUIDField, +} = require('./validation'); + +module.exports = { + async generateUID(ctx) { + const { contentTypeUID, field, data } = await validateGenerateUIDInput(ctx.request.body); + + await validateUIDField(contentTypeUID, field); + + const uidService = getService('uid'); + + ctx.body = { + data: await uidService.generateUIDField({ contentTypeUID, field, data }), + }; + }, + + async checkUIDAvailability(ctx) { + const { contentTypeUID, field, value } = await validateCheckUIDAvailabilityInput( + ctx.request.body + ); + + await validateUIDField(contentTypeUID, field); + + const uidService = getService('uid'); + + const isAvailable = await uidService.checkUIDAvailability({ contentTypeUID, field, value }); + + ctx.body = { + isAvailable, + suggestion: !isAvailable + ? await uidService.findUniqueUID({ contentTypeUID, field, value }) + : null, + }; + }, +}; diff --git a/packages/strapi-plugin-content-manager/oas.yml b/packages/strapi-plugin-content-manager/oas.yml index 57a49b4e9e..d5ea305b9f 100644 --- a/packages/strapi-plugin-content-manager/oas.yml +++ b/packages/strapi-plugin-content-manager/oas.yml @@ -2,7 +2,16 @@ openapi: 3.0.2 info: version: 1.0.0 title: Strapi Content Manager API - description: This is nice + description: | + ## REST API Reference + + This doc contains all the available routes in the content manager REST API. + + ### Requirements + + - An authenticated admin token that you can get using the login route + --- + servers: - url: http://localhost:1337 description: Local server @@ -191,23 +200,89 @@ paths: data: $ref: '#/components/schemas/component-configuration' + # UID /content-manager/uid/generate: post: tags: - UID attribute utils description: Generate a uid + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - contentTypeUID + - field + - data + properties: + contentTypeUID: + type: string + field: + type: string + data: + type: object + description: Current value of the entry being created or edited + responses: + 200: + description: A generated uid value + content: + application/json: + schema: + type: object + required: + - data + properties: + data: + type: string + /content-manager/uid/check-availability: post: tags: - UID attribute utils description: Check availability of a uid + requestBody: + required: true + content: + application/json: + schema: + type: object + required: + - contentTypeUID + - field + - data + properties: + contentTypeUID: + type: string + field: + type: string + value: + type: string + responses: + 200: + description: A generated uid value + content: + application/json: + schema: + type: object + required: + - isAvailable + properties: + isAvailable: + type: boolean + suggestion: + type: string + description: Suggestion if request value is not available + # Relationships /content-manager/relationships/{modelUid}/{targetField}: get: tags: - Relational fields description: Fetch list of possible related content + # Collection type /content-manager/collection-type/{modelUid}: get: tags: @@ -246,6 +321,7 @@ paths: - Collection Types content management description: Unpublish one entry + # Single type /content-manager/single-type/{modelUid}: get: tags: diff --git a/packages/strapi-plugin-content-manager/services/content-types.js b/packages/strapi-plugin-content-manager/services/content-types.js index c6440996a4..a712acb9c5 100644 --- a/packages/strapi-plugin-content-manager/services/content-types.js +++ b/packages/strapi-plugin-content-manager/services/content-types.js @@ -1,6 +1,6 @@ 'use strict'; -const { isNil, propEq, mapValues } = require('lodash/fp'); +const { isNil, mapValues } = require('lodash/fp'); const { contentTypes: contentTypesUtils } = require('strapi-utils'); const { getService } = require('../utils'); @@ -33,7 +33,7 @@ const service = { }, findDisplayedContentTypes() { - return this.findAllContentTypes().filter(propEq(true, 'isDisplayed')); + return this.findAllContentTypes().filter(({ isDisplayed }) => isDisplayed === true); }, findContentTypesByKind(kind = contentTypesUtils.constants.COLLECTION_TYPE) { diff --git a/packages/strapi-plugin-content-manager/test/content-manager/uid.test.e2e.js b/packages/strapi-plugin-content-manager/test/content-manager/uid.test.e2e.js index a19843f8a0..7127b97cbe 100644 --- a/packages/strapi-plugin-content-manager/test/content-manager/uid.test.e2e.js +++ b/packages/strapi-plugin-content-manager/test/content-manager/uid.test.e2e.js @@ -39,7 +39,7 @@ describe('Content Manager single types', () => { describe('Generate UID', () => { test('Throws if input is not provided', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: {}, }); @@ -59,7 +59,7 @@ describe('Content Manager single types', () => { test('Throws when contentType is not found', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: 'non-existent', @@ -79,7 +79,7 @@ describe('Content Manager single types', () => { test('Throws when field is not a uid field', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -99,9 +99,9 @@ describe('Content Manager single types', () => { }); }); - test('Generates a unique field when not targetField', async () => { + test('Generates a unique field when targetField is empty', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -122,7 +122,7 @@ describe('Content Manager single types', () => { }); const secondRes = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -137,7 +137,7 @@ describe('Content Manager single types', () => { test('Generates a unique field based on targetField', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -160,7 +160,7 @@ describe('Content Manager single types', () => { }); const secondRes = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -177,7 +177,7 @@ describe('Content Manager single types', () => { test('Avoids collisions with already generated uids', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -200,7 +200,7 @@ describe('Content Manager single types', () => { }); const secondRes = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -223,7 +223,7 @@ describe('Content Manager single types', () => { }); const thridRes = await rq({ - url: `/content-manager/explorer/uid/generate`, + url: `/content-manager/uid/generate`, method: 'POST', body: { contentTypeUID: uid, @@ -242,7 +242,7 @@ describe('Content Manager single types', () => { describe('Check UID availability', () => { test('Throws if input is not provided', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/check-availability`, + url: `/content-manager/uid/check-availability`, method: 'POST', body: {}, }); @@ -262,7 +262,7 @@ describe('Content Manager single types', () => { test('Throws on invalid uid value', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/check-availability`, + url: `/content-manager/uid/check-availability`, method: 'POST', body: { contentTypeUID: uid, @@ -281,7 +281,7 @@ describe('Content Manager single types', () => { test('Throws when contentType is not found', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/check-availability`, + url: `/content-manager/uid/check-availability`, method: 'POST', body: { contentTypeUID: 'non-existent', @@ -301,7 +301,7 @@ describe('Content Manager single types', () => { test('Throws when field is not a uid field', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/check-availability`, + url: `/content-manager/uid/check-availability`, method: 'POST', body: { contentTypeUID: uid, @@ -323,7 +323,7 @@ describe('Content Manager single types', () => { test('Checks availability', async () => { const res = await rq({ - url: `/content-manager/explorer/uid/check-availability`, + url: `/content-manager/uid/check-availability`, method: 'POST', body: { contentTypeUID: uid, @@ -350,7 +350,7 @@ describe('Content Manager single types', () => { }); const res = await rq({ - url: `/content-manager/explorer/uid/check-availability`, + url: `/content-manager/uid/check-availability`, method: 'POST', body: { contentTypeUID: uid,