Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
For #8765: Use shared list widget in exceptions (#14113)
Browse files Browse the repository at this point in the history
* For #8765: Add resource for shared list widget

* For #8765: Use shared list widget in exceptions
  • Loading branch information
NotWoods authored Aug 25, 2020
1 parent ac2d65c commit bb3fd4e
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.annotation.StringRes
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import mozilla.components.ui.widgets.WidgetSiteItemView
import org.mozilla.fenix.exceptions.viewholders.ExceptionsDeleteButtonViewHolder
import org.mozilla.fenix.exceptions.viewholders.ExceptionsHeaderViewHolder
import org.mozilla.fenix.exceptions.viewholders.ExceptionsListItemViewHolder
Expand Down Expand Up @@ -67,7 +68,7 @@ abstract class ExceptionsAdapter<T : Any>(
ExceptionsHeaderViewHolder.LAYOUT_ID ->
ExceptionsHeaderViewHolder(view, headerDescriptionResource)
ExceptionsListItemViewHolder.LAYOUT_ID ->
ExceptionsListItemViewHolder(view, interactor)
ExceptionsListItemViewHolder(view as WidgetSiteItemView, interactor)
else -> throw IllegalStateException()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,41 @@

package org.mozilla.fenix.exceptions.viewholders

import android.view.View
import kotlinx.android.synthetic.main.exception_item.*
import androidx.recyclerview.widget.RecyclerView
import mozilla.components.browser.icons.BrowserIcons
import mozilla.components.ui.widgets.WidgetSiteItemView
import org.mozilla.fenix.R
import org.mozilla.fenix.exceptions.ExceptionsInteractor
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.loadIntoView
import org.mozilla.fenix.utils.view.ViewHolder

/**
* View holder for a single website that is exempted from Tracking Protection or Logins.
*/
class ExceptionsListItemViewHolder<T : Any>(
view: View,
private val view: WidgetSiteItemView,
private val interactor: ExceptionsInteractor<T>,
private val icons: BrowserIcons = view.context.components.core.icons
) : ViewHolder(view) {
) : RecyclerView.ViewHolder(view) {

private lateinit var item: T

init {
delete_exception.setOnClickListener {
view.setSecondaryButton(
icon = R.drawable.ic_close,
contentDescription = R.string.history_delete_item
) {
interactor.onDeleteOne(item)
}
}

fun bind(item: T, url: String) {
this.item = item
webAddressView.text = url
icons.loadIntoView(favicon_image, url)
view.setText(label = url, caption = null)
icons.loadIntoView(view.iconView, url)
}

companion object {
const val LAYOUT_ID = R.layout.exception_item
const val LAYOUT_ID = R.layout.site_list_item
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/layout/site_list_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<mozilla.components.ui.widgets.WidgetSiteItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/site_list_item"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
1 change: 1 addition & 0 deletions app/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<color name="primary_text_normal_theme">@color/primary_text_dark_theme</color>
<color name="secondary_text_normal_theme">@color/secondary_text_dark_theme</color>
<color name="contrast_text_normal_theme">@color/contrast_text_dark_theme</color>
<color name="caption_text_normal_theme">@color/caption_text_dark_theme</color>
<color name="foundation_normal_theme">@color/foundation_dark_theme</color>
<color name="above_normal_theme">@color/above_dark_theme</color>
<color name="inset_normal_theme">@color/inset_dark_theme</color>
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<color name="primary_text_light_theme">#20123A</color>
<color name="secondary_text_light_theme">@color/photonGrey50</color>
<color name="contrast_text_light_theme">@color/primary_text_dark_theme</color>
<color name="caption_text_light_theme">@color/photonLightGrey90</color>
<color name="foundation_light_theme">#F9F9FB</color>
<color name="inset_light_theme">#E0E0E6</color>
<color name="above_light_theme">#FFF</color>
Expand Down Expand Up @@ -85,6 +86,7 @@
<color name="primary_text_dark_theme">#FBFBFE</color>
<color name="secondary_text_dark_theme">#A7A2B7</color>
<color name="contrast_text_dark_theme">@color/primary_text_dark_theme</color>
<color name="caption_text_dark_theme">@color/photonLightGrey70</color>
<color name="foundation_dark_theme">#1C1B22</color>
<color name="inset_dark_theme">#32313C</color>
<color name="above_dark_theme">#32313C</color>
Expand Down Expand Up @@ -151,6 +153,7 @@
<color name="primary_text_private_theme">#FBFBFE</color>
<color name="secondary_text_private_theme">#A7A2B7</color>
<color name="contrast_text_private_theme">@color/primary_text_private_theme</color>
<color name="caption_text_private_theme">@color/photonLightGrey70</color>
<color name="foundation_private_theme">#261E4B</color>
<color name="inset_private_theme">@color/photonInk50</color>
<color name="above_private_theme">@color/photonInk50</color>
Expand Down Expand Up @@ -209,6 +212,7 @@
<color name="primary_text_normal_theme">@color/primary_text_light_theme</color>
<color name="secondary_text_normal_theme">@color/secondary_text_light_theme</color>
<color name="contrast_text_normal_theme">@color/contrast_text_light_theme</color>
<color name="caption_text_normal_theme">@color/caption_text_light_theme</color>
<color name="foundation_normal_theme">@color/foundation_light_theme</color>
<color name="above_normal_theme">@color/above_light_theme</color>
<color name="inset_normal_theme">@color/inset_light_theme</color>
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@
<item name="awesomeBarIndicatorBookmarkColor">@color/search_suggestion_indicator_icon_bookmark_color_normal_theme</item>

<!-- Shared widget colors -->
<item name="mozac_primary_text_color">@color/primary_text_normal_theme</item>
<item name="mozac_caption_text_color">@color/caption_text_normal_theme</item>
<item name="mozac_widget_favicon_background_color">@color/mozac_widget_favicon_background_normal_theme</item>
<item name="mozac_widget_favicon_border_color">@color/mozac_widget_favicon_border_normal_theme</item>

Expand Down Expand Up @@ -221,6 +223,8 @@
<item name="awesomeBarIndicatorBookmarkColor">@color/search_suggestion_indicator_icon_bookmark_color_dark_theme</item>

<!-- Shared widget colors -->
<item name="mozac_primary_text_color">@color/primary_text_private_theme</item>
<item name="mozac_caption_text_color">@color/caption_text_private_theme</item>
<item name="mozac_widget_favicon_background_color">@color/mozac_widget_favicon_background_private_theme</item>
<item name="mozac_widget_favicon_border_color">@color/mozac_widget_favicon_border_private_theme</item>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
package org.mozilla.fenix.exceptions.viewholders

import android.view.View
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.TextView
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.every
Expand All @@ -18,55 +15,49 @@ import io.mockk.slot
import io.mockk.verify
import mozilla.components.browser.icons.BrowserIcons
import mozilla.components.browser.icons.IconRequest
import mozilla.components.ui.widgets.WidgetSiteItemView
import org.junit.Before
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.exceptions.ExceptionsInteractor

class ExceptionsListItemViewHolderTest {

@MockK private lateinit var view: View
@MockK(relaxUnitFun = true) private lateinit var url: TextView
@MockK(relaxUnitFun = true) private lateinit var deleteButton: ImageButton
@MockK private lateinit var favicon: ImageView
@MockK(relaxed = true) private lateinit var view: WidgetSiteItemView
@MockK private lateinit var icons: BrowserIcons
@MockK private lateinit var interactor: ExceptionsInteractor<Exception>

@Before
fun setup() {
MockKAnnotations.init(this)

every { view.findViewById<TextView>(R.id.webAddressView) } returns url
every { view.findViewById<ImageButton>(R.id.delete_exception) } returns deleteButton
every { view.findViewById<ImageView>(R.id.favicon_image) } returns favicon
every { icons.loadIntoView(favicon, any()) } returns mockk()
every { icons.loadIntoView(view.iconView, any()) } returns mockk()
}

@Test
fun `sets url text and loads favicon - mozilla`() {
ExceptionsListItemViewHolder(view, interactor, icons)
.bind(Exception(), url = "mozilla.org")
verify { url.text = "mozilla.org" }
verify { icons.loadIntoView(favicon, IconRequest("mozilla.org")) }
verify { view.setText(label = "mozilla.org", caption = null) }
verify { icons.loadIntoView(view.iconView, IconRequest("mozilla.org")) }
}

@Test
fun `sets url text and loads favicon - example`() {
ExceptionsListItemViewHolder(view, interactor, icons)
.bind(Exception(), url = "https://example.com/icon.svg")
verify { url.text = "https://example.com/icon.svg" }
verify { icons.loadIntoView(favicon, IconRequest("https://example.com/icon.svg")) }
verify { view.setText(label = "https://example.com/icon.svg", caption = null) }
verify { icons.loadIntoView(view.iconView, IconRequest("https://example.com/icon.svg")) }
}

@Test
fun `delete button calls interactor`() {
val slot = slot<View.OnClickListener>()
val slot = slot<(View) -> Unit>()
val exception = Exception()
every { deleteButton.setOnClickListener(capture(slot)) } just Runs
every { view.setSecondaryButton(any(), any<Int>(), capture(slot)) } just Runs
ExceptionsListItemViewHolder(view, interactor, icons).bind(exception, url = "mozilla.org")

every { interactor.onDeleteOne(exception) } just Runs
slot.captured.onClick(mockk())
slot.captured.invoke(mockk())
verify { interactor.onDeleteOne(exception) }
}

Expand Down

0 comments on commit bb3fd4e

Please sign in to comment.