mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: check if child and parent are in the same project (#5093)
This commit is contained in:
		
							parent
							
								
									7195a63e56
								
							
						
					
					
						commit
						56892c54d9
					
				| @ -96,9 +96,10 @@ export class DependentFeaturesService { | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         const [children, parentExists] = await Promise.all([ | ||||
|         const [children, parentExists, sameProject] = await Promise.all([ | ||||
|             this.dependentFeaturesReadModel.getChildren([child]), | ||||
|             this.featuresReadModel.featureExists(parent), | ||||
|             this.featuresReadModel.featuresInTheSameProject(child, parent), | ||||
|         ]); | ||||
| 
 | ||||
|         if (children.length > 0) { | ||||
| @ -113,6 +114,12 @@ export class DependentFeaturesService { | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         if (!sameProject) { | ||||
|             throw new InvalidOperationError( | ||||
|                 'Parent and child features should be in the same project', | ||||
|             ); | ||||
|         } | ||||
| 
 | ||||
|         const featureDependency: FeatureDependency = | ||||
|             enabled === false | ||||
|                 ? { | ||||
|  | ||||
| @ -11,7 +11,9 @@ import { | ||||
|     FEATURE_DEPENDENCY_ADDED, | ||||
|     FEATURE_DEPENDENCY_REMOVED, | ||||
|     IEventStore, | ||||
|     IUser, | ||||
| } from '../../types'; | ||||
| import { ProjectService } from '../../services'; | ||||
| 
 | ||||
| let app: IUnleashTest; | ||||
| let db: ITestDb; | ||||
| @ -34,6 +36,15 @@ beforeAll(async () => { | ||||
|     eventStore = db.stores.eventStore; | ||||
| }); | ||||
| 
 | ||||
| const createProject = async (name: string) => { | ||||
|     await db.stores.projectStore.create({ | ||||
|         name: name, | ||||
|         description: '', | ||||
|         id: name, | ||||
|         mode: 'open' as const, | ||||
|     }); | ||||
| }; | ||||
| 
 | ||||
| const getRecordedEventTypesForDependencies = async () => | ||||
|     (await eventStore.getEvents()) | ||||
|         .map((event) => event.type) | ||||
| @ -207,3 +218,19 @@ test('should not allow to add dependency to self', async () => { | ||||
|         403, | ||||
|     ); | ||||
| }); | ||||
| 
 | ||||
| test('should not allow to add dependency to feature from another project', async () => { | ||||
|     const child = uuidv4(); | ||||
|     const parent = uuidv4(); | ||||
|     await app.createFeature(parent); | ||||
|     await createProject('another-project'); | ||||
|     await app.createFeature(child, 'another-project'); | ||||
| 
 | ||||
|     await addFeatureDependency( | ||||
|         child, | ||||
|         { | ||||
|             feature: parent, | ||||
|         }, | ||||
|         403, | ||||
|     ); | ||||
| }); | ||||
|  | ||||
| @ -4,4 +4,11 @@ export class FakeFeaturesReadModel implements IFeaturesReadModel { | ||||
|     featureExists(): Promise<boolean> { | ||||
|         return Promise.resolve(false); | ||||
|     } | ||||
| 
 | ||||
|     featuresInTheSameProject( | ||||
|         featureA: string, | ||||
|         featureB: string, | ||||
|     ): Promise<boolean> { | ||||
|         return Promise.resolve(true); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -16,4 +16,14 @@ export class FeaturesReadModel implements IFeaturesReadModel { | ||||
| 
 | ||||
|         return rows.length > 0; | ||||
|     } | ||||
| 
 | ||||
|     async featuresInTheSameProject( | ||||
|         featureA: string, | ||||
|         featureB: string, | ||||
|     ): Promise<boolean> { | ||||
|         const rows = await this.db('features') | ||||
|             .countDistinct('project as count') | ||||
|             .whereIn('name', [featureA, featureB]); | ||||
|         return Number(rows[0].count) === 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,7 @@ | ||||
| export interface IFeaturesReadModel { | ||||
|     featureExists(parent: string): Promise<boolean>; | ||||
|     featuresInTheSameProject( | ||||
|         featureA: string, | ||||
|         featureB: string, | ||||
|     ): Promise<boolean>; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user