Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
xenonnn4w committed Aug 8, 2024
1 parent a63b688 commit b8e71b8
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import timber.log.Timber
class DeckPickerWidgetConfig : FragmentActivity(), DeckSelectionListener {

private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
private lateinit var deckAdapter: WidgetConfigScreenAdapter
lateinit var deckAdapter: WidgetConfigScreenAdapter
private lateinit var deckPickerWidgetPreferences: WidgetPreferences
private val MAX_DECKS_ALLOWED = 5 // Maximum number of decks allowed in the widget

Expand Down Expand Up @@ -113,7 +113,7 @@ class DeckPickerWidgetConfig : FragmentActivity(), DeckSelectionListener {
unregisterReceiver(widgetRemovedReceiver)
}

private fun loadSavedPreferences() {
fun loadSavedPreferences() {
val selectedDeckIds = deckPickerWidgetPreferences.getSelectedDeckIdsFromPreferencesDeckPickerWidget(appWidgetId)
if (selectedDeckIds.isNotEmpty()) {
lifecycleScope.launch {
Expand Down Expand Up @@ -167,7 +167,7 @@ class DeckPickerWidgetConfig : FragmentActivity(), DeckSelectionListener {
}

/** Updates the visibility of the "no decks" placeholder and the widget configuration container */
private fun updateViewVisibility() {
fun updateViewVisibility() {
val noDecksPlaceholder = findViewById<View>(R.id.no_decks_placeholder)
val widgetConfigContainer = findViewById<View>(R.id.widgetConfigContainer)

Expand Down Expand Up @@ -208,7 +208,7 @@ class DeckPickerWidgetConfig : FragmentActivity(), DeckSelectionListener {
* to a comma-separated string, and stores it in SharedPreferences.
* It then sends a broadcast to update the widget with the new deck selection.
*/
private fun saveSelectedDecksToPreferencesDeckPickerWidget() {
fun saveSelectedDecksToPreferencesDeckPickerWidget() {
// Get the list of selected deck IDs as strings
val selectedDecks = deckAdapter.deckIds.map { it.toString() }
deckPickerWidgetPreferences.saveSelectedDecks(appWidgetId, selectedDecks)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import org.hamcrest.Matchers
import org.junit.Test
import org.junit.runner.RunWith

// TODO : To handle the DeckPickerWidgetConfig
@RunWith(AndroidJUnit4::class)
class ActivityStartupMetaTest : RobolectricTest() {
@Test
Expand All @@ -40,7 +39,6 @@ class ActivityStartupMetaTest : RobolectricTest() {
.map { it.name }
.filter { it != "com.ichi2.anki.TestCardTemplatePreviewer" }
.filter { it != "com.ichi2.anki.AnkiCardContextMenuAction" }
.filter { it != "com.ichi2.widget.DeckPickerWidgetConfig" }
.filter { it != "com.ichi2.anki.analytics.AnkiDroidCrashReportDialog" }
.filter { !it.startsWith("androidx") }
.filter { !it.startsWith("org.acra") }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*
Copyright (c) 2024 Anoop <[email protected]>
This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
* Copyright (c) 2024 Anoop <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.ichi2.anki.widget

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2024 Anoop <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.ichi2.anki.widget

import android.appwidget.AppWidgetManager
import android.content.Intent
import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleRegistry
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.ichi2.anki.R
import com.ichi2.anki.RobolectricTest
import com.ichi2.anki.dialogs.DeckSelectionDialog
import com.ichi2.widget.DeckPickerWidgetConfig
import com.ichi2.widget.WidgetPreferences
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric

@RunWith(AndroidJUnit4::class)
class DeckPickerWidgetConfigTest : RobolectricTest() {

private lateinit var activity: DeckPickerWidgetConfig
private lateinit var lifecycle: LifecycleRegistry
private lateinit var widgetPreferences: WidgetPreferences

/**
* Sets up the test environment before each test.
*
* Initializes the `DeckPickerWidgetConfig` activity and associated components like
* `LifecycleRegistry` and `WidgetPreferences`. This setup is executed before each test method.
*/
@Before
override fun setUp() {
super.setUp()
val intent = Intent(ApplicationProvider.getApplicationContext(), DeckPickerWidgetConfig::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 1)
}

activity = Robolectric.buildActivity(DeckPickerWidgetConfig::class.java, intent)
.create()
.start()
.resume()
.get()

lifecycle = LifecycleRegistry(activity)
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)

widgetPreferences = WidgetPreferences(ApplicationProvider.getApplicationContext())
}

/**
* Tests the functionality of saving selected decks to preferences.
*
* This test adds a deck to the adapter and verifies if it gets correctly saved to the
* `WidgetPreferences`.
*/
@Test
fun testSaveSelectedDecksToPreferences() {
// Add decks to adapter
val deck1 = DeckSelectionDialog.SelectableDeck(1, "Deck 1")
activity.deckAdapter.addDeck(deck1)

// Save selected decks
activity.saveSelectedDecksToPreferencesDeckPickerWidget()

// Verify saved decks
val selectedDeckIds = widgetPreferences.getSelectedDeckIdsFromPreferencesDeckPickerWidget(1)
assert(selectedDeckIds.contains(deck1.deckId))
}

/**
* Tests the loading of saved preferences into the activity's view.
*
* This test saves decks to preferences, then loads them into the activity and checks if the
* `RecyclerView` displays the correct number of items based on the saved preferences.
*/
@Test
fun testLoadSavedPreferences() {
// Save decks to preferences
val deckIds = listOf(1L)
widgetPreferences.saveSelectedDecks(1, deckIds.map { it.toString() })

// Load preferences
activity.loadSavedPreferences()

// Ensure all tasks on the UI thread are completed
Robolectric.flushForegroundThreadScheduler()

// Get the RecyclerView and its adapter
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerViewSelectedDecks)
val adapter = recyclerView.adapter

// Verify the adapter has the correct item count
assert(adapter != null && adapter.itemCount == deckIds.size)
}

/**
* Tests the visibility of different views based on the selected decks.
*
* This test checks the visibility of the placeholder and configuration container views
* before and after adding a deck.
*/
@Test
fun testUpdateViewVisibility() {
val noDecksPlaceholder = activity.findViewById<View>(R.id.no_decks_placeholder)
val widgetConfigContainer = activity.findViewById<View>(R.id.widgetConfigContainer)

// Initially, no decks should be selected
activity.updateViewVisibility()
assert(noDecksPlaceholder.visibility == View.VISIBLE)
assert(widgetConfigContainer.visibility == View.GONE)

// Add a deck and update view visibility
val deck = DeckSelectionDialog.SelectableDeck(1, "Deck 1")
activity.deckAdapter.addDeck(deck)
activity.updateViewVisibility()

assert(noDecksPlaceholder.visibility == View.GONE)
assert(widgetConfigContainer.visibility == View.VISIBLE)
}

/**
* Tests the selection of a deck.
*
* This test verifies that when a deck is selected, it gets added to the adapter and displayed
* in the `RecyclerView`.
*/
@Test
fun testOnDeckSelected() {
val deck = DeckSelectionDialog.SelectableDeck(1, "Deck 1")
activity.onDeckSelected(deck)

// Verify deck is added to adapter
val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerViewSelectedDecks)
assert(recyclerView.adapter?.itemCount == 1)
}
}

0 comments on commit b8e71b8

Please sign in to comment.