add Android unit test coverage
This commit is contained in:
@@ -23,6 +23,7 @@ This is the canonical working plan and progress log for the project. Use this fi
|
||||
- Backend analytics coverage now includes a representative key user flow batch.
|
||||
- iOS project scaffolding now exists as `mobile/ios-app/HermesApp.xcodeproj` with a shared scheme and XCTest target.
|
||||
- iOS sources and tests build and pass in Xcode on an iPhone simulator, and a standalone localization/error-mapping harness passes.
|
||||
- Android local unit tests now cover localization, error mapping, and analytics batch conversion, and `./gradlew testDebugUnitTest` passes with the Android SDK installed.
|
||||
|
||||
### Still Open
|
||||
|
||||
|
||||
@@ -24,6 +24,10 @@ android {
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests.isIncludeAndroidResources = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
@@ -67,4 +71,9 @@ dependencies {
|
||||
|
||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||
|
||||
testImplementation(kotlin("test"))
|
||||
testImplementation("androidx.test:core:1.6.1")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
testImplementation("org.robolectric:robolectric:4.13")
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.hermes.app.core.analytics
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
import java.util.UUID
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [34])
|
||||
class HermesAnalyticsTrackerTest {
|
||||
@Test
|
||||
fun convertsPendingEventsToBatchRequest() {
|
||||
val tracker = HermesAnalyticsTracker()
|
||||
val event = HermesTrackedEvent(
|
||||
id = UUID.fromString("00000000-0000-0000-0000-000000000001"),
|
||||
name = "screen_viewed",
|
||||
attributes = mapOf("screen_name" to "feed"),
|
||||
timestamp = Instant.fromEpochMilliseconds(1_000),
|
||||
)
|
||||
|
||||
val batch = tracker.toBatchRequest(listOf(event))
|
||||
|
||||
assertEquals(1, batch.events.size)
|
||||
assertEquals("screen_viewed", batch.events.first().eventName)
|
||||
assertEquals("feed", batch.events.first().attributes!!.first().value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun marksDeliveredEventsAsRemoved() {
|
||||
val tracker = HermesAnalyticsTracker()
|
||||
|
||||
tracker.track("screen_viewed", mapOf("screen_name" to "feed"))
|
||||
val trackedId = tracker.pendingEventsSnapshot().first().id
|
||||
tracker.markDelivered(setOf(trackedId))
|
||||
|
||||
assertTrue(tracker.pendingEventsSnapshot().isEmpty())
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.hermes.app.core.errors
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.hermes.app.R
|
||||
import com.hermes.app.core.localization.HermesLocalizationStore
|
||||
import java.io.IOException
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNull
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [34])
|
||||
class HermesErrorMapperTest {
|
||||
private val context = ApplicationProvider.getApplicationContext<android.content.Context>()
|
||||
private val store = HermesLocalizationStore(context)
|
||||
|
||||
@Test
|
||||
fun mapsNetworkErrorsToLocalizedCopy() {
|
||||
assertEquals(
|
||||
"Nätverksfel. Kontrollera anslutningen.",
|
||||
mapUserFacingError(store, "sv", IOException("boom")),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun mapsGenericErrorsToLocalizedCopy() {
|
||||
assertEquals(
|
||||
"Försök igen.",
|
||||
mapUserFacingError(store, "sv", IllegalStateException("boom")),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ignoresCancellation() {
|
||||
assertNull(mapUserFacingError(store, "en", kotlinx.coroutines.CancellationException()))
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.hermes.app.core.localization
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.hermes.app.R
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(sdk = [34])
|
||||
class HermesLocalizationStoreTest {
|
||||
private val context = ApplicationProvider.getApplicationContext<android.content.Context>()
|
||||
private val store = HermesLocalizationStore(context)
|
||||
|
||||
@Test
|
||||
fun englishStringsLoad() {
|
||||
assertEquals("Settings", store.string("en", R.string.settings_title))
|
||||
assertEquals("Enabled", store.string("en", R.string.settings_enabled))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun swedishStringsLoad() {
|
||||
assertEquals("Inställningar", store.string("sv", R.string.settings_title))
|
||||
assertEquals("Aktiverad", store.string("sv", R.string.settings_enabled))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unsupportedLocaleFallsBackToEnglish() {
|
||||
store.setLocale("fr")
|
||||
|
||||
assertEquals("en", store.localeCode.value)
|
||||
assertEquals("English", store.localeName("en", "fr"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user