Merge remote-tracking branch 'origin/develop' into HEAD

This commit is contained in:
bxdxnn
2026-08-27 18:40:10 +00:00
596 changed files with 5364 additions and 2447 deletions
@@ -49,12 +49,12 @@ class KonsistArchitectureTest {
}
@Test
fun `Events MUST be sealed interface`() {
fun `Event MUST be sealed interface`() {
Konsist.scopeFromProject()
.classes()
.withSealedModifier()
.withNameEndingWith("Events")
.assertEmpty(additionalMessage = "Events class MUST be sealed interface")
.withNameEndingWith("Event")
.assertEmpty(additionalMessage = "Event class MUST be sealed interface")
}
@Test
@@ -103,6 +103,7 @@ class KonsistClassNameTest {
"FakeImageLoader",
"FakeKeyStore",
"FakeListenableFuture",
"FakeMediaStoreContentProvider",
"FakeParentNode",
)
.assertTrue {
@@ -67,11 +67,14 @@ class KonsistImmutableTest {
}
@Test
fun `Immutable annotation is not used on sealed interface for Presenter Events`() {
fun `Immutable annotation is not used on sealed interface for Presenter Event`() {
Konsist
.scopeFromProduction()
.interfaces()
.withNameEndingWith("Events")
.withoutName(
"LatestEvent",
)
.withNameEndingWith("Event")
.withAnnotationOf(Immutable::class)
.assertEmpty()
}
@@ -134,6 +134,7 @@ class KonsistPreviewTest {
"SecureBackupSetupViewChangePreview",
"SelectedUserCannotRemovePreview",
"SpaceMembersViewNoHeroesPreview",
"SyncStateViewServerUnreachablePreview",
"TextComposerAddCaptionPreview",
"TextComposerCaptionPreview",
"TextComposerEditCaptionPreview",
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.tests.testutils.fake
import android.content.ContentProvider
import android.content.ContentValues
import android.content.pm.ProviderInfo
import android.database.Cursor
import android.net.Uri
import android.os.ParcelFileDescriptor
import android.provider.MediaStore
import androidx.test.core.app.ApplicationProvider
import org.robolectric.shadows.ShadowContentResolver
import java.io.File
/**
* Stands in for the MediaStore provider: it records the display names an insert is attempted with,
* writes what is copied into it to a temporary directory, and can make any display name collide the
* way MediaStore does once a directory already holds 32 files with the same name.
*/
class FakeMediaStoreContentProvider : ContentProvider() {
private val directory: File = File.createTempFile("fake-media-store", null).apply {
delete()
mkdir()
}
val insertedDisplayNames = mutableListOf<String>()
var conflictingDisplayNames: Set<String> = emptySet()
/** When true, an insert reports that it created nothing, the way a rejected insert does. */
var returnsNoUriOnInsert: Boolean = false
fun savedFileNames(): List<String> = directory.list().orEmpty().toList()
fun savedContent(displayName: String): String = File(directory, displayName).readText()
override fun onCreate() = true
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val displayName = values?.getAsString(MediaStore.MediaColumns.DISPLAY_NAME).orEmpty()
insertedDisplayNames += displayName
check(displayName !in conflictingDisplayNames) { "Failed to build unique file" }
return if (returnsNoUriOnInsert) null else uri.buildUpon().appendPath(displayName).build()
}
override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor {
val file = File(directory, uri.lastPathSegment.orEmpty())
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_CREATE or ParcelFileDescriptor.MODE_READ_WRITE)
}
override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? = null
override fun getType(uri: Uri): String? = null
override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?) = 0
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?) = 0
}
fun registerFakeMediaStoreContentProvider(): FakeMediaStoreContentProvider {
return FakeMediaStoreContentProvider().apply {
attachInfo(
ApplicationProvider.getApplicationContext(),
ProviderInfo().apply { authority = MediaStore.AUTHORITY }
)
ShadowContentResolver.registerProviderInternal(MediaStore.AUTHORITY, this)
}
}

Some files were not shown because too many files have changed in this diff Show More