Skip to content

Commit 45267bf

Browse files
david-allisoncriticalAY
authored andcommitted
test: fix SetDueDateDialogTest
Dialog had changed since tests were written * Lifecycle.State.CREATED * Use CardIds * Fix labels * Use strongly-typed value for comparison `SetDueDateDays("1-2!")` Assisted-by: Claude Opus 4.7
1 parent 35ea506 commit 45267bf

1 file changed

Lines changed: 25 additions & 17 deletions

File tree

AnkiDroid/src/test/java/com/ichi2/anki/scheduling/SetDueDateDialogTest.kt

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,21 @@ import androidx.appcompat.app.AlertDialog
2323
import androidx.fragment.app.testing.launchFragment
2424
import androidx.lifecycle.Lifecycle
2525
import androidx.test.ext.junit.runners.AndroidJUnit4
26+
import androidx.viewpager2.widget.ViewPager2
2627
import com.google.android.material.tabs.TabLayout
2728
import com.google.android.material.textfield.TextInputLayout
2829
import com.ichi2.anki.R
2930
import com.ichi2.anki.RobolectricTest
31+
import com.ichi2.anki.RobolectricTest.Companion.advanceRobolectricLooper
3032
import com.ichi2.anki.common.annotations.NeedsTest
31-
import com.ichi2.anki.libanki.CardId
33+
import com.ichi2.anki.libanki.sched.SetDueDateDays
3234
import com.ichi2.anki.scheduling.SetDueDateViewModel.Tab
3335
import com.ichi2.utils.positiveButton
3436
import org.hamcrest.MatcherAssert.assertThat
3537
import org.hamcrest.Matchers.equalTo
36-
import org.junit.Ignore
3738
import org.junit.Test
3839
import org.junit.runner.RunWith
3940

40-
@Ignore("selectTab(1) does not attach Ids")
41-
@NeedsTest("get the tests working")
4241
@NeedsTest("set interval to same value visibility with FSRS")
4342
@RunWith(AndroidJUnit4::class)
4443
class SetDueDateDialogTest : RobolectricTest() {
@@ -56,6 +55,7 @@ class SetDueDateDialogTest : RobolectricTest() {
5655
testDialog {
5756
selectTab(0)
5857
assertThat(singleDayTextLayout.suffixText, equalTo("days"))
58+
selectTab(1)
5959
assertThat(dateRangeStartLayout.suffixText, equalTo("days"))
6060
assertThat(dateRangeEndLayout.suffixText, equalTo("days"))
6161
}
@@ -89,18 +89,18 @@ class SetDueDateDialogTest : RobolectricTest() {
8989

9090
@Test
9191
fun `singular text`() =
92-
testDialog(cards = listOf(1)) {
92+
testDialog(cardCount = 1) {
9393
selectTab(0)
94-
assertThat(singleDayTextLayout.hint, equalTo("Show card in"))
94+
assertThat(dateSingleLabel.text, equalTo("Show card in"))
9595
selectTab(1)
9696
assertThat(dateRangeLabel.text, equalTo("Show card in range"))
9797
}
9898

9999
@Test
100100
fun `plural text`() =
101-
testDialog(cards = listOf(1, 2)) {
101+
testDialog(cardCount = 2) {
102102
selectTab(0)
103-
assertThat(singleDayTextLayout.hint, equalTo("Show cards in"))
103+
assertThat(dateSingleLabel.text, equalTo("Show cards in"))
104104
selectTab(1)
105105
assertThat(dateRangeLabel.text, equalTo("Show cards in range"))
106106
}
@@ -114,7 +114,7 @@ class SetDueDateDialogTest : RobolectricTest() {
114114
dateRangeEnd.setText("2")
115115
changeInterval.isChecked = true
116116

117-
assertThat(viewModel.calculateDaysParameter(), equalTo("1-2!"))
117+
assertThat(viewModel.calculateDaysParameter(), equalTo(SetDueDateDays("1-2!")))
118118
}
119119

120120
@Test
@@ -142,17 +142,19 @@ class SetDueDateDialogTest : RobolectricTest() {
142142
}
143143

144144
private fun testDialog(
145-
cards: List<CardId> = listOf(1),
145+
cardCount: Int = 1,
146146
action: SetDueDateDialog.() -> Unit,
147147
) = runTest {
148-
val dialog = SetDueDateDialog.newInstance(cards)
148+
val cardIds = List(cardCount) { addBasicNote().firstCard().id }
149+
val dialog = SetDueDateDialog.newInstance(cardIds)
149150
launchFragment(
150151
themeResId = R.style.Base_Theme_Light,
151152
fragmentArgs = dialog.arguments,
152153
) {
153154
return@launchFragment dialog
154155
}.apply {
155-
moveToState(Lifecycle.State.CREATED)
156+
moveToState(Lifecycle.State.RESUMED)
157+
advanceRobolectricLooper()
156158
this.onFragment {
157159
action(it)
158160
}
@@ -170,12 +172,15 @@ fun TabLayout.selectTab(index: Int) =
170172
{ "Tab $index not found" }
171173
.also { tab -> selectTab(tab) }
172174

175+
/**
176+
* Selects a tab by index, and waits for the [androidx.viewpager2.adapter.FragmentStateAdapter]
177+
* to attach the page's fragment view to the dialog's view hierarchy.
178+
*/
173179
fun SetDueDateDialog.selectTab(index: Int) {
174-
val tabLayout = dialog!!.findViewById<TabLayout>(R.id.tab_layout)
175-
tabLayout.selectTab(index)
176-
if (index == 1) {
177-
TODO("Flaky: FragmentStateAdapter does not include views")
178-
}
180+
val viewPager = dialog!!.findViewById<ViewPager2>(R.id.set_due_date_pager)
181+
viewPager.setCurrentItem(index, false)
182+
// FragmentStateAdapter attaches fragments asynchronously via the main looper
183+
advanceRobolectricLooper()
179184
}
180185

181186
val SetDueDateDialog.positiveButtonIsEnabled get() =
@@ -203,3 +208,6 @@ val SetDueDateDialog.changeInterval: CheckBox get() =
203208

204209
val SetDueDateDialog.dateRangeLabel: TextView get() =
205210
dialog!!.findViewById(R.id.date_range_label)
211+
212+
val SetDueDateDialog.dateSingleLabel: TextView get() =
213+
dialog!!.findViewById(R.id.date_single_label)

0 commit comments

Comments
 (0)