From 7b3eb3376b09cfb2b2397a56f853136b47afa1c4 Mon Sep 17 00:00:00 2001 From: Zyad Date: Fri, 27 Jun 2025 16:44:35 +0300 Subject: [PATCH] refactor: remove nullability from domain entity --- .../moscow/tudee/data/local/mapper/mapper.kt | 20 ++++++++++++++++--- .../data/service/CategoryServicesImpl.kt | 17 ++++++++++------ .../tudee/data/service/TasksServicesImpl.kt | 2 +- .../com/moscow/tudee/domain/entity/Task.kt | 2 +- .../tudee/domain/service/CategoryServices.kt | 7 ++++++- .../tudee/presentation/mapper/UiMapper.kt | 2 +- .../categoriesScreen/CategoryViewModel.kt | 10 ++++++++-- .../task/AddTaskBottomSheetViewModel.kt | 2 +- .../data/service/TasksServicesImplTest.kt | 8 ++++---- .../categoriesScreen/CategoryViewModelTest.kt | 11 ++++++++-- 10 files changed, 59 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/moscow/tudee/data/local/mapper/mapper.kt b/app/src/main/java/com/moscow/tudee/data/local/mapper/mapper.kt index e9e328df..5adc1db4 100644 --- a/app/src/main/java/com/moscow/tudee/data/local/mapper/mapper.kt +++ b/app/src/main/java/com/moscow/tudee/data/local/mapper/mapper.kt @@ -1,4 +1,3 @@ - package com.moscow.tudee.data.local.mapper import com.moscow.tudee.data.local.entity.CategoryEntity @@ -29,7 +28,7 @@ fun Category.toCategoryEntity(): CategoryEntity { fun TaskEntity.toTask(category: Category): Task { return Task( - id = id.takeIf { it.toInt() != 0 }, + id = id, title = title, description = description, priority = getPriorityFromString(priority), @@ -45,7 +44,7 @@ fun TaskEntity.toTask(category: Category): Task { fun Task.toTaskEntity(): TaskEntity { return TaskEntity( - id = id ?: 0, + id = id, title = title, description = description, priority = priority.toString(), @@ -84,4 +83,19 @@ fun List.toTasksByCategories(categoriesById: Map.toTasksBySingleCategory(categoryEntity: CategoryEntity): List { val domainCategory = categoryEntity.toCategory() return this.map { it.toTask(domainCategory) } +} + +fun createCategoryEntity( + title: String, + iconUri: String, + isPredefined: Boolean, + countOfTasks: Int +): CategoryEntity { + return CategoryEntity( + id = 0, + title = title, + iconUri = iconUri, + isPredefined = isPredefined, + countOfTasks = countOfTasks + ) } \ No newline at end of file diff --git a/app/src/main/java/com/moscow/tudee/data/service/CategoryServicesImpl.kt b/app/src/main/java/com/moscow/tudee/data/service/CategoryServicesImpl.kt index 8d3bc07f..f1f9790c 100644 --- a/app/src/main/java/com/moscow/tudee/data/service/CategoryServicesImpl.kt +++ b/app/src/main/java/com/moscow/tudee/data/service/CategoryServicesImpl.kt @@ -1,23 +1,27 @@ package com.moscow.tudee.data.service import com.moscow.tudee.data.local.dao.CategoryDao +import com.moscow.tudee.data.local.mapper.createCategoryEntity import com.moscow.tudee.data.local.mapper.toCategory import com.moscow.tudee.data.local.mapper.toCategoryEntity -import com.moscow.tudee.data.local.mapper.toTask import com.moscow.tudee.domain.entity.Category -import com.moscow.tudee.domain.entity.Task import com.moscow.tudee.domain.service.CategoryServices class CategoryServicesImpl( private val categoryDao: CategoryDao -): CategoryServices { +) : CategoryServices { override suspend fun getCategories(): List { return categoryDao.getCategories().map { it.toCategory() } } - override suspend fun addCategory(category: Category) { - categoryDao.addCategory(category.toCategoryEntity()) + override suspend fun addCategory( + title: String, + iconUri: String, + isPredefined: Boolean, + countOfTasks: Int + ) { + categoryDao.addCategory(createCategoryEntity(title, iconUri, isPredefined, countOfTasks)) } override suspend fun updateCategory(category: Category) { @@ -29,6 +33,7 @@ class CategoryServicesImpl( } override suspend fun getCategoryById(categoryId: Long): Category { - return categoryDao.getCategoryById(categoryId)?.toCategory() ?: throw Exception("task category found") + return categoryDao.getCategoryById(categoryId)?.toCategory() + ?: throw Exception("task category found") } } \ No newline at end of file diff --git a/app/src/main/java/com/moscow/tudee/data/service/TasksServicesImpl.kt b/app/src/main/java/com/moscow/tudee/data/service/TasksServicesImpl.kt index c5e96908..6c3b7edf 100644 --- a/app/src/main/java/com/moscow/tudee/data/service/TasksServicesImpl.kt +++ b/app/src/main/java/com/moscow/tudee/data/service/TasksServicesImpl.kt @@ -86,7 +86,7 @@ class TasksServicesImpl( } override suspend fun updateTask(task: Task) { - task.id?.let { taskId -> + task.id.let { taskId -> taskDao.getTaskById(taskId)?.let { oldTask -> categoryDao.getCategoryById(oldTask.categoryId)?.let { oldCategory -> categoryDao.decrementTaskCount(oldCategory.id) diff --git a/app/src/main/java/com/moscow/tudee/domain/entity/Task.kt b/app/src/main/java/com/moscow/tudee/domain/entity/Task.kt index 1adf973e..9a111721 100644 --- a/app/src/main/java/com/moscow/tudee/domain/entity/Task.kt +++ b/app/src/main/java/com/moscow/tudee/domain/entity/Task.kt @@ -3,7 +3,7 @@ import kotlinx.datetime.LocalDateTime data class Task( - val id: Long? = null, + val id: Long, val title: String, val description: String, val priority: Priority, diff --git a/app/src/main/java/com/moscow/tudee/domain/service/CategoryServices.kt b/app/src/main/java/com/moscow/tudee/domain/service/CategoryServices.kt index 7d4bb8ea..e88bd87d 100644 --- a/app/src/main/java/com/moscow/tudee/domain/service/CategoryServices.kt +++ b/app/src/main/java/com/moscow/tudee/domain/service/CategoryServices.kt @@ -6,7 +6,12 @@ interface CategoryServices { suspend fun getCategories(): List - suspend fun addCategory(category: Category) + suspend fun addCategory( + title: String, + iconUri: String, + isPredefined: Boolean = false, + countOfTasks: Int = 0 + ) suspend fun updateCategory(category: Category) diff --git a/app/src/main/java/com/moscow/tudee/presentation/mapper/UiMapper.kt b/app/src/main/java/com/moscow/tudee/presentation/mapper/UiMapper.kt index b67c2303..7511b581 100644 --- a/app/src/main/java/com/moscow/tudee/presentation/mapper/UiMapper.kt +++ b/app/src/main/java/com/moscow/tudee/presentation/mapper/UiMapper.kt @@ -38,7 +38,7 @@ fun Category.toCategoryUi() = CategoryUi( fun TaskUi.toTask(): Task = Task( - id = id, + id = id ?: 0L, title = title, description = description, priority = priority ?: Priority.LOW, diff --git a/app/src/main/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModel.kt b/app/src/main/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModel.kt index f2b31d17..71d14031 100644 --- a/app/src/main/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModel.kt +++ b/app/src/main/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModel.kt @@ -4,7 +4,6 @@ import com.moscow.tudee.R import com.moscow.tudee.domain.entity.Category import com.moscow.tudee.domain.service.CategoryServices import com.moscow.tudee.presentation.base.BaseViewModel -import com.moscow.tudee.presentation.mapper.toCategory import com.moscow.tudee.presentation.mapper.toCategoryUi import com.moscow.tudee.presentation.model.CategoryUi import com.moscow.tudee.presentation.screen.category.CategoriesScreenState @@ -60,7 +59,14 @@ class CategoryViewModel( override fun onAddCategory(categoryUi: CategoryUi) { launchWithResult( - action = { categoryServices.addCategory(categoryUi.toCategory()) }, + action = { + categoryServices.addCategory( + title = categoryUi.title, + iconUri = categoryUi.iconUrl, + isPredefined = categoryUi.isPredefined, + countOfTasks = categoryUi.countOfTasks, + ) + }, onSuccess = { onAddCategorySuccess() }, onError = ::onAddCategoryFailed, onStart = ::onLoading, diff --git a/app/src/main/java/com/moscow/tudee/presentation/screen/task/AddTaskBottomSheetViewModel.kt b/app/src/main/java/com/moscow/tudee/presentation/screen/task/AddTaskBottomSheetViewModel.kt index 1d21704b..736b4e29 100644 --- a/app/src/main/java/com/moscow/tudee/presentation/screen/task/AddTaskBottomSheetViewModel.kt +++ b/app/src/main/java/com/moscow/tudee/presentation/screen/task/AddTaskBottomSheetViewModel.kt @@ -54,7 +54,7 @@ class AddTaskBottomSheetViewModel( action = { tasksServices.addTask( Task( - id = null, + id = 0L, title = uiState.value.title, description = uiState.value.description, priority = uiState.value.priority ?: return@launchWithResult onErrorAddTask( diff --git a/app/src/test/java/com/moscow/tudee/data/service/TasksServicesImplTest.kt b/app/src/test/java/com/moscow/tudee/data/service/TasksServicesImplTest.kt index 505ca7bd..d72924ff 100644 --- a/app/src/test/java/com/moscow/tudee/data/service/TasksServicesImplTest.kt +++ b/app/src/test/java/com/moscow/tudee/data/service/TasksServicesImplTest.kt @@ -204,7 +204,7 @@ class TasksServicesImplTest { @Test fun `should insert task into dao when adding new task`() = runTest { val newTask = Task( - id = null, + id = 0L, title = "Test Task", description = "Description", priority = Task.Priority.HIGH, @@ -217,7 +217,7 @@ class TasksServicesImplTest { title = "Test Task", description = "Description", priority = Task.Priority.HIGH.name, - categoryId = sampleCategory.id!!, + categoryId = sampleCategory.id, status = Task.Status.TODO.name, date = "2025-06-18" ) @@ -226,7 +226,7 @@ class TasksServicesImplTest { tasksServices.addTask(newTask) coVerify { taskDao.addTask(expectedEntity) } - coVerify { categoryDao.incrementTaskCount(sampleCategory.id!!) } + coVerify { categoryDao.incrementTaskCount(sampleCategory.id) } } @Test @@ -245,7 +245,7 @@ class TasksServicesImplTest { title = "Updated Task", description = "Updated Description", priority = Task.Priority.MEDIUM.name, - categoryId = sampleCategory.id!!, + categoryId = sampleCategory.id, status = Task.Status.IN_PROGRESS.name, date = "2025-06-18" ) diff --git a/app/src/test/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModelTest.kt b/app/src/test/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModelTest.kt index ce0e52fd..dae0e21b 100644 --- a/app/src/test/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModelTest.kt +++ b/app/src/test/java/com/moscow/tudee/presentation/screen/category/categoriesScreen/CategoryViewModelTest.kt @@ -92,7 +92,7 @@ class CategoryViewModelTest { @Test fun `should return success state when category is added successfully`() { - coEvery { categoryServices.addCategory(any()) } returns Unit + coEvery { categoryServices.addCategory(any(), any(), any(), any()) } returns Unit coEvery { categoryServices.getCategories() } returns listOf(category) viewModel.onAddCategory(category.toCategoryUi()) @@ -106,7 +106,14 @@ class CategoryViewModelTest { @Test fun `should return error state when adding category fails`() { - coEvery { categoryServices.addCategory(any()) } throws Exception("Failed") + coEvery { + categoryServices.addCategory( + any(), + any(), + any(), + any() + ) + } throws Exception("Failed") viewModel.onAddCategory(category.toCategoryUi()) testScope.advanceUntilIdle()