mirror of
https://github.com/bitwarden/android.git
synced 2026-03-09 03:33:36 -05:00
[PM-19793] Migrate ZonedDateTimeSerializer to core module (#4960)
This commit is contained in:
@@ -4,7 +4,6 @@ import com.bitwarden.authenticator.data.platform.datasource.network.interceptor.
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.interceptor.HeadersInterceptor
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.retrofit.Retrofits
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.retrofit.RetrofitsImpl
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.serializer.ZonedDateTimeSerializer
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.service.ConfigService
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.service.ConfigServiceImpl
|
||||
import dagger.Module
|
||||
@@ -12,8 +11,6 @@ import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.contextual
|
||||
import retrofit2.create
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -46,23 +43,4 @@ object PlatformNetworkModule {
|
||||
headersInterceptor = headersInterceptor,
|
||||
json = json,
|
||||
)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesJson(): Json = Json {
|
||||
|
||||
// If there are keys returned by the server not modeled by a serializable class,
|
||||
// ignore them.
|
||||
// This makes additive server changes non-breaking.
|
||||
ignoreUnknownKeys = true
|
||||
|
||||
// We allow for nullable values to have keys missing in the JSON response.
|
||||
explicitNulls = false
|
||||
serializersModule = SerializersModule {
|
||||
contextual(ZonedDateTimeSerializer())
|
||||
}
|
||||
|
||||
// Respect model default property values.
|
||||
coerceInputValues = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.bitwarden.authenticator.data.platform.datasource.network.serializer
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
/**
|
||||
* Used to serialize and deserialize [ZonedDateTime].
|
||||
*/
|
||||
class ZonedDateTimeSerializer : KSerializer<ZonedDateTime> {
|
||||
private val dateTimeFormatterDeserialization = DateTimeFormatter
|
||||
.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.][:][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]X")
|
||||
|
||||
private val dateTimeFormatterSerialization =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX")
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor(serialName = "ZonedDateTime", kind = PrimitiveKind.STRING)
|
||||
|
||||
override fun deserialize(decoder: Decoder): ZonedDateTime =
|
||||
decoder.decodeString().let { dateString ->
|
||||
ZonedDateTime.parse(dateString, dateTimeFormatterDeserialization)
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: ZonedDateTime) {
|
||||
encoder.encodeString(dateTimeFormatterSerialization.format(value))
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.bitwarden.authenticator.data.platform.base
|
||||
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.core.ResultCallAdapterFactory
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.MediaType.Companion.toMediaType
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
@@ -14,7 +14,7 @@ import retrofit2.converter.kotlinx.serialization.asConverterFactory
|
||||
*/
|
||||
abstract class BaseServiceTest {
|
||||
|
||||
protected val json = PlatformNetworkModule.providesJson()
|
||||
protected val json = CoreModule.providesJson()
|
||||
|
||||
protected val server = MockWebServer().apply { start() }
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@ import androidx.core.content.edit
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.authenticator.data.platform.base.FakeSharedPreferences
|
||||
import com.bitwarden.authenticator.data.platform.datasource.disk.model.ServerConfig
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.model.ConfigResponseJson
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.model.ConfigResponseJson.EnvironmentJson
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.model.ConfigResponseJson.ServerJson
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
@@ -16,7 +16,7 @@ import org.junit.jupiter.api.Test
|
||||
import java.time.Instant
|
||||
|
||||
class ConfigDiskSourceTest {
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
|
||||
private val fakeSharedPreferences = FakeSharedPreferences()
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import androidx.core.content.edit
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.authenticator.data.platform.base.FakeSharedPreferences
|
||||
import com.bitwarden.authenticator.data.platform.datasource.disk.model.FeatureFlagsConfiguration
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.bitwarden.authenticator.data.platform.manager.model.FlagKey
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
@@ -13,7 +13,7 @@ import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class FeatureFlagDiskSourceTest {
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
|
||||
private val fakeSharedPreferences = FakeSharedPreferences()
|
||||
|
||||
@@ -58,7 +58,7 @@ class FeatureFlagDiskSourceTest {
|
||||
private const val FEATURE_FLAGS_CONFIGURATION_JSON = """
|
||||
{
|
||||
"featureFlags" : {
|
||||
"bitwarden-authentication-enabled" : true
|
||||
"bitwarden-authentication-enabled" : true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.bitwarden.authenticator.data.platform.datasource.network.serializer
|
||||
|
||||
import com.bitwarden.authenticator.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
class ZonedDateTimeSerializerTest {
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
|
||||
@Test
|
||||
fun `properly deserializes raw JSON to ZonedDateTime`() {
|
||||
assertEquals(
|
||||
ZonedDateTimeData(
|
||||
dataAsZonedDateTime = ZonedDateTime.of(
|
||||
2023,
|
||||
10,
|
||||
6,
|
||||
17,
|
||||
22,
|
||||
28,
|
||||
440000000,
|
||||
ZoneOffset.UTC,
|
||||
),
|
||||
),
|
||||
json.decodeFromString<ZonedDateTimeData>(
|
||||
"""
|
||||
{
|
||||
"dataAsZonedDateTime": "2023-10-06T17:22:28.44Z"
|
||||
}
|
||||
""",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `properly deserializes raw JSON with nano seconds to ZonedDateTime`() {
|
||||
assertEquals(
|
||||
ZonedDateTimeData(
|
||||
dataAsZonedDateTime = ZonedDateTime.of(
|
||||
2023,
|
||||
8,
|
||||
1,
|
||||
16,
|
||||
13,
|
||||
3,
|
||||
502391000,
|
||||
ZoneOffset.UTC,
|
||||
),
|
||||
),
|
||||
json.decodeFromString<ZonedDateTimeData>(
|
||||
"""
|
||||
{
|
||||
"dataAsZonedDateTime": "2023-08-01T16:13:03.502391Z"
|
||||
}
|
||||
""",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `properly serializes external model back to raw JSON`() {
|
||||
assertEquals(
|
||||
json.parseToJsonElement(
|
||||
"""
|
||||
{
|
||||
"dataAsZonedDateTime": "2023-10-06T17:22:28.440Z"
|
||||
}
|
||||
""",
|
||||
),
|
||||
json.encodeToJsonElement(
|
||||
ZonedDateTimeData(
|
||||
dataAsZonedDateTime = ZonedDateTime.of(
|
||||
2023,
|
||||
10,
|
||||
6,
|
||||
17,
|
||||
22,
|
||||
28,
|
||||
440000000,
|
||||
ZoneId.of("UTC"),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
private data class ZonedDateTimeData(
|
||||
@Serializable(ZonedDateTimeSerializer::class)
|
||||
@SerialName("dataAsZonedDateTime")
|
||||
val dataAsZonedDateTime: ZonedDateTime,
|
||||
)
|
||||
Reference in New Issue
Block a user