diff --git a/src/lib/features/dependent-features/dependent-features-service.ts b/src/lib/features/dependent-features/dependent-features-service.ts index ce6bf2929c93..45ccb5bd5b69 100644 --- a/src/lib/features/dependent-features/dependent-features-service.ts +++ b/src/lib/features/dependent-features/dependent-features-service.ts @@ -214,17 +214,26 @@ export class DependentFeaturesService { projectId: string, auditUser: IAuditUser, ): Promise { - await this.dependentFeaturesStore.deleteAll(features); - await this.eventService.storeEvents( - features.map( - (feature) => - new FeatureDependenciesRemovedEvent({ - project: projectId, - featureName: feature, - auditUser, - }), - ), + const dependencies = + await this.dependentFeaturesReadModel.getDependencies(features); + const featuresWithDependencies = dependencies.map( + (dependency) => dependency.feature, ); + if (featuresWithDependencies.length > 0) { + await this.dependentFeaturesStore.deleteAll( + featuresWithDependencies, + ); + await this.eventService.storeEvents( + featuresWithDependencies.map( + (feature) => + new FeatureDependenciesRemovedEvent({ + project: projectId, + featureName: feature, + auditUser, + }), + ), + ); + } } async getPossibleParentFeatures(feature: string): Promise { diff --git a/src/lib/features/dependent-features/dependent.features.e2e.test.ts b/src/lib/features/dependent-features/dependent.features.e2e.test.ts index 30decd0d8228..b84d85a0f7f8 100644 --- a/src/lib/features/dependent-features/dependent.features.e2e.test.ts +++ b/src/lib/features/dependent-features/dependent.features.e2e.test.ts @@ -58,6 +58,7 @@ beforeEach(async () => { await db.stores.dependentFeaturesStore.deleteAll(); await db.stores.featureToggleStore.deleteAll(); await db.stores.featureEnvironmentStore.deleteAll(); + await db.stores.eventStore.deleteAll(); }); const addFeatureDependency = async ( @@ -168,11 +169,13 @@ const checkDependenciesExist = async (expectedCode = 200) => { test('should add and delete feature dependencies', async () => { const parent = uuidv4(); const child = uuidv4(); + const child2 = uuidv4(); await app.createFeature(parent); await app.createFeature(child); + await app.createFeature(child2); const { body: options } = await getPossibleParentFeatures(child); - expect(options).toStrictEqual([parent]); + expect(options).toMatchObject([parent, child2].sort()); // save explicit enabled and variants await addFeatureDependency(child, { @@ -185,14 +188,21 @@ test('should add and delete feature dependencies', async () => { variants: ['variantB'], }); + await addFeatureDependency(child2, { + feature: parent, + enabled: false, + }); + await deleteFeatureDependency(child, parent); // single - await deleteFeatureDependencies(child); // all + await deleteFeatureDependencies(child2); // all - expect(await getRecordedEventTypesForDependencies()).toStrictEqual([ + const eventTypes = await getRecordedEventTypesForDependencies(); + expect(eventTypes).toStrictEqual([ FEATURE_DEPENDENCIES_REMOVED, FEATURE_DEPENDENCY_REMOVED, FEATURE_DEPENDENCY_ADDED, FEATURE_DEPENDENCY_ADDED, + FEATURE_DEPENDENCY_ADDED, ]); }); @@ -338,3 +348,35 @@ test('should not allow to add dependency to feature from another project', async 403, ); }); +test('should create feature-dependency-removed when archiving and has dependency', async () => { + const child = uuidv4(); + const parent = uuidv4(); + await app.createFeature(parent); + await app.createFeature(child); + + await addFeatureDependency(child, { + feature: parent, + }); + await app.archiveFeature(child); + const events = await eventStore.getEvents(); + expect(events).toEqual( + expect.arrayContaining([ + expect.objectContaining({ type: 'feature-dependencies-removed' }), + ]), + ); +}); + +test('should not create feature-dependency-removed when archiving and no dependency', async () => { + const child = uuidv4(); + const parent = uuidv4(); + await app.createFeature(parent); + await app.createFeature(child); + + await app.archiveFeature(child); + const events = await eventStore.getEvents(); + expect(events).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ type: 'feature-dependencies-removed' }), + ]), + ); +});