Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Refactor text view test
Browse files Browse the repository at this point in the history
  • Loading branch information
jonnyandrew committed Nov 29, 2023
1 parent c74e671 commit be00fcf
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import io.element.android.wysiwyg.test.R
import io.element.android.wysiwyg.test.utils.FakeLinkClickedListener
import io.element.android.wysiwyg.test.utils.TestActivity
import io.element.android.wysiwyg.test.utils.TextViewActions
import io.element.android.wysiwyg.view.spans.CustomMentionSpan
import io.element.android.wysiwyg.view.spans.LinkSpan
import io.element.android.wysiwyg.view.spans.PillSpan
import org.junit.Assert
import org.junit.Rule
import org.junit.Test

Expand All @@ -28,125 +28,110 @@ internal class EditorStyledTextViewTest {
@get:Rule
val scenarioRule = ActivityScenarioRule(TestActivity::class.java)

private val fakeLinkClickedListener = FakeLinkClickedListener()

companion object {
const val HELLO_WORLD = "Hello, world"
const val HELLO_WORLD_HTML = "<p>$HELLO_WORLD</p>"
val HELLO_WORLD_SPANNED = buildSpannedString {
inSpans(LinkSpan("")) {
append(HELLO_WORLD)
}
}
const val MENTION_TEXT = "@Alice"
const val MENTION_URI = "https://matrix.to/#/@alice:matrix.org"
const val MENTION_HTML = "<p><a href='$MENTION_URI'>$MENTION_TEXT</a></p>"
}

@Test
fun testSetText() {
onView(ViewMatchers.withId(R.id.styledTextView))
.perform(TextViewActions.setText("Hello, world"))
.check(matches(withText("Hello, world")))
.perform(TextViewActions.setText(HELLO_WORLD))
.check(matches(withText(HELLO_WORLD)))
}

@Test
fun testSetHtml() {
scenarioRule.scenario.onActivity {
it.findViewById<EditorStyledTextView>(R.id.styledTextView).apply {
setHtml("<p>Hello, world</p>")
}
}
onView(ViewMatchers.withId(R.id.styledTextView))
.check(matches(withText("Hello, world")))
.perform(TextViewActions.setHtml(HELLO_WORLD_HTML))
.check(matches(withText(HELLO_WORLD)))
}

@Test
fun testSetHtmlWithMention() {
scenarioRule.scenario.onActivity {
it.findViewById<EditorStyledTextView>(R.id.styledTextView).apply {
setHtml("<p>Hello, <a href='https://matrix.to/#/@alice:matrix.org'>@Alice</a></p>")
}
}
onView(ViewMatchers.withId(R.id.styledTextView))
.check(matches(withText("Hello, @Alice")))
.perform(TextViewActions.setHtml(MENTION_HTML))
.check(matches(withText(MENTION_TEXT)))
}

@Test
fun testUrlClicks() {
var pass = false
scenarioRule.scenario.onActivity {
it.findViewById<EditorStyledTextView>(R.id.styledTextView).apply {
val spanned = buildSpannedString {
inSpans(URLSpan("")) {
append("Hello, world")
}
}
setText(spanned, TextView.BufferType.SPANNABLE)
onLinkClickedListener = {
pass = true
}
val urlSpanText = buildSpannedString {
inSpans(URLSpan("")) {
append(HELLO_WORLD)
}
}
onView(ViewMatchers.withId(R.id.styledTextView))
.check(matches(withText("Hello, world")))
.perform(TextViewActions.setText(urlSpanText, TextView.BufferType.SPANNABLE))
.perform(TextViewActions.setOnLinkClickedListener(fakeLinkClickedListener))
.check(matches(withText(HELLO_WORLD)))
.perform(ViewActions.click())

Assert.assertTrue(pass)
fakeLinkClickedListener.assertIsClicked()
}

@Test
fun testLinkClicks() {
var pass = false
scenarioRule.scenario.onActivity {
it.findViewById<EditorStyledTextView>(R.id.styledTextView).apply {
val spanned = buildSpannedString {
inSpans(LinkSpan("")) {
append("Hello, world")
}
}
setText(spanned, TextView.BufferType.SPANNABLE)
onLinkClickedListener = {
pass = true
}
}
}
onView(ViewMatchers.withId(R.id.styledTextView))
.check(matches(withText("Hello, world")))
.perform(TextViewActions.setText(HELLO_WORLD_SPANNED, TextView.BufferType.SPANNABLE))
.perform(TextViewActions.setOnLinkClickedListener(fakeLinkClickedListener))
.check(matches(withText(HELLO_WORLD)))
.perform(ViewActions.click())

Assert.assertTrue(pass)
fakeLinkClickedListener.assertIsClicked()
}

@Test
fun testPillSpanClicks() {
var pass = false
scenarioRule.scenario.onActivity {
it.findViewById<EditorStyledTextView>(R.id.styledTextView).apply {
val spanned = buildSpannedString {
inSpans(PillSpan(backgroundColor = 0, url = "")) {
append("Hello, world")
}
}
setText(spanned, TextView.BufferType.SPANNABLE)
onLinkClickedListener = {
pass = true
}
val pillSpanText = buildSpannedString {
inSpans(PillSpan(backgroundColor = 0, url = "")) {
append(HELLO_WORLD)
}
}
onView(ViewMatchers.withId(R.id.styledTextView))
.check(matches(withText("Hello, world")))
.perform(TextViewActions.setText(pillSpanText, TextView.BufferType.SPANNABLE))
.perform(TextViewActions.setOnLinkClickedListener(fakeLinkClickedListener))
.check(matches(withText(HELLO_WORLD)))
.perform(ViewActions.click())

Assert.assertTrue(pass)
fakeLinkClickedListener.assertIsClicked()
}

@Test
fun testCustomMentionSpanClicks() {
var pass = false
scenarioRule.scenario.onActivity {
it.findViewById<EditorStyledTextView>(R.id.styledTextView).apply {
val spanned = buildSpannedString {
inSpans(CustomMentionSpan(DummyReplacementSpan, url = "")) {
append("Hello, world")
}
}
setText(spanned, TextView.BufferType.SPANNABLE)
onLinkClickedListener = {
pass = true
}
val mentionSpanText = buildSpannedString {
inSpans(CustomMentionSpan(DummyReplacementSpan, url = "")) {
append(HELLO_WORLD)
}
}
onView(ViewMatchers.withId(R.id.styledTextView))
.check(matches(withText("Hello, world")))
.perform(TextViewActions.setText(mentionSpanText, TextView.BufferType.SPANNABLE))
.perform(TextViewActions.setOnLinkClickedListener(fakeLinkClickedListener))
.check(matches(withText(HELLO_WORLD)))
.perform(ViewActions.click())

fakeLinkClickedListener.assertIsClicked()
}

@Test
fun testParsedMentionHtmlClicks() {
onView(ViewMatchers.withId(R.id.styledTextView))
.perform(TextViewActions.setHtml(MENTION_HTML))
.perform(TextViewActions.setOnLinkClickedListener(fakeLinkClickedListener))
.check(matches(withText(MENTION_TEXT)))
.perform(ViewActions.click())

Assert.assertTrue(pass)
fakeLinkClickedListener.assertIsClicked(MENTION_URI)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.element.android.wysiwyg.test.utils

import org.junit.Assert

class FakeLinkClickedListener: (String) -> Unit {
private val clickedLinks: MutableList<String> = mutableListOf()

override fun invoke(link: String) {
clickedLinks.add(link)
}

fun assertIsClicked(url: String? = null) {
Assert.assertTrue(clickedLinks.size == 1)
if (url != null) {
Assert.assertTrue(clickedLinks.contains(url))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,57 @@ package io.element.android.wysiwyg.test.utils

import android.view.View
import android.widget.TextView
import android.widget.TextView.BufferType
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import io.element.android.wysiwyg.EditorStyledTextView
import org.hamcrest.Matcher

object TextViewAction {
class SetText(
private val text: String,
private val text: CharSequence,
private val type: BufferType = BufferType.NORMAL,
) : ViewAction {
override fun getConstraints(): Matcher<View> = isDisplayed()

override fun getDescription(): String = "Set text to $text"

override fun perform(uiController: UiController?, view: View?) {
val textView = view as? TextView ?: return
textView.setText(text)
textView.setText(text, type)
}
}

class SetHtml(
private val html: String,
) : ViewAction {
override fun getConstraints(): Matcher<View> = isDisplayed()

override fun getDescription(): String = "Set html to $html"

override fun perform(uiController: UiController?, view: View?) {
val textView = view as? EditorStyledTextView ?: return
textView.setHtml(html)
}
}

class SetOnLinkClickedListener(
private val listener: (String) -> Unit,
) : ViewAction {
override fun getConstraints(): Matcher<View> = isDisplayed()

override fun getDescription(): String = "Set link clicked listener"

override fun perform(uiController: UiController?, view: View?) {
val textView = view as? EditorStyledTextView ?: return
textView.onLinkClickedListener = listener
}
}
}

object TextViewActions {
fun setText(text: String) = TextViewAction.SetText(text)
fun setText(text: CharSequence, type: BufferType = BufferType.NORMAL) = TextViewAction.SetText(text, type)
fun setHtml(html: String) = TextViewAction.SetHtml(html)
fun setOnLinkClickedListener(listener: (String) -> Unit) = TextViewAction.SetOnLinkClickedListener(listener)
}

0 comments on commit be00fcf

Please sign in to comment.