1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-28 00:17:12 +01:00

fix: feature-dependencies-removed event should not be created always (#9100)

Currently, every time you archived feature, it created
feature-dependencies-removed event.

This PR adds a check to only create events for those features that have
dependency.
This commit is contained in:
Jaanus Sellin 2025-01-15 11:55:01 +02:00 committed by GitHub
parent d6ec0f1776
commit 3a50750a33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 14 deletions

View File

@ -214,9 +214,17 @@ export class DependentFeaturesService {
projectId: string, projectId: string,
auditUser: IAuditUser, auditUser: IAuditUser,
): Promise<void> { ): Promise<void> {
await this.dependentFeaturesStore.deleteAll(features); 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( await this.eventService.storeEvents(
features.map( featuresWithDependencies.map(
(feature) => (feature) =>
new FeatureDependenciesRemovedEvent({ new FeatureDependenciesRemovedEvent({
project: projectId, project: projectId,
@ -226,6 +234,7 @@ export class DependentFeaturesService {
), ),
); );
} }
}
async getPossibleParentFeatures(feature: string): Promise<string[]> { async getPossibleParentFeatures(feature: string): Promise<string[]> {
return this.dependentFeaturesReadModel.getPossibleParentFeatures( return this.dependentFeaturesReadModel.getPossibleParentFeatures(

View File

@ -58,6 +58,7 @@ beforeEach(async () => {
await db.stores.dependentFeaturesStore.deleteAll(); await db.stores.dependentFeaturesStore.deleteAll();
await db.stores.featureToggleStore.deleteAll(); await db.stores.featureToggleStore.deleteAll();
await db.stores.featureEnvironmentStore.deleteAll(); await db.stores.featureEnvironmentStore.deleteAll();
await db.stores.eventStore.deleteAll();
}); });
const addFeatureDependency = async ( const addFeatureDependency = async (
@ -168,11 +169,13 @@ const checkDependenciesExist = async (expectedCode = 200) => {
test('should add and delete feature dependencies', async () => { test('should add and delete feature dependencies', async () => {
const parent = uuidv4(); const parent = uuidv4();
const child = uuidv4(); const child = uuidv4();
const child2 = uuidv4();
await app.createFeature(parent); await app.createFeature(parent);
await app.createFeature(child); await app.createFeature(child);
await app.createFeature(child2);
const { body: options } = await getPossibleParentFeatures(child); const { body: options } = await getPossibleParentFeatures(child);
expect(options).toStrictEqual([parent]); expect(options).toMatchObject([parent, child2].sort());
// save explicit enabled and variants // save explicit enabled and variants
await addFeatureDependency(child, { await addFeatureDependency(child, {
@ -185,14 +188,21 @@ test('should add and delete feature dependencies', async () => {
variants: ['variantB'], variants: ['variantB'],
}); });
await deleteFeatureDependency(child, parent); // single await addFeatureDependency(child2, {
await deleteFeatureDependencies(child); // all feature: parent,
enabled: false,
});
expect(await getRecordedEventTypesForDependencies()).toStrictEqual([ await deleteFeatureDependency(child, parent); // single
await deleteFeatureDependencies(child2); // all
const eventTypes = await getRecordedEventTypesForDependencies();
expect(eventTypes).toStrictEqual([
FEATURE_DEPENDENCIES_REMOVED, FEATURE_DEPENDENCIES_REMOVED,
FEATURE_DEPENDENCY_REMOVED, FEATURE_DEPENDENCY_REMOVED,
FEATURE_DEPENDENCY_ADDED, FEATURE_DEPENDENCY_ADDED,
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, 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' }),
]),
);
});