[fenix] Add tests for addon details
parent
84cc714d59
commit
832b4b0f34
@ -0,0 +1,112 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.addons
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.View
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.text.HtmlCompat
|
||||
import kotlinx.android.extensions.LayoutContainer
|
||||
import kotlinx.android.synthetic.main.fragment_add_on_details.*
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.feature.addons.ui.translatedDescription
|
||||
import org.mozilla.fenix.R
|
||||
import java.text.DateFormat
|
||||
import java.text.NumberFormat
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
interface AddonDetailsInteractor {
|
||||
|
||||
/**
|
||||
* Open the given addon siteUrl in the browser.
|
||||
*/
|
||||
fun openWebsite(addonSiteUrl: Uri)
|
||||
|
||||
/**
|
||||
* Display the updater dialog.
|
||||
*/
|
||||
fun showUpdaterDialog(addon: Addon)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the details of an add-on.
|
||||
*/
|
||||
class AddonDetailsView(
|
||||
override val containerView: View,
|
||||
private val interactor: AddonDetailsInteractor
|
||||
) : LayoutContainer {
|
||||
|
||||
private val dateParser = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault())
|
||||
private val dateFormatter = DateFormat.getDateInstance()
|
||||
private val numberFormatter = NumberFormat.getNumberInstance(Locale.getDefault())
|
||||
|
||||
fun bind(addon: Addon) {
|
||||
bindDetails(addon)
|
||||
bindAuthors(addon)
|
||||
bindVersion(addon)
|
||||
bindLastUpdated(addon)
|
||||
bindWebsite(addon)
|
||||
bindRating(addon)
|
||||
}
|
||||
|
||||
private fun bindRating(addon: Addon) {
|
||||
addon.rating?.let { rating ->
|
||||
val resources = containerView.resources
|
||||
val ratingContentDescription =
|
||||
resources.getString(R.string.mozac_feature_addons_rating_content_description)
|
||||
rating_view.contentDescription = String.format(ratingContentDescription, rating.average)
|
||||
rating_view.rating = rating.average
|
||||
|
||||
users_count.text = numberFormatter.format(rating.reviews)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindWebsite(addon: Addon) {
|
||||
home_page_label.setOnClickListener {
|
||||
interactor.openWebsite(addon.siteUrl.toUri())
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindLastUpdated(addon: Addon) {
|
||||
last_updated_text.text = formatDate(addon.updatedAt)
|
||||
}
|
||||
|
||||
private fun bindVersion(addon: Addon) {
|
||||
var version = addon.installedState?.version
|
||||
if (version.isNullOrEmpty()) {
|
||||
version = addon.version
|
||||
}
|
||||
version_text.text = version
|
||||
|
||||
if (addon.isInstalled()) {
|
||||
version_text.setOnLongClickListener {
|
||||
interactor.showUpdaterDialog(addon)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
version_text.setOnLongClickListener(null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindAuthors(addon: Addon) {
|
||||
author_text.text = addon.authors.joinToString { author -> author.name }.trim()
|
||||
}
|
||||
|
||||
private fun bindDetails(addon: Addon) {
|
||||
val detailsText = addon.translatedDescription
|
||||
|
||||
val parsedText = detailsText.replace("\n", "<br/>")
|
||||
val text = HtmlCompat.fromHtml(parsedText, HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||
|
||||
details.text = text
|
||||
details.movementMethod = LinkMovementMethod.getInstance()
|
||||
}
|
||||
|
||||
private fun formatDate(text: String): String {
|
||||
return dateFormatter.format(dateParser.parse(text)!!)
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.addons
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.android.synthetic.main.fragment_add_on_details.view.*
|
||||
import mozilla.components.feature.addons.Addon
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class AddonDetailsViewTest {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var interactor: AddonDetailsInteractor
|
||||
private lateinit var detailsView: AddonDetailsView
|
||||
private val baseAddon = Addon(
|
||||
id = "",
|
||||
translatableDescription = mapOf(
|
||||
Addon.DEFAULT_LOCALE to "Some blank addon\nwith a blank line"
|
||||
),
|
||||
updatedAt = "2020-11-23T08:00:00Z"
|
||||
)
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext).inflate(R.layout.fragment_add_on_details, null)
|
||||
interactor = mockk(relaxed = true)
|
||||
|
||||
detailsView = AddonDetailsView(view, interactor)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons rating`() {
|
||||
detailsView.bind(baseAddon.copy(
|
||||
rating = null
|
||||
))
|
||||
assertEquals(0f, view.rating_view.rating)
|
||||
|
||||
detailsView.bind(baseAddon.copy(
|
||||
rating = Addon.Rating(
|
||||
average = 4.3f,
|
||||
reviews = 100
|
||||
)
|
||||
))
|
||||
assertEquals("4.30/5", view.rating_view.contentDescription)
|
||||
assertEquals(4.5f, view.rating_view.rating)
|
||||
assertEquals("100", view.users_count.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons website`() {
|
||||
detailsView.bind(baseAddon.copy(
|
||||
siteUrl = "https://mozilla.org"
|
||||
))
|
||||
|
||||
view.home_page_label.performClick()
|
||||
|
||||
verify { interactor.openWebsite(Uri.parse("https://mozilla.org")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons last updated`() {
|
||||
detailsView.bind(baseAddon)
|
||||
|
||||
assertEquals("Nov 23, 2020", view.last_updated_text.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons version`() {
|
||||
detailsView.bind(baseAddon.copy(
|
||||
version = "1.0.0",
|
||||
installedState = null
|
||||
))
|
||||
assertEquals("1.0.0", view.version_text.text)
|
||||
view.version_text.performLongClick()
|
||||
verify(exactly = 0) { interactor.showUpdaterDialog(any()) }
|
||||
|
||||
detailsView.bind(baseAddon.copy(
|
||||
version = "1.0.0",
|
||||
installedState = Addon.InstalledState(
|
||||
id = "",
|
||||
version = "2.0.0",
|
||||
optionsPageUrl = null
|
||||
)
|
||||
))
|
||||
assertEquals("2.0.0", view.version_text.text)
|
||||
view.version_text.performLongClick()
|
||||
verify { interactor.showUpdaterDialog(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons authors`() {
|
||||
val baseAuthor = Addon.Author("", "", "", "")
|
||||
detailsView.bind(baseAddon.copy(
|
||||
authors = listOf(
|
||||
baseAuthor.copy(name = " Sarah Jane"),
|
||||
baseAuthor.copy(name = "John Smith ")
|
||||
)
|
||||
))
|
||||
|
||||
assertEquals("Sarah Jane, John Smith", view.author_text.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind addons details`() {
|
||||
detailsView.bind(baseAddon)
|
||||
|
||||
assertEquals(
|
||||
"Some blank addon\nwith a blank line",
|
||||
view.details.text.toString()
|
||||
)
|
||||
assertTrue(view.details.movementMethod is LinkMovementMethod)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue