1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-05-31 01:16:01 +02:00

feat: create stubs for bulk toggle (#3792)

This commit is contained in:
Mateusz Kwasniewski 2023-05-17 10:21:08 +02:00 committed by GitHub
parent 6a12403eca
commit 45505d6996
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 259 additions and 1 deletions

View File

@ -11,6 +11,7 @@ import {
applicationSchema,
applicationsSchema,
batchFeaturesSchema,
bulkToggleFeaturesSchema,
changePasswordSchema,
clientApplicationSchema,
clientFeatureSchema,
@ -194,6 +195,7 @@ export const schemas: UnleashSchemas = {
batchStaleSchema,
bulkRegistrationSchema,
bulkMetricsSchema,
bulkToggleFeaturesSchema,
changePasswordSchema,
clientApplicationSchema,
clientFeatureSchema,

View File

@ -289,7 +289,7 @@ const metaRules: Rule[] = [
describe.each(metaRules)('OpenAPI schemas $name', (rule) => {
const validateMetaSchema = ajv.compile(rule.metaSchema);
// test all schemas agaisnt the rule
// test all schemas against the rule
Object.entries(schemas).forEach(([schemaName, schema]) => {
if (!rule.match || rule.match(schemaName, schema)) {
it(`${schemaName}`, () => {

View File

@ -0,0 +1,24 @@
import { FromSchema } from 'json-schema-to-ts';
export const bulkToggleFeaturesSchema = {
$id: '#/components/schemas/bulkToggleFeaturesSchema',
type: 'object',
required: ['features'],
description: 'The feature list used for bulk toggle operations',
properties: {
features: {
type: 'array',
description: 'The features that we want to bulk toggle',
items: {
type: 'string',
description: 'The feature name we want to toggle',
},
example: ['feature-a', 'feature-b'],
},
},
components: {},
} as const;
export type BulkToggleFeaturesSchema = FromSchema<
typeof bulkToggleFeaturesSchema
>;

View File

@ -134,3 +134,4 @@ export * from './tags-bulk-add-schema';
export * from './upsert-segment-schema';
export * from './batch-features-schema';
export * from './token-string-list-schema';
export * from './bulk-toggle-features-schema';

View File

@ -20,6 +20,7 @@ import { extractUsername } from '../../../util';
import { IAuthRequest } from '../../unleash-types';
import {
AdminFeaturesQuerySchema,
BulkToggleFeaturesSchema,
CreateFeatureSchema,
CreateFeatureStrategySchema,
createRequestSchema,
@ -49,6 +50,11 @@ interface FeatureStrategyParams {
sortOrder?: number;
}
interface BulkFeaturesStrategyParams {
projectId: string;
environment: string;
}
interface FeatureStrategyQuery {
shouldActivateDisabledStrategies: string;
}
@ -78,6 +84,7 @@ const PATH_STALE = '/:projectId/stale';
const PATH_FEATURE = `${PATH}/:featureName`;
const PATH_FEATURE_CLONE = `${PATH_FEATURE}/clone`;
const PATH_ENV = `${PATH_FEATURE}/environments/:environment`;
const BULK_PATH_ENV = `/:projectId/bulk_features/environments/:environment`;
const PATH_STRATEGIES = `${PATH_ENV}/strategies`;
const PATH_STRATEGY = `${PATH_STRATEGIES}/:strategyId`;
@ -151,6 +158,46 @@ export default class ProjectFeaturesController extends Controller {
],
});
this.route({
method: 'post',
path: `${BULK_PATH_ENV}/on`,
handler: this.bulkToggleFeaturesEnvironmentOn,
permission: UPDATE_FEATURE_ENVIRONMENT,
middleware: [
openApiService.validPath({
tags: ['Unstable'],
description:
'This endpoint enables multiple feature toggles.',
summary: 'Bulk enable a list of features.',
operationId: 'bulkToggleFeaturesEnvironmentOn',
requestBody: createRequestSchema(
'bulkToggleFeaturesSchema',
),
responses: { 405: emptyResponse },
}),
],
});
this.route({
method: 'post',
path: `${BULK_PATH_ENV}/off`,
handler: this.bulkToggleFeaturesEnvironmentOff,
permission: UPDATE_FEATURE_ENVIRONMENT,
middleware: [
openApiService.validPath({
tags: ['Unstable'],
description:
'This endpoint disables multiple feature toggles.',
summary: 'Bulk disabled a list of features.',
operationId: 'bulkToggleFeaturesEnvironmentOff',
requestBody: createRequestSchema(
'bulkToggleFeaturesSchema',
),
responses: { 405: emptyResponse },
}),
],
});
this.route({
method: 'get',
path: PATH_STRATEGIES,
@ -667,6 +714,30 @@ export default class ProjectFeaturesController extends Controller {
res.status(200).end();
}
async bulkToggleFeaturesEnvironmentOn(
req: IAuthRequest<
BulkFeaturesStrategyParams,
any,
BulkToggleFeaturesSchema,
FeatureStrategyQuery
>,
res: Response<void>,
): Promise<void> {
res.status(405).end();
}
async bulkToggleFeaturesEnvironmentOff(
req: IAuthRequest<
BulkFeaturesStrategyParams,
any,
BulkToggleFeaturesSchema,
FeatureStrategyQuery
>,
res: Response<void>,
): Promise<void> {
res.status(405).end();
}
async toggleFeatureEnvironmentOff(
req: IAuthRequest<FeatureStrategyParams, any, any, any>,
res: Response<void>,

View File

@ -372,6 +372,57 @@ test('Can enable/disable environment for feature with strategies', async () => {
});
});
test('Can bulk enable/disable environment for feature with strategies', async () => {
const envName = 'bulk-enable-feature-environment';
const featureName = 'com.test.bulk.enable.environment';
const project = 'default';
// Create environment
await db.stores.environmentStore.create({
name: envName,
type: 'production',
});
// Connect environment to project
await app.request
.post(`/api/admin/projects/${project}/environments`)
.send({
environment: envName,
})
.expect(200);
// Create feature
await app.createFeature(featureName).expect((res) => {
expect(res.body.name).toBe(featureName);
expect(res.body.createdAt).toBeTruthy();
});
// Add strategy to it
await app.request
.post(
`/api/admin/projects/${project}/features/${featureName}/environments/${envName}/strategies`,
)
.send({
name: 'default',
parameters: {
userId: 'string',
},
})
.expect(200);
await app.request
.post(
`/api/admin/projects/${project}/bulk_features/environments/${envName}/on`,
)
.send({ features: [featureName] })
.set('Content-Type', 'application/json')
.expect(405);
await app.request
.post(
`/api/admin/projects/${project}/bulk_features/environments/${envName}/off`,
)
.send({ features: [featureName] })
.expect(405);
});
test("Trying to get a project that doesn't exist yields 404", async () => {
await app.request.get('/api/admin/projects/nonexisting').expect(404);
});

View File

@ -926,6 +926,27 @@ The provider you choose for your addon dictates what properties the \`parameters
],
"type": "object",
},
"bulkToggleFeaturesSchema": {
"description": "The feature list used for bulk toggle operations",
"properties": {
"features": {
"description": "The features that we want to bulk toggle",
"example": [
"feature-a",
"feature-b",
],
"items": {
"description": "The feature name we want to toggle",
"type": "string",
},
"type": "array",
},
},
"required": [
"features",
],
"type": "object",
},
"changePasswordSchema": {
"additionalProperties": false,
"properties": {
@ -9159,6 +9180,94 @@ If the provided project does not exist, the list of events will be empty.",
],
},
},
"/api/admin/projects/{projectId}/bulk_features/environments/{environment}/off": {
"post": {
"description": "This endpoint disables multiple feature toggles.",
"operationId": "bulkToggleFeaturesEnvironmentOff",
"parameters": [
{
"in": "path",
"name": "projectId",
"required": true,
"schema": {
"type": "string",
},
},
{
"in": "path",
"name": "environment",
"required": true,
"schema": {
"type": "string",
},
},
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/bulkToggleFeaturesSchema",
},
},
},
"description": "bulkToggleFeaturesSchema",
"required": true,
},
"responses": {
"405": {
"description": "This response has no body.",
},
},
"summary": "Bulk disabled a list of features.",
"tags": [
"Unstable",
],
},
},
"/api/admin/projects/{projectId}/bulk_features/environments/{environment}/on": {
"post": {
"description": "This endpoint enables multiple feature toggles.",
"operationId": "bulkToggleFeaturesEnvironmentOn",
"parameters": [
{
"in": "path",
"name": "projectId",
"required": true,
"schema": {
"type": "string",
},
},
{
"in": "path",
"name": "environment",
"required": true,
"schema": {
"type": "string",
},
},
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/bulkToggleFeaturesSchema",
},
},
},
"description": "bulkToggleFeaturesSchema",
"required": true,
},
"responses": {
"405": {
"description": "This response has no body.",
},
},
"summary": "Bulk enable a list of features.",
"tags": [
"Unstable",
],
},
},
"/api/admin/projects/{projectId}/delete": {
"post": {
"description": "This endpoint deletes the specified features, that are in archive.",