mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-19 01:17:18 +02:00
Trigger STALE events when patching stale field
- Also moved the patch function into service, instead of performing the operation in the controller
This commit is contained in:
parent
1e2a0d9045
commit
d176028a00
@ -172,15 +172,11 @@ export default class ProjectFeaturesController extends Controller {
|
|||||||
res: Response,
|
res: Response,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { projectId, featureName } = req.params;
|
const { projectId, featureName } = req.params;
|
||||||
const featureToggle = await this.featureService.getFeatureMetadata(
|
const updated = await this.featureService.patchFeature(
|
||||||
featureName,
|
|
||||||
);
|
|
||||||
const { newDocument } = applyPatch(featureToggle, req.body);
|
|
||||||
const userName = extractUsername(req);
|
|
||||||
const updated = await this.featureService.updateFeatureToggle(
|
|
||||||
projectId,
|
projectId,
|
||||||
newDocument,
|
featureName,
|
||||||
userName,
|
extractUsername(req),
|
||||||
|
req.body,
|
||||||
);
|
);
|
||||||
res.status(200).json(updated);
|
res.status(200).json(updated);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import {
|
|||||||
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
|
||||||
import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client-store';
|
import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client-store';
|
||||||
import { DEFAULT_ENV } from '../util/constants';
|
import { DEFAULT_ENV } from '../util/constants';
|
||||||
|
import { applyPatch, deepClone, Operation } from 'fast-json-patch';
|
||||||
|
|
||||||
class FeatureToggleServiceV2 {
|
class FeatureToggleServiceV2 {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
@ -94,6 +95,34 @@ class FeatureToggleServiceV2 {
|
|||||||
this.featureEnvironmentStore = featureEnvironmentStore;
|
this.featureEnvironmentStore = featureEnvironmentStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async patchFeature(
|
||||||
|
projectId: string,
|
||||||
|
featureName: string,
|
||||||
|
userName: string,
|
||||||
|
operations: Operation[],
|
||||||
|
): Promise<FeatureToggle> {
|
||||||
|
const featureToggle = await this.getFeatureMetadata(featureName);
|
||||||
|
|
||||||
|
const { newDocument } = applyPatch(
|
||||||
|
deepClone(featureToggle),
|
||||||
|
operations,
|
||||||
|
);
|
||||||
|
const updated = await this.updateFeatureToggle(
|
||||||
|
projectId,
|
||||||
|
newDocument,
|
||||||
|
userName,
|
||||||
|
);
|
||||||
|
if (featureToggle.stale !== newDocument.stale) {
|
||||||
|
await this.eventStore.store({
|
||||||
|
type: newDocument.stale ? FEATURE_STALE_ON : FEATURE_STALE_OFF,
|
||||||
|
data: updated,
|
||||||
|
project: projectId,
|
||||||
|
createdBy: userName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return updated;
|
||||||
|
}
|
||||||
|
|
||||||
async createStrategy(
|
async createStrategy(
|
||||||
strategyConfig: Omit<IStrategyConfig, 'id'>,
|
strategyConfig: Omit<IStrategyConfig, 'id'>,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
|
@ -6,6 +6,8 @@ import {
|
|||||||
FEATURE_ENVIRONMENT_DISABLED,
|
FEATURE_ENVIRONMENT_DISABLED,
|
||||||
FEATURE_ENVIRONMENT_ENABLED,
|
FEATURE_ENVIRONMENT_ENABLED,
|
||||||
FEATURE_METADATA_UPDATED,
|
FEATURE_METADATA_UPDATED,
|
||||||
|
FEATURE_STALE_OFF,
|
||||||
|
FEATURE_STALE_ON,
|
||||||
FEATURE_STRATEGY_REMOVE,
|
FEATURE_STRATEGY_REMOVE,
|
||||||
} from '../../../../../lib/types/events';
|
} from '../../../../../lib/types/events';
|
||||||
|
|
||||||
@ -531,6 +533,56 @@ test('Should patch feature toggle', async () => {
|
|||||||
expect(updateForOurToggle.data.type).toBe('kill-switch');
|
expect(updateForOurToggle.data.type).toBe('kill-switch');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Patching feature toggles to stale should trigger FEATURE_STALE_ON event', async () => {
|
||||||
|
const url = '/api/admin/projects/default/features';
|
||||||
|
const name = 'toggle.stale.on.patch';
|
||||||
|
await app.request
|
||||||
|
.post(url)
|
||||||
|
.send({ name, description: 'some', type: 'release', stale: false })
|
||||||
|
.expect(201);
|
||||||
|
await app.request
|
||||||
|
.patch(`${url}/${name}`)
|
||||||
|
.send([{ op: 'replace', path: '/stale', value: true }])
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
const { body: toggle } = await app.request.get(`${url}/${name}`);
|
||||||
|
|
||||||
|
expect(toggle.name).toBe(name);
|
||||||
|
expect(toggle.archived).toBeFalsy();
|
||||||
|
expect(toggle.stale).toBeTruthy();
|
||||||
|
const events = await db.stores.eventStore.getAll({
|
||||||
|
type: FEATURE_STALE_ON,
|
||||||
|
});
|
||||||
|
const updateForOurToggle = events.find((e) => e.data.name === name);
|
||||||
|
expect(updateForOurToggle).toBeTruthy();
|
||||||
|
expect(updateForOurToggle.data.stale).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Patching feature toggles to active (turning stale to false) should trigger FEATURE_STALE_OFF event', async () => {
|
||||||
|
const url = '/api/admin/projects/default/features';
|
||||||
|
const name = 'toggle.stale.off.patch';
|
||||||
|
await app.request
|
||||||
|
.post(url)
|
||||||
|
.send({ name, description: 'some', type: 'release', stale: true })
|
||||||
|
.expect(201);
|
||||||
|
await app.request
|
||||||
|
.patch(`${url}/${name}`)
|
||||||
|
.send([{ op: 'replace', path: '/stale', value: false }])
|
||||||
|
.expect(200);
|
||||||
|
|
||||||
|
const { body: toggle } = await app.request.get(`${url}/${name}`);
|
||||||
|
|
||||||
|
expect(toggle.name).toBe(name);
|
||||||
|
expect(toggle.archived).toBeFalsy();
|
||||||
|
expect(toggle.stale).toBe(false);
|
||||||
|
const events = await db.stores.eventStore.getAll({
|
||||||
|
type: FEATURE_STALE_OFF,
|
||||||
|
});
|
||||||
|
const updateForOurToggle = events.find((e) => e.data.name === name);
|
||||||
|
expect(updateForOurToggle).toBeTruthy();
|
||||||
|
expect(updateForOurToggle.data.stale).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
test('Should archive feature toggle', async () => {
|
test('Should archive feature toggle', async () => {
|
||||||
const url = '/api/admin/projects/default/features';
|
const url = '/api/admin/projects/default/features';
|
||||||
const name = 'new.toggle.archive';
|
const name = 'new.toggle.archive';
|
||||||
|
Loading…
Reference in New Issue
Block a user