From 7780eb111bba98e685a50acfd879240753c90203 Mon Sep 17 00:00:00 2001 From: wadii Date: Thu, 25 Jun 2026 13:59:37 +0200 Subject: [PATCH] feat: skip exposure event for disabled flags in getExperimentFlag getExperimentFlag no longer fires a $flag_exposure event when the resolved flag is disabled, even if it has a variant, keeping experimentation data clean. The flag is still returned to the caller. --- flagsmith-core.ts | 4 ++++ test/data/identities_test_experiment_identity.json | 10 ++++++++++ test/events.test.ts | 11 +++++++++++ 3 files changed, 25 insertions(+) diff --git a/flagsmith-core.ts b/flagsmith-core.ts index 6efcab3..94cc249 100644 --- a/flagsmith-core.ts +++ b/flagsmith-core.ts @@ -1001,6 +1001,10 @@ const Flagsmith = class { this.log(`Flagsmith: getExperimentFlag called for "${featureName}" which does not exist. No exposure recorded.`); return null; } + if (!flag.enabled) { + this.log(`Flagsmith: getExperimentFlag called for "${featureName}" which is disabled. No exposure recorded.`); + return flag; + } if (!flag.variant) { this.log(`Flagsmith: getExperimentFlag called for "${featureName}" which has no variant; experiments require a multivariate flag. No exposure recorded.`); return flag; diff --git a/test/data/identities_test_experiment_identity.json b/test/data/identities_test_experiment_identity.json index eae5c4b..da57aee 100644 --- a/test/data/identities_test_experiment_identity.json +++ b/test/data/identities_test_experiment_identity.json @@ -19,6 +19,16 @@ "enabled": true, "feature_state_value": 16, "variant": "control" + }, + { + "feature": { + "id": 80321, + "name": "disabled_experiment", + "type": "MULTIVARIATE" + }, + "enabled": false, + "feature_state_value": null, + "variant": "control" } ], "traits": [] diff --git a/test/events.test.ts b/test/events.test.ts index 310954a..f4f68f9 100644 --- a/test/events.test.ts +++ b/test/events.test.ts @@ -144,6 +144,17 @@ describe('getExperimentFlag', () => { expect(eventCalls(mockFetch)).toHaveLength(0); }); + test('skips exposure for a disabled flag even when it has a variant, still returns it', async () => { + const { flagsmith, initConfig, mockFetch } = getFlagsmith(eventsConfig({ identity: experimentIdentity })); + await flagsmith.init(initConfig); // identified, source SERVER + + const flag = flagsmith.getExperimentFlag('disabled_experiment'); + expect(flag).toEqual(expect.objectContaining({ enabled: false, variant: 'control' })); + + await flagsmith.flushEvents(); + expect(eventCalls(mockFetch)).toHaveLength(0); + }); + test('skips exposure and returns null for an absent feature', async () => { const { flagsmith, initConfig, mockFetch } = getFlagsmith(eventsConfig({ identity: testIdentity })); await flagsmith.init(initConfig);