From 1a174548cca921a6136bfe7b1c3a4190ec1f5eda Mon Sep 17 00:00:00 2001 From: Kenneth Yeh Date: Thu, 7 May 2026 22:50:41 -0700 Subject: [PATCH] fix: include experiment key on local-eval exposure events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set [Experiment] Experiment Key on exposure event properties when variant.metadata["experimentKey"] is present, so proxy-emitted exposures are run-aware when a flag is reused across experiment runs. Mirrors the same change in experiment-jvm-server#53 and experiment-node-server#83. Additive only — metadata blob, flag key, variant, user properties, and insertId are unchanged. --- .../main/kotlin/exposure/ExposureTracker.kt | 4 +++ .../kotlin/exposure/ExposureTrackerTest.kt | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/core/src/main/kotlin/exposure/ExposureTracker.kt b/core/src/main/kotlin/exposure/ExposureTracker.kt index a2fdc63..071b450 100644 --- a/core/src/main/kotlin/exposure/ExposureTracker.kt +++ b/core/src/main/kotlin/exposure/ExposureTracker.kt @@ -108,6 +108,10 @@ internal fun Exposure.toAmplitudeEvents(): List { if (variant.key != null) { put("[Experiment] Variant", variant.key) } + val experimentKey = variant.metadata?.get("experimentKey") as? String + if (experimentKey != null) { + put("[Experiment] Experiment Key", experimentKey) + } if (variant.metadata != null) { put("metadata", JSONObject(variant.metadata)) } diff --git a/core/src/test/kotlin/exposure/ExposureTrackerTest.kt b/core/src/test/kotlin/exposure/ExposureTrackerTest.kt index 22a234f..6c15752 100644 --- a/core/src/test/kotlin/exposure/ExposureTrackerTest.kt +++ b/core/src/test/kotlin/exposure/ExposureTrackerTest.kt @@ -55,6 +55,37 @@ class ExposureTrackerTest { } } + @Test + fun `test exposure includes experiment key when present in metadata`() = + runBlocking { + val context = user(userId = "user", deviceId = "device").toEvaluationContext() + val results = + mapOf( + "with-exp-key" to + EvaluationVariant( + key = "treatment", + metadata = mapOf("deployed" to true, "experimentKey" to "exp-1"), + ), + "without-exp-key" to + EvaluationVariant( + key = "on", + metadata = mapOf("deployed" to true), + ), + ) + val exposure = Exposure(context, results) + val events = exposure.toAmplitudeEvents() + + Assert.assertEquals(2, events.size) + for (event in events) { + val flagKey = event.eventProperties.getString("[Experiment] Flag Key") + if (flagKey == "with-exp-key") { + Assert.assertEquals("exp-1", event.eventProperties.getString("[Experiment] Experiment Key")) + } else { + Assert.assertFalse(event.eventProperties.has("[Experiment] Experiment Key")) + } + } + } + @Test fun `test exposure skips default variants`() = runBlocking {