mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
Merge pull request #696 from Unleash/feat-695-tags-included-in-events
Added tags to events table and emitted events
This commit is contained in:
commit
187798262e
@ -3,7 +3,14 @@
|
||||
const { EventEmitter } = require('events');
|
||||
const { DROP_FEATURES } = require('../event-type');
|
||||
|
||||
const EVENT_COLUMNS = ['id', 'type', 'created_by', 'created_at', 'data'];
|
||||
const EVENT_COLUMNS = [
|
||||
'id',
|
||||
'type',
|
||||
'created_by',
|
||||
'created_at',
|
||||
'data',
|
||||
'tags',
|
||||
];
|
||||
|
||||
class EventStore extends EventEmitter {
|
||||
constructor(db) {
|
||||
@ -14,8 +21,9 @@ class EventStore extends EventEmitter {
|
||||
async store(event) {
|
||||
await this.db('events').insert({
|
||||
type: event.type,
|
||||
created_by: event.createdBy, // eslint-disable-line
|
||||
created_by: event.createdBy, // eslint-disable-line
|
||||
data: event.data,
|
||||
tags: event.tags ? JSON.stringify(event.tags) : [],
|
||||
});
|
||||
this.emit(event.type, event);
|
||||
}
|
||||
@ -56,6 +64,7 @@ class EventStore extends EventEmitter {
|
||||
createdBy: row.created_by,
|
||||
createdAt: row.created_at,
|
||||
data: row.data,
|
||||
tags: row.tags,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ test('should revive toggle', t => {
|
||||
});
|
||||
|
||||
test('should create event when reviving toggle', async t => {
|
||||
t.plan(4);
|
||||
t.plan(6);
|
||||
const name = 'name1';
|
||||
const {
|
||||
request,
|
||||
@ -99,13 +99,24 @@ test('should create event when reviving toggle', async t => {
|
||||
strategies: [{ name: 'default' }],
|
||||
});
|
||||
|
||||
await featureToggleService.addTag(
|
||||
name,
|
||||
{
|
||||
type: 'simple',
|
||||
value: 'tag',
|
||||
},
|
||||
'test@test.com',
|
||||
);
|
||||
|
||||
await request.post(`${base}/api/admin/archive/revive/${name}`);
|
||||
|
||||
const events = await eventStore.getEvents();
|
||||
t.is(events.length, 1);
|
||||
t.is(events[0].type, 'feature-revived');
|
||||
t.is(events[0].data.name, name);
|
||||
t.is(events[0].createdBy, 'unknown');
|
||||
t.is(events.length, 3);
|
||||
t.is(events[2].type, 'feature-revived');
|
||||
t.is(events[2].data.name, name);
|
||||
t.is(events[2].createdBy, 'unknown');
|
||||
t.is(events[2].tags[0].type, 'simple');
|
||||
t.is(events[2].tags[0].value, 'tag');
|
||||
});
|
||||
|
||||
test('should require toggle name when reviving', t => {
|
||||
|
@ -8,7 +8,11 @@ const { createServices } = require('../../services');
|
||||
const permissions = require('../../../test/fixtures/permissions');
|
||||
const getLogger = require('../../../test/fixtures/no-logger');
|
||||
const getApp = require('../../app');
|
||||
const { UPDATE_FEATURE, CREATE_FEATURE } = require('../../permissions');
|
||||
const {
|
||||
UPDATE_FEATURE,
|
||||
CREATE_FEATURE,
|
||||
DELETE_FEATURE,
|
||||
} = require('../../permissions');
|
||||
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
@ -31,6 +35,7 @@ function getSetup() {
|
||||
base,
|
||||
perms,
|
||||
featureToggleStore: stores.featureToggleStore,
|
||||
eventStore: stores.eventStore,
|
||||
request: supertest(app),
|
||||
};
|
||||
}
|
||||
@ -523,3 +528,55 @@ test('Should be able to filter on project', t => {
|
||||
t.is(res.body.features[1].name, 'a_tag.toggle');
|
||||
});
|
||||
});
|
||||
|
||||
test('Tags should be included in archive events', async t => {
|
||||
const { request, eventStore, featureToggleStore, base, perms } = getSetup();
|
||||
perms.withPermissions(UPDATE_FEATURE, DELETE_FEATURE);
|
||||
|
||||
featureToggleStore.createFeature({
|
||||
name: 'a_team.toggle',
|
||||
enabled: false,
|
||||
strategies: [{ name: 'default' }],
|
||||
project: 'projecta',
|
||||
});
|
||||
featureToggleStore.tagFeature('a_team.toggle', {
|
||||
type: 'simple',
|
||||
value: 'tag',
|
||||
});
|
||||
await request
|
||||
.delete(`${base}/api/admin/features/a_team.toggle`)
|
||||
.expect(200);
|
||||
const events = await eventStore.getEvents();
|
||||
t.is(events[0].type, 'feature-archived');
|
||||
t.is(events[0].tags[0].type, 'simple');
|
||||
t.is(events[0].tags[0].value, 'tag');
|
||||
});
|
||||
|
||||
test('Tags should be included in updated events', async t => {
|
||||
const { request, eventStore, featureToggleStore, base, perms } = getSetup();
|
||||
perms.withPermissions(UPDATE_FEATURE, DELETE_FEATURE);
|
||||
|
||||
featureToggleStore.createFeature({
|
||||
name: 'a_team.toggle',
|
||||
enabled: false,
|
||||
strategies: [{ name: 'default' }],
|
||||
project: 'projecta',
|
||||
});
|
||||
featureToggleStore.tagFeature('a_team.toggle', {
|
||||
type: 'simple',
|
||||
value: 'tag',
|
||||
});
|
||||
await request
|
||||
.put(`${base}/api/admin/features/a_team.toggle`)
|
||||
.send({
|
||||
name: 'a_team.toggle',
|
||||
enabled: false,
|
||||
strategies: [{ name: 'default' }],
|
||||
project: 'projectb',
|
||||
})
|
||||
.expect(200);
|
||||
const events = await eventStore.getEvents();
|
||||
t.is(events[0].type, 'feature-updated');
|
||||
t.is(events[0].tags[0].type, 'simple');
|
||||
t.is(events[0].tags[0].value, 'tag');
|
||||
});
|
||||
|
@ -75,29 +75,41 @@ class FeatureToggleService {
|
||||
await this.featureToggleStore.getFeature(updatedFeature.name);
|
||||
const value = await featureSchema.validateAsync(updatedFeature);
|
||||
await this.featureToggleStore.updateFeature(value);
|
||||
const tags =
|
||||
(await this.featureToggleStore.getAllTagsForFeature(
|
||||
updatedFeature.name,
|
||||
)) || [];
|
||||
await this.eventStore.store({
|
||||
type: FEATURE_UPDATED,
|
||||
createdBy: userName,
|
||||
data: updatedFeature,
|
||||
tags,
|
||||
});
|
||||
}
|
||||
|
||||
async archiveToggle(name, userName) {
|
||||
await this.featureToggleStore.getFeature(name);
|
||||
await this.featureToggleStore.archiveFeature(name);
|
||||
const tags =
|
||||
(await this.featureToggleStore.getAllTagsForFeature(name)) || [];
|
||||
await this.eventStore.store({
|
||||
type: FEATURE_ARCHIVED,
|
||||
createdBy: userName,
|
||||
data: { name },
|
||||
tags,
|
||||
});
|
||||
}
|
||||
|
||||
async reviveToggle(name, userName) {
|
||||
await this.featureToggleStore.reviveFeature({ name });
|
||||
const tags =
|
||||
(await this.featureToggleStore.getAllTagsForFeature(name)) || [];
|
||||
|
||||
await this.eventStore.store({
|
||||
type: FEATURE_REVIVED,
|
||||
createdBy: userName,
|
||||
data: { name },
|
||||
tags,
|
||||
});
|
||||
}
|
||||
|
||||
@ -181,10 +193,15 @@ class FeatureToggleService {
|
||||
const feature = await this.featureToggleStore.getFeature(featureName);
|
||||
feature[field] = value;
|
||||
await this.featureToggleStore.updateFeature(feature);
|
||||
const tags =
|
||||
(await this.featureToggleStore.getAllTagsForFeature(featureName)) ||
|
||||
[];
|
||||
|
||||
await this.eventStore.store({
|
||||
type: FEATURE_UPDATED,
|
||||
createdBy: userName,
|
||||
data: feature,
|
||||
tags,
|
||||
});
|
||||
return feature;
|
||||
}
|
||||
|
18
migrations/20210127094440-add-tags-column-to-events.js
Normal file
18
migrations/20210127094440-add-tags-column-to-events.js
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
exports.up = function(db, cb) {
|
||||
db.runSql(
|
||||
`
|
||||
ALTER TABLE events ADD COLUMN IF NOT EXISTS tags json DEFAULT '[]'
|
||||
`,
|
||||
cb,
|
||||
);
|
||||
};
|
||||
exports.down = function(db, cb) {
|
||||
db.runSql(
|
||||
`
|
||||
ALTER TABLE events DROP COLUMN IF EXISTS tags;
|
||||
`,
|
||||
cb,
|
||||
);
|
||||
};
|
7
test/fixtures/fake-feature-toggle-store.js
vendored
7
test/fixtures/fake-feature-toggle-store.js
vendored
@ -31,6 +31,13 @@ module.exports = () => {
|
||||
);
|
||||
_features.push(updatedFeature);
|
||||
},
|
||||
archiveFeature: feature => {
|
||||
_features.slice(
|
||||
_features.indexOf(({ name }) => name === feature.name),
|
||||
1,
|
||||
);
|
||||
_archive.push(feature);
|
||||
},
|
||||
createFeature: feature => _features.push(feature),
|
||||
getArchivedFeatures: () => Promise.resolve(_archive),
|
||||
addArchivedFeature: feature => _archive.push(feature),
|
||||
|
Loading…
Reference in New Issue
Block a user