Skip to content

Commit 50e8b70

Browse files
committed
update tests
1 parent cdb7ce9 commit 50e8b70

File tree

5 files changed

+430
-21
lines changed

5 files changed

+430
-21
lines changed

domain/src/test/java/com/example/util/simpletimetracker/domain/complexRule/interactor/ComplexRuleProcessActionInteractorTest.kt

Lines changed: 134 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.util.simpletimetracker.domain.complexRule.interactor
22

3+
import com.example.util.simpletimetracker.domain.base.ResultContainer
34
import com.example.util.simpletimetracker.domain.complexRule.model.ComplexRule
45
import com.example.util.simpletimetracker.domain.daysOfWeek.interactor.GetCurrentDayInteractor
56
import com.example.util.simpletimetracker.domain.daysOfWeek.model.DayOfWeek
@@ -33,6 +34,7 @@ class ComplexRuleProcessActionInteractorTest {
3334

3435
@Test
3536
fun mergesSelectOnStart(): Unit = runBlocking {
37+
// Given
3638
val rule1 = assignTagRule(
3739
actionAssignTagValues = listOf(tag(10L, numericValue = null)),
3840
actionAssignTagValueOnStartIds = setOf(10L),
@@ -41,54 +43,169 @@ class ComplexRuleProcessActionInteractorTest {
4143
actionAssignTagValues = listOf(tag(20L, numericValue = null)),
4244
actionAssignTagValueOnStartIds = setOf(20L),
4345
)
44-
4546
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(rule1, rule2))
4647

48+
// When
4749
val result = subject.processRules(
4850
timeStarted = 0L,
4951
startingTypeId = startingTypeId,
5052
currentTypeIds = currentTypeIds,
5153
)
5254

55+
// Then
5356
assertEquals(setOf(10L, 20L), result.tagIdsToSelectValueOnStart)
5457
}
5558

5659
@Test
5760
fun dropsSelectOnStartWhenNumericExists(): Unit = runBlocking {
61+
// Given
5862
val rule = assignTagRule(
5963
actionAssignTagValues = listOf(tag(30L, numericValue = 3.5)),
6064
actionAssignTagValueOnStartIds = setOf(30L),
6165
)
62-
6366
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(rule))
6467

68+
// When
6569
val result = subject.processRules(
6670
timeStarted = 0L,
6771
startingTypeId = startingTypeId,
6872
currentTypeIds = currentTypeIds,
6973
)
7074

75+
// Then
7176
assertEquals(emptySet<Long>(), result.tagIdsToSelectValueOnStart)
7277
}
7378

7479
@Test
7580
fun ignoresSelectOnStartWithoutMergedTag(): Unit = runBlocking {
81+
// Given
7682
val rule = assignTagRule(
7783
actionAssignTagValues = listOf(tag(40L, numericValue = null)),
7884
actionAssignTagValueOnStartIds = setOf(40L, 99L),
7985
)
80-
8186
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(rule))
8287

88+
// When
8389
val result = subject.processRules(
8490
timeStarted = 0L,
8591
startingTypeId = startingTypeId,
8692
currentTypeIds = currentTypeIds,
8793
)
8894

95+
// Then
8996
assertEquals(setOf(40L), result.tagIdsToSelectValueOnStart)
9097
}
9198

99+
@Test
100+
fun mergesAssignedTags(): Unit = runBlocking {
101+
// Given
102+
val rule1 = assignTagRule(
103+
actionAssignTagValues = listOf(tag(50L, numericValue = null)),
104+
actionAssignTagValueOnStartIds = emptySet(),
105+
)
106+
val rule2 = assignTagRule(
107+
actionAssignTagValues = listOf(tag(60L, numericValue = null)),
108+
actionAssignTagValueOnStartIds = emptySet(),
109+
)
110+
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(rule1, rule2))
111+
112+
// When
113+
val result = subject.processRules(
114+
timeStarted = 0L,
115+
startingTypeId = startingTypeId,
116+
currentTypeIds = currentTypeIds,
117+
)
118+
119+
// Then
120+
assertEquals(
121+
listOf(tag(50L, numericValue = null), tag(60L, numericValue = null)),
122+
result.tags,
123+
)
124+
}
125+
126+
@Test
127+
fun numericValuesOverrideEarlierNull(): Unit = runBlocking {
128+
// Given
129+
val ruleWithNull = assignTagRule(
130+
actionAssignTagValues = listOf(tag(70L, numericValue = null)),
131+
actionAssignTagValueOnStartIds = emptySet(),
132+
)
133+
val ruleWithNumeric = assignTagRule(
134+
actionAssignTagValues = listOf(tag(70L, numericValue = 9.0)),
135+
actionAssignTagValueOnStartIds = emptySet(),
136+
)
137+
val ruleWithLateNull = assignTagRule(
138+
actionAssignTagValues = listOf(tag(70L, numericValue = null)),
139+
actionAssignTagValueOnStartIds = emptySet(),
140+
)
141+
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(ruleWithNull, ruleWithNumeric, ruleWithLateNull))
142+
143+
// When
144+
val result = subject.processRules(
145+
timeStarted = 0L,
146+
startingTypeId = startingTypeId,
147+
currentTypeIds = currentTypeIds,
148+
)
149+
150+
// Then
151+
assertEquals(listOf(tag(70L, numericValue = 9.0)), result.tags)
152+
}
153+
154+
@Test
155+
fun allowsMultitaskingWhenAllowRuleExistsEvenWithDisallow(): Unit = runBlocking {
156+
// Given
157+
val disallowRule = multitaskingRule(ComplexRule.Action.DisallowMultitasking)
158+
val allowRule = multitaskingRule(ComplexRule.Action.AllowMultitasking)
159+
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(disallowRule, allowRule))
160+
161+
// When
162+
val result = subject.processRules(
163+
timeStarted = 0L,
164+
startingTypeId = startingTypeId,
165+
currentTypeIds = currentTypeIds,
166+
)
167+
168+
// Then
169+
assertEquals(ResultContainer.Defined(true), result.isMultitaskingAllowed)
170+
}
171+
172+
@Test
173+
fun disallowsMultitaskingWhenOnlyDisallowRulesRun(): Unit = runBlocking {
174+
// Given
175+
val rule = multitaskingRule(ComplexRule.Action.DisallowMultitasking)
176+
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(rule))
177+
178+
// When
179+
val result = subject.processRules(
180+
timeStarted = 0L,
181+
startingTypeId = startingTypeId,
182+
currentTypeIds = currentTypeIds,
183+
)
184+
185+
// Then
186+
assertEquals(ResultContainer.Defined(false), result.isMultitaskingAllowed)
187+
}
188+
189+
@Test
190+
fun leavesMultitaskingUndefinedWhenNoAllowOrDisallowRules(): Unit = runBlocking {
191+
// Given
192+
val rule = assignTagRule(
193+
actionAssignTagValues = listOf(tag(80L, numericValue = null)),
194+
actionAssignTagValueOnStartIds = emptySet(),
195+
)
196+
`when`(complexRuleInteractor.getAll()).thenReturn(listOf(rule))
197+
198+
// When
199+
val result = subject.processRules(
200+
timeStarted = 0L,
201+
startingTypeId = startingTypeId,
202+
currentTypeIds = currentTypeIds,
203+
)
204+
205+
// Then
206+
assertEquals(ResultContainer.Undefined, result.isMultitaskingAllowed)
207+
}
208+
92209
private fun assignTagRule(
93210
actionAssignTagValues: List<RecordBase.Tag>,
94211
actionAssignTagValueOnStartIds: Set<Long>,
@@ -112,4 +229,18 @@ class ComplexRuleProcessActionInteractorTest {
112229
): RecordBase.Tag {
113230
return RecordBase.Tag(tagId = tagId, numericValue = numericValue)
114231
}
232+
233+
private fun multitaskingRule(action: ComplexRule.Action): ComplexRule {
234+
return ComplexRule(
235+
id = 0L,
236+
disabled = false,
237+
action = action,
238+
actionDisallowOnlyPrevious = false,
239+
actionAssignTagValues = emptyList(),
240+
actionAssignTagValueOnStartIds = emptySet(),
241+
conditionStartingTypeIds = setOf(startingTypeId),
242+
conditionCurrentTypeIds = currentTypeIds,
243+
conditionDaysOfWeek = setOf(currentDay),
244+
)
245+
}
115246
}

domain/src/test/java/com/example/util/simpletimetracker/domain/mapper/AddRunningRecordMediatorTest.kt renamed to domain/src/test/java/com/example/util/simpletimetracker/domain/record/interactor/AddRunningRecordMediatorTest.kt

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
1-
package com.example.util.simpletimetracker.domain.mapper
1+
package com.example.util.simpletimetracker.domain.record.interactor
22

3-
import com.example.util.simpletimetracker.domain.notifications.interactor.ActivityStartedStoppedBroadcastInteractor
4-
import com.example.util.simpletimetracker.domain.record.interactor.AddRecordMediator
5-
import com.example.util.simpletimetracker.domain.record.interactor.AddRunningRecordMediator
3+
import com.example.util.simpletimetracker.domain.base.CurrentTimestampProvider
4+
import com.example.util.simpletimetracker.domain.base.ResultContainer
5+
import com.example.util.simpletimetracker.domain.color.model.AppColor
66
import com.example.util.simpletimetracker.domain.complexRule.interactor.ComplexRuleProcessActionInteractor
7+
import com.example.util.simpletimetracker.domain.notifications.interactor.ActivityStartedStoppedBroadcastInteractor
78
import com.example.util.simpletimetracker.domain.notifications.interactor.NotificationGoalCountInteractor
9+
import com.example.util.simpletimetracker.domain.notifications.interactor.UpdateExternalViewsInteractor
810
import com.example.util.simpletimetracker.domain.pomodoro.interactor.PomodoroStartInteractor
911
import com.example.util.simpletimetracker.domain.prefs.interactor.PrefsInteractor
10-
import com.example.util.simpletimetracker.domain.record.interactor.RecordInteractor
11-
import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeInteractor
12-
import com.example.util.simpletimetracker.domain.recordTag.interactor.RecordTypeToDefaultTagInteractor
13-
import com.example.util.simpletimetracker.domain.record.interactor.RemoveRunningRecordMediator
14-
import com.example.util.simpletimetracker.domain.record.interactor.RunningRecordInteractor
15-
import com.example.util.simpletimetracker.domain.record.interactor.ShouldShowRecordDataSelectionInteractor
16-
import com.example.util.simpletimetracker.domain.notifications.interactor.UpdateExternalViewsInteractor
17-
import com.example.util.simpletimetracker.domain.color.model.AppColor
1812
import com.example.util.simpletimetracker.domain.record.model.Record
13+
import com.example.util.simpletimetracker.domain.record.model.RecordBase
1914
import com.example.util.simpletimetracker.domain.record.model.RecordDataSelectionDialogResult
20-
import com.example.util.simpletimetracker.domain.recordType.model.RecordType
21-
import com.example.util.simpletimetracker.domain.base.ResultContainer
2215
import com.example.util.simpletimetracker.domain.record.model.RunningRecord
23-
import com.example.util.simpletimetracker.domain.base.CurrentTimestampProvider
24-
import com.example.util.simpletimetracker.domain.record.interactor.ProcessRulesInteractor
25-
import com.example.util.simpletimetracker.domain.record.model.RecordBase
16+
import com.example.util.simpletimetracker.domain.recordTag.interactor.RecordTypeToDefaultTagInteractor
17+
import com.example.util.simpletimetracker.domain.recordType.interactor.RecordTypeInteractor
18+
import com.example.util.simpletimetracker.domain.recordType.model.RecordType
2619
import kotlinx.coroutines.runBlocking
2720
import org.junit.Before
2821
import org.junit.Test
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.example.util.simpletimetracker.domain.record.interactor
2+
3+
import com.example.util.simpletimetracker.domain.base.ResultContainer
4+
import com.example.util.simpletimetracker.domain.base.suspendLazy
5+
import com.example.util.simpletimetracker.domain.complexRule.interactor.ComplexRuleProcessActionInteractor
6+
import com.example.util.simpletimetracker.domain.record.model.Record
7+
import com.example.util.simpletimetracker.domain.record.model.RecordBase
8+
import com.example.util.simpletimetracker.domain.recordTag.interactor.RecordTypeToDefaultTagInteractor
9+
import kotlinx.coroutines.runBlocking
10+
import org.junit.Assert.assertEquals
11+
import org.junit.Assert.assertSame
12+
import org.junit.Test
13+
import org.mockito.kotlin.any
14+
import org.mockito.kotlin.never
15+
import org.mockito.kotlin.verify
16+
import org.mockito.kotlin.whenever
17+
import org.mockito.kotlin.mock
18+
19+
internal class ProcessRulesInteractorTest {
20+
21+
private val runningRecordInteractor: RunningRecordInteractor = mock()
22+
private val complexRuleProcessActionInteractor: ComplexRuleProcessActionInteractor = mock()
23+
private val recordTypeToDefaultTagInteractor: RecordTypeToDefaultTagInteractor = mock()
24+
25+
private val subject = ProcessRulesInteractor(
26+
runningRecordInteractor = runningRecordInteractor,
27+
complexRuleProcessActionInteractor = complexRuleProcessActionInteractor,
28+
recordTypeToDefaultTagInteractor = recordTypeToDefaultTagInteractor,
29+
)
30+
31+
private fun tag(tagId: Long, numericValue: Double? = null): RecordBase.Tag {
32+
return RecordBase.Tag(tagId = tagId, numericValue = numericValue)
33+
}
34+
35+
private fun recordWithType(typeId: Long): Record {
36+
return Record(
37+
id = typeId,
38+
typeId = typeId,
39+
timeStarted = 1L,
40+
timeEnded = 2L,
41+
comment = "",
42+
tags = emptyList(),
43+
)
44+
}
45+
46+
@Test
47+
fun getRulesResultForStart_retroactiveMergeSkipsProcessing(): Unit = runBlocking {
48+
// Given
49+
val typeId = 11L
50+
val prevRecords = suspendLazy { listOf(recordWithType(typeId)) }
51+
52+
val defaultResult = ComplexRuleProcessActionInteractor.Result(
53+
isMultitaskingAllowed = ResultContainer.Undefined,
54+
disallowOnlyPreviousTypeIds = emptySet(),
55+
tags = emptyList(),
56+
tagIdsToSelectValueOnStart = emptySet(),
57+
)
58+
59+
// When
60+
val result = subject.getRulesResultForStart(
61+
typeId = typeId,
62+
timeStarted = 10L,
63+
prevRecords = prevRecords,
64+
retroactiveTrackingMode = true,
65+
)
66+
67+
// Then
68+
assertEquals(defaultResult, result)
69+
verify(complexRuleProcessActionInteractor, never()).processRules(any(), any(), any())
70+
}
71+
72+
@Test
73+
fun getRulesResultForStart_executesRulesWhenNeeded(): Unit = runBlocking {
74+
// Given
75+
val typeId = 11L
76+
val timeStarted = 10L
77+
val prevRecord = recordWithType(typeId = typeId + 1)
78+
val prevRecords = suspendLazy { listOf(prevRecord) }
79+
80+
val expectedResult = ComplexRuleProcessActionInteractor.Result(
81+
isMultitaskingAllowed = ResultContainer.Defined(true),
82+
disallowOnlyPreviousTypeIds = setOf(2L, 3L),
83+
tags = listOf(tag(5L, 1.0)),
84+
tagIdsToSelectValueOnStart = setOf(6L),
85+
)
86+
87+
whenever(complexRuleProcessActionInteractor.hasRules()).thenReturn(true)
88+
whenever(runningRecordInteractor.getAll()).thenReturn(emptyList())
89+
whenever(
90+
complexRuleProcessActionInteractor.processRules(
91+
timeStarted = timeStarted,
92+
startingTypeId = typeId,
93+
currentTypeIds = setOf(prevRecord.typeId),
94+
),
95+
).thenReturn(expectedResult)
96+
97+
// When
98+
val result = subject.getRulesResultForStart(
99+
typeId = typeId,
100+
timeStarted = timeStarted,
101+
prevRecords = prevRecords,
102+
retroactiveTrackingMode = false,
103+
)
104+
105+
// Then
106+
assertSame(expectedResult, result)
107+
verify(complexRuleProcessActionInteractor).processRules(
108+
timeStarted = timeStarted,
109+
startingTypeId = typeId,
110+
currentTypeIds = setOf(prevRecord.typeId),
111+
)
112+
}
113+
114+
@Test
115+
fun getAllTags_mergesTagsWithPriority(): Unit = runBlocking {
116+
// Given
117+
val typeId = 99L
118+
val currentTags = listOf(tag(1L, 10.0))
119+
val tagValuesFromRules = listOf(tag(2L, 5.0), tag(4L, 7.0))
120+
121+
whenever(recordTypeToDefaultTagInteractor.getTags(typeId)).thenReturn(setOf(1L, 2L, 3L))
122+
123+
// When
124+
val result = subject.getAllTags(typeId, currentTags, tagValuesFromRules)
125+
126+
// Then
127+
assertEquals(
128+
listOf(
129+
tag(1L, 10.0),
130+
tag(2L, 5.0),
131+
tag(3L, null),
132+
tag(4L, 7.0),
133+
),
134+
result,
135+
)
136+
}
137+
}

0 commit comments

Comments
 (0)