diff --git a/.changeset/android-v4-major.md b/.changeset/android-v4-major.md index 5a2892275..e89b373a7 100644 --- a/.changeset/android-v4-major.md +++ b/.changeset/android-v4-major.md @@ -10,3 +10,4 @@ - **Breaking:** remove the deprecated `PostHogSessionReplayConfig.debouncerDelayMs`; use `throttleDelayMs` instead - **Breaking:** return `null` instead of the raw string for a malformed, empty or whitespace-only feature flag payload from `getFeatureFlagResult(key)?.payload`; payloads must be valid JSON (a JSON `null` payload now also reads as `null` instead of the string `"null"`) - **Breaking:** make SDK-internal helpers in the `com.posthog.internal` and `com.posthog.android.replay.internal` packages non-public +- **Breaking:** remove the deprecated `remoteConfig` config option; the SDK now always loads remote config at setup diff --git a/posthog-android-surveys-compose/src/testDebug/java/com/posthog/android/surveys/compose/internal/PostHogSurveyHostTest.kt b/posthog-android-surveys-compose/src/testDebug/java/com/posthog/android/surveys/compose/internal/PostHogSurveyHostTest.kt index 16b3ee565..fe5b5a8a1 100644 --- a/posthog-android-surveys-compose/src/testDebug/java/com/posthog/android/surveys/compose/internal/PostHogSurveyHostTest.kt +++ b/posthog-android-surveys-compose/src/testDebug/java/com/posthog/android/surveys/compose/internal/PostHogSurveyHostTest.kt @@ -279,7 +279,6 @@ internal class PostHogSurveyHostTest { PostHogConfig("host-reset", "http://127.0.0.1:1").apply { cachePreferences = PostHogMemoryPreferences() preloadFeatureFlags = false - remoteConfig = false reuseAnonymousId = true } } diff --git a/posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayIntegration.kt b/posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayIntegration.kt index daec3775b..46af13767 100644 --- a/posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayIntegration.kt +++ b/posthog-android/src/main/java/com/posthog/android/replay/PostHogReplayIntegration.kt @@ -3054,15 +3054,9 @@ public class PostHogReplayIntegration( } // Whether to buffer until the live remote config resolves: only when a remote config holder - // exists and hasn't resolved yet, AND a fetch will actually be attempted at setup. If neither - // remoteConfig nor preloadFeatureFlags is enabled, PostHog.setup dispatches no /config or /flags - // request, so no onRemoteConfig callback ever arrives to disarm the gate — - // buffering would then grow unbounded for the whole session. Don't arm in that case. + // exists and hasn't resolved yet. PostHog.setup always requests /config, so the + // onRemoteConfig callback disarms the gate. private fun shouldAwaitFirstRemoteConfig(): Boolean { - @Suppress("DEPRECATION") - if (!config.remoteConfig && !config.preloadFeatureFlags) { - return false - } return config.remoteConfigHolder?.let { !it.hasRemoteConfigFetched() } ?: false } diff --git a/posthog-android/src/test/java/com/posthog/android/PostHogAndroidAppVersionTest.kt b/posthog-android/src/test/java/com/posthog/android/PostHogAndroidAppVersionTest.kt index 9b16bcb53..68518c7df 100644 --- a/posthog-android/src/test/java/com/posthog/android/PostHogAndroidAppVersionTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/PostHogAndroidAppVersionTest.kt @@ -43,10 +43,9 @@ internal class PostHogAndroidAppVersionTest { events: MutableList, configure: PostHogAndroidConfig.() -> Unit = {}, ): PostHogAndroidConfig = - PostHogAndroidConfig(projectToken).apply { + PostHogAndroidConfig(projectToken, "http://127.0.0.1:1").apply { cachePreferences = preferences captureApplicationLifecycleEvents = captureLifecycle - remoteConfig = false preloadFeatureFlags = false configure() addBeforeSend { diff --git a/posthog-android/src/test/java/com/posthog/android/PostHogAndroidEventSnapshotsTest.kt b/posthog-android/src/test/java/com/posthog/android/PostHogAndroidEventSnapshotsTest.kt index e59c0977c..ae466718a 100644 --- a/posthog-android/src/test/java/com/posthog/android/PostHogAndroidEventSnapshotsTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/PostHogAndroidEventSnapshotsTest.kt @@ -94,7 +94,7 @@ internal class PostHogAndroidEventSnapshotsTest { sut.captureException(fixedThrowable(), mapOf("handled" to true, "component" to "checkout")) sut.flush() - val request = fixture.server.takeRequests("/flags/?v=2", "/batch").single { it.path == "/batch" } + val request = fixture.server.takeRequests(CONFIG_PATH, "/flags/?v=2", "/batch").single { it.path == "/batch" } val snapshot = requestSnapshot(request, fixture.config) normalizeBatchVolatileFields(snapshot) @@ -118,7 +118,7 @@ internal class PostHogAndroidEventSnapshotsTest { fixture.client.reloadFeatureFlags(PostHogOnFeatureFlags { loaded.countDown() }) assertTrue(loaded.await(10, TimeUnit.SECONDS), "Feature flags request did not finish") - val request = fixture.server.takeRequests("/flags/?v=2").single() + val request = fixture.server.takeRequests(CONFIG_PATH, "/flags/?v=2").single { it.path == "/flags/?v=2" } assertSnapshot("flags-request.json", requestSnapshot(request, fixture.config), fixture.config) } @@ -152,7 +152,7 @@ internal class PostHogAndroidEventSnapshotsTest { ) fixture.client.flush() - val request = fixture.server.takeRequests("/s/").single() + val request = fixture.server.takeRequests(CONFIG_PATH, "/s/").single { it.path == "/s/" } val snapshot = requestSnapshot(request, fixture.config) normalizeReplayVolatileFields(snapshot) @@ -163,6 +163,8 @@ internal class PostHogAndroidEventSnapshotsTest { mockContextAppStart(context, tmpDir) val server = MockWebServer().apply { + // setup always requests /config first + enqueue(MockResponse().setBody(CONFIG_RESPONSE).setHeader("Content-Type", "application/json")) repeat(10) { enqueue(MockResponse().setBody(FLAGS_RESPONSE).setHeader("Content-Type", "application/json")) } @@ -185,8 +187,6 @@ internal class PostHogAndroidEventSnapshotsTest { flushIntervalSeconds = 60 maxBatchSize = 20 preloadFeatureFlags = false - @Suppress("DEPRECATION") - remoteConfig = false captureApplicationLifecycleEvents = false captureDeepLinks = false captureScreenViews = false @@ -412,6 +412,8 @@ internal class PostHogAndroidEventSnapshotsTest { private val FIXED_DATE = Date(FIXED_MILLIS) private val SESSION_ID = UUID.fromString("018bcfe5-687b-7abc-8def-0123456789ab") private const val FIXED_TIMESTAMP = "2023-11-14T22:13:20.123Z" + private const val CONFIG_PATH = "/array/$PROJECT_TOKEN/config" + private const val CONFIG_RESPONSE = """{"hasFeatureFlags":true}""" private const val FLAGS_RESPONSE = """{ "flags": { diff --git a/posthog-android/src/test/java/com/posthog/android/internal/InteractionActivityTest.kt b/posthog-android/src/test/java/com/posthog/android/internal/InteractionActivityTest.kt index 9e7a8dc2b..f888f61e3 100644 --- a/posthog-android/src/test/java/com/posthog/android/internal/InteractionActivityTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/internal/InteractionActivityTest.kt @@ -46,7 +46,7 @@ internal class InteractionActivityTest { fun `real Compose and embedded Views capture through window with replay off`() { val events = CopyOnWriteArrayList() val config = - PostHogAndroidConfig("test").apply { + PostHogAndroidConfig("test", "http://127.0.0.1:1").apply { captureElementInteractions = true sessionReplay = false captureApplicationLifecycleEvents = false @@ -54,8 +54,6 @@ internal class InteractionActivityTest { captureDeepLinks = false capturePushNotificationOpened = false capturePushNotificationSubscriptions = false - @Suppress("DEPRECATION") // Test isolation: do not fetch remote configuration. - remoteConfig = false preloadFeatureFlags = false addBeforeSend { event -> events += event diff --git a/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorActivityTest.kt b/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorActivityTest.kt index a380c5325..7091f75f4 100644 --- a/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorActivityTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorActivityTest.kt @@ -53,7 +53,7 @@ internal class InteractionDetectorActivityTest { @Suppress("DEPRECATION") private fun setup() { val config = - PostHogAndroidConfig("test").apply { + PostHogAndroidConfig("test", "http://127.0.0.1:1").apply { captureRageClicks = true captureDeadClicks = true sessionReplay = false @@ -62,7 +62,6 @@ internal class InteractionDetectorActivityTest { captureDeepLinks = false capturePushNotificationOpened = false capturePushNotificationSubscriptions = false - remoteConfig = false preloadFeatureFlags = false addBeforeSend { event -> events += event diff --git a/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorIntegrationTest.kt b/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorIntegrationTest.kt index 90d2b7c89..730e1d45f 100644 --- a/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorIntegrationTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/internal/InteractionDetectorIntegrationTest.kt @@ -48,12 +48,11 @@ internal class InteractionDetectorIntegrationTest { @Suppress("DEPRECATION") private val config = - PostHogAndroidConfig(PROJECT_TOKEN).apply { + PostHogAndroidConfig(PROJECT_TOKEN, "http://127.0.0.1:1").apply { captureRageClicks = true captureDeadClicks = true sessionReplay = false cachePreferences = PostHogMemoryPreferences() - remoteConfig = false preloadFeatureFlags = false addBeforeSend { event -> if (event.event in listOf("\$rageclick", "\$dead_click", "\$autocapture")) events += event @@ -253,9 +252,8 @@ internal class InteractionDetectorIntegrationTest { fun `secondary session changes use normal capture context when owner is not notified`() { val secondary = PostHog.with( - PostHogAndroidConfig("secondary-test-key").apply { + PostHogAndroidConfig("secondary-test-key", "http://127.0.0.1:1").apply { cachePreferences = PostHogMemoryPreferences() - remoteConfig = false preloadFeatureFlags = false addBeforeSend { null } }, diff --git a/posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayIntegrationTest.kt b/posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayIntegrationTest.kt index fcf0b0a72..a4571077a 100644 --- a/posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayIntegrationTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/replay/PostHogReplayIntegrationTest.kt @@ -2127,53 +2127,6 @@ internal class PostHogReplayIntegrationTest { } } - @Test - fun `gate does not arm when neither remoteConfig nor preloadFeatureFlags will fetch`() { - // With both remoteConfig and preloadFeatureFlags disabled, setup dispatches no /config or - // /flags request, so no onRemoteConfig callback arrives to disarm the gate. Arming it would - // buffer every snapshot for the whole session; instead it must stay disarmed and persist. - val remoteConfigMock = - mock { - on { isSessionReplayFlagActive() } doReturn true - on { hasRemoteConfigFetched() } doReturn false - on { makeSamplingDecision(any()) } doReturn true - on { getEventTriggers() } doReturn emptySet() - on { getRecordingMinimumDurationMs() } doReturn null - } - val config = - PostHogAndroidConfig(PROJECT_TOKEN).apply { - remoteConfigHolder = remoteConfigMock - sessionReplay = true - @Suppress("DEPRECATION") - remoteConfig = false - preloadFeatureFlags = false - } - val storagePrefix = tmpDir.newFolder().absolutePath - val executor = createReplayExecutor() - val innerQueue = - PostHogQueue( - config, - EndpointSpec.snapshot(config, PostHogApi(config), storagePrefix), - executor, - ) - val replayQueue = PostHogReplayQueue(config, innerQueue, storagePrefix, executor) - config.replayQueueHolder = replayQueue - val sut = PostHogReplayIntegration(mock(), config, MainHandler()) - val postHog = mock() - whenever(postHog.getSessionId()).thenReturn(UUID.randomUUID()) - sut.install(postHog) - sut.start(resumeCurrent = true) - try { - // No remote-config callback will ever fire, so buffering must not be armed. - replayQueue.add(createTestEvent("snapshot_1")) - awaitCondition { replayQueue.depth == 1 } - assertEquals(0, replayQueue.bufferDepth) - assertEquals(1, replayQueue.depth) - } finally { - sut.uninstall() - } - } - @Test fun `mid-session resume forces a fresh keyframe by clearing per-view snapshot state`() { // A mid-session flag-on resume must emit a fresh full snapshot: while stopped, per-view state @@ -2599,9 +2552,7 @@ internal class PostHogReplayIntegrationTest { @Test @Config(sdk = [26], shadows = [SnapshotBoundaryShadowPixelCopy::class]) fun `committed snapshot keeps its session when rotation precedes core enrichment`() { - val config = PostHogAndroidConfig(PROJECT_TOKEN) - @Suppress("DEPRECATION") - config.remoteConfig = false + val config = PostHogAndroidConfig(PROJECT_TOKEN, "http://127.0.0.1:1") config.preloadFeatureFlags = false var captured: PostHogEvent? = null config.addBeforeSend { event -> diff --git a/posthog-android/src/test/java/com/posthog/android/surveys/PostHogSurveysRestartTest.kt b/posthog-android/src/test/java/com/posthog/android/surveys/PostHogSurveysRestartTest.kt index cb2c57ea5..16521bde8 100644 --- a/posthog-android/src/test/java/com/posthog/android/surveys/PostHogSurveysRestartTest.kt +++ b/posthog-android/src/test/java/com/posthog/android/surveys/PostHogSurveysRestartTest.kt @@ -139,7 +139,6 @@ internal class PostHogSurveysRestartTest { PostHogAndroidConfig(projectToken), ) preloadFeatureFlags = false - remoteConfig = false surveys = true surveysConfig.surveysDelegate = renderer surveysConfig.overrideDisplayLanguage = language diff --git a/posthog-server/src/main/java/com/posthog/server/PostHogConfig.kt b/posthog-server/src/main/java/com/posthog/server/PostHogConfig.kt index 264e46bee..e0adad853 100644 --- a/posthog-server/src/main/java/com/posthog/server/PostHogConfig.kt +++ b/posthog-server/src/main/java/com/posthog/server/PostHogConfig.kt @@ -306,7 +306,6 @@ public open class PostHogConfig constructor( debug = debug, sendFeatureFlagEvent = sendFeatureFlagEvent, preloadFeatureFlags = preloadFeatureFlags, - remoteConfig = remoteConfig, flushAt = flushAt, maxQueueSize = maxQueueSize, maxBatchSize = maxBatchSize, diff --git a/posthog-server/src/test/java/com/posthog/server/PostHogConfigTest.kt b/posthog-server/src/test/java/com/posthog/server/PostHogConfigTest.kt index 6d36783ea..b68787d37 100644 --- a/posthog-server/src/test/java/com/posthog/server/PostHogConfigTest.kt +++ b/posthog-server/src/test/java/com/posthog/server/PostHogConfigTest.kt @@ -175,7 +175,6 @@ internal class PostHogConfigTest { assertEquals(true, coreConfig.debug) assertEquals(false, coreConfig.sendFeatureFlagEvent) assertEquals(false, coreConfig.preloadFeatureFlags) - assertEquals(false, coreConfig.remoteConfig) assertEquals(15, coreConfig.flushAt) assertEquals(750, coreConfig.maxQueueSize) assertEquals(30, coreConfig.maxBatchSize) diff --git a/posthog/api/posthog.api b/posthog/api/posthog.api index 1d18f638e..d515cea20 100644 --- a/posthog/api/posthog.api +++ b/posthog/api/posthog.api @@ -156,8 +156,8 @@ public class com/posthog/PostHogConfig { public static final field DEFAULT_MAX_QUEUE_SIZE I public static final field DEFAULT_US_ASSETS_HOST Ljava/lang/String; public static final field DEFAULT_US_HOST Ljava/lang/String; - public fun (Ljava/lang/String;Ljava/lang/String;ZZZIZLjava/util/List;ZZIIIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLkotlin/jvm/functions/Function1;ZLcom/posthog/PersonProfiles;ZLjava/net/Proxy;Lcom/posthog/surveys/PostHogSurveysConfig;Lcom/posthog/logs/PostHogLogsConfig;Lkotlin/jvm/functions/Function6;Lkotlin/jvm/functions/Function5;Lcom/posthog/errortracking/PostHogErrorTrackingConfig;Ljava/lang/String;Lcom/posthog/PostHogBootstrapConfig;Lkotlin/jvm/functions/Function3;)V - public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZZZIZLjava/util/List;ZZIIIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLkotlin/jvm/functions/Function1;ZLcom/posthog/PersonProfiles;ZLjava/net/Proxy;Lcom/posthog/surveys/PostHogSurveysConfig;Lcom/posthog/logs/PostHogLogsConfig;Lkotlin/jvm/functions/Function6;Lkotlin/jvm/functions/Function5;Lcom/posthog/errortracking/PostHogErrorTrackingConfig;Ljava/lang/String;Lcom/posthog/PostHogBootstrapConfig;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Ljava/lang/String;ZZZIZLjava/util/List;ZIIIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLkotlin/jvm/functions/Function1;ZLcom/posthog/PersonProfiles;ZLjava/net/Proxy;Lcom/posthog/surveys/PostHogSurveysConfig;Lcom/posthog/logs/PostHogLogsConfig;Lkotlin/jvm/functions/Function6;Lkotlin/jvm/functions/Function5;Lcom/posthog/errortracking/PostHogErrorTrackingConfig;Ljava/lang/String;Lcom/posthog/PostHogBootstrapConfig;Lkotlin/jvm/functions/Function3;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZZZIZLjava/util/List;ZIIIIIILcom/posthog/PostHogEncryption;Lcom/posthog/PostHogOnFeatureFlags;ZLkotlin/jvm/functions/Function1;ZLcom/posthog/PersonProfiles;ZLjava/net/Proxy;Lcom/posthog/surveys/PostHogSurveysConfig;Lcom/posthog/logs/PostHogLogsConfig;Lkotlin/jvm/functions/Function6;Lkotlin/jvm/functions/Function5;Lcom/posthog/errortracking/PostHogErrorTrackingConfig;Ljava/lang/String;Lcom/posthog/PostHogBootstrapConfig;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun addBeforeSend (Lcom/posthog/PostHogBeforeSend;)V public final fun addIntegration (Lcom/posthog/PostHogIntegration;)V public final fun getBeforeSendList ()Ljava/util/List; @@ -196,7 +196,6 @@ public class com/posthog/PostHogConfig { public final fun getPushIdentityProvider ()Lkotlin/jvm/functions/Function3; public final fun getQueueProvider ()Lkotlin/jvm/functions/Function5; public final fun getReleaseIdentifier ()Ljava/lang/String; - public final fun getRemoteConfig ()Z public final fun getRemoteConfigHolder ()Lcom/posthog/internal/PostHogRemoteConfig; public final fun getRemoteConfigProvider ()Lkotlin/jvm/functions/Function6; public final fun getReplayStoragePrefix ()Ljava/lang/String; @@ -246,7 +245,6 @@ public class com/posthog/PostHogConfig { public final fun setProxy (Ljava/net/Proxy;)V public final fun setPushIdentityProvider (Lkotlin/jvm/functions/Function3;)V public final fun setReleaseIdentifier (Ljava/lang/String;)V - public final fun setRemoteConfig (Z)V public final fun setRemoteConfigHolder (Lcom/posthog/internal/PostHogRemoteConfig;)V public final fun setReplayStoragePrefix (Ljava/lang/String;)V public final fun setRequestHeaders (Ljava/util/Map;)V diff --git a/posthog/src/main/java/com/posthog/PostHog.kt b/posthog/src/main/java/com/posthog/PostHog.kt index 6bd98ff1e..a616e878c 100644 --- a/posthog/src/main/java/com/posthog/PostHog.kt +++ b/posthog/src/main/java/com/posthog/PostHog.kt @@ -393,7 +393,6 @@ public class PostHog private constructor( } // only because of testing in isolation, this flag is always enabled - @Suppress("DEPRECATION") if (reloadFeatureFlags) { // Bootstrap already seeded the flags in RemoteConfig's init; fire the flags-loaded // callbacks now so listeners aren't blocked on the first network response. @@ -401,15 +400,10 @@ public class PostHog private constructor( notifyFeatureFlagsCallback(internalOnFeatureFlagsLoaded) notifyFeatureFlagsCallback(config.onFeatureFlags) } - when { - config.remoteConfig -> - loadRemoteConfigRequest( - internalOnFeatureFlagsLoaded, - config.onFeatureFlags, - ) - - config.preloadFeatureFlags -> reloadFeatureFlags(config.onFeatureFlags) - } + loadRemoteConfigRequest( + internalOnFeatureFlagsLoaded, + config.onFeatureFlags, + ) } // Reconcile a differing identified bootstrap after the setup reload is dispatched. diff --git a/posthog/src/main/java/com/posthog/PostHogConfig.kt b/posthog/src/main/java/com/posthog/PostHogConfig.kt index c01078500..c72ffa1e4 100644 --- a/posthog/src/main/java/com/posthog/PostHogConfig.kt +++ b/posthog/src/main/java/com/posthog/PostHogConfig.kt @@ -108,15 +108,6 @@ public open class PostHogConfig( * Default: true */ public var setDefaultPersonProperties: Boolean = true, - /** - * Preload PostHog remote config automatically - * Defaults to true - */ - @Deprecated( - message = "Remote config is now always enabled. This option is a no-op and will be removed in a future version.", - level = DeprecationLevel.WARNING, - ) - public var remoteConfig: Boolean = true, /** * Number of minimum events before they are sent over the wire * Defaults to 20 diff --git a/posthog/src/test/java/com/posthog/PostHogBeforeSendTest.kt b/posthog/src/test/java/com/posthog/PostHogBeforeSendTest.kt index 454282022..e4bbba3c1 100644 --- a/posthog/src/test/java/com/posthog/PostHogBeforeSendTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogBeforeSendTest.kt @@ -34,7 +34,6 @@ internal class PostHogBeforeSendTest { storagePrefix = tmpDir.newFolder().absolutePath replayStoragePrefix = tmpDir.newFolder().absolutePath preloadFeatureFlags = false - remoteConfig = false cachePreferences = PostHogMemoryPreferences() hooks.forEach { addBeforeSend(it) } } diff --git a/posthog/src/test/java/com/posthog/PostHogBootstrapTest.kt b/posthog/src/test/java/com/posthog/PostHogBootstrapTest.kt index b4d4c80b1..214256e76 100644 --- a/posthog/src/test/java/com/posthog/PostHogBootstrapTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogBootstrapTest.kt @@ -30,13 +30,13 @@ internal class PostHogBootstrapTest { private val serializer = PostHogSerializer(PostHogConfig(PROJECT_TOKEN)) private lateinit var config: PostHogConfig - @Suppress("DEPRECATION") private fun getSut( host: String = PostHogConfig.DEFAULT_HOST, bootstrap: PostHogBootstrapConfig? = null, cachePreferences: PostHogMemoryPreferences = PostHogMemoryPreferences(), preloadFeatureFlags: Boolean = false, - reloadFeatureFlags: Boolean = true, + // setup always requests /config; skip it when the test doesn't preload flags + reloadFeatureFlags: Boolean = preloadFeatureFlags, sendFeatureFlagEvent: Boolean = true, flushAt: Int = 1, storagePrefix: String = tmpDir.newFolder().absolutePath, @@ -52,8 +52,6 @@ internal class PostHogBootstrapTest { this.preloadFeatureFlags = preloadFeatureFlags this.sendFeatureFlagEvent = sendFeatureFlagEvent this.cachePreferences = cachePreferences - // keep setup on the single /flags path instead of the /config + /flags path - this.remoteConfig = false this.bootstrap = bootstrap this.optOut = optOut this.onFeatureFlags = onFeatureFlags @@ -370,6 +368,9 @@ internal class PostHogBootstrapTest { var loaded = false val sut = getSut( + host = "http://127.0.0.1:1", + // the callback fires from setup's flag loading, before /config answers + reloadFeatureFlags = true, bootstrap = PostHogBootstrapConfig(featureFlags = mapOf("beta-ui" to true)), onFeatureFlags = PostHogOnFeatureFlags { loaded = true }, ) diff --git a/posthog/src/test/java/com/posthog/PostHogFeatureFlagsTest.kt b/posthog/src/test/java/com/posthog/PostHogFeatureFlagsTest.kt index 82575e966..15122e4fe 100644 --- a/posthog/src/test/java/com/posthog/PostHogFeatureFlagsTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogFeatureFlagsTest.kt @@ -48,11 +48,11 @@ internal class PostHogFeatureFlagsTest { storagePrefix: String = tmpDir.newFolder().absolutePath, optOut: Boolean = false, preloadFeatureFlags: Boolean = true, - reloadFeatureFlags: Boolean = true, + // setup always requests /config; skip it when the test doesn't preload flags + reloadFeatureFlags: Boolean = preloadFeatureFlags, sendFeatureFlagEvent: Boolean = true, reuseAnonymousId: Boolean = false, integration: PostHogIntegration? = null, - remoteConfig: Boolean = false, cachePreferences: PostHogMemoryPreferences = PostHogMemoryPreferences(), beforeSend: PostHogBeforeSend? = null, evaluationContexts: List? = null, @@ -73,7 +73,6 @@ internal class PostHogFeatureFlagsTest { this.reuseAnonymousId = reuseAnonymousId this.cachePreferences = cachePreferences this.evaluationContexts = evaluationContexts - this.remoteConfig = remoteConfig if (beforeSend != null) { addBeforeSend(beforeSend) } diff --git a/posthog/src/test/java/com/posthog/PostHogIntegrationChangeTest.kt b/posthog/src/test/java/com/posthog/PostHogIntegrationChangeTest.kt index 041a7548e..258cc39ea 100644 --- a/posthog/src/test/java/com/posthog/PostHogIntegrationChangeTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogIntegrationChangeTest.kt @@ -26,9 +26,8 @@ internal class PostHogIntegrationChangeTest { @Suppress("DEPRECATION") private val client = PostHog.with( - PostHogConfig(PROJECT_TOKEN).apply { + PostHogConfig(PROJECT_TOKEN, "http://127.0.0.1:1").apply { cachePreferences = PostHogMemoryPreferences() - remoteConfig = false preloadFeatureFlags = false addBeforeSend { null } addIntegration(integration) diff --git a/posthog/src/test/java/com/posthog/PostHogIntegrationInstallFailureTest.kt b/posthog/src/test/java/com/posthog/PostHogIntegrationInstallFailureTest.kt index d5a3717b8..93dd6f259 100644 --- a/posthog/src/test/java/com/posthog/PostHogIntegrationInstallFailureTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogIntegrationInstallFailureTest.kt @@ -27,10 +27,9 @@ internal class PostHogIntegrationInstallFailureTest { @Suppress("DEPRECATION") client = PostHog.with( - PostHogConfig(PROJECT_TOKEN).apply { + PostHogConfig(PROJECT_TOKEN, "http://127.0.0.1:1").apply { logger = testLogger cachePreferences = PostHogMemoryPreferences() - remoteConfig = false preloadFeatureFlags = false addBeforeSend { null } addIntegration(broken) diff --git a/posthog/src/test/java/com/posthog/PostHogOkHttpInterceptorTest.kt b/posthog/src/test/java/com/posthog/PostHogOkHttpInterceptorTest.kt index 09467943a..d91a9b2c3 100644 --- a/posthog/src/test/java/com/posthog/PostHogOkHttpInterceptorTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogOkHttpInterceptorTest.kt @@ -194,7 +194,6 @@ internal class PostHogOkHttpInterceptorTest { this.replayStoragePrefix = tmpDir.newFolder().absolutePath this.cachePreferences = PostHogMemoryPreferences() this.preloadFeatureFlags = false - this.remoteConfig = false } val postHog = diff --git a/posthog/src/test/java/com/posthog/PostHogTest.kt b/posthog/src/test/java/com/posthog/PostHogTest.kt index 5ce8ff3be..22176defb 100644 --- a/posthog/src/test/java/com/posthog/PostHogTest.kt +++ b/posthog/src/test/java/com/posthog/PostHogTest.kt @@ -90,11 +90,11 @@ internal class PostHogTest { optOut: Boolean = false, persistOptOut: Boolean = true, preloadFeatureFlags: Boolean = true, - reloadFeatureFlags: Boolean = true, + // setup always requests /config; skip it when the test doesn't preload flags + reloadFeatureFlags: Boolean = preloadFeatureFlags, sendFeatureFlagEvent: Boolean = true, reuseAnonymousId: Boolean = false, integration: PostHogIntegration? = null, - remoteConfig: Boolean = false, surveys: Boolean = false, cachePreferences: PostHogPreferences? = PostHogMemoryPreferences(), beforeSend: PostHogBeforeSend? = null, @@ -121,7 +121,6 @@ internal class PostHogTest { this.reuseAnonymousId = reuseAnonymousId this.cachePreferences = cachePreferences this.evaluationContexts = evaluationContexts - this.remoteConfig = remoteConfig this.surveys = surveys if (beforeSend != null) { addBeforeSend(beforeSend) @@ -368,22 +367,6 @@ internal class PostHogTest { sut.close() } - @Test - fun `preload feature flags if enabled`() { - val http = mockHttp() - val url = http.url("/") - - val sut = getSut(url.toString()) - - remoteConfigExecutor.shutdownAndAwaitTermination() - - val request = http.takeRequest() - assertEquals(1, http.requestCount) - assertEquals("/flags/?v=2", request.path) - - sut.close() - } - @Test fun `reload feature flags and call the callback`() { val http = mockHttp() @@ -409,7 +392,7 @@ internal class PostHogTest { val http = mockHttp() val url = http.url("/") - val sut = getSut(url.toString(), remoteConfig = true, preloadFeatureFlags = false) + val sut = getSut(url.toString(), preloadFeatureFlags = false, reloadFeatureFlags = true) remoteConfigExecutor.shutdownAndAwaitTermination() @@ -437,7 +420,7 @@ internal class PostHogTest { ) val url = http.url("/") - val sut = getSut(url.toString(), remoteConfig = true) + val sut = getSut(url.toString()) remoteConfigExecutor.shutdownAndAwaitTermination() @@ -469,7 +452,7 @@ internal class PostHogTest { ) val url = http.url("/") - val sut = getSut(url.toString(), remoteConfig = true) + val sut = getSut(url.toString()) remoteConfigExecutor.shutdownAndAwaitTermination() @@ -1665,7 +1648,7 @@ internal class PostHogTest { override fun onSurveysLoaded(surveys: List) {} } - val sut = getSut(url.toString(), remoteConfig = true, integration = surveysIntegration) + val sut = getSut(url.toString(), integration = surveysIntegration) http.takeRequest() http.takeRequest() @@ -1690,7 +1673,7 @@ internal class PostHogTest { val url = http.url("/") val integration = FakePostHogIntegration() - val sut = getSut(url.toString(), remoteConfig = true, integration = integration) + val sut = getSut(url.toString(), integration = integration) remoteConfigExecutor.shutdownAndAwaitTermination() assertEquals(1, integration.remoteConfigCount) @@ -3207,17 +3190,25 @@ internal class PostHogTest { @Test fun `reset reloads flags as anon user`() { - val http = mockHttp() + // setup's /config reports no flags, so the only /flags request comes from reset + val http = + mockHttp( + response = + MockResponse() + .setBody(File("src/test/resources/json/basic-remote-config-no-flags.json").readText()), + ) + http.enqueue(MockResponse().setBody(responseFlagsApi)) val url = http.url("/") - val sut = getSut(url.toString(), preloadFeatureFlags = false) + val sut = getSut(url.toString(), preloadFeatureFlags = false, reloadFeatureFlags = true) sut.reset() remoteConfigExecutor.shutdownAndAwaitTermination() + assertEquals("/array/${PROJECT_TOKEN}/config", http.takeRequest().path) val request = http.takeRequest() - assertEquals(1, http.requestCount) + assertEquals(2, http.requestCount) assertEquals("/flags/?v=2", request.path) sut.close() @@ -4465,8 +4456,9 @@ internal class PostHogTest { mockHttp( response = MockResponse() - .setBody(responseFlagsApi), + .setBody(File("src/test/resources/json/basic-remote-config.json").readText()), ) + http.enqueue(MockResponse().setBody(responseFlagsApi)) val url = http.url("/") val sut = getSut(url.toString(), preloadFeatureFlags = true, context = TestPostHogContext())