mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: return 400 when enabling env of archived toggle (#6049)
Creates a new ArchivedFeatureError. Throw this error when trying to toggle a feature environment for an archived feature. Closes https://github.com/orgs/Unleash/projects/8/views/1?pane=issue&itemId=51242922 Signed-off-by: andreas-unleash <andreas@getunleash.ai>
This commit is contained in:
		
							parent
							
								
									a1fa5a4212
								
							
						
					
					
						commit
						4a2d1b0364
					
				
							
								
								
									
										13
									
								
								src/lib/error/archivedfeature-error.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/lib/error/archivedfeature-error.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | import { UnleashError } from './unleash-error'; | ||||||
|  | 
 | ||||||
|  | class ArchivedFeatureError extends UnleashError { | ||||||
|  |     statusCode = 400; | ||||||
|  | 
 | ||||||
|  |     constructor( | ||||||
|  |         message: string = 'Cannot perform this operation on archived features', | ||||||
|  |     ) { | ||||||
|  |         super(message); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | export default ArchivedFeatureError; | ||||||
|  | module.exports = ArchivedFeatureError; | ||||||
| @ -104,6 +104,7 @@ import { IDependentFeaturesReadModel } from '../dependent-features/dependent-fea | |||||||
| import EventService from '../events/event-service'; | import EventService from '../events/event-service'; | ||||||
| import { DependentFeaturesService } from '../dependent-features/dependent-features-service'; | import { DependentFeaturesService } from '../dependent-features/dependent-features-service'; | ||||||
| import { FeatureToggleInsert } from './feature-toggle-store'; | import { FeatureToggleInsert } from './feature-toggle-store'; | ||||||
|  | import ArchivedFeatureError from '../../error/archivedfeature-error'; | ||||||
| 
 | 
 | ||||||
| interface IFeatureContext { | interface IFeatureContext { | ||||||
|     featureName: string; |     featureName: string; | ||||||
| @ -259,6 +260,17 @@ class FeatureToggleService { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     async validateFeatureIsNotArchived( | ||||||
|  |         featureName: string, | ||||||
|  |         project: string, | ||||||
|  |     ): Promise<void> { | ||||||
|  |         const toggle = await this.featureToggleStore.get(featureName); | ||||||
|  | 
 | ||||||
|  |         if (toggle.archived || Boolean(toggle.archivedAt)) { | ||||||
|  |             throw new ArchivedFeatureError(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     async validateNoChildren(featureName: string): Promise<void> { |     async validateNoChildren(featureName: string): Promise<void> { | ||||||
|         const children = await this.dependentFeaturesReadModel.getChildren([ |         const children = await this.dependentFeaturesReadModel.getChildren([ | ||||||
|             featureName, |             featureName, | ||||||
| @ -1748,6 +1760,8 @@ class FeatureToggleService { | |||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         await this.validateFeatureIsNotArchived(featureName, project); | ||||||
|  | 
 | ||||||
|         if (enabled) { |         if (enabled) { | ||||||
|             const strategies = await this.getStrategiesForEnvironment( |             const strategies = await this.getStrategiesForEnvironment( | ||||||
|                 project, |                 project, | ||||||
|  | |||||||
| @ -1707,6 +1707,50 @@ test('Disabling environment creates a FEATURE_ENVIRONMENT_DISABLED event', async | |||||||
|     expect(ourFeatureEvent).toBeTruthy(); |     expect(ourFeatureEvent).toBeTruthy(); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | test('Returns 400 when toggling environment of archived feature', async () => { | ||||||
|  |     const environment = 'environment_test_archived'; | ||||||
|  |     const featureName = 'test_archived_feature'; | ||||||
|  | 
 | ||||||
|  |     // Create environment
 | ||||||
|  |     await db.stores.environmentStore.create({ | ||||||
|  |         name: environment, | ||||||
|  |         type: 'test', | ||||||
|  |     }); | ||||||
|  |     // Connect environment to project
 | ||||||
|  |     await app.request | ||||||
|  |         .post('/api/admin/projects/default/environments') | ||||||
|  |         .send({ environment }) | ||||||
|  |         .expect(200); | ||||||
|  | 
 | ||||||
|  |     // Create feature
 | ||||||
|  |     await app.request | ||||||
|  |         .post('/api/admin/projects/default/features') | ||||||
|  |         .send({ | ||||||
|  |             name: featureName, | ||||||
|  |         }) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(201); | ||||||
|  |     // Archive feature
 | ||||||
|  |     await app.request | ||||||
|  |         .delete(`/api/admin/projects/default/features/${featureName}`) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(202); | ||||||
|  | 
 | ||||||
|  |     await app.request | ||||||
|  |         .post( | ||||||
|  |             `/api/admin/projects/default/features/${featureName}/environments/${environment}/strategies`, | ||||||
|  |         ) | ||||||
|  |         .send({ name: 'default', constraints: [] }) | ||||||
|  |         .expect(200); | ||||||
|  | 
 | ||||||
|  |     await app.request | ||||||
|  |         .post( | ||||||
|  |             `/api/admin/projects/default/features/${featureName}/environments/${environment}/on`, | ||||||
|  |         ) | ||||||
|  |         .set('Content-Type', 'application/json') | ||||||
|  |         .expect(400); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
| test('Can delete strategy from feature toggle', async () => { | test('Can delete strategy from feature toggle', async () => { | ||||||
|     const envName = 'del-strategy'; |     const envName = 'del-strategy'; | ||||||
|     const featureName = 'feature.strategy.toggle.delete.strategy'; |     const featureName = 'feature.strategy.toggle.delete.strategy'; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user