Skip to content

Commit 196832a

Browse files
committed
feat: add ooni test descriptors
1 parent 1c19c1c commit 196832a

File tree

17 files changed

+703
-264
lines changed

17 files changed

+703
-264
lines changed

composeApp/src/commonMain/kotlin/org/ooni/probe/data/models/Descriptor.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ data class Descriptor(
4545
val key: String
4646
get() = when (source) {
4747
is Source.Default -> name
48-
is Source.Installed -> source.value.id.value
48+
is Source.Installed -> source.value.key.id.value
4949
}
5050

5151
val allTests get() = netTests + longRunningTests
@@ -57,6 +57,26 @@ data class Descriptor(
5757

5858
val isWebConnectivityOnly get() =
5959
allTests.size == 1 && allTests.first().test == TestType.WebConnectivity
60+
61+
val settingsPrefix: String?
62+
get() = when (isDefaultDescriptor()) {
63+
true -> null
64+
else -> (source as Source.Installed)
65+
.value.id.value
66+
.toString()
67+
}
68+
69+
fun isDefaultDescriptor(): Boolean =
70+
when (source) {
71+
is Source.Default -> true
72+
is Source.Installed -> source.value.isDefaultTestDescriptor
73+
}
74+
75+
fun isInstalledNonDefaultDescriptor(): Boolean =
76+
when (source) {
77+
is Source.Installed -> !source.value.isDefaultTestDescriptor
78+
else -> false
79+
}
6080
}
6181

6282
fun List<Descriptor>.notExpired() = filter { !it.isExpired }

composeApp/src/commonMain/kotlin/org/ooni/probe/data/models/InstalledTestDescriptorModel.kt

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@ import kotlinx.datetime.format
66
import kotlinx.datetime.format.MonthNames
77
import kotlinx.datetime.format.char
88
import kotlinx.serialization.Serializable
9-
import kotlinx.serialization.encodeToString
109
import kotlinx.serialization.json.Json
1110
import ooniprobe.composeapp.generated.resources.Dashboard_Runv2_Overview_Description
1211
import ooniprobe.composeapp.generated.resources.Dashboard_Runv2_Overview_LastUpdated
1312
import ooniprobe.composeapp.generated.resources.Res
13+
import ooniprobe.composeapp.generated.resources.TestResults_NotAvailable
14+
import ooniprobe.composeapp.generated.resources.performance_datausage
15+
import ooniprobe.composeapp.generated.resources.small_datausage
1416
import ooniprobe.composeapp.generated.resources.test_circumvention
1517
import ooniprobe.composeapp.generated.resources.test_experimental
1618
import ooniprobe.composeapp.generated.resources.test_instant_messaging
1719
import ooniprobe.composeapp.generated.resources.test_performance
1820
import ooniprobe.composeapp.generated.resources.test_websites
21+
import ooniprobe.composeapp.generated.resources.websites_datausage
22+
import org.jetbrains.compose.resources.StringResource
1923
import org.jetbrains.compose.resources.stringResource
2024
import org.ooni.engine.models.SummaryType
2125
import org.ooni.probe.data.TestDescriptor
@@ -24,6 +28,26 @@ import org.ooni.probe.shared.hexToColor
2428
import org.ooni.probe.shared.stringMonthArrayResource
2529
import org.ooni.probe.shared.toEpoch
2630

31+
enum class OoniTest(
32+
val id: Long,
33+
val key: String,
34+
) {
35+
WEBSITES(10470L, "websites"),
36+
INSTANT_MESSAGING(10471L, "instant_messaging"),
37+
CIRCUMVENTION(10472L, "circumvention"),
38+
PERFORMANCE(10473L, "performance"),
39+
EXPERIMENTAL(10474L, "experimental"),
40+
;
41+
42+
companion object {
43+
private val map = entries.associateBy(OoniTest::id)
44+
45+
fun fromId(id: Long) = map[id]
46+
47+
fun isValidId(id: Long): Boolean = entries.any { it.id == id }
48+
}
49+
}
50+
2751
@Serializable
2852
data class InstalledTestDescriptorModel(
2953
val id: Id,
@@ -56,6 +80,8 @@ data class InstalledTestDescriptorModel(
5680
val revision: Long,
5781
)
5882

83+
val isDefaultTestDescriptor get() = OoniTest.isValidId(id.value.toLongOrNull() ?: -1L)
84+
5985
val key get() = Key(id, revision)
6086

6187
val previousRevisions
@@ -85,7 +111,7 @@ fun InstalledTestDescriptorModel.toDescriptor(updateStatus: UpdateStatus = Updat
85111
icon = icon?.let(InstalledDescriptorIcons::getIconFromValue),
86112
color = color?.hexToColor(),
87113
animation = icon?.let { determineAnimation(it) } ?: animation?.let(Animation::fromFileName),
88-
dataUsage = { null },
114+
dataUsage = { if (isDefaultTestDescriptor) stringResource(getDataUsage()) else null },
89115
expirationDate = expirationDate,
90116
netTests = netTests.orEmpty(),
91117
source = Descriptor.Source.Installed(this),
@@ -94,6 +120,22 @@ fun InstalledTestDescriptorModel.toDescriptor(updateStatus: UpdateStatus = Updat
94120
summaryType = SummaryType.Anomaly,
95121
)
96122

123+
fun InstalledTestDescriptorModel.getDataUsage(): StringResource =
124+
when (
125+
OoniTest
126+
.fromId(
127+
this.key.id.value
128+
.toLong(),
129+
)?.key
130+
) {
131+
OoniTest.WEBSITES.key -> Res.string.websites_datausage
132+
OoniTest.INSTANT_MESSAGING.key -> Res.string.small_datausage
133+
OoniTest.CIRCUMVENTION.key -> Res.string.small_datausage
134+
OoniTest.PERFORMANCE.key -> Res.string.performance_datausage
135+
OoniTest.EXPERIMENTAL.key -> Res.string.TestResults_NotAvailable
136+
else -> Res.string.TestResults_NotAvailable
137+
}
138+
97139
private val iconAnimationMap = mapOf(
98140
Res.drawable.test_websites to Animation.Websites,
99141
Res.drawable.test_instant_messaging to Animation.InstantMessaging,

composeApp/src/commonMain/kotlin/org/ooni/probe/data/repositories/PreferenceRepository.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,7 @@ class PreferenceRepository(
205205
isAutoRun: Boolean,
206206
) = getPreferenceKey(
207207
name = netTest.test.preferenceKey,
208-
prefix = (descriptor.source as? Descriptor.Source.Installed)
209-
?.value
210-
?.id
211-
?.value
212-
?.toString(),
208+
prefix = descriptor.settingsPrefix,
213209
autoRun = isAutoRun,
214210
)
215211

composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ import org.ooni.probe.domain.FinishInProgressData
5555
import org.ooni.probe.domain.GetAutoRunSettings
5656
import org.ooni.probe.domain.GetAutoRunSpecification
5757
import org.ooni.probe.domain.GetBootstrapTestDescriptors
58-
import org.ooni.probe.domain.GetDefaultTestDescriptors
5958
import org.ooni.probe.domain.GetEnginePreferences
6059
import org.ooni.probe.domain.GetFirstRun
6160
import org.ooni.probe.domain.GetLastResultOfDescriptor
@@ -303,7 +302,6 @@ class Dependencies(
303302
private val getBootstrapTestDescriptors by lazy {
304303
GetBootstrapTestDescriptors(readAssetFile, json, backgroundContext)
305304
}
306-
private val getDefaultTestDescriptors by lazy { GetDefaultTestDescriptors() }
307305
private val getProxySettings by lazy { GetProxySettings(preferenceRepository) }
308306
private val getEnginePreferences by lazy {
309307
GetEnginePreferences(
@@ -366,7 +364,6 @@ class Dependencies(
366364
@VisibleForTesting
367365
val getTestDescriptors by lazy {
368366
GetTestDescriptors(
369-
getDefaultTestDescriptors = getDefaultTestDescriptors::invoke,
370367
listAllInstalledTestDescriptors = testDescriptorRepository::listAll,
371368
listLatestInstalledTestDescriptors = testDescriptorRepository::listLatest,
372369
observeDescriptorsUpdateState = descriptorUpdateStateManager::observe,

composeApp/src/dwMain/kotlin/org/ooni/probe/domain/GetBootstrapTestDescriptors.kt renamed to composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetBootstrapTestDescriptors.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class GetBootstrapTestDescriptors(
1616
) {
1717
suspend operator fun invoke(): List<InstalledTestDescriptorModel> =
1818
withContext(backgroundContext) {
19-
2019
val descriptorsJson = Res.readBytes("files/assets/descriptors.json").decodeToString()
2120
val descriptors =
2221
try {

composeApp/src/commonMain/kotlin/org/ooni/probe/domain/GetResults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ fun List<Descriptor>.forResult(result: ResultModel): Descriptor? =
3838
result.descriptorKey
3939
?.let { key ->
4040
firstOrNull {
41-
it.source is Descriptor.Source.Installed && it.source.value.key == key
41+
it.source is Descriptor.Source.Installed &&
42+
it.source.value.key
43+
.toString() == key.toString()
4244
}
4345
}
4446
?: firstOrNull { it.name == result.descriptorName }

composeApp/src/commonMain/kotlin/org/ooni/probe/domain/descriptors/GetTestDescriptors.kt

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,18 @@ package org.ooni.probe.domain.descriptors
33
import androidx.compose.runtime.Composable
44
import kotlinx.coroutines.flow.Flow
55
import kotlinx.coroutines.flow.combine
6-
import kotlinx.coroutines.flow.flowOf
76
import kotlinx.coroutines.flow.map
87
import ooniprobe.composeapp.generated.resources.Res
98
import ooniprobe.composeapp.generated.resources.Settings_TestOptions_LongRunningTest
109
import org.jetbrains.compose.resources.stringResource
1110
import org.ooni.engine.models.WebConnectivityCategory
12-
import org.ooni.probe.data.models.DefaultTestDescriptor
1311
import org.ooni.probe.data.models.Descriptor
1412
import org.ooni.probe.data.models.DescriptorsUpdateState
1513
import org.ooni.probe.data.models.InstalledTestDescriptorModel
1614
import org.ooni.probe.data.models.SettingsKey
17-
import org.ooni.probe.data.models.UpdateStatus
1815
import org.ooni.probe.data.models.toDescriptor
1916

2017
class GetTestDescriptors(
21-
private val getDefaultTestDescriptors: () -> List<DefaultTestDescriptor>,
2218
private val listAllInstalledTestDescriptors: () -> Flow<List<InstalledTestDescriptorModel>>,
2319
private val listLatestInstalledTestDescriptors: () -> Flow<List<InstalledTestDescriptorModel>>,
2420
private val observeDescriptorsUpdateState: () -> Flow<DescriptorsUpdateState>,
@@ -38,14 +34,12 @@ class GetTestDescriptors(
3834
return combine(
3935
installedDescriptorFlow(),
4036
observeDescriptorsUpdateState(),
41-
flowOf(getDefaultTestDescriptors()),
4237
isWebsitesDescriptorEnabled(),
43-
) { installedDescriptors, descriptorUpdates, defaultDescriptors, isWebsitesEnabled ->
38+
) { installedDescriptors, descriptorUpdates, isWebsitesEnabled ->
4439
val updatedDescriptors = installedDescriptors.map { item ->
4540
item.toDescriptor(updateStatus = descriptorUpdates.getStatusOf(item.id))
4641
}
47-
val allDescriptors = defaultDescriptors.map { it.toDescriptor() } + updatedDescriptors
48-
return@combine allDescriptors.map {
42+
return@combine updatedDescriptors.map {
4943
it.copy(enabled = it.name != "websites" || isWebsitesEnabled)
5044
}
5145
}
@@ -55,30 +49,6 @@ class GetTestDescriptors(
5549
getPreferenceValues(WebConnectivityCategory.entries.mapNotNull { it.settingsKey })
5650
.map { preferences -> preferences.any { it.value == true } }
5751

58-
private fun DefaultTestDescriptor.toDescriptor() =
59-
Descriptor(
60-
name = label,
61-
title = { stringResource(title) },
62-
shortDescription = { stringResource(shortDescription) },
63-
description = {
64-
if (label == "experimental") {
65-
stringResource(description, experimentalLinks())
66-
} else {
67-
stringResource(description)
68-
}
69-
},
70-
icon = icon,
71-
color = color,
72-
animation = animation,
73-
dataUsage = { stringResource(dataUsage) },
74-
expirationDate = null,
75-
netTests = netTests,
76-
longRunningTests = longRunningTests,
77-
source = Descriptor.Source.Default(this),
78-
updateStatus = UpdateStatus.NotApplicable,
79-
summaryType = summaryType,
80-
)
81-
8252
@Composable
8353
private fun experimentalLinks() =
8454
"""

composeApp/src/commonMain/kotlin/org/ooni/probe/domain/descriptors/GetTestDescriptorsBySpec.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,13 @@ class GetTestDescriptorsBySpec(
3434
// Is this descriptor contained in the RunSpecification's list of tests
3535
private fun RunSpecification.Full.forDescriptor(descriptor: Descriptor) =
3636
tests.firstOrNull { specTest ->
37-
when (descriptor.source) {
38-
is Descriptor.Source.Default -> {
37+
when (val source = descriptor.source) {
38+
is Descriptor.Source.Default ->
3939
specTest.source is RunSpecification.Test.Source.Default &&
40-
specTest.source.name == descriptor.name
41-
}
42-
43-
is Descriptor.Source.Installed -> {
40+
specTest.source.name == source.value.label
41+
is Descriptor.Source.Installed ->
4442
specTest.source is RunSpecification.Test.Source.Installed &&
45-
specTest.source.id == descriptor.source.value.id
46-
}
43+
specTest.source.id == source.value.id
4744
}
4845
}
4946

composeApp/src/commonMain/kotlin/org/ooni/probe/ui/choosewebsites/ChooseWebsitesViewModel.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import kotlinx.coroutines.flow.update
1515
import kotlinx.coroutines.launch
1616
import org.ooni.engine.models.TaskOrigin
1717
import org.ooni.engine.models.TestType
18+
import org.ooni.probe.data.models.InstalledTestDescriptorModel
1819
import org.ooni.probe.data.models.NetTest
20+
import org.ooni.probe.data.models.OoniTest
1921
import org.ooni.probe.data.models.RunSpecification
2022
import org.ooni.probe.data.models.SettingsKey
2123
import org.ooni.probe.ui.shared.isValidUrl
@@ -133,7 +135,9 @@ class ChooseWebsitesViewModel(
133135
RunSpecification.Full(
134136
tests = listOf(
135137
RunSpecification.Test(
136-
source = RunSpecification.Test.Source.Default("websites"),
138+
source = RunSpecification.Test.Source.Installed(
139+
InstalledTestDescriptorModel.Id(OoniTest.WEBSITES.key),
140+
),
137141
netTests = listOf(
138142
NetTest(
139143
test = TestType.WebConnectivity,

composeApp/src/commonMain/kotlin/org/ooni/probe/ui/dashboard/DashboardViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ class DashboardViewModel(
181181

182182
private fun List<Descriptor>.groupByType() =
183183
mapOf(
184-
DescriptorType.Default to filter { it.source is Descriptor.Source.Default },
185-
DescriptorType.Installed to filter { it.source is Descriptor.Source.Installed },
184+
DescriptorType.Default to filter { it.isDefaultDescriptor() },
185+
DescriptorType.Installed to filter { it.isInstalledNonDefaultDescriptor() },
186186
)
187187

188188
data class State(

0 commit comments

Comments
 (0)