Skip to content

Commit

Permalink
test: increase test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklasl committed Jul 9, 2024
1 parent 1084a45 commit 68d166d
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Provider/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ kover {
reports {
verify {
rule {
minBound(70)
minBound(80)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.spotify.confidence.openfeature

import com.spotify.confidence.ConfidenceValue
import dev.openfeature.sdk.Value
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test

class ConfidenceValueMappingsTest {

@Test
fun confidenceStringToValueString() {
val confidenceValue = ConfidenceValue.String("test")
val value = confidenceValue.toValue()
assertEquals("test", value.asString())
assertNull(value.asInteger())
assertNull(value.asDate())
assertNull(value.asBoolean())
assertNull(value.asStructure())
}

@Test
fun confidenceDoubleToValueDouble() {
val confidenceValue = ConfidenceValue.Double(1.23)
val value = confidenceValue.toValue()
assertEquals(1.23, value.asDouble()!!, 0.001)
assertNull(value.asString())
assertNull(value.asInteger())
assertNull(value.asDate())
assertNull(value.asBoolean())
assertNull(value.asStructure())
}

@Test
fun confidenceBooleanToValueBoolean() {
val confidenceValue = ConfidenceValue.Boolean(true)
val value = confidenceValue.toValue()
assertEquals(true, value.asBoolean())
assertNull(value.asString())
assertNull(value.asDouble())
assertNull(value.asDate())
assertNull(value.asInteger())
assertNull(value.asStructure())
}

@Test
fun confidenceIntegerToValueInteger() {
val confidenceValue = ConfidenceValue.Integer(42)
val value = confidenceValue.toValue()
assertEquals(42, value.asInteger())
assertNull(value.asString())
assertNull(value.asDouble())
assertNull(value.asDate())
assertNull(value.asBoolean())
assertNull(value.asStructure())
}

@Test
fun confidenceStructToValueStructure() {
val confidenceValue = ConfidenceValue.Struct(mapOf("key" to ConfidenceValue.String("value")))
val value = confidenceValue.toValue()
assertEquals(mapOf("key" to dev.openfeature.sdk.Value.String("value")), value.asStructure())
assertNull(value.asString())
assertNull(value.asDouble())
assertNull(value.asDate())
assertNull(value.asBoolean())
assertNull(value.asList())
}

@Test
fun confidenceListToValueList() {
val confidenceValue = ConfidenceValue.List(listOf(ConfidenceValue.String("item")))
val value = confidenceValue.toValue()
assertEquals(listOf(dev.openfeature.sdk.Value.String("item")), value.asList())
assertNull(value.asString())
assertNull(value.asDouble())
assertNull(value.asDate())
assertNull(value.asBoolean())
assertNull(value.asStructure())
}

@Test
fun confidenceDateToValueDate() {
val date = java.util.Date()
val confidenceValue = ConfidenceValue.Date(date)
val value = confidenceValue.toValue()
assertEquals(date, value.asDate())
assertNull(value.asString())
assertNull(value.asDouble())
assertNull(value.asBoolean())
assertNull(value.asInteger())
assertNull(value.asStructure())
}

@Test
fun confidenceTimestampToValueTimestamp() {
val timestamp = java.util.Date()
val confidenceValue = ConfidenceValue.Timestamp(timestamp)
val value = confidenceValue.toValue()
assertEquals(timestamp.time, value.asDate()!!.time)
assertNull(value.asString())
assertNull(value.asDouble())
assertNull(value.asBoolean())
assertNull(value.asInteger())
assertNull(value.asStructure())
}

@Test
fun confidenceNullToValueNull() {
val confidenceValue = ConfidenceValue.Null
val value = confidenceValue.toValue()
assertEquals(Value.Null, value)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import dev.openfeature.sdk.Reason
import dev.openfeature.sdk.Value
import dev.openfeature.sdk.events.EventHandler
import dev.openfeature.sdk.events.OpenFeatureEvents
import dev.openfeature.sdk.exceptions.ErrorCode
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
Expand All @@ -28,7 +29,7 @@ import java.util.UUID
private const val clientSecret = "21wxcxXpU6tKBRFtEFTXYiH7nDqL86Mm"
private val mockContext: Context = mock()

class ConfidenceIntegrationTests {
class ProviderIntegrationTest {

@get:Rule
var tmpFile = TemporaryFolder()
Expand Down Expand Up @@ -85,7 +86,7 @@ class ConfidenceIntegrationTests {
val eventsHandler = EventHandler(Dispatchers.IO).apply {
publish(OpenFeatureEvents.ProviderStale)
}
val cacheFile = File(mockContext.filesDir, FLAGS_FILE_NAME)
val cacheFile = File(mockContext.filesDir, flagsFileName)
assertEquals(0L, cacheFile.length())
val mockConfidence = ConfidenceFactory.create(mockContext, clientSecret)
OpenFeatureAPI.setProvider(
Expand Down Expand Up @@ -118,5 +119,62 @@ class ConfidenceIntegrationTests {
assertEquals(Reason.TARGETING_MATCH.name, intDetails.reason)
assertNotNull(intDetails.variant)
}
}
internal const val FLAGS_FILE_NAME = "confidence_flags_cache.json"

@Test
fun testSimpleResolveWithFetchAndActivateInMemoryCache() {
val eventsHandler = EventHandler(Dispatchers.IO).apply {
publish(OpenFeatureEvents.ProviderStale)
}
val mockConfidence = ConfidenceFactory.create(mockContext, clientSecret)

OpenFeatureAPI.setProvider(
ConfidenceFeatureProvider.create(
confidence = mockConfidence,
initialisationStrategy = InitialisationStrategy.ActivateAndFetchAsync,
eventHandler = eventsHandler
),
ImmutableContext(
targetingKey = UUID.randomUUID().toString(),
attributes = mutableMapOf(
"user" to Value.Structure(
mapOf(
"country" to Value.String("SE")
)
)
)
)
)
runBlocking {
awaitProviderReady(eventsHandler = eventsHandler)
}

val flagNotFoundDetails = OpenFeatureAPI.getClient()
.getObjectDetails(
"kotlin-test-flag",
Value.Structure(emptyMap())
)
assertEquals(ErrorCode.FLAG_NOT_FOUND, flagNotFoundDetails.errorCode)
assertNull(flagNotFoundDetails.errorMessage)
assertEquals(Value.Structure(emptyMap()), flagNotFoundDetails.value)
assertEquals(Reason.ERROR.name, flagNotFoundDetails.reason)
assertNull(flagNotFoundDetails.variant)

runBlocking {
mockConfidence.fetchAndActivate()
}

val evaluationDetails = OpenFeatureAPI.getClient()
.getObjectDetails(
"kotlin-test-flag",
Value.Structure(emptyMap())
)
assertNull(evaluationDetails.errorCode)
assertNull(evaluationDetails.errorMessage)
assertNotNull(evaluationDetails.value)
assertEquals(Reason.TARGETING_MATCH.name, evaluationDetails.reason)
assertNotNull(evaluationDetails.variant)

assertEquals(4, evaluationDetails.value.asStructure()?.getOrDefault("my-integer", Value.Integer(-1))?.asInteger())
}
private val flagsFileName = "confidence_flags_cache.json"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ suspend fun awaitProviderReady(
dispatcher: CoroutineDispatcher = Dispatchers.IO
) = suspendCancellableCoroutine { continuation ->
fun observeProviderReady() = eventsHandler
.observe<OpenFeatureEvents.ProviderReady>()
.observe<OpenFeatureEvents>()
.onStart {
if (eventsHandler.getProviderStatus() == OpenFeatureEvents.ProviderReady) {
this.emit(OpenFeatureEvents.ProviderReady)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.spotify.confidence.openfeature

import com.spotify.confidence.ConfidenceValue
import dev.openfeature.sdk.Value
import org.junit.Assert.assertEquals
import org.junit.Test

class ValueMappingsTest {

@Test
fun openFeatureStringValueToConfidenceValueString() {
val value = Value.String("test")
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals("test", confidenceValue.asString()?.string)
}

@Test
fun openFeatureDoubleValueToConfidenceValueDouble() {
val value = Value.Double(1.23)
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals(1.23, confidenceValue.asDouble()?.double!!, 0.001)
}

@Test
fun openFeatureBooleanValueToConfidenceValueBoolean() {
val value = Value.Boolean(true)
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals(true, confidenceValue.asBoolean()?.boolean)
}

@Test
fun openFeatureIntegerValueToConfidenceValueInteger() {
val value = Value.Integer(42)
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals(42, confidenceValue.asInteger()?.integer)
}

@Test
fun openFeatureStructureValueToConfidenceValueStruct() {
val value = Value.Structure(mapOf("key" to Value.String("value")))
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals("value", confidenceValue.asStructure()?.map?.get("key")?.asString()?.string)
}

@Test
fun openFeatureListValueToConfidenceValueList() {
val value = Value.List(listOf(Value.String("value")))
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals("value", confidenceValue.asList()?.list?.get(0)?.asString()?.string)
}

@Test
fun mixedListShouldReturnEmptyConfidenceList() {
val value = Value.List(listOf(Value.String("value"), Value.Integer(42)))
val confidenceValue: ConfidenceValue = value.toConfidenceValue()
assertEquals(0, confidenceValue.asList()?.list?.size)
}

private fun ConfidenceValue.asString(): ConfidenceValue.String? {
return this as? ConfidenceValue.String
}

private fun ConfidenceValue.asDouble(): ConfidenceValue.Double? {
return this as? ConfidenceValue.Double
}

private fun ConfidenceValue.asBoolean(): ConfidenceValue.Boolean? {
return this as? ConfidenceValue.Boolean
}

private fun ConfidenceValue.asInteger(): ConfidenceValue.Integer? {
return this as? ConfidenceValue.Integer
}

private fun ConfidenceValue.asStructure(): ConfidenceValue.Struct? {
return this as? ConfidenceValue.Struct
}

private fun ConfidenceValue.asList(): ConfidenceValue.List? {
return this as? ConfidenceValue.List
}
}

0 comments on commit 68d166d

Please sign in to comment.