Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion flagsmith/flagsmith.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ def get_experiment_flag(

The exposure event's ``value`` is the flag's variant key. It is only
sent when the flag exists, is enabled and the identity is enrolled in
the feature's experiment (``flag.experiment.in_experiment``); any
the feature's experiment (``flag.experiment.in_experiment``) with a
variant; any
other outcome is logged and skipped to keep experimentation data
clean. A `DefaultFlag` served via the `default_flag_handler` counts
as the feature not existing.
Expand All @@ -395,6 +396,12 @@ def get_experiment_flag(
FLAG_EXPOSURE_EVENT,
feature_name,
)
elif flag.variant is None:
logger.debug(
"Not sending %s for feature %s: flag has no variant.",
FLAG_EXPOSURE_EVENT,
feature_name,
)
else:
self.track_exposure_event(
feature_name=feature_name,
Expand Down
40 changes: 40 additions & 0 deletions tests/test_flagsmith.py
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,46 @@ def test_get_experiment_flag__not_in_experiment__skips_exposure(
)


def test_get_experiment_flag__in_experiment_without_variant__skips_exposure(
mocker: MockerFixture, api_key: str, caplog: pytest.LogCaptureFixture
) -> None:
# Given
config = EventProcessorConfig(events_api_url="http://test/")
flagsmith = Flagsmith(
environment_key=api_key, enable_events=True, event_processor_config=config
)
flag = Flag(
enabled=True,
value="blue",
feature_name="checkout_v2",
feature_id=1,
variant=None,
experiment=ExperimentMetadata(
id=42, name="New checkout CTA", in_experiment=True
),
)
mocker.patch.object(
flagsmith,
"get_identity_flags",
return_value=Flags(flags={"checkout_v2": flag}),
)
mock_track = mocker.patch.object(flagsmith._event_processor, "track_exposure_event")

# When
with caplog.at_level(logging.DEBUG, logger="flagsmith.flagsmith"):
result = flagsmith.get_experiment_flag(
feature_name="checkout_v2", identifier="user1"
)

# Then
assert result is flag
mock_track.assert_not_called()
assert (
"Not sending $flag_exposure for feature checkout_v2: flag has no variant."
in caplog.messages
)


@responses.activate()
def test_flagsmith_posts_analytics_to_analytics_url_when_set(
api_key: str, flags_json: str, mocker: MockerFixture
Expand Down
Loading