mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-28 00:06:53 +01:00
c17a1980a2
This simplifies stores to just be storage interaction, they no longer react to events. Controllers now call services and awaits the result from the call. When the service calls are returned the database is updated. This simplifies testing dramatically, cause you know that your state is updated when returned from a call, rather than hoping the store has picked up the event (which really was a command) and reacted to it. Events are still emitted from eventStore, so other parts of the app can react to events as they're being sent out. As part of the move to services, we now also emit an application-created event when we see a new client application. Fixes: #685 Fixes: #595
230 lines
5.6 KiB
JavaScript
230 lines
5.6 KiB
JavaScript
'use strict';
|
|
|
|
const test = require('ava');
|
|
const { featureSchema } = require('./feature-schema');
|
|
|
|
test('should require URL firendly name', t => {
|
|
const toggle = {
|
|
name: 'io`dasd',
|
|
enabled: false,
|
|
strategies: [{ name: 'default' }],
|
|
};
|
|
|
|
const { error } = featureSchema.validate(toggle);
|
|
t.deepEqual(error.details[0].message, '"name" must be URL friendly');
|
|
});
|
|
|
|
test('should be valid toggle name', t => {
|
|
const toggle = {
|
|
name: 'app.name',
|
|
enabled: false,
|
|
strategies: [{ name: 'default' }],
|
|
};
|
|
|
|
const { value } = featureSchema.validate(toggle);
|
|
t.is(value.name, toggle.name);
|
|
});
|
|
|
|
test('should strip extra variant fields', t => {
|
|
const toggle = {
|
|
name: 'app.name',
|
|
type: 'release',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [{ name: 'default' }],
|
|
variants: [
|
|
{
|
|
name: 'variant-a',
|
|
weight: 1,
|
|
unkown: 'not-allowed',
|
|
},
|
|
],
|
|
};
|
|
|
|
const { value } = featureSchema.validate(toggle);
|
|
t.notDeepEqual(value, toggle);
|
|
t.falsy(value.variants[0].unkown);
|
|
});
|
|
|
|
test('should allow weightType=fix', t => {
|
|
const toggle = {
|
|
name: 'app.name',
|
|
type: 'release',
|
|
project: 'default',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [{ name: 'default' }],
|
|
variants: [
|
|
{
|
|
name: 'variant-a',
|
|
weight: 1,
|
|
weightType: 'fix',
|
|
},
|
|
],
|
|
};
|
|
|
|
const { value } = featureSchema.validate(toggle);
|
|
t.deepEqual(value, toggle);
|
|
});
|
|
|
|
test('should disallow weightType=unknown', t => {
|
|
const toggle = {
|
|
name: 'app.name',
|
|
type: 'release',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [{ name: 'default' }],
|
|
variants: [
|
|
{
|
|
name: 'variant-a',
|
|
weight: 1,
|
|
weightType: 'unknown',
|
|
},
|
|
],
|
|
};
|
|
|
|
const { error } = featureSchema.validate(toggle);
|
|
t.deepEqual(
|
|
error.details[0].message,
|
|
'"variants[0].weightType" must be one of [variable, fix]',
|
|
);
|
|
});
|
|
|
|
test('should be possible to define variant overrides', t => {
|
|
const toggle = {
|
|
name: 'app.name',
|
|
type: 'release',
|
|
project: 'some',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [{ name: 'default' }],
|
|
variants: [
|
|
{
|
|
name: 'variant-a',
|
|
weight: 1,
|
|
weightType: 'variable',
|
|
overrides: [
|
|
{
|
|
contextName: 'userId',
|
|
values: ['123'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const { value, error } = featureSchema.validate(toggle);
|
|
t.deepEqual(value, toggle);
|
|
t.falsy(error);
|
|
});
|
|
|
|
test('variant overrides must have corect shape', async t => {
|
|
t.plan(1);
|
|
const toggle = {
|
|
name: 'app.name',
|
|
type: 'release',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [{ name: 'default' }],
|
|
variants: [
|
|
{
|
|
name: 'variant-a',
|
|
weight: 1,
|
|
overrides: {
|
|
userId: ['not-alloed'],
|
|
sessionId: ['not-alloed'],
|
|
},
|
|
},
|
|
],
|
|
};
|
|
|
|
try {
|
|
await featureSchema.validateAsync(toggle);
|
|
} catch (error) {
|
|
t.is(
|
|
error.details[0].message,
|
|
'"variants[0].overrides" must be an array',
|
|
);
|
|
}
|
|
});
|
|
|
|
test('should keep constraints', t => {
|
|
const toggle = {
|
|
name: 'app.constraints',
|
|
type: 'release',
|
|
project: 'default',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [
|
|
{
|
|
name: 'default',
|
|
constraints: [
|
|
{
|
|
contextName: 'environment',
|
|
operator: 'IN',
|
|
values: ['asd'],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const { value, error } = featureSchema.validate(toggle);
|
|
t.deepEqual(value, toggle);
|
|
t.falsy(error);
|
|
});
|
|
|
|
test('should not accept empty constraint values', t => {
|
|
const toggle = {
|
|
name: 'app.constraints.empty.value',
|
|
type: 'release',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [
|
|
{
|
|
name: 'default',
|
|
constraints: [
|
|
{
|
|
contextName: 'environment',
|
|
operator: 'IN',
|
|
values: [''],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const { error } = featureSchema.validate(toggle);
|
|
t.deepEqual(
|
|
error.details[0].message,
|
|
'"strategies[0].constraints[0].values[0]" is not allowed to be empty',
|
|
);
|
|
});
|
|
|
|
test('should not accept empty list of constraint values', t => {
|
|
const toggle = {
|
|
name: 'app.constraints.empty.value.list',
|
|
type: 'release',
|
|
enabled: false,
|
|
stale: false,
|
|
strategies: [
|
|
{
|
|
name: 'default',
|
|
constraints: [
|
|
{
|
|
contextName: 'environment',
|
|
operator: 'IN',
|
|
values: [],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
|
|
const { error } = featureSchema.validate(toggle);
|
|
t.deepEqual(
|
|
error.details[0].message,
|
|
'"strategies[0].constraints[0].values" must contain at least 1 items',
|
|
);
|
|
});
|