mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: create stubs for bulk toggle (#3792)
This commit is contained in:
		
							parent
							
								
									6a12403eca
								
							
						
					
					
						commit
						45505d6996
					
				@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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}`, () => {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										24
									
								
								src/lib/openapi/spec/bulk-toggle-features-schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/lib/openapi/spec/bulk-toggle-features-schema.ts
									
									
									
									
									
										Normal 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
 | 
			
		||||
>;
 | 
			
		||||
@ -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';
 | 
			
		||||
 | 
			
		||||
@ -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>,
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -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.",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user