mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: feature lifecycle completed schema (#7021)
1. Added new schema and tests 2. Controller also accepts the data 3. Also sending fake data from frontend currently Next steps, implement service/store layer and frontend
This commit is contained in:
		
							parent
							
								
									8ea034cc2f
								
							
						
					
					
						commit
						28a7797aea
					
				@ -10,6 +10,7 @@ const useFeatureLifecycleApi = () => {
 | 
				
			|||||||
        const path = `api/admin/projects/${project}/features/${name}/lifecycle/complete`;
 | 
					        const path = `api/admin/projects/${project}/features/${name}/lifecycle/complete`;
 | 
				
			||||||
        const req = createRequest(path, {
 | 
					        const req = createRequest(path, {
 | 
				
			||||||
            method: 'POST',
 | 
					            method: 'POST',
 | 
				
			||||||
 | 
					            body: JSON.stringify({ status: 'kept' }),
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return makeRequest(req.caller, req.id);
 | 
					        return makeRequest(req.caller, req.id);
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import {
 | 
				
			|||||||
} from '../../types';
 | 
					} from '../../types';
 | 
				
			||||||
import type { OpenApiService } from '../../services';
 | 
					import type { OpenApiService } from '../../services';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					    createRequestSchema,
 | 
				
			||||||
    createResponseSchema,
 | 
					    createResponseSchema,
 | 
				
			||||||
    emptyResponse,
 | 
					    emptyResponse,
 | 
				
			||||||
    featureLifecycleSchema,
 | 
					    featureLifecycleSchema,
 | 
				
			||||||
@ -78,6 +79,9 @@ export default class FeatureLifecycleController extends Controller {
 | 
				
			|||||||
                    summary: 'Set feature completed',
 | 
					                    summary: 'Set feature completed',
 | 
				
			||||||
                    description: 'This will set the feature as completed.',
 | 
					                    description: 'This will set the feature as completed.',
 | 
				
			||||||
                    operationId: 'complete',
 | 
					                    operationId: 'complete',
 | 
				
			||||||
 | 
					                    requestBody: createRequestSchema(
 | 
				
			||||||
 | 
					                        'featureLifecycleCompletedSchema',
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
                    responses: {
 | 
					                    responses: {
 | 
				
			||||||
                        200: emptyResponse,
 | 
					                        200: emptyResponse,
 | 
				
			||||||
                        ...getStandardResponses(401, 403, 404),
 | 
					                        ...getStandardResponses(401, 403, 404),
 | 
				
			||||||
 | 
				
			|||||||
@ -17,6 +17,7 @@ import {
 | 
				
			|||||||
    type FeatureLifecycleService,
 | 
					    type FeatureLifecycleService,
 | 
				
			||||||
    STAGE_ENTERED,
 | 
					    STAGE_ENTERED,
 | 
				
			||||||
} from './feature-lifecycle-service';
 | 
					} from './feature-lifecycle-service';
 | 
				
			||||||
 | 
					import type { FeatureLifecycleCompletedSchema } from '../../openapi';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let app: IUnleashTest;
 | 
					let app: IUnleashTest;
 | 
				
			||||||
let db: ITestDb;
 | 
					let db: ITestDb;
 | 
				
			||||||
@ -61,11 +62,16 @@ const getFeatureLifecycle = async (featureName: string, expectedCode = 200) => {
 | 
				
			|||||||
        .get(`/api/admin/projects/default/features/${featureName}/lifecycle`)
 | 
					        .get(`/api/admin/projects/default/features/${featureName}/lifecycle`)
 | 
				
			||||||
        .expect(expectedCode);
 | 
					        .expect(expectedCode);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
const completeFeature = async (featureName: string, expectedCode = 200) => {
 | 
					const completeFeature = async (
 | 
				
			||||||
 | 
					    featureName: string,
 | 
				
			||||||
 | 
					    status: FeatureLifecycleCompletedSchema,
 | 
				
			||||||
 | 
					    expectedCode = 200,
 | 
				
			||||||
 | 
					) => {
 | 
				
			||||||
    return app.request
 | 
					    return app.request
 | 
				
			||||||
        .post(
 | 
					        .post(
 | 
				
			||||||
            `/api/admin/projects/default/features/${featureName}/lifecycle/complete`,
 | 
					            `/api/admin/projects/default/features/${featureName}/lifecycle/complete`,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					        .send(status)
 | 
				
			||||||
        .expect(expectedCode);
 | 
					        .expect(expectedCode);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -156,7 +162,10 @@ test('should return lifecycle stages', async () => {
 | 
				
			|||||||
test('should be able to toggle between completed/uncompleted', async () => {
 | 
					test('should be able to toggle between completed/uncompleted', async () => {
 | 
				
			||||||
    await app.createFeature('my_feature_b');
 | 
					    await app.createFeature('my_feature_b');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await completeFeature('my_feature_b');
 | 
					    await completeFeature('my_feature_b', {
 | 
				
			||||||
 | 
					        status: 'kept',
 | 
				
			||||||
 | 
					        statusValue: 'variant1',
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await expectFeatureStage('my_feature_b', 'completed');
 | 
					    await expectFeatureStage('my_feature_b', 'completed');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import { validateSchema } from '../validate';
 | 
				
			||||||
 | 
					import type { FeatureLifecycleCompletedSchema } from './feature-lifecycle-completed-schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('featureLifecycleCompletedSchema', () => {
 | 
				
			||||||
 | 
					    const data: FeatureLifecycleCompletedSchema = {
 | 
				
			||||||
 | 
					        status: 'kept',
 | 
				
			||||||
 | 
					        statusValue: 'variant1',
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(
 | 
				
			||||||
 | 
					        validateSchema(
 | 
				
			||||||
 | 
					            '#/components/schemas/featureLifecycleCompletedSchema',
 | 
				
			||||||
 | 
					            data,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ).toBeUndefined();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('featureLifecycleCompletedSchema without status', () => {
 | 
				
			||||||
 | 
					    const data: FeatureLifecycleCompletedSchema = {
 | 
				
			||||||
 | 
					        status: 'kept',
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(
 | 
				
			||||||
 | 
					        validateSchema(
 | 
				
			||||||
 | 
					            '#/components/schemas/featureLifecycleCompletedSchema',
 | 
				
			||||||
 | 
					            data,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ).toBeUndefined();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/lib/openapi/spec/feature-lifecycle-completed-schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/lib/openapi/spec/feature-lifecycle-completed-schema.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					import type { FromSchema } from 'json-schema-to-ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const featureLifecycleCompletedSchema = {
 | 
				
			||||||
 | 
					    $id: '#/components/schemas/featureLifecycleCompletedSchema',
 | 
				
			||||||
 | 
					    description: 'A feature that has been marked as completed',
 | 
				
			||||||
 | 
					    additionalProperties: false,
 | 
				
			||||||
 | 
					    type: 'object',
 | 
				
			||||||
 | 
					    required: ['status'],
 | 
				
			||||||
 | 
					    properties: {
 | 
				
			||||||
 | 
					        status: {
 | 
				
			||||||
 | 
					            type: 'string',
 | 
				
			||||||
 | 
					            enum: ['kept', 'discarded'],
 | 
				
			||||||
 | 
					            example: 'kept',
 | 
				
			||||||
 | 
					            description:
 | 
				
			||||||
 | 
					                'The status of the feature after it has been marked as completed',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        statusValue: {
 | 
				
			||||||
 | 
					            type: 'string',
 | 
				
			||||||
 | 
					            example: 'variant1',
 | 
				
			||||||
 | 
					            description: 'The metadata value passed in together with status',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					        schemas: {},
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					} as const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type FeatureLifecycleCompletedSchema = FromSchema<
 | 
				
			||||||
 | 
					    typeof featureLifecycleCompletedSchema
 | 
				
			||||||
 | 
					>;
 | 
				
			||||||
@ -75,6 +75,7 @@ export * from './feature-dependencies-schema';
 | 
				
			|||||||
export * from './feature-environment-metrics-schema';
 | 
					export * from './feature-environment-metrics-schema';
 | 
				
			||||||
export * from './feature-environment-schema';
 | 
					export * from './feature-environment-schema';
 | 
				
			||||||
export * from './feature-events-schema';
 | 
					export * from './feature-events-schema';
 | 
				
			||||||
 | 
					export * from './feature-lifecycle-completed-schema';
 | 
				
			||||||
export * from './feature-lifecycle-schema';
 | 
					export * from './feature-lifecycle-schema';
 | 
				
			||||||
export * from './feature-metrics-schema';
 | 
					export * from './feature-metrics-schema';
 | 
				
			||||||
export * from './feature-schema';
 | 
					export * from './feature-schema';
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user