2019-03-13 19:10:13 +01:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const test = require('ava');
|
|
|
|
|
2020-11-03 14:56:07 +01:00
|
|
|
const store = require('../../test/fixtures/store');
|
|
|
|
const getLogger = require('../../test/fixtures/no-logger');
|
2019-04-30 21:14:23 +02:00
|
|
|
|
2019-03-13 19:10:13 +01:00
|
|
|
const StateService = require('./state-service');
|
|
|
|
const {
|
|
|
|
FEATURE_IMPORT,
|
|
|
|
DROP_FEATURES,
|
|
|
|
STRATEGY_IMPORT,
|
|
|
|
DROP_STRATEGIES,
|
2020-11-03 14:56:07 +01:00
|
|
|
} = require('../event-type');
|
2019-03-13 19:10:13 +01:00
|
|
|
|
|
|
|
function getSetup() {
|
|
|
|
const stores = store.createStores();
|
2020-09-28 21:54:44 +02:00
|
|
|
return {
|
|
|
|
stateService: new StateService(stores, { getLogger }),
|
|
|
|
stores,
|
|
|
|
};
|
2019-03-13 19:10:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
test('should import a feature', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
features: [
|
|
|
|
{
|
|
|
|
name: 'new-feature',
|
|
|
|
enabled: true,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
await stateService.import({ data });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 1);
|
|
|
|
t.is(events[0].type, FEATURE_IMPORT);
|
|
|
|
t.is(events[0].data.name, 'new-feature');
|
|
|
|
});
|
|
|
|
|
2020-11-03 14:56:07 +01:00
|
|
|
test('should not import an existing feature', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
features: [
|
|
|
|
{
|
|
|
|
name: 'new-feature',
|
|
|
|
enabled: true,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
await stores.featureToggleStore.createFeature(data.features[0]);
|
2020-11-03 14:56:07 +01:00
|
|
|
|
|
|
|
await stateService.import({ data, keepExisting: true });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should not keep existing feature if drop-before-import', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
features: [
|
|
|
|
{
|
|
|
|
name: 'new-feature',
|
|
|
|
enabled: true,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
await stores.featureToggleStore.createFeature(data.features[0]);
|
2020-11-03 14:56:07 +01:00
|
|
|
|
|
|
|
await stateService.import({
|
|
|
|
data,
|
|
|
|
keepExisting: true,
|
|
|
|
dropBeforeImport: true,
|
|
|
|
});
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 2);
|
|
|
|
t.is(events[0].type, DROP_FEATURES);
|
|
|
|
t.is(events[1].type, FEATURE_IMPORT);
|
|
|
|
});
|
|
|
|
|
2019-03-13 19:10:13 +01:00
|
|
|
test('should drop feature before import if specified', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
features: [
|
|
|
|
{
|
|
|
|
name: 'new-feature',
|
|
|
|
enabled: true,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
await stateService.import({ data, dropBeforeImport: true });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 2);
|
|
|
|
t.is(events[0].type, DROP_FEATURES);
|
|
|
|
t.is(events[1].type, FEATURE_IMPORT);
|
|
|
|
t.is(events[1].data.name, 'new-feature');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should import a strategy', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
strategies: [
|
|
|
|
{
|
|
|
|
name: 'new-strategy',
|
|
|
|
parameters: [],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
await stateService.import({ data });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 1);
|
|
|
|
t.is(events[0].type, STRATEGY_IMPORT);
|
|
|
|
t.is(events[0].data.name, 'new-strategy');
|
|
|
|
});
|
|
|
|
|
2020-11-03 14:56:07 +01:00
|
|
|
test('should not import an exiting strategy', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
strategies: [
|
|
|
|
{
|
|
|
|
name: 'new-strategy',
|
|
|
|
parameters: [],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
await stores.strategyStore.createStrategy(data.strategies[0]);
|
2020-11-03 14:56:07 +01:00
|
|
|
|
|
|
|
await stateService.import({ data, keepExisting: true });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 0);
|
|
|
|
});
|
|
|
|
|
2019-03-13 19:10:13 +01:00
|
|
|
test('should drop strategies before import if specified', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {
|
|
|
|
strategies: [
|
|
|
|
{
|
|
|
|
name: 'new-strategy',
|
|
|
|
parameters: [],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
await stateService.import({ data, dropBeforeImport: true });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 2);
|
|
|
|
t.is(events[0].type, DROP_STRATEGIES);
|
|
|
|
t.is(events[1].type, STRATEGY_IMPORT);
|
|
|
|
t.is(events[1].data.name, 'new-strategy');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should drop neither features nor strategies when neither is imported', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
|
|
|
const data = {};
|
|
|
|
|
|
|
|
await stateService.import({ data, dropBeforeImport: true });
|
|
|
|
|
|
|
|
const events = await stores.eventStore.getEvents();
|
|
|
|
t.is(events.length, 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should not accept gibberish', async t => {
|
|
|
|
const { stateService } = getSetup();
|
|
|
|
|
|
|
|
const data1 = {
|
|
|
|
type: 'gibberish',
|
|
|
|
flags: { evil: true },
|
|
|
|
};
|
|
|
|
const data2 = '{somerandomtext/';
|
|
|
|
|
|
|
|
await t.throwsAsync(stateService.import({ data: data1 }));
|
|
|
|
|
|
|
|
await t.throwsAsync(stateService.import({ data: data2 }));
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should export featureToggles', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
stores.featureToggleStore.createFeature({ name: 'a-feature' });
|
2019-03-13 19:10:13 +01:00
|
|
|
|
2019-03-14 17:56:02 +01:00
|
|
|
const data = await stateService.export({ includeFeatureToggles: true });
|
2019-03-13 19:10:13 +01:00
|
|
|
|
|
|
|
t.is(data.features.length, 1);
|
|
|
|
t.is(data.features[0].name, 'a-feature');
|
|
|
|
});
|
|
|
|
|
|
|
|
test('should export strategies', async t => {
|
|
|
|
const { stateService, stores } = getSetup();
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
stores.strategyStore.createStrategy({ name: 'a-strategy', editable: true });
|
2019-03-13 19:10:13 +01:00
|
|
|
|
2019-03-14 17:56:02 +01:00
|
|
|
const data = await stateService.export({ includeStrategies: true });
|
2019-03-13 19:10:13 +01:00
|
|
|
|
|
|
|
t.is(data.strategies.length, 1);
|
|
|
|
t.is(data.strategies[0].name, 'a-strategy');
|
|
|
|
});
|