Skip to content

Commit ddcbd4b

Browse files
committed
add repeat record action
1 parent 48c9355 commit ddcbd4b

File tree

26 files changed

+454
-2
lines changed

26 files changed

+454
-2
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
package com.example.util.simpletimetracker
2+
3+
import androidx.test.espresso.Espresso.onView
4+
import androidx.test.espresso.action.ViewActions.click
5+
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
6+
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
7+
import androidx.test.espresso.matcher.ViewMatchers.withId
8+
import androidx.test.espresso.matcher.ViewMatchers.withText
9+
import androidx.test.ext.junit.runners.AndroidJUnit4
10+
import com.example.util.simpletimetracker.utils.BaseUiTest
11+
import com.example.util.simpletimetracker.utils.NavUtils
12+
import com.example.util.simpletimetracker.utils.checkViewDoesNotExist
13+
import com.example.util.simpletimetracker.utils.checkViewIsDisplayed
14+
import com.example.util.simpletimetracker.utils.checkViewIsNotDisplayed
15+
import com.example.util.simpletimetracker.utils.clickOnRecyclerItem
16+
import com.example.util.simpletimetracker.utils.clickOnView
17+
import com.example.util.simpletimetracker.utils.clickOnViewWithId
18+
import com.example.util.simpletimetracker.utils.clickOnViewWithText
19+
import com.example.util.simpletimetracker.utils.longClickOnView
20+
import com.example.util.simpletimetracker.utils.nestedScrollTo
21+
import com.example.util.simpletimetracker.utils.recyclerItemCount
22+
import com.example.util.simpletimetracker.utils.tryAction
23+
import com.example.util.simpletimetracker.utils.withCardColor
24+
import com.example.util.simpletimetracker.utils.withTag
25+
import dagger.hilt.android.testing.HiltAndroidTest
26+
import kotlinx.coroutines.runBlocking
27+
import org.hamcrest.CoreMatchers.allOf
28+
import org.junit.Test
29+
import org.junit.runner.RunWith
30+
import java.util.Calendar
31+
import java.util.concurrent.TimeUnit
32+
import com.example.util.simpletimetracker.core.R as coreR
33+
import com.example.util.simpletimetracker.feature_base_adapter.R as baseR
34+
import com.example.util.simpletimetracker.feature_change_record.R as changeRecordR
35+
import com.example.util.simpletimetracker.feature_records.R as recordsR
36+
37+
@HiltAndroidTest
38+
@RunWith(AndroidJUnit4::class)
39+
class RecordActionsRepeatTest : BaseUiTest() {
40+
41+
@Test
42+
fun repeatRecord() {
43+
val name = "Name"
44+
val color = firstColor
45+
val icon = firstIcon
46+
val comment = "Some_comment"
47+
val tag = "Tag"
48+
val fullName = "$name - $tag"
49+
val calendar = Calendar.getInstance()
50+
51+
// Setup
52+
val current = calendar.timeInMillis
53+
val difference = TimeUnit.MINUTES.toMillis(30)
54+
val timeStartedTimestamp = current - difference
55+
val timeStartedPreview = timeStartedTimestamp.formatTime()
56+
val timeEndedPreview = current.formatTime()
57+
val timeRangePreview = (current - timeStartedTimestamp).formatInterval()
58+
59+
testUtils.addActivity(name = name, color = color, icon = icon)
60+
testUtils.addRecordTag(tag)
61+
testUtils.addRecord(
62+
typeName = name,
63+
timeStarted = timeStartedTimestamp,
64+
timeEnded = current,
65+
tagNames = listOf(tag),
66+
comment = comment
67+
)
68+
69+
// Check record
70+
NavUtils.openRecordsScreen()
71+
checkRecord(fullName, timeStartedPreview, timeEndedPreview, timeRangePreview, comment)
72+
73+
// Repeat
74+
clickOnViewWithText(fullName)
75+
clickOnViewWithText(coreR.string.change_record_actions_hint)
76+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
77+
78+
// Check record still there
79+
checkRecord(fullName, timeStartedPreview, timeEndedPreview, timeRangePreview, comment)
80+
81+
// Check running record
82+
NavUtils.openRunningRecordsScreen()
83+
checkRunningRecord(fullName, current.formatTime(), comment)
84+
}
85+
86+
@Test
87+
fun repeatUntrackedRecord() {
88+
val name = "Name"
89+
val calendar = Calendar.getInstance()
90+
91+
// Setup
92+
val current = calendar.timeInMillis
93+
val startOfDay = calendar.getMillis(0, 0)
94+
val timeStartedPreview = startOfDay.formatTime()
95+
val timeEndedPreview = current.formatTime()
96+
val timeRangePreview = (current - startOfDay).formatInterval()
97+
98+
testUtils.addActivity(name)
99+
val yesterday = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1)
100+
testUtils.addRecord(typeName = name, timeStarted = yesterday, timeEnded = yesterday)
101+
runBlocking { prefsInteractor.setShowUntrackedInRecords(true) }
102+
NavUtils.openRecordsScreen()
103+
104+
// Open untracked time
105+
checkViewIsDisplayed(
106+
allOf(
107+
withId(baseR.id.viewRecordItem),
108+
hasDescendant(withText(coreR.string.untracked_time_name)),
109+
hasDescendant(withText(timeStartedPreview)),
110+
hasDescendant(withText(timeEndedPreview)),
111+
hasDescendant(withText(timeRangePreview)),
112+
isCompletelyDisplayed()
113+
)
114+
)
115+
onView(allOf(withId(recordsR.id.rvRecordsList), isCompletelyDisplayed()))
116+
.check(recyclerItemCount(2))
117+
clickOnViewWithText(coreR.string.untracked_time_name)
118+
119+
// Repeat untracked doesn't work
120+
clickOnViewWithText(coreR.string.change_record_actions_hint)
121+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
122+
clickOnViewWithId(com.google.android.material.R.id.snackbar_text)
123+
clickOnViewWithText(coreR.string.change_record_actions_hint)
124+
125+
// Select activity
126+
clickOnViewWithText(coreR.string.change_record_type_field)
127+
clickOnRecyclerItem(changeRecordR.id.rvChangeRecordType, withText(name))
128+
129+
// Repeat
130+
clickOnViewWithText(coreR.string.change_record_actions_hint)
131+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
132+
val runningRecordTimeStartedPreview = System.currentTimeMillis().formatTime()
133+
134+
checkViewIsDisplayed(
135+
allOf(
136+
withId(baseR.id.viewRunningRecordItem),
137+
hasDescendant(withText(name)),
138+
hasDescendant(withText(runningRecordTimeStartedPreview)),
139+
isCompletelyDisplayed()
140+
)
141+
)
142+
checkViewDoesNotExist(allOf(withText(coreR.string.untracked_time_name), isCompletelyDisplayed()))
143+
onView(allOf(withId(recordsR.id.rvRecordsList), isCompletelyDisplayed()))
144+
.check(recyclerItemCount(3))
145+
146+
NavUtils.openRunningRecordsScreen()
147+
checkViewIsDisplayed(
148+
allOf(
149+
withId(baseR.id.viewRunningRecordItem),
150+
hasDescendant(withText(name)),
151+
hasDescendant(withText(runningRecordTimeStartedPreview)),
152+
isCompletelyDisplayed()
153+
)
154+
)
155+
}
156+
157+
@Test
158+
fun repeatNewRecord() {
159+
val name = "Name"
160+
val calendar = Calendar.getInstance()
161+
162+
// Setup
163+
val current = calendar.timeInMillis
164+
val difference = TimeUnit.HOURS.toMillis(1)
165+
val timeStartedTimestamp = current - difference
166+
val timeStartedPreview = timeStartedTimestamp.formatTime()
167+
168+
testUtils.addActivity(name)
169+
NavUtils.openRecordsScreen()
170+
171+
// Open add new record
172+
onView(allOf(withId(recordsR.id.rvRecordsList), isCompletelyDisplayed()))
173+
.check(recyclerItemCount(1))
174+
clickOnViewWithId(recordsR.id.btnRecordAdd)
175+
176+
// Repeat untracked doesn't work
177+
clickOnViewWithText(coreR.string.change_record_actions_hint)
178+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
179+
clickOnViewWithId(com.google.android.material.R.id.snackbar_text)
180+
clickOnViewWithText(coreR.string.change_record_actions_hint)
181+
182+
// Select activity
183+
clickOnViewWithText(coreR.string.change_record_type_field)
184+
clickOnRecyclerItem(changeRecordR.id.rvChangeRecordType, withText(name))
185+
186+
// Repeat
187+
clickOnViewWithText(coreR.string.change_record_actions_hint)
188+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
189+
val runningRecordTimeStartedPreview = System.currentTimeMillis().formatTime()
190+
191+
checkViewIsDisplayed(
192+
allOf(
193+
withId(baseR.id.viewRecordItem),
194+
hasDescendant(withText(name)),
195+
hasDescendant(withText(timeStartedPreview)),
196+
hasDescendant(withText(runningRecordTimeStartedPreview)),
197+
isCompletelyDisplayed()
198+
)
199+
)
200+
checkViewIsDisplayed(
201+
allOf(
202+
withId(baseR.id.viewRunningRecordItem),
203+
hasDescendant(withText(name)),
204+
hasDescendant(withText(runningRecordTimeStartedPreview)),
205+
isCompletelyDisplayed()
206+
)
207+
)
208+
onView(allOf(withId(recordsR.id.rvRecordsList), isCompletelyDisplayed()))
209+
.check(recyclerItemCount(3))
210+
211+
NavUtils.openRunningRecordsScreen()
212+
checkViewIsDisplayed(
213+
allOf(
214+
withId(baseR.id.viewRunningRecordItem),
215+
hasDescendant(withText(name)),
216+
hasDescendant(withText(runningRecordTimeStartedPreview)),
217+
isCompletelyDisplayed()
218+
)
219+
)
220+
}
221+
222+
@Test
223+
fun repeatRunningRecord() {
224+
val name = "Name"
225+
226+
// Setup
227+
testUtils.addActivity(name)
228+
Thread.sleep(1000)
229+
tryAction {
230+
clickOnView(
231+
allOf(withId(baseR.id.viewRecordTypeItem), hasDescendant(withText(name)))
232+
)
233+
}
234+
tryAction {
235+
longClickOnView(
236+
allOf(withId(baseR.id.viewRunningRecordItem), hasDescendant(withText(name)), isCompletelyDisplayed())
237+
)
238+
}
239+
240+
// Try continue record
241+
clickOnViewWithText(coreR.string.change_record_actions_hint)
242+
checkViewIsNotDisplayed(withText(coreR.string.change_record_repeat))
243+
}
244+
245+
@Test
246+
fun repeatRecordSameAsAlreadyRunning() {
247+
val name = "Name"
248+
249+
// Setup
250+
testUtils.addActivity(name)
251+
testUtils.addRunningRecord(name)
252+
NavUtils.openRecordsScreen()
253+
254+
// Repeat
255+
clickOnViewWithId(recordsR.id.btnRecordAdd)
256+
clickOnViewWithText(coreR.string.change_record_type_field)
257+
clickOnRecyclerItem(changeRecordR.id.rvChangeRecordType, withText(name))
258+
clickOnViewWithText(coreR.string.change_record_actions_hint)
259+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
260+
val runningRecordTimeStartedPreview = System.currentTimeMillis().formatTime()
261+
262+
// Running record stopped
263+
onView(allOf(withId(recordsR.id.rvRecordsList), isCompletelyDisplayed()))
264+
.check(recyclerItemCount(4))
265+
266+
// New running record
267+
NavUtils.openRunningRecordsScreen()
268+
checkViewIsDisplayed(
269+
allOf(
270+
withId(baseR.id.viewRunningRecordItem),
271+
hasDescendant(withText(name)),
272+
hasDescendant(withText(runningRecordTimeStartedPreview)),
273+
isCompletelyDisplayed(),
274+
)
275+
)
276+
}
277+
278+
@Test
279+
fun repeatRecordWhileMultitaskingDisabled() {
280+
val name1 = "Name1"
281+
val name2 = "Name2"
282+
283+
// Setup
284+
testUtils.addActivity(name1)
285+
testUtils.addActivity(name2)
286+
testUtils.addRunningRecord(name1)
287+
runBlocking { prefsInteractor.setAllowMultitasking(false) }
288+
NavUtils.openRecordsScreen()
289+
290+
// Repeat
291+
clickOnViewWithId(recordsR.id.btnRecordAdd)
292+
clickOnViewWithText(coreR.string.change_record_type_field)
293+
clickOnRecyclerItem(changeRecordR.id.rvChangeRecordType, withText(name2))
294+
clickOnViewWithText(coreR.string.change_record_actions_hint)
295+
onView(withText(coreR.string.change_record_repeat)).perform(nestedScrollTo(), click())
296+
297+
// Running record stopped
298+
checkViewIsDisplayed(allOf(withText(name1), isCompletelyDisplayed()))
299+
300+
// New running record
301+
NavUtils.openRunningRecordsScreen()
302+
checkViewIsDisplayed(
303+
allOf(withId(baseR.id.viewRunningRecordItem), hasDescendant(withText(name2)), isCompletelyDisplayed())
304+
)
305+
}
306+
307+
@Suppress("SameParameterValue")
308+
private fun checkRecord(
309+
name: String,
310+
timeStartedPreview: String,
311+
timeEndedPreview: String,
312+
timeRangePreview: String,
313+
comment: String,
314+
) {
315+
checkViewIsDisplayed(
316+
allOf(
317+
withId(baseR.id.viewRecordItem),
318+
withCardColor(firstColor),
319+
hasDescendant(withText(name)),
320+
hasDescendant(withTag(firstIcon)),
321+
hasDescendant(withText(timeStartedPreview)),
322+
hasDescendant(withText(timeEndedPreview)),
323+
hasDescendant(withText(timeRangePreview)),
324+
hasDescendant(withText(comment)),
325+
isCompletelyDisplayed()
326+
)
327+
)
328+
}
329+
330+
@Suppress("SameParameterValue")
331+
private fun checkRunningRecord(
332+
name: String,
333+
timeStartedPreview: String,
334+
comment: String,
335+
) {
336+
checkViewIsDisplayed(
337+
allOf(
338+
withId(baseR.id.viewRunningRecordItem),
339+
withCardColor(firstColor),
340+
hasDescendant(withText(name)),
341+
hasDescendant(withTag(firstIcon)),
342+
hasDescendant(withText(timeStartedPreview)),
343+
hasDescendant(withText(comment)),
344+
isCompletelyDisplayed()
345+
)
346+
)
347+
}
348+
349+
private fun Calendar.getMillis(hour: Int, minute: Int): Long {
350+
set(Calendar.HOUR_OF_DAY, hour)
351+
set(Calendar.MINUTE, minute)
352+
return timeInMillis
353+
}
354+
}

core/src/main/res/values-ar/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
<string name="change_record_split_hint">سيقسم التتبع الحالي إلى قسمين حسب النقطة المحددة في الوقت</string>
110110
<string name="change_record_continue">واصَل</string>
111111
<string name="change_record_continue_hint">سيلغي تتبع نقطة الوقوف ويواصل تتبع النشاط</string>
112+
<string name="change_record_repeat">@string/running_records_repeat</string>
113+
<string name="change_record_repeat_hint">سوف نكرر تتبع هذا النشاط</string>
112114
<string name="change_record_duplicate">مضاعفة</string>
113115
<string name="change_record_duplicate_hint">سينشئ نسخة مكررة من هذا التتبع</string>
114116
<string name="change_record_merge">دمج</string>

core/src/main/res/values-ca/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
<string name="change_record_split_hint">Tallarà l\'enregistrament actual en dos en el moment especificat</string>
110110
<string name="change_record_continue">Continua</string>
111111
<string name="change_record_continue_hint">Eliminarà l\'activitat actual i continuarà enregistrant aquesta activitat</string>
112+
<string name="change_record_repeat">@string/running_records_repeat</string>
113+
<string name="change_record_repeat_hint">Repetirà el seguiment d\'aquesta activitat</string>
112114
<string name="change_record_duplicate">Duplicat</string>
113115
<string name="change_record_duplicate_hint">Crearà una còpia d\'aquest registre</string>
114116
<string name="change_record_merge">Uneix</string>

core/src/main/res/values-de/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
<string name="change_record_split_hint">Schneidet den aktuellen Datensatz zum angegebenen Zeitpunkt in zwei Teile</string>
110110
<string name="change_record_continue">Fortsetzen</string>
111111
<string name="change_record_continue_hint">Wird den aktuellen Datensatz entfernen und diese Aktivität weiter verfolgen</string>
112+
<string name="change_record_repeat">@string/running_records_repeat</string>
113+
<string name="change_record_repeat_hint">Ich werde die Verfolgung dieser Aktivität wiederholen</string>
112114
<string name="change_record_duplicate">Duplikat</string>
113115
<string name="change_record_duplicate_hint">Erstellt eine Kopie dieses Datensatzes</string>
114116
<string name="change_record_merge">Verschmelzen</string>

core/src/main/res/values-es/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
<string name="change_record_split_hint">Cortará el registro actual en dos en el momento especificado</string>
110110
<string name="change_record_continue">Continuar</string>
111111
<string name="change_record_continue_hint">Eliminará el registro actual y seguirá rastreando esta actividad</string>
112+
<string name="change_record_repeat">@string/running_records_repeat</string>
113+
<string name="change_record_repeat_hint">Repetiremos el seguimiento de esta actividad</string>
112114
<string name="change_record_duplicate">Duplicada</string>
113115
<string name="change_record_duplicate_hint">Creará una copia de este registro</string>
114116
<string name="change_record_merge">Unir</string>

core/src/main/res/values-fa/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@
109109
<string name="change_record_split_hint">در زمان معین فعالیت فعلی را به دو قسمت تقسیم می کند</string>
110110
<string name="change_record_continue">ادامه</string>
111111
<string name="change_record_continue_hint">فعالیت فعلی را حذف کرده و فعالیت انتخابی را اندازه گیری می کند</string>
112+
<string name="change_record_repeat">@string/running_records_repeat</string>
113+
<string name="change_record_repeat_hint">ردیابی این فعالیت را تکرار خواهد کرد</string>
112114
<string name="change_record_duplicate">تکثیر</string>
113115
<string name="change_record_duplicate_hint">از این تاریخچه نسخه کپی می سازد</string>
114116
<string name="change_record_merge">تریکب</string>

0 commit comments

Comments
 (0)