diff --git a/changelog.d/7327.wip b/changelog.d/7327.wip
new file mode 100644
index 0000000000..8f0191f948
--- /dev/null
+++ b/changelog.d/7327.wip
@@ -0,0 +1 @@
+[Device management] Update the unknown verification status icon
diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml
index 77f16efff8..20d00563dc 100644
--- a/library/ui-strings/src/main/res/values/strings.xml
+++ b/library/ui-strings/src/main/res/values/strings.xml
@@ -3254,10 +3254,12 @@
Unknown device type
Verified session
Unverified session
+ Unknown verification status
Your current session is ready for secure messaging.
This session is ready for secure messaging.
Verify your current session for enhanced secure messaging.
Verify or sign out from this session for best security and reliability.
+ Verify your current session to reveal this session\'s verification status.
Verify Session
View Details
View All (%1$d)
diff --git a/library/ui-styles/src/main/res/values/colors.xml b/library/ui-styles/src/main/res/values/colors.xml
index 85646adb42..9d8645a707 100644
--- a/library/ui-styles/src/main/res/values/colors.xml
+++ b/library/ui-styles/src/main/res/values/colors.xml
@@ -146,6 +146,7 @@
#91A1C0
#FF4B55
#0FFF4B55
+ @color/palette_gray_200
diff --git a/vector/build.gradle b/vector/build.gradle
index c59e1a3028..048bb885bc 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -53,6 +53,8 @@ android {
// "pm clear" command after each test invocation. This command ensures
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
+
+ vectorDrawables.useSupportLibrary = true
}
testOptions {
diff --git a/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt b/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt
index 1990859668..6327daec86 100644
--- a/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt
@@ -45,8 +45,8 @@ class ShieldImageView @JvmOverloads constructor(
RoomEncryptionTrustLevel.Default -> {
contentDescription = context.getString(R.string.a11y_trust_level_default)
setImageResource(
- if (borderLess) R.drawable.ic_shield_black_no_border
- else R.drawable.ic_shield_black
+ if (borderLess) R.drawable.ic_shield_unknown_no_border
+ else R.drawable.ic_shield_unknown
)
}
RoomEncryptionTrustLevel.Warning -> {
@@ -137,7 +137,7 @@ class ShieldImageView @JvmOverloads constructor(
@DrawableRes
fun RoomEncryptionTrustLevel.toDrawableRes(): Int {
return when (this) {
- RoomEncryptionTrustLevel.Default -> R.drawable.ic_shield_black
+ RoomEncryptionTrustLevel.Default -> R.drawable.ic_shield_unknown
RoomEncryptionTrustLevel.Warning -> R.drawable.ic_shield_warning
RoomEncryptionTrustLevel.Trusted -> R.drawable.ic_shield_trusted
RoomEncryptionTrustLevel.E2EWithUnsupportedAlgorithm -> R.drawable.ic_warning_badge
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt
index 42e4cebe4c..6adb33d5ab 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCase.kt
@@ -57,7 +57,7 @@ class GetDeviceFullInfoListUseCase @Inject constructor(
} else {
emptyList()
}
- filterDevicesUseCase.execute(deviceFullInfoList, filterType, excludedDeviceIds)
+ filterDevicesUseCase.execute(currentSessionCrossSigningInfo, deviceFullInfoList, filterType, excludedDeviceIds)
}
deviceFullInfoFlow.distinctUntilChanged()
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
index 47ea96c09d..bd68cbc0ce 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt
@@ -44,6 +44,7 @@ import im.vector.app.features.settings.devices.v2.list.SESSION_IS_MARKED_AS_INAC
import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationView
import im.vector.app.features.settings.devices.v2.list.SecurityRecommendationViewState
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
+import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel
import javax.inject.Inject
/**
@@ -164,12 +165,11 @@ class VectorSettingsDevicesFragment :
if (state.devices is Success) {
val devices = state.devices()
val currentDeviceId = state.currentSessionCrossSigningInfo.deviceId
- val currentDeviceInfo = devices?.firstOrNull {
- it.deviceInfo.deviceId == currentDeviceId
- }
+ val currentDeviceInfo = devices?.firstOrNull { it.deviceInfo.deviceId == currentDeviceId }
+ val isCurrentSessionVerified = currentDeviceInfo?.roomEncryptionTrustLevel == RoomEncryptionTrustLevel.Trusted
val otherDevices = devices?.filter { it.deviceInfo.deviceId != currentDeviceId }
- renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount)
+ renderSecurityRecommendations(state.inactiveSessionsCount, state.unverifiedSessionsCount, isCurrentSessionVerified)
renderCurrentDevice(currentDeviceInfo)
renderOtherSessionsView(otherDevices)
} else {
@@ -181,14 +181,21 @@ class VectorSettingsDevicesFragment :
handleLoadingStatus(state.isLoading)
}
- private fun renderSecurityRecommendations(inactiveSessionsCount: Int, unverifiedSessionsCount: Int) {
- if (unverifiedSessionsCount == 0 && inactiveSessionsCount == 0) {
+ private fun renderSecurityRecommendations(
+ inactiveSessionsCount: Int,
+ unverifiedSessionsCount: Int,
+ isCurrentSessionVerified: Boolean,
+ ) {
+ val isUnverifiedSectionVisible = unverifiedSessionsCount > 0 && isCurrentSessionVerified
+ val isInactiveSectionVisible = inactiveSessionsCount > 0
+ if (isUnverifiedSectionVisible.not() && isInactiveSectionVisible.not()) {
hideSecurityRecommendations()
} else {
views.deviceListHeaderSectionSecurityRecommendations.isVisible = true
views.deviceListSecurityRecommendationsDivider.isVisible = true
- views.deviceListUnverifiedSessionsRecommendation.isVisible = unverifiedSessionsCount > 0
- views.deviceListInactiveSessionsRecommendation.isVisible = inactiveSessionsCount > 0
+
+ views.deviceListUnverifiedSessionsRecommendation.isVisible = isUnverifiedSectionVisible
+ views.deviceListInactiveSessionsRecommendation.isVisible = isInactiveSectionVisible
val unverifiedSessionsViewState = SecurityRecommendationViewState(
description = getString(R.string.device_manager_unverified_sessions_description),
sessionsCount = unverifiedSessionsCount,
@@ -206,11 +213,19 @@ class VectorSettingsDevicesFragment :
}
}
+ private fun hideUnverifiedSessionsRecommendation() {
+ views.deviceListUnverifiedSessionsRecommendation.isVisible = false
+ }
+
+ private fun hideInactiveSessionsRecommendation() {
+ views.deviceListInactiveSessionsRecommendation.isVisible = false
+ }
+
private fun hideSecurityRecommendations() {
views.deviceListHeaderSectionSecurityRecommendations.isVisible = false
- views.deviceListUnverifiedSessionsRecommendation.isVisible = false
- views.deviceListInactiveSessionsRecommendation.isVisible = false
views.deviceListSecurityRecommendationsDivider.isVisible = false
+ hideUnverifiedSessionsRecommendation()
+ hideInactiveSessionsRecommendation()
}
private fun renderOtherSessionsView(otherDevices: List?) {
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt
index a23a7a7108..8f23fd06cc 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCase.kt
@@ -17,22 +17,27 @@
package im.vector.app.features.settings.devices.v2.filter
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
+import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo
import org.matrix.android.sdk.api.extensions.orFalse
import javax.inject.Inject
class FilterDevicesUseCase @Inject constructor() {
fun execute(
+ currentSessionCrossSigningInfo: CurrentSessionCrossSigningInfo,
devices: List,
filterType: DeviceManagerFilterType,
excludedDeviceIds: List = emptyList(),
): List {
+ val isCurrentSessionVerified = currentSessionCrossSigningInfo.isCrossSigningVerified.orFalse()
return devices
.filter {
when (filterType) {
DeviceManagerFilterType.ALL_SESSIONS -> true
- DeviceManagerFilterType.VERIFIED -> it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse()
- DeviceManagerFilterType.UNVERIFIED -> !it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse()
+ // when current session is not verified, other session status cannot be trusted
+ DeviceManagerFilterType.VERIFIED -> isCurrentSessionVerified && it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse()
+ // when current session is not verified, other session status cannot be trusted
+ DeviceManagerFilterType.UNVERIFIED -> isCurrentSessionVerified && !it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse()
DeviceManagerFilterType.INACTIVE -> it.isInactive
}
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt
index b0ba8baa1a..59e7e1888e 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/OtherSessionsController.kt
@@ -53,7 +53,7 @@ class OtherSessionsController @Inject constructor(
data.forEach { device ->
val dateFormatKind = if (device.isInactive) DateFormatKind.TIMELINE_DAY_DIVIDER else DateFormatKind.DEFAULT_DATE_AND_TIME
val formattedLastActivityDate = host.dateFormatter.format(device.deviceInfo.lastSeenTs, dateFormatKind)
- val description = calculateDescription(device, formattedLastActivityDate)
+ val description = buildDescription(device, formattedLastActivityDate)
val descriptionColor = if (device.isCurrentDevice) {
host.colorProvider.getColorFromAttribute(R.attr.colorError)
} else {
@@ -77,7 +77,7 @@ class OtherSessionsController @Inject constructor(
}
}
- private fun calculateDescription(device: DeviceFullInfo, formattedLastActivityDate: String): String {
+ private fun buildDescription(device: DeviceFullInfo, formattedLastActivityDate: String): String {
return when {
device.isInactive -> {
stringProvider.getQuantityString(
@@ -93,6 +93,9 @@ class OtherSessionsController @Inject constructor(
device.isCurrentDevice -> {
stringProvider.getString(R.string.device_manager_other_sessions_description_unverified_current_session)
}
+ device.roomEncryptionTrustLevel == RoomEncryptionTrustLevel.Default -> {
+ stringProvider.getString(R.string.device_manager_session_last_activity, formattedLastActivityDate)
+ }
else -> {
stringProvider.getString(R.string.device_manager_other_sessions_description_unverified, formattedLastActivityDate)
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
index 6f6c5b24e2..3d9c3a8f37 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/list/SessionInfoView.kt
@@ -90,10 +90,10 @@ class SessionInfoView @JvmOverloads constructor(
isVerifyButtonVisible: Boolean,
) {
views.sessionInfoVerificationStatusImageView.render(encryptionTrustLevel)
- if (encryptionTrustLevel == RoomEncryptionTrustLevel.Trusted) {
- renderCrossSigningVerified(isCurrentSession)
- } else {
- renderCrossSigningUnverified(isCurrentSession, isVerifyButtonVisible)
+ when {
+ encryptionTrustLevel == RoomEncryptionTrustLevel.Trusted -> renderCrossSigningVerified(isCurrentSession)
+ encryptionTrustLevel == RoomEncryptionTrustLevel.Default && !isCurrentSession -> renderCrossSigningUnknown()
+ else -> renderCrossSigningUnverified(isCurrentSession, isVerifyButtonVisible)
}
if (hasLearnMoreLink) {
appendLearnMoreToVerificationStatus()
@@ -142,6 +142,12 @@ class SessionInfoView @JvmOverloads constructor(
views.sessionInfoVerifySessionButton.isVisible = isVerifyButtonVisible
}
+ private fun renderCrossSigningUnknown() {
+ views.sessionInfoVerificationStatusTextView.text = context.getString(R.string.device_manager_verification_status_unknown)
+ views.sessionInfoVerificationStatusDetailTextView.text = context.getString(R.string.device_manager_verification_status_detail_other_session_unknown)
+ views.sessionInfoVerifySessionButton.isVisible = false
+ }
+
private fun renderDeviceInfo(sessionName: String, deviceType: DeviceType, stringProvider: StringProvider) {
setDeviceTypeIconUseCase.execute(deviceType, views.sessionInfoDeviceTypeImageView, stringProvider)
views.sessionInfoNameTextView.text = sessionName
@@ -155,34 +161,31 @@ class SessionInfoView @JvmOverloads constructor(
drawableProvider: DrawableProvider,
colorProvider: ColorProvider,
) {
- deviceInfo.lastSeenTs
- ?.takeIf { isLastSeenDetailsVisible }
- ?.let { timestamp ->
- views.sessionInfoLastActivityTextView.isVisible = true
- views.sessionInfoLastActivityTextView.text = if (isInactive) {
- val formattedTs = dateFormatter.format(timestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)
- context.resources.getQuantityString(
- R.plurals.device_manager_other_sessions_description_inactive,
- SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
- SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
- formattedTs
- )
- } else {
- val formattedTs = dateFormatter.format(timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME)
- context.getString(R.string.device_manager_session_last_activity, formattedTs)
- }
- val drawable = if (isInactive) {
- val drawableColor = colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
- drawableProvider.getDrawable(R.drawable.ic_inactive_sessions, drawableColor)
- } else {
- null
- }
- views.sessionInfoLastActivityTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
- }
- ?: run {
- views.sessionInfoLastActivityTextView.isGone = true
- }
-
+ if (deviceInfo.lastSeenTs != null && isLastSeenDetailsVisible) {
+ val timestamp = deviceInfo.lastSeenTs
+ views.sessionInfoLastActivityTextView.isVisible = true
+ views.sessionInfoLastActivityTextView.text = if (isInactive) {
+ val formattedTs = dateFormatter.format(timestamp, DateFormatKind.TIMELINE_DAY_DIVIDER)
+ context.resources.getQuantityString(
+ R.plurals.device_manager_other_sessions_description_inactive,
+ SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
+ SESSION_IS_MARKED_AS_INACTIVE_AFTER_DAYS,
+ formattedTs
+ )
+ } else {
+ val formattedTs = dateFormatter.format(timestamp, DateFormatKind.DEFAULT_DATE_AND_TIME)
+ context.getString(R.string.device_manager_session_last_activity, formattedTs)
+ }
+ val drawable = if (isInactive) {
+ val drawableColor = colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
+ drawableProvider.getDrawable(R.drawable.ic_inactive_sessions, drawableColor)
+ } else {
+ null
+ }
+ views.sessionInfoLastActivityTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
+ } else {
+ views.sessionInfoLastActivityTextView.isGone = true
+ }
views.sessionInfoLastIPAddressTextView.setTextOrHide(deviceInfo.lastSeenIp?.takeIf { isLastSeenDetailsVisible })
}
diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
index 7c133bc229..463d5bb495 100644
--- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt
@@ -24,7 +24,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.isGone
import androidx.core.view.isVisible
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.fragmentViewModel
@@ -42,7 +41,6 @@ import im.vector.app.core.resources.StringProvider
import im.vector.app.databinding.FragmentSessionOverviewBinding
import im.vector.app.features.auth.ReAuthActivity
import im.vector.app.features.crypto.recover.SetupMode
-import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState
import im.vector.app.features.settings.devices.v2.more.SessionLearnMoreBottomSheet
import im.vector.app.features.workers.signout.SignOutUiWorker
@@ -181,11 +179,6 @@ class SessionOverviewFragment :
updateSessionInfo(state)
updateLoading(state.isLoading)
updatePushNotificationToggle(state.deviceId, state.pushers.invoke().orEmpty())
- if (state.deviceInfo is Success) {
- renderSessionInfo(state.isCurrentSessionTrusted, state.deviceInfo.invoke())
- } else {
- hideSessionInfo()
- }
}
private fun updateToolbar(viewState: SessionOverviewViewState) {
@@ -214,7 +207,7 @@ class SessionOverviewFragment :
deviceFullInfo = deviceInfo,
isVerifyButtonVisible = isCurrentSession || viewState.isCurrentSessionTrusted,
isDetailsButtonVisible = false,
- isLearnMoreLinkVisible = true,
+ isLearnMoreLinkVisible = deviceInfo.roomEncryptionTrustLevel != RoomEncryptionTrustLevel.Default,
isLastSeenDetailsVisible = !isCurrentSession,
)
views.sessionOverviewInfo.render(infoViewState, dateFormatter, drawableProvider, colorProvider, stringProvider)
@@ -243,18 +236,6 @@ class SessionOverviewFragment :
}
}
- private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) {
- views.sessionOverviewInfo.isVisible = true
- val viewState = SessionInfoViewState(
- isCurrentSession = isCurrentSession,
- deviceFullInfo = deviceFullInfo,
- isDetailsButtonVisible = false,
- isLearnMoreLinkVisible = true,
- isLastSeenDetailsVisible = true,
- )
- views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider, stringProvider)
- }
-
private fun updateLoading(isLoading: Boolean) {
if (isLoading) {
showLoading(null)
@@ -313,8 +294,4 @@ class SessionOverviewFragment :
)
SessionLearnMoreBottomSheet.show(childFragmentManager, args)
}
-
- private fun hideSessionInfo() {
- views.sessionOverviewInfo.isGone = true
- }
}
diff --git a/vector/src/main/res/drawable/ic_shield_unknown.xml b/vector/src/main/res/drawable/ic_shield_unknown.xml
new file mode 100644
index 0000000000..de56aa475e
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_shield_unknown.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/vector/src/main/res/drawable/ic_shield_unknown_no_border.xml b/vector/src/main/res/drawable/ic_shield_unknown_no_border.xml
new file mode 100644
index 0000000000..bdc35ed891
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_shield_unknown_no_border.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt
index ebdb74b74d..17ad58668a 100644
--- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/GetDeviceFullInfoListUseCaseTest.kt
@@ -144,10 +144,11 @@ class GetDeviceFullInfoListUseCaseTest {
matrixClientInfo = matrixClientInfo3,
)
val expectedResult = listOf(expectedResult3, expectedResult2, expectedResult1)
- every { filterDevicesUseCase.execute(any(), any()) } returns expectedResult
+ every { filterDevicesUseCase.execute(any(), any(), any()) } returns expectedResult
+ val filterType = DeviceManagerFilterType.ALL_SESSIONS
// When
- val result = getDeviceFullInfoListUseCase.execute(DeviceManagerFilterType.ALL_SESSIONS, excludeCurrentDevice = false)
+ val result = getDeviceFullInfoListUseCase.execute(filterType, excludeCurrentDevice = false)
.test(this)
// Then
@@ -166,6 +167,7 @@ class GetDeviceFullInfoListUseCaseTest {
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID_1)
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID_2)
getMatrixClientInfoUseCase.execute(fakeActiveSessionHolder.fakeSession, A_DEVICE_ID_3)
+ filterDevicesUseCase.execute(currentSessionCrossSigningInfo, expectedResult, filterType, emptyList())
}
}
diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt
index 3a418cf2c0..79dff5bc16 100644
--- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt
+++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/filter/FilterDevicesUseCaseTest.kt
@@ -20,6 +20,7 @@ import im.vector.app.core.session.clientinfo.MatrixClientInfoContent
import im.vector.app.features.settings.devices.v2.DeviceFullInfo
import im.vector.app.features.settings.devices.v2.details.extended.DeviceExtendedInfo
import im.vector.app.features.settings.devices.v2.list.DeviceType
+import im.vector.app.features.settings.devices.v2.verification.CurrentSessionCrossSigningInfo
import org.amshove.kluent.shouldBeEqualTo
import org.amshove.kluent.shouldContainAll
import org.junit.Test
@@ -94,32 +95,58 @@ class FilterDevicesUseCaseTest {
@Test
fun `given a device list when filter type is ALL_SESSIONS then returns the same list`() {
- val filteredDeviceList = filterDevicesUseCase.execute(devices, DeviceManagerFilterType.ALL_SESSIONS, emptyList())
+ val currentSessionCrossSigningInfo = givenCurrentSessionVerified(true)
+ val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.ALL_SESSIONS, emptyList())
filteredDeviceList.size shouldBeEqualTo devices.size
}
@Test
- fun `given a device list when filter type is VERIFIED then returns only verified devices`() {
- val filteredDeviceList = filterDevicesUseCase.execute(devices, DeviceManagerFilterType.VERIFIED, emptyList())
+ fun `given a device list and current session is verified when filter type is VERIFIED then returns only verified devices`() {
+ val currentSessionCrossSigningInfo = givenCurrentSessionVerified(true)
+ val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.VERIFIED, emptyList())
filteredDeviceList.size shouldBeEqualTo 2
filteredDeviceList shouldContainAll listOf(activeVerifiedDevice, inactiveVerifiedDevice)
}
@Test
- fun `given a device list when filter type is UNVERIFIED then returns only unverified devices`() {
- val filteredDeviceList = filterDevicesUseCase.execute(devices, DeviceManagerFilterType.UNVERIFIED, emptyList())
+ fun `given a device list and current session is unverified when filter type is VERIFIED then returns empty list of devices`() {
+ val currentSessionCrossSigningInfo = givenCurrentSessionVerified(false)
+ val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.VERIFIED, emptyList())
+
+ filteredDeviceList.size shouldBeEqualTo 0
+ }
+
+ @Test
+ fun `given a device list and current session is verified when filter type is UNVERIFIED then returns only unverified devices`() {
+ val currentSessionCrossSigningInfo = givenCurrentSessionVerified(true)
+ val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.UNVERIFIED, emptyList())
filteredDeviceList.size shouldBeEqualTo 2
filteredDeviceList shouldContainAll listOf(activeUnverifiedDevice, inactiveUnverifiedDevice)
}
+ @Test
+ fun `given a device list and current session is unverified when filter type is UNVERIFIED then returns empty list of devices`() {
+ val currentSessionCrossSigningInfo = givenCurrentSessionVerified(false)
+ val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.UNVERIFIED, emptyList())
+
+ filteredDeviceList.size shouldBeEqualTo 0
+ }
+
@Test
fun `given a device list when filter type is INACTIVE then returns only inactive devices`() {
- val filteredDeviceList = filterDevicesUseCase.execute(devices, DeviceManagerFilterType.INACTIVE, emptyList())
+ val currentSessionCrossSigningInfo = givenCurrentSessionVerified(true)
+ val filteredDeviceList = filterDevicesUseCase.execute(currentSessionCrossSigningInfo, devices, DeviceManagerFilterType.INACTIVE, emptyList())
filteredDeviceList.size shouldBeEqualTo 2
filteredDeviceList shouldContainAll listOf(inactiveVerifiedDevice, inactiveUnverifiedDevice)
}
+
+ private fun givenCurrentSessionVerified(isVerified: Boolean): CurrentSessionCrossSigningInfo = CurrentSessionCrossSigningInfo(
+ isCrossSigningVerified = isVerified,
+ isCrossSigningInitialized = true,
+ deviceId = ""
+ )
}