mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: revived feature goes to initial lifecycle stage (#6944)
This commit is contained in:
parent
675e1a9f8b
commit
8ed15165d2
@ -35,6 +35,10 @@ export class FakeFeatureLifecycleStore implements IFeatureLifecycleStore {
|
|||||||
return this.lifecycles[feature] || [];
|
return this.lifecycles[feature] || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async delete(feature: string): Promise<void> {
|
||||||
|
this.lifecycles[feature] = [];
|
||||||
|
}
|
||||||
|
|
||||||
async stageExists(stage: FeatureLifecycleStage): Promise<boolean> {
|
async stageExists(stage: FeatureLifecycleStage): Promise<boolean> {
|
||||||
const lifecycle = await this.get(stage.feature);
|
const lifecycle = await this.get(stage.feature);
|
||||||
return Boolean(lifecycle.find((s) => s.stage === stage.stage));
|
return Boolean(lifecycle.find((s) => s.stage === stage.stage));
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
FEATURE_ARCHIVED,
|
FEATURE_ARCHIVED,
|
||||||
FEATURE_COMPLETED,
|
FEATURE_COMPLETED,
|
||||||
FEATURE_CREATED,
|
FEATURE_CREATED,
|
||||||
|
FEATURE_REVIVED,
|
||||||
type IEnvironment,
|
type IEnvironment,
|
||||||
type IUnleashConfig,
|
type IUnleashConfig,
|
||||||
type StageName,
|
type StageName,
|
||||||
@ -82,6 +83,14 @@ test('can insert and read lifecycle stages', async () => {
|
|||||||
{ stage: 'completed', enteredStageAt: expect.any(Date) },
|
{ stage: 'completed', enteredStageAt: expect.any(Date) },
|
||||||
{ stage: 'archived', enteredStageAt: expect.any(Date) },
|
{ stage: 'archived', enteredStageAt: expect.any(Date) },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
eventStore.emit(FEATURE_REVIVED, { featureName });
|
||||||
|
await reachedStage('initial');
|
||||||
|
const initialLifecycle =
|
||||||
|
await featureLifecycleService.getFeatureLifecycle(featureName);
|
||||||
|
expect(initialLifecycle).toEqual([
|
||||||
|
{ stage: 'initial', enteredStageAt: expect.any(Date) },
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ignores lifecycle state updates when flag disabled', async () => {
|
test('ignores lifecycle state updates when flag disabled', async () => {
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
FEATURE_ARCHIVED,
|
FEATURE_ARCHIVED,
|
||||||
FEATURE_COMPLETED,
|
FEATURE_COMPLETED,
|
||||||
FEATURE_CREATED,
|
FEATURE_CREATED,
|
||||||
|
FEATURE_REVIVED,
|
||||||
type IEnvironmentStore,
|
type IEnvironmentStore,
|
||||||
type IEventStore,
|
type IEventStore,
|
||||||
type IFlagResolver,
|
type IFlagResolver,
|
||||||
@ -93,6 +94,11 @@ export class FeatureLifecycleService extends EventEmitter {
|
|||||||
this.featureArchived(event.featureName),
|
this.featureArchived(event.featureName),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
this.eventStore.on(FEATURE_REVIVED, async (event) => {
|
||||||
|
await this.checkEnabled(() =>
|
||||||
|
this.featureRevived(event.featureName),
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFeatureLifecycle(feature: string): Promise<FeatureLifecycleView> {
|
async getFeatureLifecycle(feature: string): Promise<FeatureLifecycleView> {
|
||||||
@ -155,4 +161,9 @@ export class FeatureLifecycleService extends EventEmitter {
|
|||||||
]);
|
]);
|
||||||
this.emit(STAGE_ENTERED, { stage: 'archived' });
|
this.emit(STAGE_ENTERED, { stage: 'archived' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async featureRevived(feature: string) {
|
||||||
|
await this.featureLifecycleStore.delete(feature);
|
||||||
|
await this.featureInitialized(feature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,5 @@ export interface IFeatureLifecycleStore {
|
|||||||
insert(featureLifecycleStages: FeatureLifecycleStage[]): Promise<void>;
|
insert(featureLifecycleStages: FeatureLifecycleStage[]): Promise<void>;
|
||||||
get(feature: string): Promise<FeatureLifecycleView>;
|
get(feature: string): Promise<FeatureLifecycleView>;
|
||||||
stageExists(stage: FeatureLifecycleStage): Promise<boolean>;
|
stageExists(stage: FeatureLifecycleStage): Promise<boolean>;
|
||||||
|
delete(feature: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,10 @@ export class FeatureLifecycleStore implements IFeatureLifecycleStore {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async delete(feature: string): Promise<void> {
|
||||||
|
await this.db('feature_lifecycles').where({ feature }).del();
|
||||||
|
}
|
||||||
|
|
||||||
async stageExists(stage: FeatureLifecycleStage): Promise<boolean> {
|
async stageExists(stage: FeatureLifecycleStage): Promise<boolean> {
|
||||||
const result = await this.db.raw(
|
const result = await this.db.raw(
|
||||||
`SELECT EXISTS(SELECT 1 FROM feature_lifecycles WHERE stage = ? and feature = ?) AS present`,
|
`SELECT EXISTS(SELECT 1 FROM feature_lifecycles WHERE stage = ? and feature = ?) AS present`,
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
CLIENT_METRICS,
|
CLIENT_METRICS,
|
||||||
FEATURE_ARCHIVED,
|
FEATURE_ARCHIVED,
|
||||||
FEATURE_CREATED,
|
FEATURE_CREATED,
|
||||||
|
FEATURE_REVIVED,
|
||||||
type IEventStore,
|
type IEventStore,
|
||||||
type StageName,
|
type StageName,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
@ -117,4 +118,7 @@ test('should return lifecycle stages', async () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await expectFeatureStage('archived');
|
await expectFeatureStage('archived');
|
||||||
|
|
||||||
|
eventStore.emit(FEATURE_REVIVED, { featureName: 'my_feature_a' });
|
||||||
|
await reachedStage('initial');
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user