Refactored uid utils

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-10-27 15:16:20 +01:00
parent cdefc1d2de
commit b37a92c60f
6 changed files with 141 additions and 58 deletions

View File

@ -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",

View File

@ -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
*/

View File

@ -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,
};
},
};

View File

@ -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:

View File

@ -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) {

View File

@ -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,