2018-12-12 10:09:38 +01:00
|
|
|
'use strict';
|
|
|
|
|
2021-01-22 13:39:42 +01:00
|
|
|
const { featureSchema, querySchema } = require('./feature-schema');
|
2018-12-12 10:09:38 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should require URL firendly name', () => {
|
2018-12-12 10:09:38 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'io`dasd',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { error } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toEqual('"name" must be URL friendly');
|
2018-12-12 10:09:38 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should be valid toggle name', () => {
|
2018-12-12 10:09:38 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.name',
|
|
|
|
enabled: false,
|
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { value } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value.name).toBe(toggle.name);
|
2018-12-12 10:09:38 +01:00
|
|
|
});
|
2019-01-29 09:21:54 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should strip extra variant fields', () => {
|
2019-01-29 09:21:54 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.name',
|
2020-08-06 11:18:52 +02:00
|
|
|
type: 'release',
|
2019-01-29 09:21:54 +01:00
|
|
|
enabled: false,
|
2020-08-07 10:46:35 +02:00
|
|
|
stale: false,
|
2019-01-29 09:21:54 +01:00
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
variants: [
|
|
|
|
{
|
|
|
|
name: 'variant-a',
|
|
|
|
weight: 1,
|
|
|
|
unkown: 'not-allowed',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { value } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value).not.toEqual(toggle);
|
|
|
|
expect(value.variants[0].unkown).toBeFalsy();
|
2019-01-29 09:21:54 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should allow weightType=fix', () => {
|
2020-08-03 13:24:51 +02:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.name',
|
2020-08-06 11:18:52 +02:00
|
|
|
type: 'release',
|
2020-09-28 21:54:44 +02:00
|
|
|
project: 'default',
|
2020-08-03 13:24:51 +02:00
|
|
|
enabled: false,
|
2020-08-07 10:46:35 +02:00
|
|
|
stale: false,
|
2020-08-03 13:24:51 +02:00
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
variants: [
|
|
|
|
{
|
|
|
|
name: 'variant-a',
|
|
|
|
weight: 1,
|
|
|
|
weightType: 'fix',
|
2021-02-11 17:59:16 +01:00
|
|
|
stickiness: 'default',
|
2020-08-03 13:24:51 +02:00
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { value } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value).toEqual(toggle);
|
2020-08-03 13:24:51 +02:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should disallow weightType=unknown', () => {
|
2020-08-03 13:24:51 +02:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.name',
|
2020-08-06 11:18:52 +02:00
|
|
|
type: 'release',
|
2020-08-03 13:24:51 +02:00
|
|
|
enabled: false,
|
2020-08-07 10:46:35 +02:00
|
|
|
stale: false,
|
2020-08-03 13:24:51 +02:00
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
variants: [
|
|
|
|
{
|
|
|
|
name: 'variant-a',
|
|
|
|
weight: 1,
|
|
|
|
weightType: 'unknown',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { error } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toEqual(
|
2020-08-03 13:24:51 +02:00
|
|
|
'"variants[0].weightType" must be one of [variable, fix]',
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should be possible to define variant overrides', () => {
|
2019-01-29 09:21:54 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.name',
|
2020-08-06 11:18:52 +02:00
|
|
|
type: 'release',
|
2020-09-28 21:54:44 +02:00
|
|
|
project: 'some',
|
2019-01-29 09:21:54 +01:00
|
|
|
enabled: false,
|
2020-08-07 10:46:35 +02:00
|
|
|
stale: false,
|
2019-01-29 09:21:54 +01:00
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
variants: [
|
|
|
|
{
|
|
|
|
name: 'variant-a',
|
|
|
|
weight: 1,
|
2020-08-03 13:24:51 +02:00
|
|
|
weightType: 'variable',
|
2021-02-11 17:59:16 +01:00
|
|
|
stickiness: 'default',
|
2019-01-29 09:21:54 +01:00
|
|
|
overrides: [
|
|
|
|
{
|
2019-02-04 14:04:58 +01:00
|
|
|
contextName: 'userId',
|
2019-01-29 09:21:54 +01:00
|
|
|
values: ['123'],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { value, error } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value).toEqual(toggle);
|
|
|
|
expect(error).toBeFalsy();
|
2019-01-29 09:21:54 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('variant overrides must have corect shape', async () => {
|
|
|
|
expect.assertions(1);
|
2019-01-29 09:21:54 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.name',
|
2020-08-06 11:18:52 +02:00
|
|
|
type: 'release',
|
2019-01-29 09:21:54 +01:00
|
|
|
enabled: false,
|
2020-08-07 10:46:35 +02:00
|
|
|
stale: false,
|
2019-01-29 09:21:54 +01:00
|
|
|
strategies: [{ name: 'default' }],
|
|
|
|
variants: [
|
|
|
|
{
|
|
|
|
name: 'variant-a',
|
|
|
|
weight: 1,
|
|
|
|
overrides: {
|
|
|
|
userId: ['not-alloed'],
|
|
|
|
sessionId: ['not-alloed'],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
|
|
|
try {
|
2021-01-18 12:32:19 +01:00
|
|
|
await featureSchema.validateAsync(toggle);
|
2019-01-29 09:21:54 +01:00
|
|
|
} catch (error) {
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toBe(
|
2020-04-14 22:29:11 +02:00
|
|
|
'"variants[0].overrides" must be an array',
|
2020-01-02 19:23:52 +01:00
|
|
|
);
|
2019-01-29 09:21:54 +01:00
|
|
|
}
|
|
|
|
});
|
2019-11-20 22:11:30 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should keep constraints', () => {
|
2019-11-20 22:11:30 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.constraints',
|
2020-08-06 11:18:52 +02:00
|
|
|
type: 'release',
|
2020-09-28 21:54:44 +02:00
|
|
|
project: 'default',
|
2019-11-20 22:11:30 +01:00
|
|
|
enabled: false,
|
2020-08-07 10:46:35 +02:00
|
|
|
stale: false,
|
2019-11-20 22:11:30 +01:00
|
|
|
strategies: [
|
|
|
|
{
|
|
|
|
name: 'default',
|
|
|
|
constraints: [
|
|
|
|
{
|
|
|
|
contextName: 'environment',
|
|
|
|
operator: 'IN',
|
|
|
|
values: ['asd'],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { value, error } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value).toEqual(toggle);
|
|
|
|
expect(error).toBeFalsy();
|
2019-11-20 22:11:30 +01:00
|
|
|
});
|
2020-10-30 10:30:28 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should not accept empty constraint values', () => {
|
2020-10-30 10:30:28 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.constraints.empty.value',
|
|
|
|
type: 'release',
|
|
|
|
enabled: false,
|
|
|
|
stale: false,
|
|
|
|
strategies: [
|
|
|
|
{
|
|
|
|
name: 'default',
|
|
|
|
constraints: [
|
|
|
|
{
|
|
|
|
contextName: 'environment',
|
|
|
|
operator: 'IN',
|
|
|
|
values: [''],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { error } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toEqual(
|
2020-10-30 10:30:28 +01:00
|
|
|
'"strategies[0].constraints[0].values[0]" is not allowed to be empty',
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('should not accept empty list of constraint values', () => {
|
2020-10-30 10:30:28 +01:00
|
|
|
const toggle = {
|
|
|
|
name: 'app.constraints.empty.value.list',
|
|
|
|
type: 'release',
|
|
|
|
enabled: false,
|
|
|
|
stale: false,
|
|
|
|
strategies: [
|
|
|
|
{
|
|
|
|
name: 'default',
|
|
|
|
constraints: [
|
|
|
|
{
|
|
|
|
contextName: 'environment',
|
|
|
|
operator: 'IN',
|
|
|
|
values: [],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2021-01-18 12:32:19 +01:00
|
|
|
const { error } = featureSchema.validate(toggle);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toEqual(
|
2020-10-30 16:40:29 +01:00
|
|
|
'"strategies[0].constraints[0].values" must contain at least 1 items',
|
|
|
|
);
|
2020-10-30 10:30:28 +01:00
|
|
|
});
|
2021-01-22 13:39:42 +01:00
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('Filter queries should accept a list of tag values', () => {
|
2021-01-22 13:39:42 +01:00
|
|
|
const query = {
|
|
|
|
tag: ['simple:valuea', 'simple:valueb'],
|
|
|
|
};
|
|
|
|
const { value } = querySchema.validate(query);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value).toEqual({ tag: ['simple:valuea', 'simple:valueb'] });
|
2021-01-22 13:39:42 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('Filter queries should reject tag values with missing type prefix', () => {
|
2021-01-22 13:39:42 +01:00
|
|
|
const query = {
|
|
|
|
tag: ['simple', 'simple'],
|
|
|
|
};
|
|
|
|
const { error } = querySchema.validate(query);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toEqual(
|
2021-01-22 13:39:42 +01:00
|
|
|
'"tag[0]" with value "simple" fails to match the tag pattern',
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('Filter queries should allow project names', () => {
|
2021-01-22 13:39:42 +01:00
|
|
|
const query = {
|
|
|
|
project: ['projecta'],
|
|
|
|
};
|
|
|
|
const { value } = querySchema.validate(query);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(value).toEqual({ project: ['projecta'] });
|
2021-01-22 13:39:42 +01:00
|
|
|
});
|
|
|
|
|
2021-05-28 11:10:24 +02:00
|
|
|
test('Filter queries should reject project names that are not alphanum', () => {
|
2021-01-22 13:39:42 +01:00
|
|
|
const query = {
|
|
|
|
project: ['project name with space'],
|
|
|
|
};
|
|
|
|
const { error } = querySchema.validate(query);
|
2021-05-28 11:10:24 +02:00
|
|
|
expect(error.details[0].message).toEqual(
|
|
|
|
'"project[0]" must be URL friendly',
|
|
|
|
);
|
2021-01-22 13:39:42 +01:00
|
|
|
});
|