diff --git a/src/lib/db/feature-strategy-store.ts b/src/lib/db/feature-strategy-store.ts index fd2d7c9ee7..d2bd270df5 100644 --- a/src/lib/db/feature-strategy-store.ts +++ b/src/lib/db/feature-strategy-store.ts @@ -287,6 +287,7 @@ class FeatureStrategiesStore implements IFeatureStrategiesStore { return e; }); featureToggle.variants = featureToggle.variants || []; + featureToggle.variants.sort((a, b) => a.name.localeCompare(b.name)); featureToggle.archived = archived; return featureToggle; } diff --git a/src/test/e2e/api/admin/project/features.e2e.test.ts b/src/test/e2e/api/admin/project/features.e2e.test.ts index df87a15ccd..edec135748 100644 --- a/src/test/e2e/api/admin/project/features.e2e.test.ts +++ b/src/test/e2e/api/admin/project/features.e2e.test.ts @@ -13,6 +13,7 @@ import { import ApiUser from '../../../../../lib/types/api-user'; import { ApiTokenType } from '../../../../../lib/types/models/api-token'; import IncompatibleProjectError from '../../../../../lib/error/incompatible-project-error'; +import { IVariant, WeightType } from '../../../../../lib/types/model'; let app: IUnleashTest; let db: ITestDb; @@ -1827,3 +1828,49 @@ test('Should allow changing project to target project with the same enabled envi ), ).resolves; }); + +test(`a feature's variants should be sorted by name in increasing order`, async () => { + const featureName = 'variants.are.sorted'; + const project = 'default'; + await app.request + .post(`/api/admin/projects/${project}/features`) + .send({ + name: featureName, + }) + .expect(201); + + const newVariants: IVariant[] = [ + { + name: 'z', + stickiness: 'default', + weight: 250, + weightType: WeightType.FIX, + }, + { + name: 'f', + stickiness: 'default', + weight: 375, + weightType: WeightType.VARIABLE, + }, + { + name: 'a', + stickiness: 'default', + weight: 450, + weightType: WeightType.VARIABLE, + }, + ]; + + await app.request + .put(`/api/admin/projects/${project}/features/${featureName}/variants`) + .send(newVariants) + .expect(200); + + await app.request + .get(`/api/admin/projects/${project}/features/${featureName}`) + .expect(200) + .expect((res) => { + expect(res.body.variants[0].name).toBe('a'); + expect(res.body.variants[1].name).toBe('f'); + expect(res.body.variants[2].name).toBe('z'); + }); +});