Skip to content
Draft
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
6 changes: 6 additions & 0 deletions .changeset/fresh-keys-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"posthog": patch
"posthog-android": patch
---

No-op SDK setup when the API key is null, empty, or whitespace after trimming.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public class PostHogAndroid private constructor() {
config: T,
) {
synchronized(lock) {
if (config.apiKey.isEmpty()) {
PostHog.setup(config)
return
}

setAndroidConfig(context.appContext(), config)

PostHog.setup(config)
Expand All @@ -69,6 +74,10 @@ public class PostHogAndroid private constructor() {
context: Context,
config: T,
): PostHogInterface {
if (config.apiKey.isEmpty()) {
return PostHog.with(config)
}

setAndroidConfig(context.appContext(), config)
return PostHog.with(config)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import com.posthog.android.replay.PostHogSessionReplayConfig
public open class PostHogAndroidConfig
@JvmOverloads
constructor(
apiKey: String,
apiKey: String?,
host: String = DEFAULT_HOST,
public var captureApplicationLifecycleEvents: Boolean = true,
public var captureDeepLinks: Boolean = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.posthog.android;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class PostHogAndroidConfigJavaTest {
@Test
public void nullApiKeyFromJavaDefaultsToEmptyString() {
PostHogAndroidConfig config = new PostHogAndroidConfig(null);

assertEquals("", config.getApiKey());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ internal class PostHogAndroidConfigTest {
assertEquals(API_KEY, config.apiKey)
}

@Test
fun `defaults null api key to empty string`() {
val config = PostHogAndroidConfig(null)

assertEquals("", config.apiKey)
}

@Test
fun `captureApplicationLifecycleEvents should be enabled by default`() {
assertTrue(config.captureApplicationLifecycleEvents)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ internal class PostHogAndroidTest {
tmpDir.root.deleteRecursively()
}

@Test
fun `setup no-ops for null api key`() {
val config = PostHogAndroidConfig(null)

PostHogAndroid.setup(context, config)

assertNull(config.cachePreferences)
assertTrue(config.integrations.isEmpty())
}

@Test
fun `setup no-ops for empty trimmed api key`() {
val config = PostHogAndroidConfig(" \n\t ")

PostHogAndroid.setup(context, config)

assertNull(config.cachePreferences)
assertTrue(config.integrations.isEmpty())
}

@Test
fun `sets Android Logger if System logger`() {
val config = PostHogAndroidConfig(API_KEY)
Expand Down
1 change: 1 addition & 0 deletions posthog/src/main/java/com/posthog/PostHog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public class PostHog private constructor(

if (config.apiKey.isEmpty()) {
config.logger.log("apiKey is empty after trimming whitespace; check your project API key")
return
}

if (!apiKeys.add(config.apiKey)) {
Expand Down
4 changes: 2 additions & 2 deletions posthog/src/main/java/com/posthog/PostHogConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public open class PostHogConfig(
/**
* The PostHog API Key
*/
apiKey: String,
apiKey: String?,
/**
* The PostHog Host
* Defaults to https://us.i.posthog.com
Expand Down Expand Up @@ -328,7 +328,7 @@ public open class PostHogConfig(
/**
* The PostHog API Key
*/
public val apiKey: String = apiKey.trim()
public val apiKey: String = apiKey?.trim().orEmpty()

/**
* The PostHog Host
Expand Down
1 change: 1 addition & 0 deletions posthog/src/main/java/com/posthog/PostHogStateless.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public open class PostHogStateless protected constructor(

if (config.apiKey.isEmpty()) {
config.logger.log("apiKey is empty after trimming whitespace; check your project API key")
return
}

if (!apiKeys.add(config.apiKey)) {
Expand Down
7 changes: 7 additions & 0 deletions posthog/src/test/java/com/posthog/PostHogConfigTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ internal class PostHogConfigTest {
assertEquals("https://eu.i.posthog.com/", config.host)
}

@Test
fun `defaults null api key to empty string`() {
val config = PostHogConfig(null, "https://api.posthog.com")

assertEquals("", config.apiKey)
}

@Test
fun `defaults a blank host after trimming whitespace`() {
val config = PostHogConfig(API_KEY, " \n\t ")
Expand Down
3 changes: 2 additions & 1 deletion posthog/src/test/java/com/posthog/PostHogStatelessTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,14 @@ internal class PostHogStatelessTest {
}

@Test
fun `setup logs empty trimmed api key after logger initialization`() {
fun `setup no-ops for empty trimmed api key after logger initialization`() {
sut = createStatelessInstance()
val mockLogger = MockLogger()
config = PostHogConfig(" \n\t ", "https://api.posthog.com").apply { logger = mockLogger }

sut.setup(config)

assertFalse(sut.isEnabledPublic())
assertTrue(mockLogger.messages.any { it.contains("apiKey is empty after trimming whitespace") })
}

Expand Down
19 changes: 19 additions & 0 deletions posthog/src/test/java/com/posthog/PostHogTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@ internal class PostHogTest {
sut.close()
}

@Test
fun `setup no-ops for empty trimmed api key`() {
val config = PostHogConfig(" \n\t ", "https://api.posthog.com")
val sut =
PostHog.withInternal(
config,
queueExecutor,
replayQueueExecutor,
remoteConfigExecutor,
cachedEventsExecutor,
reloadFeatureFlags = true,
)

assertTrue(config.integrations.isEmpty())
assertNull(config.cachePreferences)

sut.close()
}

@Test
fun `setup adds integration by default`() {
val http = mockHttp()
Expand Down
Loading