diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index de97b26fbf..d8c1bb6c49 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -14,50 +14,6 @@ env:
-Porg.gradle.jvmargs=-Xmx4g
-Porg.gradle.parallel=false
jobs:
- # Build Android Tests [Matrix SDK]
- build-android-test-matrix-sdk:
- name: Matrix SDK - Build Android Tests
- runs-on: macos-latest
- # No concurrency required, runs every time on a schedule.
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-java@v2
- with:
- distribution: 'adopt'
- java-version: 11
- - uses: actions/cache@v2
- with:
- path: |
- ~/.gradle/caches
- ~/.gradle/wrapper
- key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
- - name: Build Android Tests for matrix-sdk-android
- run: ./gradlew clean matrix-sdk-android:assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
-
- # Build Android Tests [Matrix APP]
- build-android-test-app:
- name: App - Build Android Tests
- runs-on: macos-latest
- # No concurrency required, runs every time on a schedule.
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-java@v2
- with:
- distribution: 'adopt'
- java-version: 11
- - uses: actions/cache@v2
- with:
- path: |
- ~/.gradle/caches
- ~/.gradle/wrapper
- key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
- - name: Build Android Tests for vector
- run: ./gradlew clean vector:assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
-
# Run Android Tests
integration-tests:
name: Matrix SDK - Running Integration Tests
@@ -367,9 +323,6 @@ jobs:
needs:
- integration-tests
- ui-tests
-# - unit-tests
- - build-android-test-matrix-sdk
- - build-android-test-app
- sonarqube
if: always() && github.event_name != 'workflow_dispatch'
# No concurrency required, runs every time on a schedule.
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d739afcd30..587bf14488 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -12,6 +12,30 @@ env:
-Porg.gradle.parallel=false
jobs:
+ # Build Android Tests
+ build-android-tests:
+ name: Build Android Tests
+ runs-on: ubuntu-latest
+ concurrency:
+ group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('build-android-tests-{0}', github.ref) }}
+ cancel-in-progress: true
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-java@v2
+ with:
+ distribution: 'adopt'
+ java-version: 11
+ - uses: actions/cache@v2
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+ restore-keys: |
+ ${{ runner.os }}-gradle-
+ - name: Build Android Tests
+ run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES --stacktrace
+
unit-tests:
name: Run Unit Tests
runs-on: ubuntu-latest
@@ -41,3 +65,20 @@ jobs:
( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository )
with:
files: ./**/build/test-results/**/*.xml
+
+# Notify the channel about runs against develop or main that have failures, as PRs should have caught these first.
+ notify:
+ runs-on: ubuntu-latest
+ needs:
+ - unit-tests
+ - build-android-tests
+ if: ${{ (github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' ) && failure() }}
+ steps:
+ - uses: michaelkaye/matrix-hookshot-action@v0.3.0
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ matrix_access_token: ${{ secrets.ELEMENT_ANDROID_NOTIFICATION_ACCESS_TOKEN }}
+ matrix_room_id: ${{ secrets.ELEMENT_ANDROID_INTERNAL_ROOM_ID }}
+ text_template: "Build is broken for ${{ github.ref }}: {{#each job_statuses }}{{#with this }}{{#if completed }}{{name}} {{conclusion}} at {{completed_at}}, {{/if}}{{/with}}{{/each}}"
+ html_template: "Build is broken for ${{ github.ref }}: {{#each job_statuses }}{{#with this }}{{#if completed }}
{{icon conclusion }} {{name}} {{conclusion}} at {{completed_at}} [details]{{/if}}{{/with}}{{/each}}"
+
diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml
index ed572b573f..85290e72df 100644
--- a/.idea/dictionaries/bmarty.xml
+++ b/.idea/dictionaries/bmarty.xml
@@ -11,6 +11,7 @@
emoji
emojis
fdroid
+ ganfra
gplay
hmac
homeserver
@@ -18,6 +19,7 @@
ktlint
linkified
linkify
+ manu
megolm
msisdn
msisdns
diff --git a/changelog.d/4860.bugfix b/changelog.d/4860.bugfix
new file mode 100644
index 0000000000..32049face4
--- /dev/null
+++ b/changelog.d/4860.bugfix
@@ -0,0 +1 @@
+Add colors for shield vector drawable
\ No newline at end of file
diff --git a/changelog.d/5443.misc b/changelog.d/5443.misc
new file mode 100644
index 0000000000..f9fd715403
--- /dev/null
+++ b/changelog.d/5443.misc
@@ -0,0 +1 @@
+Adds stable room hierarchy endpoint with a fallback to the unstable one
diff --git a/library/ui-styles/src/main/res/values/colors.xml b/library/ui-styles/src/main/res/values/colors.xml
index 1b214cfc59..75b03a7d2e 100644
--- a/library/ui-styles/src/main/res/values/colors.xml
+++ b/library/ui-styles/src/main/res/values/colors.xml
@@ -126,4 +126,10 @@
@color/palette_prune
@color/palette_prune
+
+
+ #0DBD8B
+ #17191C
+ #FF4B55
+
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index 4a5b45c4f9..2b2c38e22a 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -166,7 +166,7 @@ dependencies {
implementation libs.apache.commonsImaging
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.44'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.45'
testImplementation libs.tests.junit
testImplementation 'org.robolectric:robolectric:4.7.3'
@@ -174,7 +174,7 @@ dependencies {
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
testImplementation libs.mockk.mockk
testImplementation libs.tests.kluent
- implementation libs.jetbrains.coroutinesAndroid
+ testImplementation libs.jetbrains.coroutinesTest
// Plant Timber tree for test
testImplementation 'net.lachlanmckee:timber-junit-rule:1.0.1'
// Transitively required for mocking realm as monarchy doesn't expose Rx
diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt
index 767334dfbd..41ec69cdc5 100644
--- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt
+++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt
@@ -41,6 +41,7 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.SessionTestParams
+import org.matrix.android.sdk.common.TestConstants
import org.matrix.android.sdk.common.TestMatrixCallback
import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
@@ -99,7 +100,6 @@ class E2eeSanityTests : InstrumentedTest {
ensureMembersHaveJoined(aliceSession, otherAccounts, e2eRoomID)
Log.v("#E2E TEST", "All users have joined the room")
-
Log.v("#E2E TEST", "Alice is sending the message")
val text = "This is my message"
@@ -172,7 +172,7 @@ class E2eeSanityTests : InstrumentedTest {
}
timelineEvent != null &&
timelineEvent.root.getClearType() == EventType.MESSAGE &&
- secondMessage.equals(timelineEvent.root.getClearContent().toModel()?.body)
+ secondMessage == timelineEvent.root.getClearContent().toModel()?.body
}
}
}
@@ -186,11 +186,11 @@ class E2eeSanityTests : InstrumentedTest {
}
/**
- * Quick test for basic keybackup
+ * Quick test for basic key backup
* 1. Create e2e between Alice and Bob
* 2. Alice sends 3 messages, using 3 different sessions
* 3. Ensure bob can decrypt
- * 4. Create backup for bob and uplaod keys
+ * 4. Create backup for bob and upload keys
*
* 5. Sign out alice and bob to ensure no gossiping will happen
*
@@ -206,14 +206,14 @@ class E2eeSanityTests : InstrumentedTest {
val bobSession = cryptoTestData.secondSession!!
val e2eRoomID = cryptoTestData.roomId
- Log.v("#E2E TEST", "Create and start keybackup for bob ...")
- val keysBackupService = bobSession.cryptoService().keysBackupService()
+ Log.v("#E2E TEST", "Create and start key backup for bob ...")
+ val bobKeysBackupService = bobSession.cryptoService().keysBackupService()
val keyBackupPassword = "FooBarBaz"
val megolmBackupCreationInfo = testHelper.doSync {
- keysBackupService.prepareKeysBackupVersion(keyBackupPassword, null, it)
+ bobKeysBackupService.prepareKeysBackupVersion(keyBackupPassword, null, it)
}
val version = testHelper.doSync {
- keysBackupService.createKeysBackupVersion(megolmBackupCreationInfo, it)
+ bobKeysBackupService.createKeysBackupVersion(megolmBackupCreationInfo, it)
}
Log.v("#E2E TEST", "... Key backup started and enabled for bob")
// Bob session should now have
@@ -249,12 +249,12 @@ class E2eeSanityTests : InstrumentedTest {
Log.v("#E2E TEST", "Force key backup for Bob...")
testHelper.waitWithLatch { latch ->
- keysBackupService.backupAllGroupSessions(
+ bobKeysBackupService.backupAllGroupSessions(
null,
TestMatrixCallback(latch, true)
)
}
- Log.v("#E2E TEST", "... Keybackup done for Bob")
+ Log.v("#E2E TEST", "... Key backup done for Bob")
// Now lets logout both alice and bob to ensure that we won't have any gossiping
@@ -397,7 +397,7 @@ class E2eeSanityTests : InstrumentedTest {
}
/**
- * Test that if a better key is forwared (lower index, it is then used)
+ * Test that if a better key is forwarded (lower index, it is then used)
*/
@Test
fun testForwardBetterKey() {
@@ -525,15 +525,16 @@ class E2eeSanityTests : InstrumentedTest {
private fun sendMessageInRoom(aliceRoomPOV: Room, text: String): String? {
aliceRoomPOV.sendTextMessage(text)
var sentEventId: String? = null
- testHelper.waitWithLatch(4 * 60_000) {
+ testHelper.waitWithLatch(4 * TestConstants.timeOutMillis) { latch ->
val timeline = aliceRoomPOV.createTimeline(null, TimelineSettings(60))
timeline.start()
- testHelper.retryPeriodicallyWithLatch(it) {
+ testHelper.retryPeriodicallyWithLatch(latch) {
val decryptedMsg = timeline.getSnapshot()
.filter { it.root.getClearType() == EventType.MESSAGE }
- .also {
- Log.v("#E2E TEST", "Timeline snapshot is ${it.map { "${it.root.type}|${it.root.sendState}" }.joinToString(",", "[", "]")}")
+ .also { list ->
+ val message = list.joinToString(",", "[", "]") { "${it.root.type}|${it.root.sendState}" }
+ Log.v("#E2E TEST", "Timeline snapshot is $message")
}
.filter { it.root.sendState == SendState.SYNCED }
.firstOrNull { it.root.getClearContent().toModel()?.body?.startsWith(text) == true }
@@ -547,8 +548,8 @@ class E2eeSanityTests : InstrumentedTest {
}
private fun ensureMembersHaveJoined(aliceSession: Session, otherAccounts: List, e2eRoomID: String) {
- testHelper.waitWithLatch {
- testHelper.retryPeriodicallyWithLatch(it) {
+ testHelper.waitWithLatch { latch ->
+ testHelper.retryPeriodicallyWithLatch(latch) {
otherAccounts.map {
aliceSession.getRoomMember(it.myUserId, e2eRoomID)?.membership
}.all {
@@ -559,8 +560,8 @@ class E2eeSanityTests : InstrumentedTest {
}
private fun waitForAndAcceptInviteInRoom(otherSession: Session, e2eRoomID: String) {
- testHelper.waitWithLatch {
- testHelper.retryPeriodicallyWithLatch(it) {
+ testHelper.waitWithLatch { latch ->
+ testHelper.retryPeriodicallyWithLatch(latch) {
val roomSummary = otherSession.getRoomSummary(e2eRoomID)
(roomSummary != null && roomSummary.membership == Membership.INVITE).also {
if (it) {
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
index 1ab1042129..5aec7db66c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConstants.kt
@@ -21,6 +21,7 @@ internal object NetworkConstants {
private const val URI_API_PREFIX_PATH = "_matrix/client"
const val URI_API_PREFIX_PATH_ = "$URI_API_PREFIX_PATH/"
const val URI_API_PREFIX_PATH_R0 = "$URI_API_PREFIX_PATH/r0/"
+ const val URI_API_PREFIX_PATH_V1 = "$URI_API_PREFIX_PATH/v1/"
const val URI_API_PREFIX_PATH_UNSTABLE = "$URI_API_PREFIX_PATH/unstable/"
// Media
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt
index c18055e089..e764ab551a 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt
@@ -113,71 +113,108 @@ internal class DefaultSpaceService @Inject constructor(
return peekSpaceTask.execute(PeekSpaceTask.Params(spaceId))
}
- override suspend fun querySpaceChildren(spaceId: String,
- suggestedOnly: Boolean?,
- limit: Int?,
- from: String?,
- knownStateList: List?): SpaceHierarchyData {
- return resolveSpaceInfoTask.execute(
- ResolveSpaceInfoTask.Params(
- spaceId = spaceId, limit = limit, maxDepth = 1, from = from, suggestedOnly = suggestedOnly
- )
- ).let { response ->
- val spaceDesc = response.rooms?.firstOrNull { it.roomId == spaceId }
- val root = RoomSummary(
- roomId = spaceDesc?.roomId ?: spaceId,
- roomType = spaceDesc?.roomType,
- name = spaceDesc?.name ?: "",
- displayName = spaceDesc?.name ?: "",
- topic = spaceDesc?.topic ?: "",
- joinedMembersCount = spaceDesc?.numJoinedMembers,
- avatarUrl = spaceDesc?.avatarUrl ?: "",
- encryptionEventTs = null,
- typingUsers = emptyList(),
- isEncrypted = false,
- flattenParentIds = emptyList(),
- canonicalAlias = spaceDesc?.canonicalAlias,
- joinRules = RoomJoinRules.PUBLIC.takeIf { spaceDesc?.worldReadable == true }
- )
- val children = response.rooms
- ?.filter { it.roomId != spaceId }
- ?.flatMap { childSummary ->
- (spaceDesc?.childrenState ?: knownStateList)
- ?.filter { it.stateKey == childSummary.roomId && it.type == EventType.STATE_SPACE_CHILD }
- ?.mapNotNull { childStateEv ->
- // create a child entry for everytime this room is the child of a space
- // beware that a room could appear then twice in this list
- childStateEv.content.toModel()?.let { childStateEvContent ->
- SpaceChildInfo(
- childRoomId = childSummary.roomId,
- isKnown = true,
- roomType = childSummary.roomType,
- name = childSummary.name,
- topic = childSummary.topic,
- avatarUrl = childSummary.avatarUrl,
- order = childStateEvContent.order,
-// autoJoin = childStateEvContent.autoJoin ?: false,
- viaServers = childStateEvContent.via.orEmpty(),
- activeMemberCount = childSummary.numJoinedMembers,
- parentRoomId = childStateEv.roomId,
- suggested = childStateEvContent.suggested,
- canonicalAlias = childSummary.canonicalAlias,
- aliases = childSummary.aliases,
- worldReadable = childSummary.worldReadable
- )
- }
- }.orEmpty()
- }
- .orEmpty()
- SpaceHierarchyData(
- rootSummary = root,
- children = children,
- childrenState = spaceDesc?.childrenState.orEmpty(),
- nextToken = response.nextBatch
- )
- }
+ override suspend fun querySpaceChildren(
+ spaceId: String,
+ suggestedOnly: Boolean?,
+ limit: Int?,
+ from: String?,
+ knownStateList: List?
+ ): SpaceHierarchyData {
+ val spacesResponse = getSpacesResponse(spaceId, suggestedOnly, limit, from)
+ val spaceRootResponse = spacesResponse.getRoot(spaceId)
+ val spaceRoot = spaceRootResponse?.toRoomSummary() ?: createBlankRoomSummary(spaceId)
+ val spaceChildren = spacesResponse.rooms.mapSpaceChildren(spaceId, spaceRootResponse, knownStateList)
+
+ return SpaceHierarchyData(
+ rootSummary = spaceRoot,
+ children = spaceChildren,
+ childrenState = spaceRootResponse?.childrenState.orEmpty(),
+ nextToken = spacesResponse.nextBatch
+ )
}
+ private suspend fun getSpacesResponse(spaceId: String, suggestedOnly: Boolean?, limit: Int?, from: String?) =
+ resolveSpaceInfoTask.execute(
+ ResolveSpaceInfoTask.Params(spaceId = spaceId, limit = limit, maxDepth = 1, from = from, suggestedOnly = suggestedOnly)
+ )
+
+ private fun SpacesResponse.getRoot(spaceId: String) = rooms?.firstOrNull { it.roomId == spaceId }
+
+ private fun SpaceChildSummaryResponse.toRoomSummary() = RoomSummary(
+ roomId = roomId,
+ roomType = roomType,
+ name = name ?: "",
+ displayName = name ?: "",
+ topic = topic ?: "",
+ joinedMembersCount = numJoinedMembers,
+ avatarUrl = avatarUrl ?: "",
+ encryptionEventTs = null,
+ typingUsers = emptyList(),
+ isEncrypted = false,
+ flattenParentIds = emptyList(),
+ canonicalAlias = canonicalAlias,
+ joinRules = RoomJoinRules.PUBLIC.takeIf { isWorldReadable }
+ )
+
+ private fun createBlankRoomSummary(spaceId: String) = RoomSummary(
+ roomId = spaceId,
+ joinedMembersCount = null,
+ encryptionEventTs = null,
+ typingUsers = emptyList(),
+ isEncrypted = false,
+ flattenParentIds = emptyList(),
+ canonicalAlias = null,
+ joinRules = null
+ )
+
+ private fun List?.mapSpaceChildren(
+ spaceId: String,
+ spaceRootResponse: SpaceChildSummaryResponse?,
+ knownStateList: List?,
+ ) = this?.filterIdIsNot(spaceId)
+ ?.toSpaceChildInfoList(spaceId, spaceRootResponse, knownStateList)
+ .orEmpty()
+
+ private fun List.filterIdIsNot(spaceId: String) = filter { it.roomId != spaceId }
+
+ private fun List.toSpaceChildInfoList(
+ spaceId: String,
+ rootRoomResponse: SpaceChildSummaryResponse?,
+ knownStateList: List?,
+ ) = flatMap { spaceChildSummary ->
+ (rootRoomResponse?.childrenState ?: knownStateList)
+ ?.filter { it.isChildOf(spaceChildSummary) }
+ ?.mapNotNull { childStateEvent -> childStateEvent.toSpaceChildInfo(spaceId, spaceChildSummary) }
+ .orEmpty()
+ }
+
+ private fun Event.isChildOf(space: SpaceChildSummaryResponse) = stateKey == space.roomId && type == EventType.STATE_SPACE_CHILD
+
+ private fun Event.toSpaceChildInfo(spaceId: String, summary: SpaceChildSummaryResponse) = content.toModel()?.let { content ->
+ createSpaceChildInfo(spaceId, summary, content)
+ }
+
+ private fun createSpaceChildInfo(
+ spaceId: String,
+ summary: SpaceChildSummaryResponse,
+ content: SpaceChildContent
+ ) = SpaceChildInfo(
+ childRoomId = summary.roomId,
+ isKnown = true,
+ roomType = summary.roomType,
+ name = summary.name,
+ topic = summary.topic,
+ avatarUrl = summary.avatarUrl,
+ order = content.order,
+ viaServers = content.via.orEmpty(),
+ activeMemberCount = summary.numJoinedMembers,
+ parentRoomId = spaceId,
+ suggested = content.suggested,
+ canonicalAlias = summary.canonicalAlias,
+ aliases = summary.aliases,
+ worldReadable = summary.isWorldReadable
+ )
+
override suspend fun joinSpace(spaceIdOrAlias: String,
reason: String?,
viaServers: List): JoinSpaceResult {
@@ -192,10 +229,6 @@ internal class DefaultSpaceService @Inject constructor(
leaveRoomTask.execute(LeaveRoomTask.Params(spaceId, reason))
}
-// override fun getSpaceParentsOfRoom(roomId: String): List {
-// return spaceSummaryDataSource.getParentsOfRoom(roomId)
-// }
-
override suspend fun setSpaceParent(childRoomId: String, parentSpaceId: String, canonical: Boolean, viaServers: List) {
// Should we perform some validation here?,
// and if client want to bypass, it could use sendStateEvent directly?
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/ResolveSpaceInfoTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/ResolveSpaceInfoTask.kt
index 2a396d6ee7..d59ca06c2c 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/ResolveSpaceInfoTask.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/ResolveSpaceInfoTask.kt
@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.space
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
+import retrofit2.HttpException
import javax.inject.Inject
internal interface ResolveSpaceInfoTask : Task {
@@ -28,7 +29,6 @@ internal interface ResolveSpaceInfoTask : Task(500, "".toResponseBody()))
+ }
+}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeSpaceApi.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeSpaceApi.kt
new file mode 100644
index 0000000000..d4fc986791
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeSpaceApi.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.test.fakes
+
+import io.mockk.coEvery
+import io.mockk.mockk
+import org.matrix.android.sdk.internal.session.space.SpaceApi
+import org.matrix.android.sdk.internal.session.space.SpacesResponse
+import org.matrix.android.sdk.test.fixtures.ResolveSpaceInfoTaskParamsFixture
+
+internal class FakeSpaceApi {
+
+ val instance: SpaceApi = mockk()
+ val params = ResolveSpaceInfoTaskParamsFixture.aResolveSpaceInfoTaskParams()
+
+ fun givenStableEndpointReturns(response: SpacesResponse) {
+ coEvery { instance.getSpaceHierarchy(params.spaceId, params.suggestedOnly, params.limit, params.maxDepth, params.from) } returns response
+ }
+
+ fun givenStableEndpointThrows(throwable: Throwable) {
+ coEvery { instance.getSpaceHierarchy(params.spaceId, params.suggestedOnly, params.limit, params.maxDepth, params.from) } throws throwable
+ }
+
+ fun givenUnstableEndpointReturns(response: SpacesResponse) {
+ coEvery { instance.getSpaceHierarchyUnstable(params.spaceId, params.suggestedOnly, params.limit, params.maxDepth, params.from) } returns response
+ }
+}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/ResolveSpaceInfoTaskParamsFixture.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/ResolveSpaceInfoTaskParamsFixture.kt
new file mode 100644
index 0000000000..28f8c3637d
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/ResolveSpaceInfoTaskParamsFixture.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.test.fixtures
+
+import org.matrix.android.sdk.internal.session.space.ResolveSpaceInfoTask
+
+internal object ResolveSpaceInfoTaskParamsFixture {
+ fun aResolveSpaceInfoTaskParams(
+ spaceId: String = "",
+ limit: Int? = null,
+ maxDepth: Int? = null,
+ from: String? = null,
+ suggestedOnly: Boolean? = null,
+ ) = ResolveSpaceInfoTask.Params(
+ spaceId,
+ limit,
+ maxDepth,
+ from,
+ suggestedOnly,
+ )
+}
diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/SpacesResponseFixture.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/SpacesResponseFixture.kt
new file mode 100644
index 0000000000..0a08331114
--- /dev/null
+++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/SpacesResponseFixture.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2021 The Matrix.org Foundation C.I.C.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.matrix.android.sdk.test.fixtures
+
+import org.matrix.android.sdk.internal.session.space.SpaceChildSummaryResponse
+import org.matrix.android.sdk.internal.session.space.SpacesResponse
+
+internal object SpacesResponseFixture {
+ fun aSpacesResponse(
+ nextBatch: String? = null,
+ rooms: List? = null,
+ ) = SpacesResponse(
+ nextBatch,
+ rooms,
+ )
+}
diff --git a/vector/build.gradle b/vector/build.gradle
index 438e8f2003..2b37c12323 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -367,7 +367,7 @@ dependencies {
implementation 'com.facebook.stetho:stetho:1.6.0'
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.44'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.45'
// FlowBinding
implementation libs.github.flowBinding
diff --git a/vector/src/main/res/drawable/ic_shield_black.xml b/vector/src/main/res/drawable/ic_shield_black.xml
index 8ab70d981b..ddde3442b7 100644
--- a/vector/src/main/res/drawable/ic_shield_black.xml
+++ b/vector/src/main/res/drawable/ic_shield_black.xml
@@ -6,6 +6,6 @@
diff --git a/vector/src/main/res/drawable/ic_shield_black_no_border.xml b/vector/src/main/res/drawable/ic_shield_black_no_border.xml
index 1e322c77c3..f9fa5de9f6 100644
--- a/vector/src/main/res/drawable/ic_shield_black_no_border.xml
+++ b/vector/src/main/res/drawable/ic_shield_black_no_border.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/vector/src/main/res/drawable/ic_shield_custom.xml b/vector/src/main/res/drawable/ic_shield_custom.xml
index ca58f028d9..aa6cbabad3 100644
--- a/vector/src/main/res/drawable/ic_shield_custom.xml
+++ b/vector/src/main/res/drawable/ic_shield_custom.xml
@@ -4,7 +4,7 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/vector/src/main/res/drawable/ic_shield_trusted.xml b/vector/src/main/res/drawable/ic_shield_trusted.xml
index cac0cfcaf6..c122446a3c 100644
--- a/vector/src/main/res/drawable/ic_shield_trusted.xml
+++ b/vector/src/main/res/drawable/ic_shield_trusted.xml
@@ -6,7 +6,7 @@
+ android:fillColor="@color/shield_color_trust"/>
diff --git a/vector/src/main/res/drawable/ic_shield_warning.xml b/vector/src/main/res/drawable/ic_shield_warning.xml
index ace7d7dbae..237f2aa5fd 100644
--- a/vector/src/main/res/drawable/ic_shield_warning.xml
+++ b/vector/src/main/res/drawable/ic_shield_warning.xml
@@ -6,7 +6,7 @@
+ android:fillColor="@color/shield_color_warning"/>