From 5cea6956667a37697587d089c1efc1b4a56fb938 Mon Sep 17 00:00:00 2001 From: Polat Olu Date: Mon, 13 Oct 2025 10:55:07 +0100 Subject: [PATCH 1/3] implementation and testing --- .../src/main/java/com/flagsmith/Flagsmith.kt | 2 +- .../internal/FlagsmithEventService.kt | 3 + .../internal/FlagsmithRetrofitService.kt | 23 +++++ .../test/java/com/flagsmith/UserAgentTests.kt | 83 +++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt diff --git a/FlagsmithClient/src/main/java/com/flagsmith/Flagsmith.kt b/FlagsmithClient/src/main/java/com/flagsmith/Flagsmith.kt index 2842383..bf24dc6 100644 --- a/FlagsmithClient/src/main/java/com/flagsmith/Flagsmith.kt +++ b/FlagsmithClient/src/main/java/com/flagsmith/Flagsmith.kt @@ -51,7 +51,7 @@ class Flagsmith constructor( private val eventService: FlagsmithEventService? = if (!enableRealtimeUpdates) null - else FlagsmithEventService(eventSourceBaseUrl = eventSourceBaseUrl, environmentKey = environmentKey) { event -> + else FlagsmithEventService(eventSourceBaseUrl = eventSourceBaseUrl, environmentKey = environmentKey, context = context) { event -> if (event.isSuccess) { lastEventUpdate = event.getOrNull()?.updatedAt ?: lastEventUpdate diff --git a/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithEventService.kt b/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithEventService.kt index e10888d..8d24fda 100644 --- a/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithEventService.kt +++ b/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithEventService.kt @@ -1,5 +1,6 @@ package com.flagsmith.internal +import android.content.Context import android.util.Log import com.flagsmith.entities.FlagEvent import com.google.gson.Gson @@ -15,10 +16,12 @@ import java.util.concurrent.TimeUnit internal class FlagsmithEventService constructor( private val eventSourceBaseUrl: String?, private val environmentKey: String, + private val context: Context?, private val updates: (Result) -> Unit ) { private val sseClient = OkHttpClient.Builder() .addInterceptor(FlagsmithRetrofitService.envKeyInterceptor(environmentKey)) + .addInterceptor(FlagsmithRetrofitService.userAgentInterceptor(context)) .connectTimeout(6, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.MINUTES) .writeTimeout(10, TimeUnit.MINUTES) diff --git a/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt b/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt index 60e9eab..1a06cde 100644 --- a/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt +++ b/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt @@ -39,6 +39,28 @@ interface FlagsmithRetrofitService { private const val UPDATED_AT_HEADER = "x-flagsmith-document-updated-at" private const val ACCEPT_HEADER_VALUE = "application/json" private const val CONTENT_TYPE_HEADER_VALUE = "application/json; charset=utf-8" + private const val USER_AGENT_HEADER = "User-Agent" + private const val USER_AGENT_PREFIX = "flagsmith-kotlin-android-sdk" + + private fun getUserAgent(context: Context?): String { + return try { + val packageInfo = context?.packageManager?.getPackageInfo(context.packageName, 0) + val version = packageInfo?.versionName ?: "unknown" + "$USER_AGENT_PREFIX/$version" + } catch (e: Exception) { + "$USER_AGENT_PREFIX/unknown" + } + } + + fun userAgentInterceptor(context: Context?): Interceptor { + return Interceptor { chain -> + val userAgent = getUserAgent(context) + val request = chain.request().newBuilder() + .addHeader(USER_AGENT_HEADER, userAgent) + .build() + chain.proceed(request) + } + } fun create( baseUrl: String, @@ -92,6 +114,7 @@ interface FlagsmithRetrofitService { val client = OkHttpClient.Builder() .addInterceptor(envKeyInterceptor(environmentKey)) + .addInterceptor(userAgentInterceptor(context)) .addInterceptor(updatedAtInterceptor(timeTracker)) .addInterceptor(jsonContentTypeInterceptor()) .let { if (cacheConfig.enableCache) it.addNetworkInterceptor(cacheControlInterceptor()) else it } diff --git a/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt b/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt new file mode 100644 index 0000000..c4a5f38 --- /dev/null +++ b/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt @@ -0,0 +1,83 @@ +package com.flagsmith + +import android.content.Context +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import com.flagsmith.internal.FlagsmithRetrofitService +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner +import kotlin.test.assertEquals + +@RunWith(MockitoJUnitRunner::class) +class UserAgentTests { + + @Mock + private lateinit var mockContext: Context + + @Mock + private lateinit var mockPackageManager: PackageManager + + @Mock + private lateinit var mockPackageInfo: PackageInfo + + @Test + fun `test User-Agent header format with valid version`() { + // Given + val expectedVersion = "1.2.3" + mockPackageInfo.versionName = expectedVersion + Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) + + // When + val interceptor = FlagsmithRetrofitService.userAgentInterceptor(mockContext) + + // Then + // We can't easily test the interceptor without making actual HTTP calls, + // but we can verify the User-Agent string format by testing the logic + val expectedUserAgent = "flagsmith-kotlin-android-sdk/$expectedVersion" + assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/$expectedVersion") + } + + @Test + fun `test User-Agent header format with null context`() { + // When + val interceptor = FlagsmithRetrofitService.userAgentInterceptor(null) + + // Then + val expectedUserAgent = "flagsmith-kotlin-android-sdk/unknown" + assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/unknown") + } + + @Test + fun `test User-Agent header format with exception during version retrieval`() { + // Given + Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)) + .thenThrow(PackageManager.NameNotFoundException("Package not found")) + + // When + val interceptor = FlagsmithRetrofitService.userAgentInterceptor(mockContext) + + // Then + val expectedUserAgent = "flagsmith-kotlin-android-sdk/unknown" + assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/unknown") + } + + @Test + fun `test User-Agent header format with null version name`() { + // Given + mockPackageInfo.versionName = null + Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) + + // When + val interceptor = FlagsmithRetrofitService.userAgentInterceptor(mockContext) + + // Then + val expectedUserAgent = "flagsmith-kotlin-android-sdk/unknown" + assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/unknown") + } +} \ No newline at end of file From b184964126207d6c2d8c22ca535a953925ad202b Mon Sep 17 00:00:00 2001 From: Polat Olu Date: Thu, 16 Oct 2025 16:44:06 +0100 Subject: [PATCH 2/3] Test improvements --- .../test/java/com/flagsmith/UserAgentTests.kt | 220 +++++++++++++++--- 1 file changed, 191 insertions(+), 29 deletions(-) diff --git a/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt b/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt index c4a5f38..4286921 100644 --- a/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt +++ b/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt @@ -3,17 +3,28 @@ package com.flagsmith import android.content.Context import android.content.pm.PackageInfo import android.content.pm.PackageManager -import com.flagsmith.internal.FlagsmithRetrofitService +import com.flagsmith.entities.Trait +import com.flagsmith.mockResponses.MockEndpoint +import com.flagsmith.mockResponses.mockResponseFor +import kotlinx.coroutines.runBlocking +import org.junit.After +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith +import org.mockserver.integration.ClientAndServer +import org.mockserver.model.HttpRequest.request import org.mockito.Mock import org.mockito.Mockito import org.mockito.junit.MockitoJUnitRunner -import kotlin.test.assertEquals +import org.junit.runner.RunWith @RunWith(MockitoJUnitRunner::class) class UserAgentTests { + private lateinit var mockServer: ClientAndServer + private lateinit var flagsmith: Flagsmith + @Mock private lateinit var mockContext: Context @@ -23,61 +34,212 @@ class UserAgentTests { @Mock private lateinit var mockPackageInfo: PackageInfo + @Before + fun setup() { + mockServer = ClientAndServer.startClientAndServer() + } + + @After + fun tearDown() { + mockServer.stop() + } + @Test - fun `test User-Agent header format with valid version`() { - // Given - val expectedVersion = "1.2.3" - mockPackageInfo.versionName = expectedVersion + fun testUserAgentHeaderSentWithValidVersion() { + // Given - Use a realistic app version (not SDK version) + // The User-Agent shows the APP's version, not the SDK's version + // This helps Flagsmith support team identify which app version is making requests + val expectedAppVersion = "2.4.1" + mockPackageInfo.versionName = expectedAppVersion Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) + flagsmith = Flagsmith( + environmentKey = "test-key", + baseUrl = "http://localhost:${mockServer.localPort}", + context = mockContext, + enableAnalytics = false, + cacheConfig = FlagsmithCacheConfig(enableCache = false) + ) + + mockServer.mockResponseFor(MockEndpoint.GET_FLAGS) + // When - val interceptor = FlagsmithRetrofitService.userAgentInterceptor(mockContext) - - // Then - // We can't easily test the interceptor without making actual HTTP calls, - // but we can verify the User-Agent string format by testing the logic - val expectedUserAgent = "flagsmith-kotlin-android-sdk/$expectedVersion" - assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/$expectedVersion") + runBlocking { + val result = flagsmith.getFeatureFlagsSync() + assertTrue(result.isSuccess) + } + + // Then - Verify User-Agent contains the APP's version, not SDK version + mockServer.verify( + request() + .withPath("/flags/") + .withMethod("GET") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/$expectedAppVersion") + ) } @Test - fun `test User-Agent header format with null context`() { + fun testUserAgentHeaderSentWithNullContext() { + // Given + flagsmith = Flagsmith( + environmentKey = "test-key", + baseUrl = "http://localhost:${mockServer.localPort}", + context = null, + enableAnalytics = false, + cacheConfig = FlagsmithCacheConfig(enableCache = false) + ) + + mockServer.mockResponseFor(MockEndpoint.GET_FLAGS) + // When - val interceptor = FlagsmithRetrofitService.userAgentInterceptor(null) - + runBlocking { + val result = flagsmith.getFeatureFlagsSync() + assertTrue(result.isSuccess) + } + // Then - val expectedUserAgent = "flagsmith-kotlin-android-sdk/unknown" - assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/unknown") + mockServer.verify( + request() + .withPath("/flags/") + .withMethod("GET") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/unknown") + ) } @Test - fun `test User-Agent header format with exception during version retrieval`() { + fun testUserAgentHeaderSentWithExceptionDuringVersionRetrieval() { // Given Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)) .thenThrow(PackageManager.NameNotFoundException("Package not found")) + flagsmith = Flagsmith( + environmentKey = "test-key", + baseUrl = "http://localhost:${mockServer.localPort}", + context = mockContext, + enableAnalytics = false, + cacheConfig = FlagsmithCacheConfig(enableCache = false) + ) + + mockServer.mockResponseFor(MockEndpoint.GET_FLAGS) + // When - val interceptor = FlagsmithRetrofitService.userAgentInterceptor(mockContext) - + runBlocking { + val result = flagsmith.getFeatureFlagsSync() + assertTrue(result.isSuccess) + } + // Then - val expectedUserAgent = "flagsmith-kotlin-android-sdk/unknown" - assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/unknown") + mockServer.verify( + request() + .withPath("/flags/") + .withMethod("GET") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/unknown") + ) } @Test - fun `test User-Agent header format with null version name`() { + fun testUserAgentHeaderSentWithNullVersionName() { // Given mockPackageInfo.versionName = null Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) + flagsmith = Flagsmith( + environmentKey = "test-key", + baseUrl = "http://localhost:${mockServer.localPort}", + context = mockContext, + enableAnalytics = false, + cacheConfig = FlagsmithCacheConfig(enableCache = false) + ) + + mockServer.mockResponseFor(MockEndpoint.GET_FLAGS) + // When - val interceptor = FlagsmithRetrofitService.userAgentInterceptor(mockContext) - + runBlocking { + val result = flagsmith.getFeatureFlagsSync() + assertTrue(result.isSuccess) + } + // Then - val expectedUserAgent = "flagsmith-kotlin-android-sdk/unknown" - assertEquals(expectedUserAgent, "flagsmith-kotlin-android-sdk/unknown") + mockServer.verify( + request() + .withPath("/flags/") + .withMethod("GET") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/unknown") + ) + } + + @Test + fun testUserAgentHeaderSentWithIdentityRequest() { + // Given + val expectedVersion = "2.1.0" + mockPackageInfo.versionName = expectedVersion + Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") + Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) + + flagsmith = Flagsmith( + environmentKey = "test-key", + baseUrl = "http://localhost:${mockServer.localPort}", + context = mockContext, + enableAnalytics = false, + cacheConfig = FlagsmithCacheConfig(enableCache = false) + ) + + mockServer.mockResponseFor(MockEndpoint.GET_IDENTITIES) + + // When + runBlocking { + val result = flagsmith.getIdentitySync("test-user") + assertTrue(result.isSuccess) + } + + // Then + mockServer.verify( + request() + .withPath("/identities/") + .withMethod("GET") + .withQueryStringParameter("identifier", "test-user") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/$expectedVersion") + ) + } + + @Test + fun testUserAgentHeaderSentWithTraitRequest() { + // Given + val expectedAppVersion = "3.0.1" + mockPackageInfo.versionName = expectedAppVersion + Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) + Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") + Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) + + flagsmith = Flagsmith( + environmentKey = "test-key", + baseUrl = "http://localhost:${mockServer.localPort}", + context = mockContext, + enableAnalytics = false, + cacheConfig = FlagsmithCacheConfig(enableCache = false) + ) + + mockServer.mockResponseFor(MockEndpoint.SET_TRAIT) + + // When + runBlocking { + val result = flagsmith.setTraitSync(Trait(key = "test-key", traitValue = "test-value"), "test-user") + assertTrue(result.isSuccess) + } + + // Then - Verify the traits request has correct User-Agent + mockServer.verify( + request() + .withPath("/identities/") + .withMethod("POST") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/$expectedAppVersion") + ) } } \ No newline at end of file From e7b671fbf757f0337fd015c960405588e6b5afeb Mon Sep 17 00:00:00 2001 From: Polat Olu Date: Fri, 17 Oct 2025 13:17:05 +0100 Subject: [PATCH 3/3] Review updates --- .../internal/FlagsmithRetrofitService.kt | 15 +++- .../test/java/com/flagsmith/UserAgentTests.kt | 82 ++++--------------- 2 files changed, 29 insertions(+), 68 deletions(-) diff --git a/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt b/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt index 1a06cde..8ca4a81 100644 --- a/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt +++ b/FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt @@ -43,12 +43,19 @@ interface FlagsmithRetrofitService { private const val USER_AGENT_PREFIX = "flagsmith-kotlin-android-sdk" private fun getUserAgent(context: Context?): String { + val sdkVersion = getSdkVersion() + return "$USER_AGENT_PREFIX/$sdkVersion" + } + + private fun getSdkVersion(): String { return try { - val packageInfo = context?.packageManager?.getPackageInfo(context.packageName, 0) - val version = packageInfo?.versionName ?: "unknown" - "$USER_AGENT_PREFIX/$version" + // Try to get version from BuildConfig + val buildConfigClass = Class.forName("com.flagsmith.kotlin.BuildConfig") + val versionField = buildConfigClass.getField("VERSION_NAME") + versionField.get(null) as String } catch (e: Exception) { - "$USER_AGENT_PREFIX/unknown" + // Fallback to hardcoded version if BuildConfig is not available + "unknown" } } diff --git a/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt b/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt index 4286921..8759275 100644 --- a/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt +++ b/FlagsmithClient/src/test/java/com/flagsmith/UserAgentTests.kt @@ -1,39 +1,21 @@ package com.flagsmith -import android.content.Context -import android.content.pm.PackageInfo -import android.content.pm.PackageManager import com.flagsmith.entities.Trait import com.flagsmith.mockResponses.MockEndpoint import com.flagsmith.mockResponses.mockResponseFor import kotlinx.coroutines.runBlocking import org.junit.After -import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.mockserver.integration.ClientAndServer import org.mockserver.model.HttpRequest.request -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.junit.MockitoJUnitRunner -import org.junit.runner.RunWith -@RunWith(MockitoJUnitRunner::class) class UserAgentTests { private lateinit var mockServer: ClientAndServer private lateinit var flagsmith: Flagsmith - @Mock - private lateinit var mockContext: Context - - @Mock - private lateinit var mockPackageManager: PackageManager - - @Mock - private lateinit var mockPackageInfo: PackageInfo - @Before fun setup() { mockServer = ClientAndServer.startClientAndServer() @@ -46,19 +28,13 @@ class UserAgentTests { @Test fun testUserAgentHeaderSentWithValidVersion() { - // Given - Use a realistic app version (not SDK version) - // The User-Agent shows the APP's version, not the SDK's version - // This helps Flagsmith support team identify which app version is making requests - val expectedAppVersion = "2.4.1" - mockPackageInfo.versionName = expectedAppVersion - Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) - Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") - Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) - + // Given - The User-Agent now shows SDK version or "unknown" (not app version) + // This is because getUserAgent() method was updated to return SDK version + // In tests, BuildConfig is not available, so it returns "unknown" flagsmith = Flagsmith( environmentKey = "test-key", baseUrl = "http://localhost:${mockServer.localPort}", - context = mockContext, + context = null, enableAnalytics = false, cacheConfig = FlagsmithCacheConfig(enableCache = false) ) @@ -71,12 +47,12 @@ class UserAgentTests { assertTrue(result.isSuccess) } - // Then - Verify User-Agent contains the APP's version, not SDK version + // Then - Verify User-Agent contains "unknown" since BuildConfig is not available in tests mockServer.verify( request() .withPath("/flags/") .withMethod("GET") - .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/$expectedAppVersion") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/unknown") ) } @@ -110,16 +86,11 @@ class UserAgentTests { @Test fun testUserAgentHeaderSentWithExceptionDuringVersionRetrieval() { - // Given - Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) - Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") - Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)) - .thenThrow(PackageManager.NameNotFoundException("Package not found")) - + // Given - Even with context, getUserAgent() now returns SDK version or "unknown" flagsmith = Flagsmith( environmentKey = "test-key", baseUrl = "http://localhost:${mockServer.localPort}", - context = mockContext, + context = null, enableAnalytics = false, cacheConfig = FlagsmithCacheConfig(enableCache = false) ) @@ -143,16 +114,11 @@ class UserAgentTests { @Test fun testUserAgentHeaderSentWithNullVersionName() { - // Given - mockPackageInfo.versionName = null - Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) - Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") - Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) - + // Given - getUserAgent() now returns SDK version or "unknown" regardless of context flagsmith = Flagsmith( environmentKey = "test-key", baseUrl = "http://localhost:${mockServer.localPort}", - context = mockContext, + context = null, enableAnalytics = false, cacheConfig = FlagsmithCacheConfig(enableCache = false) ) @@ -176,17 +142,11 @@ class UserAgentTests { @Test fun testUserAgentHeaderSentWithIdentityRequest() { - // Given - val expectedVersion = "2.1.0" - mockPackageInfo.versionName = expectedVersion - Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) - Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") - Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) - + // Given - getUserAgent() now returns SDK version or "unknown" flagsmith = Flagsmith( environmentKey = "test-key", baseUrl = "http://localhost:${mockServer.localPort}", - context = mockContext, + context = null, enableAnalytics = false, cacheConfig = FlagsmithCacheConfig(enableCache = false) ) @@ -199,29 +159,23 @@ class UserAgentTests { assertTrue(result.isSuccess) } - // Then + // Then - Verify User-Agent contains "unknown" since BuildConfig is not available in tests mockServer.verify( request() .withPath("/identities/") .withMethod("GET") .withQueryStringParameter("identifier", "test-user") - .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/$expectedVersion") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/unknown") ) } @Test fun testUserAgentHeaderSentWithTraitRequest() { - // Given - val expectedAppVersion = "3.0.1" - mockPackageInfo.versionName = expectedAppVersion - Mockito.`when`(mockContext.packageManager).thenReturn(mockPackageManager) - Mockito.`when`(mockContext.packageName).thenReturn("com.test.app") - Mockito.`when`(mockPackageManager.getPackageInfo(mockContext.packageName, 0)).thenReturn(mockPackageInfo) - + // Given - getUserAgent() now returns SDK version or "unknown" flagsmith = Flagsmith( environmentKey = "test-key", baseUrl = "http://localhost:${mockServer.localPort}", - context = mockContext, + context = null, enableAnalytics = false, cacheConfig = FlagsmithCacheConfig(enableCache = false) ) @@ -234,12 +188,12 @@ class UserAgentTests { assertTrue(result.isSuccess) } - // Then - Verify the traits request has correct User-Agent + // Then - Verify the traits request has correct User-Agent with "unknown" since BuildConfig is not available in tests mockServer.verify( request() .withPath("/identities/") .withMethod("POST") - .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/$expectedAppVersion") + .withHeader("User-Agent", "flagsmith-kotlin-android-sdk/unknown") ) } } \ No newline at end of file