2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-17 15:26:23 +00:00

[fenix] Merge bookmark item and folder view holders

This commit is contained in:
Tiger Oakes 2020-08-17 10:32:04 -07:00 committed by ekager
parent a684ab65ca
commit d29e90717c
7 changed files with 242 additions and 355 deletions

View File

@ -63,8 +63,6 @@ class LibrarySiteItemView @JvmOverloads constructor(
val overflowView: ImageButton get() = overflow_menu val overflowView: ImageButton get() = overflow_menu
private var iconUrl: String? = null
init { init {
LayoutInflater.from(context).inflate(R.layout.library_site_item, this, true) LayoutInflater.from(context).inflate(R.layout.library_site_item, this, true)
@ -86,9 +84,6 @@ class LibrarySiteItemView @JvmOverloads constructor(
} }
fun loadFavicon(url: String) { fun loadFavicon(url: String) {
if (iconUrl == url) return
iconUrl = url
context.components.core.icons.loadIntoView(favicon, url) context.components.core.icons.loadIntoView(favicon, url)
} }

View File

@ -14,10 +14,7 @@ import androidx.recyclerview.widget.RecyclerView
import mozilla.appservices.places.BookmarkRoot import mozilla.appservices.places.BookmarkRoot
import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType import mozilla.components.concept.storage.BookmarkNodeType
import org.mozilla.fenix.R
import org.mozilla.fenix.library.LibrarySiteItemView import org.mozilla.fenix.library.LibrarySiteItemView
import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkFolderViewHolder
import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkItemViewHolder
import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkNodeViewHolder import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkNodeViewHolder
import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkSeparatorViewHolder import org.mozilla.fenix.library.bookmarks.viewholders.BookmarkSeparatorViewHolder
@ -70,7 +67,8 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm
titleChanged = oldItem.title != newItem.title, titleChanged = oldItem.title != newItem.title,
urlChanged = oldItem.url != newItem.url, urlChanged = oldItem.url != newItem.url,
selectedChanged = oldItem in oldMode.selectedItems != newItem in newMode.selectedItems, selectedChanged = oldItem in oldMode.selectedItems != newItem in newMode.selectedItems,
modeChanged = oldMode::class != newMode::class modeChanged = oldMode::class != newMode::class,
iconChanged = oldItem.type != newItem.type || oldItem.url != newItem.url
) )
} }
@ -79,24 +77,20 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = LayoutInflater.from(parent.context) val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false)
.inflate(R.layout.bookmark_list_item, parent, false) as LibrarySiteItemView
return when (viewType) { return when (viewType) {
LibrarySiteItemView.ItemType.SITE.ordinal -> BookmarkItemViewHolder(view, interactor) BookmarkNodeViewHolder.LAYOUT_ID ->
LibrarySiteItemView.ItemType.FOLDER.ordinal -> BookmarkFolderViewHolder(view, interactor) BookmarkNodeViewHolder(view as LibrarySiteItemView, interactor)
BookmarkSeparatorViewHolder.LAYOUT_ID -> BookmarkSeparatorViewHolder(view) BookmarkSeparatorViewHolder.LAYOUT_ID ->
BookmarkSeparatorViewHolder(view)
else -> throw IllegalStateException("ViewType $viewType does not match to a ViewHolder") else -> throw IllegalStateException("ViewType $viewType does not match to a ViewHolder")
} }
} }
override fun getItemViewType(position: Int): Int { override fun getItemViewType(position: Int) = when (tree[position].type) {
return when (tree[position].type) { BookmarkNodeType.ITEM, BookmarkNodeType.FOLDER -> BookmarkNodeViewHolder.LAYOUT_ID
BookmarkNodeType.ITEM -> LibrarySiteItemView.ItemType.SITE.ordinal
BookmarkNodeType.FOLDER -> LibrarySiteItemView.ItemType.FOLDER.ordinal
BookmarkNodeType.SEPARATOR -> BookmarkSeparatorViewHolder.LAYOUT_ID BookmarkNodeType.SEPARATOR -> BookmarkSeparatorViewHolder.LAYOUT_ID
else -> throw IllegalStateException("Item $tree[position] does not match to a ViewType")
}
} }
override fun getItemCount(): Int = tree.size override fun getItemCount(): Int = tree.size
@ -106,16 +100,18 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm
position: Int, position: Int,
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
if (payloads.isNotEmpty() && payloads[0] is BookmarkPayload) { (holder as? BookmarkNodeViewHolder)?.apply {
(holder as? BookmarkNodeViewHolder) val diffPayload = if (payloads.isNotEmpty() && payloads[0] is BookmarkPayload) {
?.bind(tree[position], mode, payloads[0] as BookmarkPayload) payloads[0] as BookmarkPayload
} else { } else {
super.onBindViewHolder(holder, position, payloads) BookmarkPayload()
}
bind(tree[position], mode, diffPayload)
} }
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder as? BookmarkNodeViewHolder)?.bind(tree[position], mode) (holder as? BookmarkNodeViewHolder)?.bind(tree[position], mode, BookmarkPayload())
} }
} }
@ -126,12 +122,22 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm
* @property urlChanged true if there has been a change to [BookmarkNode.url]. * @property urlChanged true if there has been a change to [BookmarkNode.url].
* @property selectedChanged true if there has been a change in the BookmarkNode's selected state. * @property selectedChanged true if there has been a change in the BookmarkNode's selected state.
* @property modeChanged true if there has been a change in the state's mode type. * @property modeChanged true if there has been a change in the state's mode type.
* @property iconChanged true if the icon displayed for the node should be changed.
*/ */
data class BookmarkPayload( data class BookmarkPayload(
val titleChanged: Boolean, val titleChanged: Boolean,
val urlChanged: Boolean, val urlChanged: Boolean,
val selectedChanged: Boolean, val selectedChanged: Boolean,
val modeChanged: Boolean val modeChanged: Boolean,
val iconChanged: Boolean
) {
constructor() : this(
titleChanged = true,
urlChanged = true,
selectedChanged = true,
modeChanged = true,
iconChanged = true
) )
}
fun BookmarkNode.inRoots() = enumValues<BookmarkRoot>().any { it.id == guid } fun BookmarkNode.inRoots() = enumValues<BookmarkRoot>().any { it.id == guid }

View File

@ -1,81 +0,0 @@
/* 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.library.bookmarks.viewholders
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import mozilla.components.concept.storage.BookmarkNode
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.hideAndDisable
import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.library.LibrarySiteItemView
import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState
import org.mozilla.fenix.library.bookmarks.BookmarkPayload
import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor
import org.mozilla.fenix.library.bookmarks.inRoots
/**
* Represents a folder with other bookmarks inside.
*/
class BookmarkFolderViewHolder(
view: LibrarySiteItemView,
interactor: BookmarkViewInteractor
) : BookmarkNodeViewHolder(view, interactor) {
override var item: BookmarkNode? = null
init {
containerView.displayAs(LibrarySiteItemView.ItemType.FOLDER)
}
override fun bind(
item: BookmarkNode,
mode: BookmarkFragmentState.Mode
) {
bind(item, mode, BookmarkPayload(true, true, true, true))
}
override fun bind(item: BookmarkNode, mode: BookmarkFragmentState.Mode, payload: BookmarkPayload) {
this.item = item
setSelectionListeners(item, mode)
if (!item.inRoots()) {
updateMenu(item.type)
if (payload.modeChanged) {
if (mode is BookmarkFragmentState.Mode.Selecting) {
containerView.overflowView.hideAndDisable()
} else {
containerView.overflowView.showAndEnable()
}
}
} else {
containerView.overflowView.visibility = View.GONE
}
if (payload.selectedChanged) {
containerView.changeSelected(item in mode.selectedItems)
}
containerView.iconView.setImageDrawable(
AppCompatResources.getDrawable(
containerView.context,
R.drawable.ic_folder_icon
)?.apply {
setTint(
ContextCompat.getColor(
containerView.context,
R.color.primary_text_light_theme
)
)
}
)
if (payload.titleChanged) {
containerView.titleView.text = item.title
}
}
}

View File

@ -1,76 +0,0 @@
/* 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.library.bookmarks.viewholders
import androidx.annotation.VisibleForTesting
import mozilla.components.concept.storage.BookmarkNode
import org.mozilla.fenix.ext.hideAndDisable
import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.library.LibrarySiteItemView
import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState
import org.mozilla.fenix.library.bookmarks.BookmarkPayload
import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor
/**
* Represents a bookmarked website in the bookmarks page.
*/
class BookmarkItemViewHolder(
view: LibrarySiteItemView,
interactor: BookmarkViewInteractor
) : BookmarkNodeViewHolder(view, interactor) {
override var item: BookmarkNode? = null
init {
containerView.displayAs(LibrarySiteItemView.ItemType.SITE)
}
override fun bind(
item: BookmarkNode,
mode: BookmarkFragmentState.Mode
) {
bind(item, mode, BookmarkPayload(true, true, true, true))
}
override fun bind(item: BookmarkNode, mode: BookmarkFragmentState.Mode, payload: BookmarkPayload) {
this.item = item
updateMenu(item.type)
if (payload.modeChanged) {
if (mode is BookmarkFragmentState.Mode.Selecting) {
containerView.overflowView.hideAndDisable()
} else {
containerView.overflowView.showAndEnable()
}
}
if (payload.selectedChanged) {
containerView.changeSelected(item in mode.selectedItems)
}
if (payload.titleChanged) {
containerView.titleView.text = if (item.title.isNullOrBlank()) item.url else item.title
} else if (payload.urlChanged && item.title.isNullOrBlank()) {
containerView.titleView.text = item.url
}
if (payload.urlChanged) {
containerView.urlView.text = item.url
setColorsAndIcons(item.url)
}
setSelectionListeners(item, mode)
}
@VisibleForTesting
internal fun setColorsAndIcons(url: String?) {
if (url != null && url.startsWith("http")) {
containerView.loadFavicon(url)
} else {
containerView.iconView.setImageDrawable(null)
}
}
}

View File

@ -4,45 +4,38 @@
package org.mozilla.fenix.library.bookmarks.viewholders package org.mozilla.fenix.library.bookmarks.viewholders
import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.support.ktx.android.content.getDrawableWithTint
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.hideAndDisable
import org.mozilla.fenix.ext.loadIntoView
import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.library.LibrarySiteItemView import org.mozilla.fenix.library.LibrarySiteItemView
import org.mozilla.fenix.library.SelectionHolder
import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState
import org.mozilla.fenix.library.bookmarks.BookmarkItemMenu import org.mozilla.fenix.library.bookmarks.BookmarkItemMenu
import org.mozilla.fenix.library.bookmarks.BookmarkPayload import org.mozilla.fenix.library.bookmarks.BookmarkPayload
import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor import org.mozilla.fenix.library.bookmarks.BookmarkViewInteractor
import org.mozilla.fenix.library.bookmarks.inRoots
import org.mozilla.fenix.utils.Do import org.mozilla.fenix.utils.Do
/** /**
* Base class for bookmark node view holders. * Base class for bookmark node view holders.
*/ */
abstract class BookmarkNodeViewHolder( class BookmarkNodeViewHolder(
protected val containerView: LibrarySiteItemView, private val containerView: LibrarySiteItemView,
private val interactor: BookmarkViewInteractor private val interactor: BookmarkViewInteractor
) : RecyclerView.ViewHolder(containerView) { ) : RecyclerView.ViewHolder(containerView) {
abstract var item: BookmarkNode? var item: BookmarkNode? = null
private lateinit var menu: BookmarkItemMenu private val menu: BookmarkItemMenu
init { init {
setupMenu()
}
abstract fun bind(item: BookmarkNode, mode: BookmarkFragmentState.Mode)
abstract fun bind(
item: BookmarkNode,
mode: BookmarkFragmentState.Mode,
payload: BookmarkPayload
)
protected fun setSelectionListeners(item: BookmarkNode, selectionHolder: SelectionHolder<BookmarkNode>) {
containerView.setSelectionInteractor(item, selectionHolder, interactor)
}
private fun setupMenu() {
menu = BookmarkItemMenu(containerView.context) { menuItem -> menu = BookmarkItemMenu(containerView.context) { menuItem ->
val item = this.item ?: return@BookmarkItemMenu val item = this.item ?: return@BookmarkItemMenu
Do exhaustive when (menuItem) { Do exhaustive when (menuItem) {
@ -58,5 +51,71 @@ abstract class BookmarkNodeViewHolder(
containerView.attachMenu(menu.menuController) containerView.attachMenu(menu.menuController)
} }
protected fun updateMenu(itemType: BookmarkNodeType) = menu.updateMenu(itemType) fun bind(
item: BookmarkNode,
mode: BookmarkFragmentState.Mode,
payload: BookmarkPayload
) {
this.item = item
containerView.urlView.isVisible = item.type == BookmarkNodeType.ITEM
containerView.setSelectionInteractor(item, mode, interactor)
menu.updateMenu(item.type)
// Hide menu button if this item is a root folder or is selected
if (item.type == BookmarkNodeType.FOLDER && item.inRoots()) {
containerView.overflowView.visibility = View.GONE
} else if (payload.modeChanged) {
if (mode is BookmarkFragmentState.Mode.Selecting) {
containerView.overflowView.hideAndDisable()
} else {
containerView.overflowView.showAndEnable()
}
}
if (payload.selectedChanged) {
containerView.changeSelected(item in mode.selectedItems)
}
val useTitleFallback = item.type == BookmarkNodeType.ITEM && item.title.isNullOrBlank()
if (payload.titleChanged) {
containerView.titleView.text = if (useTitleFallback) item.url else item.title
} else if (payload.urlChanged && useTitleFallback) {
containerView.titleView.text = item.url
}
if (payload.urlChanged) {
containerView.urlView.text = item.url
}
if (payload.iconChanged) {
updateIcon(item)
}
}
private fun updateIcon(item: BookmarkNode) {
val context = containerView.context
val iconView = containerView.iconView
val url = item.url
when {
// Item is a folder
item.type == BookmarkNodeType.FOLDER ->
iconView.setImageDrawable(
context.getDrawableWithTint(
R.drawable.ic_folder_icon,
ContextCompat.getColor(context, R.color.primary_text_light_theme)
)
)
// Item has a http/https URL
url != null && url.startsWith("http") ->
context.components.core.icons.loadIntoView(iconView, url)
else ->
iconView.setImageDrawable(null)
}
}
companion object {
const val LAYOUT_ID = R.layout.bookmark_list_item
}
} }

View File

@ -1,87 +0,0 @@
/* 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.library.bookmarks.viewholders
import androidx.appcompat.content.res.AppCompatResources
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.verify
import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType
import org.junit.Before
import org.junit.Test
import org.mozilla.fenix.ext.hideAndDisable
import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.library.LibrarySiteItemView
import org.mozilla.fenix.library.bookmarks.BookmarkFragmentInteractor
import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState
import org.mozilla.fenix.library.bookmarks.BookmarkPayload
class BookmarkFolderViewHolderTest {
@MockK
private lateinit var interactor: BookmarkFragmentInteractor
@MockK(relaxed = true)
private lateinit var siteItemView: LibrarySiteItemView
private lateinit var holder: BookmarkFolderViewHolder
private val folder = BookmarkNode(
type = BookmarkNodeType.FOLDER,
guid = "456",
parentGuid = "123",
position = 0,
title = "Folder",
url = null,
children = listOf()
)
@Before
fun setup() {
MockKAnnotations.init(this)
mockkStatic(AppCompatResources::class)
every { AppCompatResources.getDrawable(any(), any()) } returns mockk(relaxed = true)
holder = BookmarkFolderViewHolder(siteItemView, interactor)
}
@Test
fun `binds title and selected state`() {
holder.bind(folder, BookmarkFragmentState.Mode.Normal())
verify {
siteItemView.titleView.text = folder.title
siteItemView.overflowView.showAndEnable()
siteItemView.changeSelected(false)
}
holder.bind(folder, BookmarkFragmentState.Mode.Selecting(setOf(folder)))
verify {
siteItemView.titleView.text = folder.title
siteItemView.overflowView.hideAndDisable()
siteItemView.changeSelected(true)
}
}
@Test
fun `bind with payload of no changes does not rebind views`() {
holder.bind(
folder,
BookmarkFragmentState.Mode.Normal(),
BookmarkPayload(false, false, false, false)
)
verify(inverse = true) {
siteItemView.titleView.text = folder.title
siteItemView.overflowView.showAndEnable()
siteItemView.overflowView.hideAndDisable()
siteItemView.changeSelected(any())
}
}
}

View File

@ -4,13 +4,23 @@
package org.mozilla.fenix.library.bookmarks.viewholders package org.mozilla.fenix.library.bookmarks.viewholders
import androidx.appcompat.content.res.AppCompatResources
import io.mockk.Called
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import io.mockk.verify import io.mockk.verify
import mozilla.components.browser.icons.BrowserIcons
import mozilla.components.browser.icons.IconRequest
import mozilla.components.concept.storage.BookmarkNode import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType import mozilla.components.concept.storage.BookmarkNodeType
import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.hideAndDisable import org.mozilla.fenix.ext.hideAndDisable
import org.mozilla.fenix.ext.showAndEnable import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.library.LibrarySiteItemView import org.mozilla.fenix.library.LibrarySiteItemView
@ -18,15 +28,12 @@ import org.mozilla.fenix.library.bookmarks.BookmarkFragmentInteractor
import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState import org.mozilla.fenix.library.bookmarks.BookmarkFragmentState
import org.mozilla.fenix.library.bookmarks.BookmarkPayload import org.mozilla.fenix.library.bookmarks.BookmarkPayload
class BookmarkItemViewHolderTest { class BookmarkNodeViewHolderTest {
@MockK @MockK private lateinit var interactor: BookmarkFragmentInteractor
private lateinit var interactor: BookmarkFragmentInteractor @MockK(relaxed = true) private lateinit var siteItemView: LibrarySiteItemView
@MockK private lateinit var icons: BrowserIcons
@MockK(relaxed = true) private lateinit var holder: BookmarkNodeViewHolder
private lateinit var siteItemView: LibrarySiteItemView
private lateinit var holder: BookmarkItemViewHolder
private val item = BookmarkNode( private val item = BookmarkNode(
type = BookmarkNodeType.ITEM, type = BookmarkNodeType.ITEM,
@ -37,17 +44,45 @@ class BookmarkItemViewHolderTest {
url = "https://www.mozilla.org", url = "https://www.mozilla.org",
children = listOf() children = listOf()
) )
private val folder = BookmarkNode(
type = BookmarkNodeType.FOLDER,
guid = "456",
parentGuid = "123",
position = 0,
title = "Folder",
url = null,
children = listOf()
)
private val falsePayload = BookmarkPayload(
titleChanged = false,
urlChanged = false,
selectedChanged = false,
modeChanged = false,
iconChanged = false
)
@Before @Before
fun setup() { fun setup() {
MockKAnnotations.init(this) MockKAnnotations.init(this)
holder = BookmarkItemViewHolder(siteItemView, interactor)
mockkStatic(AppCompatResources::class)
every { AppCompatResources.getDrawable(any(), any()) } returns mockk(relaxed = true)
every { siteItemView.context.components.core.icons } returns icons
every { icons.loadIntoView(siteItemView.iconView, any()) } returns mockk()
holder = BookmarkNodeViewHolder(siteItemView, interactor)
}
@After
fun teardown() {
unmockkStatic(AppCompatResources::class)
} }
@Test @Test
fun `binds views for unselected item`() { fun `binds views for unselected item`() {
val mode = BookmarkFragmentState.Mode.Normal() val mode = BookmarkFragmentState.Mode.Normal()
holder.bind(item, mode) holder.bind(item, mode, BookmarkPayload())
verify { verify {
siteItemView.setSelectionInteractor(item, mode, interactor) siteItemView.setSelectionInteractor(item, mode, interactor)
@ -55,14 +90,14 @@ class BookmarkItemViewHolderTest {
siteItemView.urlView.text = item.url siteItemView.urlView.text = item.url
siteItemView.overflowView.showAndEnable() siteItemView.overflowView.showAndEnable()
siteItemView.changeSelected(false) siteItemView.changeSelected(false)
holder.setColorsAndIcons(item.url) icons.loadIntoView(siteItemView.iconView, IconRequest(item.url!!))
} }
} }
@Test @Test
fun `binds views for selected item`() { fun `binds views for selected item for item`() {
val mode = BookmarkFragmentState.Mode.Selecting(setOf(item)) val mode = BookmarkFragmentState.Mode.Selecting(setOf(item))
holder.bind(item, mode) holder.bind(item, mode, BookmarkPayload())
verify { verify {
siteItemView.setSelectionInteractor(item, mode, interactor) siteItemView.setSelectionInteractor(item, mode, interactor)
@ -70,16 +105,15 @@ class BookmarkItemViewHolderTest {
siteItemView.urlView.text = item.url siteItemView.urlView.text = item.url
siteItemView.overflowView.hideAndDisable() siteItemView.overflowView.hideAndDisable()
siteItemView.changeSelected(true) siteItemView.changeSelected(true)
holder.setColorsAndIcons(item.url)
} }
} }
@Test @Test
fun `bind with payload of no changes does not rebind views`() { fun `bind with payload of no changes does not rebind views for item`() {
holder.bind( holder.bind(
item, item,
BookmarkFragmentState.Mode.Normal(), BookmarkFragmentState.Mode.Normal(),
BookmarkPayload(false, false, false, false) falsePayload
) )
verify(inverse = true) { verify(inverse = true) {
@ -88,28 +122,28 @@ class BookmarkItemViewHolderTest {
siteItemView.overflowView.showAndEnable() siteItemView.overflowView.showAndEnable()
siteItemView.overflowView.hideAndDisable() siteItemView.overflowView.hideAndDisable()
siteItemView.changeSelected(any()) siteItemView.changeSelected(any())
holder.setColorsAndIcons(item.url)
} }
verify { siteItemView.iconView wasNot Called }
} }
@Test @Test
fun `binding an item with a null title uses the url as the title`() { fun `binding an item with a null title uses the url as the title for item`() {
val item = item.copy(title = null) val item = item.copy(title = null)
holder.bind(item, BookmarkFragmentState.Mode.Normal()) holder.bind(item, BookmarkFragmentState.Mode.Normal(), BookmarkPayload())
verify { siteItemView.titleView.text = item.url } verify { siteItemView.titleView.text = item.url }
} }
@Test @Test
fun `binding an item with a blank title uses the url as the title`() { fun `binding an item with a blank title uses the url as the title for item`() {
val item = item.copy(title = " ") val item = item.copy(title = " ")
holder.bind(item, BookmarkFragmentState.Mode.Normal()) holder.bind(item, BookmarkFragmentState.Mode.Normal(), BookmarkPayload())
verify { siteItemView.titleView.text = item.url } verify { siteItemView.titleView.text = item.url }
} }
@Test @Test
fun `rebinds title if item title is null and the item url has changed`() { fun `rebinds title if item title is null and the item url has changed for item`() {
val item = item.copy(title = null) val item = item.copy(title = null)
holder.bind( holder.bind(
item, item,
@ -118,7 +152,8 @@ class BookmarkItemViewHolderTest {
titleChanged = false, titleChanged = false,
urlChanged = true, urlChanged = true,
selectedChanged = false, selectedChanged = false,
modeChanged = false modeChanged = false,
iconChanged = false
) )
) )
@ -126,7 +161,7 @@ class BookmarkItemViewHolderTest {
} }
@Test @Test
fun `rebinds title if item title is blank and the item url has changed`() { fun `rebinds title if item title is blank and the item url has changed for item`() {
val item = item.copy(title = " ") val item = item.copy(title = " ")
holder.bind( holder.bind(
item, item,
@ -135,10 +170,46 @@ class BookmarkItemViewHolderTest {
titleChanged = false, titleChanged = false,
urlChanged = true, urlChanged = true,
selectedChanged = false, selectedChanged = false,
modeChanged = false modeChanged = false,
iconChanged = false
) )
) )
verify { siteItemView.titleView.text = item.url } verify { siteItemView.titleView.text = item.url }
} }
@Test
fun `binds title and selected state for folder`() {
holder.bind(folder, BookmarkFragmentState.Mode.Normal(), BookmarkPayload())
verify {
siteItemView.titleView.text = folder.title
siteItemView.overflowView.showAndEnable()
siteItemView.changeSelected(false)
}
holder.bind(folder, BookmarkFragmentState.Mode.Selecting(setOf(folder)), BookmarkPayload())
verify {
siteItemView.titleView.text = folder.title
siteItemView.overflowView.hideAndDisable()
siteItemView.changeSelected(true)
}
}
@Test
fun `bind with payload of no changes does not rebind views for folder`() {
holder.bind(
folder,
BookmarkFragmentState.Mode.Normal(),
falsePayload
)
verify(inverse = true) {
siteItemView.titleView.text = folder.title
siteItemView.overflowView.showAndEnable()
siteItemView.overflowView.hideAndDisable()
siteItemView.changeSelected(any())
}
}
} }