diff --git a/app/build.gradle b/app/build.gradle index bc3ffe10d..443a910c9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -336,15 +336,15 @@ dependencies { testImplementation 'org.robolectric:robolectric:4.4' testImplementation 'org.robolectric:shadows-multidex:4.4' - implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.1' - implementation 'androidx.compose.ui:ui:1.4.3' - implementation 'androidx.compose.ui:ui-tooling:1.4.3' - implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.31.5-beta" - implementation "com.google.accompanist:accompanist-pager-indicators:0.31.5-beta" - implementation "androidx.compose.runtime:runtime-livedata:1.4.3" + implementation 'com.github.bumptech.glide:compose:1.0.0-alpha.5' + implementation 'androidx.compose.ui:ui:1.5.1' + implementation 'androidx.compose.ui:ui-tooling:1.5.1' + implementation "com.google.accompanist:accompanist-themeadapter-appcompat:0.33.1-alpha" + implementation "com.google.accompanist:accompanist-pager-indicators:0.33.1-alpha" + implementation "androidx.compose.runtime:runtime-livedata:1.5.1" - implementation 'androidx.compose.foundation:foundation-layout:1.5.0-alpha02' - implementation 'androidx.compose.material:material:1.5.0-alpha02' + implementation 'androidx.compose.foundation:foundation-layout:1.6.0-alpha06' + implementation 'androidx.compose.material:material:1.6.0-alpha06' } static def getLastCommitTimestamp() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt index 330534e23..d76e6f2b3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/components/AlbumThumbnailView.kt @@ -7,7 +7,6 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.MotionEvent import android.view.ViewGroup -import android.widget.FrameLayout import android.widget.RelativeLayout import android.widget.TextView import androidx.core.view.children @@ -41,7 +40,7 @@ class AlbumThumbnailView : RelativeLayout { private var slides: List = listOf() private var slideSize: Int = 0 - override fun dispatchDraw(canvas: Canvas?) { + override fun dispatchDraw(canvas: Canvas) { super.dispatchDraw(canvas) cornerMask.mask(canvas) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt index f2d17af56..fd49e501b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/DownloadDialog.kt @@ -36,7 +36,7 @@ class AutoDownloadDialog(private val threadRecipient: Recipient, val displayName = when { threadRecipient.isOpenGroupRecipient -> storage.getOpenGroup(threadId)?.name ?: "UNKNOWN" threadRecipient.isLegacyClosedGroupRecipient -> storage.getGroup(threadRecipient.address.toGroupString())?.title ?: "UNKNOWN" - // TODO: threadRecipient.isClosedGroupRecipient -> storage.getLibSessionGroup(threadRecipient.address.serialize())?.groupName ?: "UNKNOWN" or something + threadRecipient.isClosedGroupRecipient -> threadRecipient.name ?: "UNKNOWN" else -> storage.getContactWithSessionID(threadRecipient.address.serialize())?.displayName(Contact.ContactContext.REGULAR) ?: "UNKNOWN" } title(resources.getString(R.string.dialog_auto_download_title)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailProgressBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailProgressBar.kt index 3abfd235c..8188c4f7d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailProgressBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/ThumbnailProgressBar.kt @@ -30,8 +30,7 @@ class ThumbnailProgressBar: View { private val objectRect = Rect() private val drawingRect = Rect() - override fun dispatchDraw(canvas: Canvas?) { - if (canvas == null) return + override fun dispatchDraw(canvas: Canvas) { getDrawingRect(objectRect) drawingRect.set(objectRect) diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupViewModel.kt index e74e75d10..c13f4b6a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/CreateGroupViewModel.kt @@ -54,10 +54,16 @@ class CreateGroupViewModel @Inject constructor( ) return null } - // TODO: add future validation for empty group ? we'll add ourselves anyway ig + + if (members.isEmpty()) { + _viewState.postValue( + CreateGroupFragment.ViewState(false, R.string.error) + ) + return null + } // make a group - val newGroup = storage.createNewGroup(name, description, members) // TODO: handle optional + val newGroup = storage.createNewGroup(name, description, members) if (!newGroup.isPresent) { _viewState.postValue(CreateGroupFragment.ViewState(isLoading = false, null)) } diff --git a/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt b/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt new file mode 100644 index 000000000..f28d5f9ab --- /dev/null +++ b/app/src/test/java/org/thoughtcrime/securesms/MainCoroutineRule.kt @@ -0,0 +1,25 @@ +package org.thoughtcrime.securesms + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +@ExperimentalCoroutinesApi +class MainCoroutineRule(private val dispatcher: TestDispatcher = StandardTestDispatcher()) : + TestWatcher() { + + override fun starting(description: Description) { + super.starting(description) + Dispatchers.setMain(dispatcher) + } + + override fun finished(description: Description) { + super.finished(description) + Dispatchers.resetMain() + } +} \ No newline at end of file diff --git a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationSettingsViewModelTest.kt b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationSettingsViewModelTest.kt index 2f18136d5..5641fb535 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationSettingsViewModelTest.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/conversation/v2/ConversationSettingsViewModelTest.kt @@ -44,9 +44,9 @@ class ConversationSettingsViewModelTest: BaseViewModelTest() { @Test fun `it should report correct pin status`() { - whenever(mockedStorage.isThreadPinned(TEST_THREAD_ID)).thenReturn(true) + whenever(mockedStorage.isPinned(TEST_THREAD_ID)).thenReturn(true) val pinStatus = viewModel.isPinned() - verify(mockedStorage).isThreadPinned(TEST_THREAD_ID) + verify(mockedStorage).isPinned(TEST_THREAD_ID) assertTrue(pinStatus) } diff --git a/app/src/test/java/org/thoughtcrime/securesms/groups/ClosedGroupViewTests.kt b/app/src/test/java/org/thoughtcrime/securesms/groups/ClosedGroupViewTests.kt new file mode 100644 index 000000000..29ed3e3f6 --- /dev/null +++ b/app/src/test/java/org/thoughtcrime/securesms/groups/ClosedGroupViewTests.kt @@ -0,0 +1,55 @@ +package org.thoughtcrime.securesms.groups + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import junit.framework.TestCase.assertNotNull +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.session.libsession.utilities.TextSecurePreferences +import org.thoughtcrime.securesms.MainCoroutineRule +import org.thoughtcrime.securesms.database.Storage + +@OptIn(ExperimentalCoroutinesApi::class) +@RunWith(MockitoJUnitRunner::class) +class ClosedGroupViewTests { + + @ExperimentalCoroutinesApi + @get:Rule + var mainCoroutineRule = MainCoroutineRule() + + @get:Rule + var taskRule = InstantTaskExecutorRule() + + @Mock lateinit var textSecurePreferences: TextSecurePreferences + @Mock lateinit var storage: Storage + + @Test + fun `Should error on empty name`() { + val viewModel = createViewModel() + val state = CreateGroupState( + groupName = "", + groupDescription = "", + members = emptySet() + ) + viewModel.tryCreateGroup(state) + assertNotNull(viewModel.viewState.value?.error) + } + + @Test + fun `Should error on empty members`() { + val viewModel = createViewModel() + val state = CreateGroupState( + groupName = "group", + groupDescription = "anything", + members = emptySet() + ) + viewModel.tryCreateGroup(state) + assertNotNull(viewModel.viewState.value?.error) + } + + private fun createViewModel() = CreateGroupViewModel(textSecurePreferences, storage) + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2cb531a7c..46c7d0664 100644 --- a/build.gradle +++ b/build.gradle @@ -12,11 +12,9 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:$gradlePluginVersion" - classpath files('libs/gradle-witness.jar') classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" classpath "com.google.gms:google-services:$googleServicesVersion" - classpath files('libs/gradle-witness.jar') classpath "com.squareup:javapoet:1.13.0" classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerVersion" if (project.hasProperty('huawei')) classpath 'com.huawei.agconnect:agcp:1.9.1.300' @@ -76,7 +74,7 @@ allprojects { project.ext { androidMinimumSdkVersion = 23 - androidTargetSdkVersion = 33 - androidCompileSdkVersion = 33 + androidTargetSdkVersion = 34 + androidCompileSdkVersion = 34 } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt index 451081fd1..d3c956ce9 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt @@ -100,7 +100,8 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) handleFailure(Error.NoSender, null) return } - if (!threadRecipient.isGroupRecipient && (contact?.isTrusted == true || storage.getUserPublicKey() != sender)) { + + if (!storage.shouldAutoDownloadAttachments(threadRecipient)) { // if we aren't receiving a group message, a message from ourselves (self-send) and the contact sending is not trusted: // do not continue, but do not fail return