1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01: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:
Christopher Kolstad 2021-10-11 11:27:20 +02:00
parent 1e2a0d9045
commit d176028a00
3 changed files with 85 additions and 8 deletions

View File

@ -172,15 +172,11 @@ export default class ProjectFeaturesController extends Controller {
res: Response,
): Promise<void> {
const { projectId, featureName } = req.params;
const featureToggle = await this.featureService.getFeatureMetadata(
featureName,
);
const { newDocument } = applyPatch(featureToggle, req.body);
const userName = extractUsername(req);
const updated = await this.featureService.updateFeatureToggle(
const updated = await this.featureService.patchFeature(
projectId,
newDocument,
userName,
featureName,
extractUsername(req),
req.body,
);
res.status(200).json(updated);
}

View File

@ -45,6 +45,7 @@ import {
import { IFeatureEnvironmentStore } from '../types/stores/feature-environment-store';
import { IFeatureToggleClientStore } from '../types/stores/feature-toggle-client-store';
import { DEFAULT_ENV } from '../util/constants';
import { applyPatch, deepClone, Operation } from 'fast-json-patch';
class FeatureToggleServiceV2 {
private logger: Logger;
@ -94,6 +95,34 @@ class FeatureToggleServiceV2 {
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(
strategyConfig: Omit<IStrategyConfig, 'id'>,
projectId: string,

View File

@ -6,6 +6,8 @@ import {
FEATURE_ENVIRONMENT_DISABLED,
FEATURE_ENVIRONMENT_ENABLED,
FEATURE_METADATA_UPDATED,
FEATURE_STALE_OFF,
FEATURE_STALE_ON,
FEATURE_STRATEGY_REMOVE,
} from '../../../../../lib/types/events';
@ -531,6 +533,56 @@ test('Should patch feature toggle', async () => {
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 () => {
const url = '/api/admin/projects/default/features';
const name = 'new.toggle.archive';