diff --git a/changelog.d/7327.wip b/changelog.d/7327.wip
new file mode 100644
index 00000000000..8f0191f948f
--- /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 77f16efff80..20d00563dce 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 85646adb425..9d8645a7076 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 c59e1a30281..048bb885bcf 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 19908596682..6327daec86d 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 42e4cebe4cf..6adb33d5abe 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 47ea96c09d2..bd68cbc0ceb 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 hideSecurityRecommendations() {
- views.deviceListHeaderSectionSecurityRecommendations.isVisible = false
+ private fun hideUnverifiedSessionsRecommendation() {
views.deviceListUnverifiedSessionsRecommendation.isVisible = false
+ }
+
+ private fun hideInactiveSessionsRecommendation() {
views.deviceListInactiveSessionsRecommendation.isVisible = false
+ }
+
+ private fun hideSecurityRecommendations() {
+ views.deviceListHeaderSectionSecurityRecommendations.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 a23a7a71088..8f23fd06cc2 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 b0ba8baa1af..59e7e1888e3 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 6f6c5b24e20..3d9c3a8f372 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 7c133bc2296..463d5bb4952 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 00000000000..de56aa475e7
--- /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 00000000000..bdc35ed8916
--- /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 ebdb74b74d3..17ad58668ae 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 3a418cf2c07..79dff5bc169 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 = ""
+ )
}