Skip to content

Commit c4453cc

Browse files
authored
exclude transient field from identities request (#63)
1 parent 370b584 commit c4453cc

File tree

5 files changed

+128
-8
lines changed

5 files changed

+128
-8
lines changed
Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
package com.flagsmith.entities
22

3+
import com.google.gson.*
34
import com.google.gson.annotations.SerializedName
5+
import java.lang.reflect.Type
46

57
data class IdentityAndTraits(
68
@SerializedName(value = "identifier") val identifier: String,
79
@SerializedName(value = "traits") val traits: List<Trait>,
810
@SerializedName(value = "transient") val transient: Boolean? = null
9-
)
11+
)
12+
13+
class IdentityAndTraitsSerializer : JsonSerializer<IdentityAndTraits> {
14+
override fun serialize(src: IdentityAndTraits, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
15+
// Create a JsonObject with all fields except transient
16+
val jsonObject = JsonObject()
17+
jsonObject.addProperty("identifier", src.identifier)
18+
jsonObject.add("traits", context.serialize(src.traits))
19+
20+
// Only add transient if it's true
21+
if (src.transient == true) {
22+
jsonObject.addProperty("transient", true)
23+
}
24+
25+
return jsonObject
26+
}
27+
}

FlagsmithClient/src/main/java/com/flagsmith/entities/Trait.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.flagsmith.entities
22

3-
3+
import com.google.gson.*
44
import com.google.gson.annotations.SerializedName
5-
5+
import java.lang.reflect.Type
66

77
data class Trait (
88
val identifier: String? = null,
@@ -46,6 +46,19 @@ data class Trait (
4646
get() = traitValue as? Boolean
4747
}
4848

49+
class TraitSerializer : JsonSerializer<Trait> {
50+
override fun serialize(src: Trait, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
51+
val jsonObject = JsonObject()
52+
src.identifier?.let { jsonObject.addProperty("identifier", it) }
53+
jsonObject.addProperty("trait_key", src.key)
54+
jsonObject.addProperty("trait_value", src.traitValue.toString())
55+
if (src.transient) {
56+
jsonObject.addProperty("transient", true)
57+
}
58+
return jsonObject
59+
}
60+
}
61+
4962
data class TraitWithIdentity (
5063
@SerializedName(value = "trait_key") val key: String,
5164
@SerializedName(value = "trait_value") val traitValue: Any,

FlagsmithClient/src/main/java/com/flagsmith/internal/FlagsmithRetrofitService.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import android.util.Log
55
import com.flagsmith.FlagsmithCacheConfig
66
import com.flagsmith.entities.Flag
77
import com.flagsmith.entities.IdentityAndTraits
8+
import com.flagsmith.entities.IdentityAndTraitsSerializer
89
import com.flagsmith.entities.IdentityFlagsAndTraits
10+
import com.flagsmith.entities.Trait
11+
import com.flagsmith.entities.TraitSerializer
912
import okhttp3.Cache
1013
import okhttp3.Interceptor
1114
import okhttp3.OkHttpClient
@@ -15,6 +18,7 @@ import retrofit2.http.Body
1518
import retrofit2.http.GET
1619
import retrofit2.http.POST
1720
import retrofit2.http.Query
21+
import com.google.gson.GsonBuilder
1822

1923
interface FlagsmithRetrofitService {
2024

@@ -97,9 +101,14 @@ interface FlagsmithRetrofitService {
97101
.cache(cache)
98102
.build()
99103

104+
val gson = GsonBuilder()
105+
.registerTypeAdapter(IdentityAndTraits::class.java, IdentityAndTraitsSerializer())
106+
.registerTypeAdapter(Trait::class.java, TraitSerializer())
107+
.create()
108+
100109
val retrofit = Retrofit.Builder()
101110
.baseUrl(baseUrl)
102-
.addConverterFactory(GsonConverterFactory.create())
111+
.addConverterFactory(GsonConverterFactory.create(gson))
103112
.client(client)
104113
.build()
105114

FlagsmithClient/src/test/java/com/flagsmith/FeatureFlagTests.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,9 @@ class FeatureFlagTests {
182182
},
183183
{
184184
"trait_key": "persisted-trait",
185-
"trait_value": "value",
186-
"transient": false
185+
"trait_value": "value"
187186
}
188-
],
189-
"transient": false
187+
]
190188
}
191189
""".trimIndent()
192190
)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package com.flagsmith.entities
2+
3+
import com.google.gson.GsonBuilder
4+
import org.junit.Assert.assertEquals
5+
import org.junit.Test
6+
7+
class SerializerTests {
8+
private val gson = GsonBuilder()
9+
.registerTypeAdapter(IdentityAndTraits::class.java, IdentityAndTraitsSerializer())
10+
.registerTypeAdapter(Trait::class.java, TraitSerializer())
11+
.create()
12+
13+
@Test
14+
fun `IdentityAndTraitsSerializer omits transient field when false`() {
15+
val identity = IdentityAndTraits(
16+
identifier = "test-user",
17+
traits = listOf(Trait("key", "value")),
18+
transient = false
19+
)
20+
21+
val json = gson.toJson(identity)
22+
assertEquals(
23+
"""{"identifier":"test-user","traits":[{"trait_key":"key","trait_value":"value"}]}""",
24+
json
25+
)
26+
}
27+
28+
@Test
29+
fun `IdentityAndTraitsSerializer includes transient field when true`() {
30+
val identity = IdentityAndTraits(
31+
identifier = "test-user",
32+
traits = listOf(Trait("key", "value")),
33+
transient = true
34+
)
35+
36+
val json = gson.toJson(identity)
37+
assertEquals(
38+
"""{"identifier":"test-user","traits":[{"trait_key":"key","trait_value":"value"}],"transient":true}""",
39+
json
40+
)
41+
}
42+
43+
@Test
44+
fun `TraitSerializer omits transient field when false`() {
45+
val trait = Trait("key", "value", false)
46+
val json = gson.toJson(trait)
47+
assertEquals(
48+
"""{"trait_key":"key","trait_value":"value"}""",
49+
json
50+
)
51+
}
52+
53+
@Test
54+
fun `TraitSerializer includes transient field when true`() {
55+
val trait = Trait("key", "value", true)
56+
val json = gson.toJson(trait)
57+
assertEquals(
58+
"""{"trait_key":"key","trait_value":"value","transient":true}""",
59+
json
60+
)
61+
}
62+
63+
@Test
64+
fun `TraitSerializer handles optional identifier`() {
65+
val traitWithId = Trait(
66+
identifier = "test-id",
67+
key = "key",
68+
traitValue = "value",
69+
transient = false
70+
)
71+
val traitWithoutId = Trait("key", "value", false)
72+
73+
assertEquals(
74+
"""{"identifier":"test-id","trait_key":"key","trait_value":"value"}""",
75+
gson.toJson(traitWithId)
76+
)
77+
assertEquals(
78+
"""{"trait_key":"key","trait_value":"value"}""",
79+
gson.toJson(traitWithoutId)
80+
)
81+
}
82+
}

0 commit comments

Comments
 (0)