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 { NONE } from '../../types/permissions';
|
||||||
import Controller from '../controller';
|
import Controller from '../controller';
|
||||||
import { Logger } from '../../logger';
|
import { Logger } from '../../logger';
|
||||||
|
import { OpenApiService } from '../../services/openapi-service';
|
||||||
|
import { createRequestSchema } from '../../openapi';
|
||||||
|
|
||||||
export default class ConstraintController extends Controller {
|
export default class ConstraintController extends Controller {
|
||||||
private featureService: FeatureToggleService;
|
private featureService: FeatureToggleService;
|
||||||
|
|
||||||
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
private readonly logger: Logger;
|
private readonly logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{
|
{
|
||||||
featureToggleServiceV2,
|
featureToggleServiceV2,
|
||||||
}: Pick<IUnleashServices, 'featureToggleServiceV2'>,
|
openApiService,
|
||||||
|
}: Pick<IUnleashServices, 'featureToggleServiceV2' | 'openApiService'>,
|
||||||
) {
|
) {
|
||||||
super(config);
|
super(config);
|
||||||
this.featureService = featureToggleServiceV2;
|
this.featureService = featureToggleServiceV2;
|
||||||
|
this.openApiService = openApiService;
|
||||||
this.logger = config.getLogger('/admin-api/validation.ts');
|
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(
|
async validateConstraint(
|
||||||
req: Request<{}, undefined, IConstraint>,
|
req: Request<void, void, IConstraint>,
|
||||||
res: Response,
|
res: Response,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await this.featureService.validateConstraint(req.body);
|
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 {
|
"/api/admin/features": Object {
|
||||||
"get": Object {
|
"get": Object {
|
||||||
"deprecated": true,
|
"deprecated": true,
|
||||||
|
Loading…
Reference in New Issue
Block a user