diff --git a/lib/routes/admin-api/feature-schema.js b/lib/routes/admin-api/feature-schema.js index fc730624fc..17b8f6f112 100644 --- a/lib/routes/admin-api/feature-schema.js +++ b/lib/routes/admin-api/feature-schema.js @@ -24,6 +24,15 @@ const variantsSchema = joi.object().keys({ value: joi.string().required(), }) .optional(), + overrides: joi.array().items( + joi + .object() + .keys({ + field: joi.string().required(), + values: joi.array().items(joi.string()), + }) + .optional() + ), }); const featureShema = joi diff --git a/lib/routes/admin-api/feature-schema.test.js b/lib/routes/admin-api/feature-schema.test.js index 8dc789a63c..b3a9249ff6 100644 --- a/lib/routes/admin-api/feature-schema.test.js +++ b/lib/routes/admin-api/feature-schema.test.js @@ -25,3 +25,71 @@ test('should be valid toggle name', t => { const { value } = joi.validate(toggle, featureShema); t.deepEqual(value, toggle); }); + +test('should strip extra variant fields', t => { + const toggle = { + name: 'app.name', + enabled: false, + strategies: [{ name: 'default' }], + variants: [ + { + name: 'variant-a', + weight: 1, + unkown: 'not-allowed', + }, + ], + }; + + const { value } = joi.validate(toggle, featureShema); + t.notDeepEqual(value, toggle); + t.falsy(value.variants[0].unkown); +}); + +test('should be possible to define variant overrides', t => { + const toggle = { + name: 'app.name', + enabled: false, + strategies: [{ name: 'default' }], + variants: [ + { + name: 'variant-a', + weight: 1, + overrides: [ + { + field: 'userId', + values: ['123'], + }, + ], + }, + ], + }; + + const { value, error } = joi.validate(toggle, featureShema); + t.deepEqual(value, toggle); + t.falsy(error); +}); + +test('variant overrides must have corect shape', async t => { + t.plan(1); + const toggle = { + name: 'app.name', + enabled: false, + strategies: [{ name: 'default' }], + variants: [ + { + name: 'variant-a', + weight: 1, + overrides: { + userId: ['not-alloed'], + sessionId: ['not-alloed'], + }, + }, + ], + }; + + try { + await joi.validate(toggle, featureShema); + } catch (error) { + t.is(error.details[0].message, '"overrides" must be an array'); + } +}); diff --git a/test/e2e/api/admin/feature.e2e.test.js b/test/e2e/api/admin/feature.e2e.test.js index 4067aab271..f646ef422b 100644 --- a/test/e2e/api/admin/feature.e2e.test.js +++ b/test/e2e/api/admin/feature.e2e.test.js @@ -234,3 +234,31 @@ test.serial('should not be possible to create archived toggle', async t => { .expect(400) .then(destroy); }); + +test.serial('creates new feature toggle with variant overrides', async t => { + t.plan(0); + const { request, destroy } = await setupApp('feature_api_serial'); + return request + .post('/api/admin/features') + .send({ + name: 'com.test.variants', + enabled: false, + strategies: [{ name: 'default' }], + variants: [ + { + name: 'variant1', + weight: 50, + overrides: [ + { + field: 'userId', + values: ['123'], + }, + ], + }, + { name: 'variant2', weight: 50 }, + ], + }) + .set('Content-Type', 'application/json') + .expect(201) + .then(destroy); +});