mirror of
https://github.com/bitwarden/android.git
synced 2026-03-21 13:52:07 -05:00
[PM-19793] Migrate ZonedDateTimeSerializer to core module (#4960)
This commit is contained in:
@@ -7,7 +7,6 @@ import com.x8bit.bitwarden.data.platform.datasource.network.interceptor.BaseUrlI
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.interceptor.HeadersInterceptor
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.retrofit.Retrofits
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.retrofit.RetrofitsImpl
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.ZonedDateTimeSerializer
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.service.ConfigService
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.service.ConfigServiceImpl
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.service.EventService
|
||||
@@ -23,8 +22,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
|
||||
|
||||
@@ -103,23 +100,4 @@ object PlatformNetworkModule {
|
||||
sslManager = sslManager,
|
||||
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.x8bit.bitwarden.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))
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.auth.datasource.disk
|
||||
import androidx.core.content.edit
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.authenticatorbridge.util.generateSecretKey
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
|
||||
@@ -18,7 +19,6 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserD
|
||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.legacy.LegacySecureStorageMigrator
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockOrganization
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockPolicy
|
||||
import io.mockk.every
|
||||
@@ -44,7 +44,7 @@ class AuthDiskSourceTest {
|
||||
every { migrateIfNecessary() } just runs
|
||||
}
|
||||
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
|
||||
private val authDiskSource = AuthDiskSourceImpl(
|
||||
encryptedSharedPreferences = fakeEncryptedSharedPreferences,
|
||||
|
||||
@@ -27,6 +27,7 @@ import androidx.credentials.provider.PublicKeyCredentialEntry
|
||||
import com.bitwarden.core.data.repository.model.DataState
|
||||
import com.bitwarden.core.data.util.asFailure
|
||||
import com.bitwarden.core.data.util.asSuccess
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.bitwarden.sdk.Fido2CredentialStore
|
||||
import com.bitwarden.vault.CipherView
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus
|
||||
@@ -35,7 +36,6 @@ import com.x8bit.bitwarden.data.auth.repository.model.UserState
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.VaultUnlockType
|
||||
import com.x8bit.bitwarden.data.autofill.fido2.manager.Fido2CredentialManager
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.platform.manager.BiometricsEncryptionManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
@@ -102,7 +102,7 @@ class Fido2ProviderProcessorTest {
|
||||
}
|
||||
private val cancellationSignal: CancellationSignal = mockk()
|
||||
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
private val clock = FIXED_CLOCK
|
||||
|
||||
@BeforeEach
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.x8bit.bitwarden.data.platform.base
|
||||
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.bitwarden.network.core.NetworkResultCallAdapterFactory
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
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() }
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ package com.x8bit.bitwarden.data.platform.datasource.disk
|
||||
|
||||
import androidx.core.content.edit
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.model.ServerConfig
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.ConfigResponseJson
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.ConfigResponseJson.EnvironmentJson
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.ConfigResponseJson.ServerJson
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.x8bit.bitwarden.data.platform.datasource.disk
|
||||
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.dao.FakeOrganizationEventDao
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.entity.OrganizationEventEntity
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.OrganizationEventJson
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEventType
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -24,7 +24,7 @@ class EventDiskSourceTest {
|
||||
|
||||
private val fakeOrganizationEventDao = FakeOrganizationEventDao()
|
||||
private val fakeDispatcherManager = FakeDispatcherManager()
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
|
||||
private val eventDiskSource: EventDiskSource = EventDiskSourceImpl(
|
||||
organizationEventDao = fakeOrganizationEventDao,
|
||||
|
||||
@@ -3,8 +3,8 @@ package com.x8bit.bitwarden.data.platform.datasource.disk
|
||||
import androidx.core.content.edit
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.core.data.util.decodeFromStringOrNull
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.AppResumeScreenData
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.ClearClipboardFrequency
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.UriMatchType
|
||||
@@ -23,7 +23,7 @@ import java.time.Instant
|
||||
@Suppress("LargeClass")
|
||||
class SettingsDiskSourceTest {
|
||||
private val fakeSharedPreferences = FakeSharedPreferences()
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
|
||||
private val settingsDiskSource = SettingsDiskSourceImpl(
|
||||
sharedPreferences = fakeSharedPreferences,
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.x8bit.bitwarden.data.platform.datasource.network.serializer
|
||||
|
||||
import com.x8bit.bitwarden.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,
|
||||
)
|
||||
@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.platform.manager
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.core.data.util.asFailure
|
||||
import com.bitwarden.core.data.util.asSuccess
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson
|
||||
@@ -12,7 +13,6 @@ import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.PushDiskSourceImpl
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.PushTokenRequest
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.service.PushService
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
@@ -63,7 +63,7 @@ class PushManagerTest {
|
||||
pushService = pushService,
|
||||
dispatcherManager = dispatcherManager,
|
||||
clock = clock,
|
||||
json = PlatformNetworkModule.providesJson(),
|
||||
json = CoreModule.providesJson(),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.x8bit.bitwarden.data.util
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import io.mockk.MockKMatcherScope
|
||||
import io.mockk.every
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -15,7 +15,7 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
||||
fun assertJsonEquals(
|
||||
expected: String,
|
||||
actual: String,
|
||||
json: Json = PlatformNetworkModule.providesJson(),
|
||||
json: Json = CoreModule.providesJson(),
|
||||
) {
|
||||
assertEquals(
|
||||
json.parseToJsonElement(expected),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.x8bit.bitwarden.data.vault.datasource.disk
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.core.di.CoreModule
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.di.PlatformNetworkModule
|
||||
import com.x8bit.bitwarden.data.util.assertJsonEquals
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.dao.FakeCiphersDao
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.dao.FakeCollectionsDao
|
||||
@@ -34,7 +34,7 @@ import java.time.ZonedDateTime
|
||||
|
||||
class VaultDiskSourceTest {
|
||||
|
||||
private val json = PlatformNetworkModule.providesJson()
|
||||
private val json = CoreModule.providesJson()
|
||||
private val dispatcherManager: FakeDispatcherManager = FakeDispatcherManager()
|
||||
private lateinit var ciphersDao: FakeCiphersDao
|
||||
private lateinit var collectionsDao: FakeCollectionsDao
|
||||
|
||||
Reference in New Issue
Block a user