mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
refactor: add OpenAPI schema to constraints controller (#1683)
* refactor: add OpenAPI schema to constraints controller * refactor: add more schema tests
This commit is contained in:
parent
c55d390a53
commit
1ed8dd0f0d
@ -0,0 +1,61 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`constraintSchema invalid operator name 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"contextName": "a",
|
||||
"operator": "b",
|
||||
"value": "1",
|
||||
},
|
||||
"errors": Array [
|
||||
Object {
|
||||
"instancePath": "/operator",
|
||||
"keyword": "enum",
|
||||
"message": "must be equal to one of the allowed values",
|
||||
"params": Object {
|
||||
"allowedValues": Array [
|
||||
"NOT_IN",
|
||||
"IN",
|
||||
"STR_ENDS_WITH",
|
||||
"STR_STARTS_WITH",
|
||||
"STR_CONTAINS",
|
||||
"NUM_EQ",
|
||||
"NUM_GT",
|
||||
"NUM_GTE",
|
||||
"NUM_LT",
|
||||
"NUM_LTE",
|
||||
"DATE_AFTER",
|
||||
"DATE_BEFORE",
|
||||
"SEMVER_EQ",
|
||||
"SEMVER_GT",
|
||||
"SEMVER_LT",
|
||||
],
|
||||
},
|
||||
"schemaPath": "#/properties/operator/enum",
|
||||
},
|
||||
],
|
||||
"schema": "#/components/schemas/constraintSchema",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`constraintSchema invalid value type 1`] = `
|
||||
Object {
|
||||
"data": Object {
|
||||
"contextName": "a",
|
||||
"operator": "NUM_LTE",
|
||||
"value": 1,
|
||||
},
|
||||
"errors": Array [
|
||||
Object {
|
||||
"instancePath": "/value",
|
||||
"keyword": "type",
|
||||
"message": "must be string",
|
||||
"params": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"schemaPath": "#/properties/value/type",
|
||||
},
|
||||
],
|
||||
"schema": "#/components/schemas/constraintSchema",
|
||||
}
|
||||
`;
|
34
src/lib/openapi/spec/constraint-schema.test.ts
Normal file
34
src/lib/openapi/spec/constraint-schema.test.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { validateSchema } from '../validate';
|
||||
import { ConstraintSchema } from './constraint-schema';
|
||||
|
||||
test('constraintSchema', () => {
|
||||
const data: ConstraintSchema = {
|
||||
contextName: 'a',
|
||||
operator: 'NUM_LTE',
|
||||
value: '1',
|
||||
};
|
||||
|
||||
expect(
|
||||
validateSchema('#/components/schemas/constraintSchema', data),
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
test('constraintSchema invalid value type', () => {
|
||||
expect(
|
||||
validateSchema('#/components/schemas/constraintSchema', {
|
||||
contextName: 'a',
|
||||
operator: 'NUM_LTE',
|
||||
value: 1,
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('constraintSchema invalid operator name', () => {
|
||||
expect(
|
||||
validateSchema('#/components/schemas/constraintSchema', {
|
||||
contextName: 'a',
|
||||
operator: 'b',
|
||||
value: '1',
|
||||
}),
|
||||
).toMatchSnapshot();
|
||||
});
|
7
src/lib/openapi/validate.test.ts
Normal file
7
src/lib/openapi/validate.test.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { validateSchema } from './validate';
|
||||
|
||||
test('validateSchema', () => {
|
||||
expect(() => validateSchema('unknownSchemaId' as any, {})).toThrow(
|
||||
'no schema with key or ref "unknownSchemaId"',
|
||||
);
|
||||
});
|
@ -6,27 +6,49 @@ import { IConstraint } from '../../types/model';
|
||||
import { NONE } from '../../types/permissions';
|
||||
import Controller from '../controller';
|
||||
import { Logger } from '../../logger';
|
||||
import { OpenApiService } from '../../services/openapi-service';
|
||||
import { createRequestSchema } from '../../openapi';
|
||||
|
||||
export default class ConstraintController extends Controller {
|
||||
private featureService: FeatureToggleService;
|
||||
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(
|
||||
config: IUnleashConfig,
|
||||
{
|
||||
featureToggleServiceV2,
|
||||
}: Pick<IUnleashServices, 'featureToggleServiceV2'>,
|
||||
openApiService,
|
||||
}: Pick<IUnleashServices, 'featureToggleServiceV2' | 'openApiService'>,
|
||||
) {
|
||||
super(config);
|
||||
this.featureService = featureToggleServiceV2;
|
||||
this.openApiService = openApiService;
|
||||
this.logger = config.getLogger('/admin-api/validation.ts');
|
||||
|
||||
this.post('/validate', this.validateConstraint, NONE);
|
||||
this.route({
|
||||
method: 'post',
|
||||
path: '/validate',
|
||||
handler: this.validateConstraint,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
tags: ['admin'],
|
||||
operationId: 'validateConstraint',
|
||||
requestBody: createRequestSchema('constraintSchema'),
|
||||
responses: {
|
||||
204: { description: 'validConstraint' },
|
||||
400: { description: 'invalidConstraint' },
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async validateConstraint(
|
||||
req: Request<{}, undefined, IConstraint>,
|
||||
req: Request<void, void, IConstraint>,
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
await this.featureService.validateConstraint(req.body);
|
||||
|
@ -987,6 +987,33 @@ Object {
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/constraints/validate": Object {
|
||||
"post": Object {
|
||||
"operationId": "validateConstraint",
|
||||
"requestBody": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/constraintSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "constraintSchema",
|
||||
"required": true,
|
||||
},
|
||||
"responses": Object {
|
||||
"204": Object {
|
||||
"description": "validConstraint",
|
||||
},
|
||||
"400": Object {
|
||||
"description": "invalidConstraint",
|
||||
},
|
||||
},
|
||||
"tags": Array [
|
||||
"admin",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/features": Object {
|
||||
"get": Object {
|
||||
"deprecated": true,
|
||||
|
Loading…
Reference in New Issue
Block a user