Unverified Commit 20a5d370 authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge branch 'beta' into improvement/honor-layout-when-no-lastmessage

parents 6864b431 5382b725
......@@ -58,6 +58,9 @@ jobs:
- run:
name: Run Unit test
command: ./gradlew test
- run:
name: Compile Instrumentation test
command: ./gradlew assembleAndroidTest
- store_artifacts:
path: app/build/reports/
destination: reports
......
......@@ -114,9 +114,9 @@ dependencies {
}
testImplementation libraries.junit
androidTestImplementation(libraries.expressoCore, {
exclude group: 'com.android.support', module: 'support-annotations'
})
testImplementation libraries.truth
androidTestImplementation libraries.espressoCore
androidTestImplementation libraries.espressoIntents
}
kotlin {
......
package chat.rocket.android.chatroom.ui
import android.content.Intent
import android.support.test.espresso.intent.rule.IntentsTestRule
import android.support.test.filters.LargeTest
import org.junit.Rule
import org.junit.Test
import android.app.Activity
import android.app.Instrumentation.ActivityResult
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.intent.Intents.intended
import android.support.test.espresso.intent.Intents.intending
import android.support.test.espresso.intent.matcher.IntentMatchers.*
import org.hamcrest.Matchers.allOf
import org.hamcrest.Matchers.not
import org.junit.Before
@LargeTest
class ChatRoomFragmentTest {
@JvmField
@Rule
val activityRule = IntentsTestRule<ChatRoomActivity>(ChatRoomActivity::class.java, false, false)
@Before
fun stubAllExternalIntents() {
val activityIntent = InstrumentationRegistry.getTargetContext().chatRoomIntent("id", "name", "type", false, 0L)
activityRule.launchActivity(activityIntent)
intending(not(isInternal())).respondWith(ActivityResult(Activity.RESULT_OK, null))
}
@Test
fun showFileSelection_nonNullFiltersAreApplied() {
val fragment = activityRule.activity.supportFragmentManager.findFragmentByTag(ChatRoomActivity.TAG_CHAT_ROOM_FRAGMENT) as ChatRoomFragment
val filters = arrayOf("image/*")
fragment.showFileSelection(filters)
intended(allOf(
hasAction(Intent.ACTION_GET_CONTENT),
hasType("*/*"),
hasCategories(setOf(Intent.CATEGORY_OPENABLE)),
hasExtra(Intent.EXTRA_MIME_TYPES, filters)))
}
@Test
fun showFileSelection_nullFiltersAreNotApplied() {
val fragment = activityRule.activity.supportFragmentManager.findFragmentByTag(ChatRoomActivity.TAG_CHAT_ROOM_FRAGMENT) as ChatRoomFragment
fragment.showFileSelection(null)
intended(allOf(
hasAction(Intent.ACTION_GET_CONTENT),
hasType("*/*"),
hasCategories(setOf(Intent.CATEGORY_OPENABLE)),
not(hasExtraWithKey(Intent.EXTRA_MIME_TYPES))))
}
}
\ No newline at end of file
......@@ -14,10 +14,9 @@ class AudioAttachmentViewHolder(itemView: View,
init {
with(itemView) {
setupActionMenu(attachment_container)
image_attachment.setVisible(false)
audio_video_attachment.setVisible(true)
setupActionMenu(attachment_container)
setupActionMenu(audio_video_attachment)
}
}
......
......@@ -19,12 +19,9 @@ class AuthorAttachmentViewHolder(itemView: View,
init {
with(itemView) {
setupActionMenu(author_attachment_container)
setupActionMenu(text_fields)
setupActionMenu(text_author_name)
}
}
override fun bindViews(data: AuthorAttachmentViewModel) {
with(itemView) {
data.icon?.let { icon ->
......
......@@ -3,6 +3,8 @@ package chat.rocket.android.chatroom.adapter
import android.support.v7.widget.RecyclerView
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.bottomsheet.BottomSheetMenu
import chat.rocket.android.chatroom.ui.bottomsheet.adapter.ActionListAdapter
......@@ -74,7 +76,7 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
fun onActionSelected(item: MenuItem, message: Message)
}
val longClickListener = { view: View ->
private val longClickListener = { view: View ->
if (data?.message?.isSystemMessage() == false) {
val menuItems = view.context.inflate(R.menu.message_actions).toList()
menuItems.find { it.itemId == R.id.action_menu_msg_pin_unpin }?.apply {
......@@ -90,6 +92,13 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
internal fun setupActionMenu(view: View) {
if (listener.isActionsEnabled()) {
if (view is ViewGroup) {
for (child in view.children) {
if (child !is RecyclerView && child.id != R.id.recycler_view_reactions) {
setupActionMenu(child)
}
}
}
view.setOnLongClickListener(longClickListener)
}
}
......
......@@ -20,7 +20,6 @@ class ColorAttachmentViewHolder(itemView: View,
init {
with(itemView) {
setupActionMenu(attachment_text)
setupActionMenu(color_attachment_container)
attachment_text.movementMethod = LinkMovementMethod()
}
......
......@@ -17,11 +17,9 @@ class GenericFileAttachmentViewHolder(itemView: View,
init {
with(itemView) {
setupActionMenu(file_attachment_container)
setupActionMenu(text_file_name)
}
}
override fun bindViews(data: GenericFileAttachmentViewModel) {
with(itemView) {
text_file_name.content = data.attachmentTitle
......
......@@ -47,7 +47,6 @@ class ImageAttachmentViewHolder(itemView: View,
init {
with(itemView) {
setupActionMenu(attachment_container)
setupActionMenu(image_attachment)
}
}
......
......@@ -4,7 +4,7 @@ import android.text.method.LinkMovementMethod
import android.view.View
import chat.rocket.android.chatroom.viewmodel.MessageAttachmentViewModel
import chat.rocket.android.widget.emoji.EmojiReactionListener
import kotlinx.android.synthetic.main.item_message.view.*
import kotlinx.android.synthetic.main.item_message_attachment.view.*
class MessageAttachmentViewHolder(
itemView: View,
......@@ -14,8 +14,8 @@ class MessageAttachmentViewHolder(
init {
with(itemView) {
setupActionMenu(attachment_container)
text_content.movementMethod = LinkMovementMethod()
setupActionMenu(text_content)
}
}
......
......@@ -16,8 +16,8 @@ class MessageViewHolder(
init {
with(itemView) {
setupActionMenu(message_container)
text_content.movementMethod = LinkMovementMethod()
setupActionMenu(text_content)
}
}
......
......@@ -14,10 +14,9 @@ class VideoAttachmentViewHolder(itemView: View,
init {
with(itemView) {
setupActionMenu(attachment_container)
image_attachment.setVisible(false)
audio_video_attachment.setVisible(true)
setupActionMenu(attachment_container)
setupActionMenu(audio_video_attachment)
}
}
......
......@@ -28,7 +28,7 @@ interface ChatRoomView : LoadingView, MessageView {
/**
* Perform file selection with the mime type [filter]
*/
fun showFileSelection(filter: Array<String>)
fun showFileSelection(filter: Array<String>?)
/**
* Uploads a file to a chat room.
......
......@@ -93,8 +93,8 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
isChatRoomSubscribed = intent.getBooleanExtra(INTENT_CHAT_IS_SUBSCRIBED, true)
if (supportFragmentManager.findFragmentByTag("ChatRoomFragment") == null) {
addFragment("ChatRoomFragment", R.id.fragment_container) {
if (supportFragmentManager.findFragmentByTag(TAG_CHAT_ROOM_FRAGMENT) == null) {
addFragment(TAG_CHAT_ROOM_FRAGMENT, R.id.fragment_container) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen,
isChatRoomSubscribed)
}
......@@ -156,4 +156,8 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
super.onBackPressed()
overridePendingTransition(R.anim.close_enter, R.anim.close_exit)
}
companion object {
const val TAG_CHAT_ROOM_FRAGMENT = "ChatRoomFragment"
}
}
\ No newline at end of file
......@@ -479,12 +479,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
button_add_reaction.tag = drawableId
}
override fun showFileSelection(filter: Array<String>) {
override fun showFileSelection(filter: Array<String>?) {
ui {
val intent = Intent(Intent.ACTION_GET_CONTENT)
// Must set a type otherwise the intent won't resolve
intent.type = "*/*"
intent.putExtra(Intent.EXTRA_MIME_TYPES, filter)
intent.addCategory(Intent.CATEGORY_OPENABLE)
// Filter selectable files to those that match the whitelist for this particular server
if (filter != null) {
intent.putExtra(Intent.EXTRA_MIME_TYPES, filter)
}
startActivityForResult(intent, REQUEST_CODE_FOR_PERFORM_SAF)
}
}
......
......@@ -87,13 +87,12 @@ fun PublicSettings.allowedMessageEditing(): Boolean = this[ALLOW_MESSAGE_EDITING
fun PublicSettings.allowedMessageDeleting(): Boolean = this[ALLOW_MESSAGE_DELETING]?.value == true
fun PublicSettings.showLastMessage(): Boolean = this[STORE_LAST_MESSAGE]?.value == true
fun PublicSettings.uploadMimeTypeFilter(): Array<String> {
val values = this[UPLOAD_WHITELIST_MIMETYPES]?.value
values?.let { it as String }?.split(",")?.let {
return it.mapToTypedArray { it.trim() }
fun PublicSettings.uploadMimeTypeFilter(): Array<String>? {
val values = this[UPLOAD_WHITELIST_MIMETYPES]?.value as String?
if (!values.isNullOrBlank()) {
return values!!.split(",").mapToTypedArray { it.trim() }
}
return arrayOf("*/*")
return null
}
fun PublicSettings.uploadMaxFileSize(): Int {
......
......@@ -5,4 +5,4 @@ inline fun <T, reified R> List<T>.mapToTypedArray(transform: (T) -> R): Array<R>
is RandomAccess -> Array(size) { index -> transform(this[index]) }
else -> with(iterator()) { Array(size) { transform(next()) } }
}
}
\ No newline at end of file
}
......@@ -72,6 +72,11 @@
android:gravity="center"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="@+id/layout_unread_messages_badge"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:maxLines="2"
android:textDirection="locale"
tools:visibility="visible"
app:layout_constraintEnd_toStartOf="@+id/layout_unread_messages_badge"
app:layout_constraintTop_toTopOf="@+id/text_chat_name"
tools:text="11:45 AM" />
......
......@@ -2,6 +2,7 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/message_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
......
......@@ -2,6 +2,7 @@
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/attachment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
......
package chat.rocket.android.server.domain
import chat.rocket.core.model.Value
import com.google.common.truth.Truth.assertThat
import org.junit.Test
class SettingsRepositoryTest {
@Test
fun `uploadMimeFilter returns null if not specified`() {
val settings = emptyMap<String, Value<Any>>()
val filter = settings.uploadMimeTypeFilter()
assertThat(filter).isNull()
}
}
\ No newline at end of file
package chat.rocket.android.server.domain
import chat.rocket.core.model.Value
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@RunWith(Parameterized::class)
class `SettingsRepository UploadMimeTypeFilter WhitelistIsSet Test`(private val allowedMimeTypes: String,
private val expectedFilter: Array<String>?) {
companion object {
@JvmStatic
@Parameterized.Parameters(name = "\"{0}\"")
fun data(): Collection<Array<Any?>> = listOf(
arrayOf<Any?>("", null),
arrayOf<Any?>(" ", null),
arrayOf<Any?>("image/*", arrayOf("image/*")),
arrayOf<Any?>("image/*,video/*", arrayOf("image/*", "video/*")),
arrayOf<Any?>("image/*, video/*", arrayOf("image/*", "video/*")),
arrayOf<Any?>("image/*,\tvideo/*", arrayOf("image/*", "video/*"))
)
}
@Test
fun test() {
val settings = mapOf<String, Value<Any>>(Pair(UPLOAD_WHITELIST_MIMETYPES, Value(allowedMimeTypes)))
val filter = settings.uploadMimeTypeFilter()
assertThat(filter).isEqualTo(expectedFilter)
}
}
......@@ -9,7 +9,7 @@ ext {
dokka : '0.9.16',
// Main dependencies
support : '27.1.0',
support : '27.1.1',
constraintLayout : '1.1.0',
androidKtx : '0.3',
dagger : '2.14.1',
......@@ -35,7 +35,7 @@ ext {
// For testing
junit : '4.12',
truth : '0.36',
expresso : '3.0.1',
espresso : '3.0.2',
mockito : '2.10.0'
]
libraries = [
......@@ -98,8 +98,9 @@ ext {
// For testing
junit : "junit:junit:$versions.junit",
expressoCore : "com.android.support.test.espresso:espresso-core:${versions.expresso}",
espressoCore : "com.android.support.test.espresso:espresso-core:${versions.espresso}",
espressoIntents : "com.android.support.test.espresso:espresso-intents:${versions.espresso}",
roomTest : "android.arch.persistence.room:testing:${versions.room}",
truth : "com.google.truth:truth:$versions.truth",
]
}
\ No newline at end of file
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment