Skip to content

Commit f01fcad

Browse files
authored
Add data models, refactor local and network data sources (#908)
* Adding TaskEntity (first pass) * Add mapping function, rename TaskDataSource to NetworkDataSource * Move Task creation inside TaskRepository * More tidy ups, rename TaskEntity to LocalTask * Mapping functions return expressions and use method references * Fix spotless * Rename mapping functions from 'asSomething' to 'toSomething' * Fix spotless
1 parent 17da41e commit f01fcad

File tree

27 files changed

+552
-604
lines changed

27 files changed

+552
-604
lines changed

app/src/androidTest/java/com/example/android/architecture/blueprints/todoapp/tasks/AppNavigationTest.kt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@ import androidx.test.filters.LargeTest
3030
import com.example.android.architecture.blueprints.todoapp.HiltTestActivity
3131
import com.example.android.architecture.blueprints.todoapp.R
3232
import com.example.android.architecture.blueprints.todoapp.TodoNavGraph
33-
import com.example.android.architecture.blueprints.todoapp.data.Task
3433
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
35-
import com.example.android.architecture.blueprints.todoapp.util.saveTaskBlocking
3634
import com.google.accompanist.appcompattheme.AppCompatTheme
3735
import dagger.hilt.android.testing.HiltAndroidRule
3836
import dagger.hilt.android.testing.HiltAndroidTest
3937
import javax.inject.Inject
38+
import kotlinx.coroutines.test.runTest
4039
import org.junit.Assert.assertTrue
4140
import org.junit.Before
4241
import org.junit.Rule
@@ -129,10 +128,9 @@ class AppNavigationTest {
129128
}
130129

131130
@Test
132-
fun taskDetailScreen_doubleUIBackButton() {
131+
fun taskDetailScreen_doubleUIBackButton() = runTest {
133132
val taskName = "UI <- button"
134-
val task = Task(taskName, "Description")
135-
tasksRepository.saveTaskBlocking(task)
133+
tasksRepository.createTask(taskName, "Description")
136134

137135
setContent()
138136

@@ -159,10 +157,9 @@ class AppNavigationTest {
159157
}
160158

161159
@Test
162-
fun taskDetailScreen_doubleBackButton() {
160+
fun taskDetailScreen_doubleBackButton() = runTest {
163161
val taskName = "Back button"
164-
val task = Task(taskName, "Description")
165-
tasksRepository.saveTaskBlocking(task)
162+
tasksRepository.createTask(taskName, "Description")
166163

167164
setContent()
168165

app/src/androidTest/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksScreenTest.kt

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
2929
import androidx.test.filters.MediumTest
3030
import com.example.android.architecture.blueprints.todoapp.HiltTestActivity
3131
import com.example.android.architecture.blueprints.todoapp.R
32-
import com.example.android.architecture.blueprints.todoapp.data.Task
3332
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
34-
import com.example.android.architecture.blueprints.todoapp.util.saveTaskBlocking
3533
import com.google.accompanist.appcompattheme.AppCompatTheme
3634
import dagger.hilt.android.testing.HiltAndroidRule
3735
import dagger.hilt.android.testing.HiltAndroidTest
3836
import javax.inject.Inject
37+
import kotlinx.coroutines.ExperimentalCoroutinesApi
38+
import kotlinx.coroutines.test.runTest
3939
import org.junit.Before
4040
import org.junit.Rule
4141
import org.junit.Test
@@ -50,6 +50,7 @@ import org.junit.runner.RunWith
5050
// @LooperMode(LooperMode.Mode.PAUSED)
5151
// @TextLayoutMode(TextLayoutMode.Mode.REALISTIC)
5252
@HiltAndroidTest
53+
@OptIn(ExperimentalCoroutinesApi::class)
5354
class TasksScreenTest {
5455

5556
@get:Rule(order = 0)
@@ -68,9 +69,9 @@ class TasksScreenTest {
6869
}
6970

7071
@Test
71-
fun displayTask_whenRepositoryHasData() {
72+
fun displayTask_whenRepositoryHasData() = runTest {
7273
// GIVEN - One task already in the repository
73-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
74+
repository.createTask("TITLE1", "DESCRIPTION1")
7475

7576
// WHEN - On startup
7677
setContent()
@@ -80,8 +81,8 @@ class TasksScreenTest {
8081
}
8182

8283
@Test
83-
fun displayActiveTask() {
84-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
84+
fun displayActiveTask() = runTest {
85+
repository.createTask("TITLE1", "DESCRIPTION1")
8586

8687
setContent()
8788

@@ -96,8 +97,10 @@ class TasksScreenTest {
9697
}
9798

9899
@Test
99-
fun displayCompletedTask() {
100-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1", true))
100+
fun displayCompletedTask() = runTest {
101+
repository.apply {
102+
createTask("TITLE1", "DESCRIPTION1").also { completeTask(it.id) }
103+
}
101104

102105
setContent()
103106

@@ -111,8 +114,8 @@ class TasksScreenTest {
111114
}
112115

113116
@Test
114-
fun markTaskAsComplete() {
115-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
117+
fun markTaskAsComplete() = runTest {
118+
repository.createTask("TITLE1", "DESCRIPTION1")
116119

117120
setContent()
118121

@@ -129,8 +132,10 @@ class TasksScreenTest {
129132
}
130133

131134
@Test
132-
fun markTaskAsActive() {
133-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1", true))
135+
fun markTaskAsActive() = runTest {
136+
repository.apply {
137+
createTask("TITLE1", "DESCRIPTION1").also { completeTask(it.id) }
138+
}
134139

135140
setContent()
136141

@@ -147,10 +152,12 @@ class TasksScreenTest {
147152
}
148153

149154
@Test
150-
fun showAllTasks() {
155+
fun showAllTasks() = runTest {
151156
// Add one active task and one completed task
152-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
153-
repository.saveTaskBlocking(Task("TITLE2", "DESCRIPTION2", true))
157+
repository.apply {
158+
createTask("TITLE1", "DESCRIPTION1")
159+
createTask("TITLE2", "DESCRIPTION2").also { completeTask(it.id) }
160+
}
154161

155162
setContent()
156163

@@ -161,11 +168,13 @@ class TasksScreenTest {
161168
}
162169

163170
@Test
164-
fun showActiveTasks() {
171+
fun showActiveTasks() = runTest {
165172
// Add 2 active tasks and one completed task
166-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
167-
repository.saveTaskBlocking(Task("TITLE2", "DESCRIPTION2"))
168-
repository.saveTaskBlocking(Task("TITLE3", "DESCRIPTION3", true))
173+
repository.apply {
174+
createTask("TITLE1", "DESCRIPTION1")
175+
createTask("TITLE2", "DESCRIPTION2")
176+
createTask("TITLE3", "DESCRIPTION3").also { completeTask(it.id) }
177+
}
169178

170179
setContent()
171180

@@ -177,11 +186,13 @@ class TasksScreenTest {
177186
}
178187

179188
@Test
180-
fun showCompletedTasks() {
189+
fun showCompletedTasks() = runTest {
181190
// Add one active task and 2 completed tasks
182-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
183-
repository.saveTaskBlocking(Task("TITLE2", "DESCRIPTION2", true))
184-
repository.saveTaskBlocking(Task("TITLE3", "DESCRIPTION3", true))
191+
repository.apply {
192+
createTask("TITLE1", "DESCRIPTION1")
193+
createTask("TITLE2", "DESCRIPTION2").also { completeTask(it.id) }
194+
createTask("TITLE3", "DESCRIPTION3").also { completeTask(it.id) }
195+
}
185196

186197
setContent()
187198

@@ -193,10 +204,12 @@ class TasksScreenTest {
193204
}
194205

195206
@Test
196-
fun clearCompletedTasks() {
207+
fun clearCompletedTasks() = runTest {
197208
// Add one active task and one completed task
198-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION1"))
199-
repository.saveTaskBlocking(Task("TITLE2", "DESCRIPTION2", true))
209+
repository.apply {
210+
createTask("TITLE1", "DESCRIPTION1")
211+
createTask("TITLE2", "DESCRIPTION2").also { completeTask(it.id) }
212+
}
200213

201214
setContent()
202215

app/src/androidTest/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksTest.kt

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ import androidx.test.filters.LargeTest
3535
import com.example.android.architecture.blueprints.todoapp.HiltTestActivity
3636
import com.example.android.architecture.blueprints.todoapp.R
3737
import com.example.android.architecture.blueprints.todoapp.TodoNavGraph
38-
import com.example.android.architecture.blueprints.todoapp.data.Task
3938
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
40-
import com.example.android.architecture.blueprints.todoapp.util.saveTaskBlocking
4139
import com.google.accompanist.appcompattheme.AppCompatTheme
4240
import dagger.hilt.android.testing.HiltAndroidRule
4341
import dagger.hilt.android.testing.HiltAndroidTest
4442
import javax.inject.Inject
43+
import kotlinx.coroutines.ExperimentalCoroutinesApi
44+
import kotlinx.coroutines.test.runTest
4545
import org.junit.Before
4646
import org.junit.Rule
4747
import org.junit.Test
@@ -53,6 +53,7 @@ import org.junit.runner.RunWith
5353
@RunWith(AndroidJUnit4::class)
5454
@LargeTest
5555
@HiltAndroidTest
56+
@OptIn(ExperimentalCoroutinesApi::class)
5657
class TasksTest {
5758

5859
@get:Rule(order = 0)
@@ -75,9 +76,9 @@ class TasksTest {
7576
}
7677

7778
@Test
78-
fun editTask() {
79+
fun editTask() = runTest {
7980
val originalTaskTitle = "TITLE1"
80-
repository.saveTaskBlocking(Task(originalTaskTitle, "DESCRIPTION"))
81+
repository.createTask(originalTaskTitle, "DESCRIPTION")
8182

8283
setContent()
8384

@@ -140,9 +141,11 @@ class TasksTest {
140141
}
141142

142143
@Test
143-
fun createTwoTasks_deleteOneTask() {
144-
repository.saveTaskBlocking(Task("TITLE1", "DESCRIPTION"))
145-
repository.saveTaskBlocking(Task("TITLE2", "DESCRIPTION"))
144+
fun createTwoTasks_deleteOneTask() = runTest {
145+
repository.apply {
146+
createTask("TITLE1", "DESCRIPTION")
147+
createTask("TITLE2", "DESCRIPTION")
148+
}
146149

147150
setContent()
148151

@@ -163,10 +166,10 @@ class TasksTest {
163166
}
164167

165168
@Test
166-
fun markTaskAsCompleteOnDetailScreen_taskIsCompleteInList() {
169+
fun markTaskAsCompleteOnDetailScreen_taskIsCompleteInList() = runTest {
167170
// Add 1 active task
168171
val taskTitle = "COMPLETED"
169-
repository.saveTaskBlocking(Task(taskTitle, "DESCRIPTION"))
172+
repository.createTask(taskTitle, "DESCRIPTION")
170173

171174
setContent()
172175

@@ -188,10 +191,12 @@ class TasksTest {
188191
}
189192

190193
@Test
191-
fun markTaskAsActiveOnDetailScreen_taskIsActiveInList() {
194+
fun markTaskAsActiveOnDetailScreen_taskIsActiveInList() = runTest {
192195
// Add 1 completed task
193196
val taskTitle = "ACTIVE"
194-
repository.saveTaskBlocking(Task(taskTitle, "DESCRIPTION", true))
197+
repository.apply {
198+
createTask(taskTitle, "DESCRIPTION").also { completeTask(it.id) }
199+
}
195200

196201
setContent()
197202

@@ -213,10 +218,10 @@ class TasksTest {
213218
}
214219

215220
@Test
216-
fun markTaskAsCompleteAndActiveOnDetailScreen_taskIsActiveInList() {
221+
fun markTaskAsCompleteAndActiveOnDetailScreen_taskIsActiveInList() = runTest {
217222
// Add 1 active task
218223
val taskTitle = "ACT-COMP"
219-
repository.saveTaskBlocking(Task(taskTitle, "DESCRIPTION"))
224+
repository.createTask(taskTitle, "DESCRIPTION")
220225

221226
setContent()
222227

@@ -240,10 +245,12 @@ class TasksTest {
240245
}
241246

242247
@Test
243-
fun markTaskAsActiveAndCompleteOnDetailScreen_taskIsCompleteInList() {
248+
fun markTaskAsActiveAndCompleteOnDetailScreen_taskIsCompleteInList() = runTest {
244249
// Add 1 completed task
245250
val taskTitle = "COMP-ACT"
246-
repository.saveTaskBlocking(Task(taskTitle, "DESCRIPTION", true))
251+
repository.apply {
252+
createTask(taskTitle, "DESCRIPTION").also { completeTask(it.id) }
253+
}
247254

248255
setContent()
249256

app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskViewModel.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import androidx.lifecycle.ViewModel
2121
import androidx.lifecycle.viewModelScope
2222
import com.example.android.architecture.blueprints.todoapp.R
2323
import com.example.android.architecture.blueprints.todoapp.TodoDestinationsArgs
24-
import com.example.android.architecture.blueprints.todoapp.data.Task
2524
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
2625
import dagger.hilt.android.lifecycle.HiltViewModel
2726
import javax.inject.Inject
@@ -101,8 +100,7 @@ class AddEditTaskViewModel @Inject constructor(
101100
}
102101

103102
private fun createNewTask() = viewModelScope.launch {
104-
val newTask = Task(uiState.value.title, uiState.value.description)
105-
tasksRepository.saveTask(newTask)
103+
tasksRepository.createTask(uiState.value.title, uiState.value.description)
106104
_uiState.update {
107105
it.copy(isTaskSaved = true)
108106
}
@@ -113,13 +111,11 @@ class AddEditTaskViewModel @Inject constructor(
113111
throw RuntimeException("updateTask() was called but task is new.")
114112
}
115113
viewModelScope.launch {
116-
val updatedTask = Task(
114+
tasksRepository.updateTask(
115+
taskId,
117116
title = uiState.value.title,
118117
description = uiState.value.description,
119-
isCompleted = uiState.value.isTaskCompleted,
120-
id = taskId
121118
)
122-
tasksRepository.saveTask(updatedTask)
123119
_uiState.update {
124120
it.copy(isTaskSaved = true)
125121
}

0 commit comments

Comments
 (0)