1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-07-12 13:48:35 +02:00

fix: export features with variants event when feature is disabled (#2824)

## About the changes
When exporting features one is normally also interested in disabled
features, so they are also included in the export file, while the
variants are not. I do not see a good reason for that, so this PR
removes the check and exports the variants then as well.
I could also add an option as well, but as long as there is no good
reason for ignoring the variants I would just export them with the
features.

This PR adds tests on #2719

Closes #2719

Co-authored-by: Martin Joehren <martin.joehren@esailors.de>
This commit is contained in:
Gastón Fournier 2023-01-05 11:30:07 +01:00 committed by GitHub
parent 36f849e9e9
commit 58dd09f3e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 69 deletions

View File

@ -28,77 +28,43 @@ function getSetup() {
async function setupV3VariantsCompatibilityScenario( async function setupV3VariantsCompatibilityScenario(
variantsPerEnvironment: boolean, variantsPerEnvironment: boolean,
envs = [
{ name: 'env-2', enabled: true },
{ name: 'env-3', enabled: true },
{ name: 'env-1', enabled: true },
],
) { ) {
const stores = createStores(); const stores = createStores();
await stores.environmentStore.create({
name: 'env-1',
type: 'production',
sortOrder: 3,
});
await stores.environmentStore.create({
name: 'env-2',
type: 'production',
sortOrder: 1,
});
await stores.environmentStore.create({
name: 'env-3',
type: 'production',
sortOrder: 2,
});
await stores.featureToggleStore.create('some-project', { await stores.featureToggleStore.create('some-project', {
name: 'Feature-with-variants', name: 'Feature-with-variants',
}); });
await stores.featureEnvironmentStore.addEnvironmentToFeature( let sortOrder = 1;
'Feature-with-variants', envs.forEach(async (env) => {
'env-1', await stores.environmentStore.create({
true, name: env.name,
); type: 'production',
await stores.featureEnvironmentStore.addEnvironmentToFeature( sortOrder: sortOrder++,
'Feature-with-variants', });
'env-2', await stores.featureEnvironmentStore.addEnvironmentToFeature(
true, 'Feature-with-variants',
); env.name,
await stores.featureEnvironmentStore.addEnvironmentToFeature( env.enabled,
'Feature-with-variants', );
'env-3', await stores.featureEnvironmentStore.addVariantsToFeatureEnvironment(
true, 'Feature-with-variants',
); env.name,
await stores.featureEnvironmentStore.addVariantsToFeatureEnvironment( [
'Feature-with-variants', {
'env-1', name: variantsPerEnvironment
[ ? `${env.name}-variant`
{ : 'variant-name',
name: 'env-1-variant', stickiness: 'default',
stickiness: 'default', weight: 1000,
weight: 1000, weightType: 'variable',
weightType: 'variable', },
}, ],
], );
); });
await stores.featureEnvironmentStore.addVariantsToFeatureEnvironment(
'Feature-with-variants',
'env-2',
[
{
name: 'env-2-variant',
stickiness: 'default',
weight: 1000,
weightType: 'variable',
},
],
);
await stores.featureEnvironmentStore.addVariantsToFeatureEnvironment(
'Feature-with-variants',
'env-3',
[
{
name: 'env-3-variant',
stickiness: 'default',
weight: 1000,
weightType: 'variable',
},
],
);
return { return {
stateService: new StateService(stores, { stateService: new StateService(stores, {
getLogger, getLogger,
@ -671,10 +637,60 @@ test('exporting variants to v3 format should pick variants from the correct env'
const exported = await stateService.export({}); const exported = await stateService.export({});
expect(exported.features).toHaveLength(1); expect(exported.features).toHaveLength(1);
// env 2 has the lowest sortOrder so we expect env-2-variant to be selected
expect(exported.features[0].variants).toStrictEqual([ expect(exported.features[0].variants).toStrictEqual([
{ {
name: 'env-2-variant', name: 'variant-name',
stickiness: 'default',
weight: 1000,
weightType: 'variable',
},
]);
exported.featureEnvironments.forEach((fe) =>
expect(fe.variants).toBeUndefined(),
);
expect(exported.environments).toHaveLength(3);
});
// This test should be removed as soon as variants per environment is GA
test('exporting variants to v3 format when some envs are disabled should export variants', async () => {
const { stateService } = await setupV3VariantsCompatibilityScenario(false, [
{ name: 'env-2', enabled: false },
{ name: 'env-3', enabled: false },
{ name: 'env-1', enabled: true },
]);
const exported = await stateService.export({});
expect(exported.features).toHaveLength(1);
expect(exported.features[0].variants).toStrictEqual([
{
name: 'variant-name',
stickiness: 'default',
weight: 1000,
weightType: 'variable',
},
]);
exported.featureEnvironments.forEach((fe) =>
expect(fe.variants).toBeUndefined(),
);
expect(exported.environments).toHaveLength(3);
});
// This test should be removed as soon as variants per environment is GA
test('exporting variants to v3 format when all envs are disabled should export variants', async () => {
const { stateService } = await setupV3VariantsCompatibilityScenario(false, [
{ name: 'env-2', enabled: false },
{ name: 'env-3', enabled: false },
{ name: 'env-1', enabled: false },
]);
const exported = await stateService.export({});
expect(exported.features).toHaveLength(1);
expect(exported.features[0].variants).toStrictEqual([
{
name: 'variant-name',
stickiness: 'default', stickiness: 'default',
weight: 1000, weight: 1000,
weightType: 'variable', weightType: 'variable',

View File

@ -730,7 +730,7 @@ export default class StateService {
); );
v4.features = v4.features.map((f) => { v4.features = v4.features.map((f) => {
const variants = featureEnvs.find( const variants = featureEnvs.find(
(fe) => fe.enabled !== false && fe.featureName === f.name, (fe) => fe.featureName === f.name,
)?.variants; )?.variants;
return { ...f, variants }; return { ...f, variants };
}); });