diff --git a/data/build.gradle.kts b/data/build.gradle.kts index d7aab12..ca92b3a 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -31,6 +31,7 @@ android { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } + compileSdkMinor = 0 } kotlin { diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/aiusecase/SuggestSummaryUseCase.kt similarity index 94% rename from domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/aiusecase/SuggestSummaryUseCase.kt index 5c75d4d..985aba8 100644 --- a/domain/src/main/java/com/itlab/domain/aiusecase/SuggestSummaryUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/aiusecase/SuggestSummaryUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.aiusecase +package com.itlab.domain.usecase.aiusecase import com.itlab.domain.ai.NoteAiService import com.itlab.domain.model.ContentItem diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/aiusecase/SuggestTagsUseCase.kt similarity index 96% rename from domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/aiusecase/SuggestTagsUseCase.kt index 6de701a..2360269 100644 --- a/domain/src/main/java/com/itlab/domain/aiusecase/SuggestTagsUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/aiusecase/SuggestTagsUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.aiusecase +package com.itlab.domain.usecase.aiusecase import com.itlab.domain.ai.NoteAiService import com.itlab.domain.model.ContentItem diff --git a/domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/CreateFolderUseCase.kt similarity index 52% rename from domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/folderusecase/CreateFolderUseCase.kt index b0d06dc..20a5727 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/CreateFolderUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/CreateFolderUseCase.kt @@ -1,15 +1,21 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.folderusecase import com.itlab.domain.model.NoteFolder import com.itlab.domain.repository.NoteFolderRepository import kotlinx.datetime.Clock +import java.util.UUID class CreateFolderUseCase( private val repo: NoteFolderRepository, ) { suspend operator fun invoke(folder: NoteFolder): String { - // discuss - val folder = folder.copy(createdAt = Clock.System.now()) + val now = Clock.System.now() + val folder = + folder.copy( + id = UUID.randomUUID().toString(), + createdAt = now, + updatedAt = now, + ) return repo.createFolder(folder) } } diff --git a/domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/DeleteFolderUseCase.kt similarity index 82% rename from domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/folderusecase/DeleteFolderUseCase.kt index 9dd0169..3b18008 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/DeleteFolderUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/DeleteFolderUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.folderusecase import com.itlab.domain.repository.NoteFolderRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/GetFolderUseCase.kt similarity index 84% rename from domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/folderusecase/GetFolderUseCase.kt index dbbd872..3519e82 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/GetFolderUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/GetFolderUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.folderusecase import com.itlab.domain.model.NoteFolder import com.itlab.domain.repository.NoteFolderRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/ObserveFoldersUseCase.kt similarity index 85% rename from domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/folderusecase/ObserveFoldersUseCase.kt index 92b7a3a..6b814fe 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/ObserveFoldersUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/ObserveFoldersUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.folderusecase import com.itlab.domain.model.NoteFolder import com.itlab.domain.repository.NoteFolderRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/UpdateFolderUseCase.kt similarity index 88% rename from domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/folderusecase/UpdateFolderUseCase.kt index 2539c82..d4ecd78 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/UpdateFolderUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/folderusecase/UpdateFolderUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.folderusecase import com.itlab.domain.model.NoteFolder import com.itlab.domain.repository.NoteFolderRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/noteusecase/AddTagUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/AddTagUseCase.kt new file mode 100644 index 0000000..f81614f --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/AddTagUseCase.kt @@ -0,0 +1,25 @@ +package com.itlab.domain.usecase.noteusecase + +import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock + +class AddTagUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke( + noteId: String, + tagToAdd: String, + ) { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found: $noteId") + + val updated = + note.copy( + tags = note.tags + tagToAdd, + updatedAt = Clock.System.now(), + ) + + repo.updateNote(updated) + } +} diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ApplySummaryUseCase.kt similarity index 83% rename from domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/ApplySummaryUseCase.kt index db484de..60c7a19 100644 --- a/domain/src/main/java/com/itlab/domain/aiusecase/ApplySummaryUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ApplySummaryUseCase.kt @@ -1,6 +1,7 @@ -package com.itlab.domain.aiusecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock class ApplySummaryUseCase( private val repo: NotesRepository, @@ -17,7 +18,7 @@ class ApplySummaryUseCase( note.copy( summary = newSummary, updatedAt = - kotlinx.datetime.Clock.System + Clock.System .now(), ) diff --git a/domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ApplyTagsUseCase.kt similarity index 83% rename from domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/ApplyTagsUseCase.kt index 85e5114..8953f5f 100644 --- a/domain/src/main/java/com/itlab/domain/aiusecase/ApplyTagsUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ApplyTagsUseCase.kt @@ -1,6 +1,7 @@ -package com.itlab.domain.aiusecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock class ApplyTagsUseCase( private val repo: NotesRepository, @@ -17,7 +18,7 @@ class ApplyTagsUseCase( note.copy( tags = newTags, updatedAt = - kotlinx.datetime.Clock.System + Clock.System .now(), ) diff --git a/domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/CreateNoteUseCase.kt similarity index 50% rename from domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/CreateNoteUseCase.kt index fdc390a..49807b9 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/CreateNoteUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/CreateNoteUseCase.kt @@ -1,14 +1,22 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.model.Note import com.itlab.domain.repository.NotesRepository import kotlinx.datetime.Clock +import java.util.UUID class CreateNoteUseCase( private val repo: NotesRepository, ) { suspend operator fun invoke(note: Note): String { - val note = note.copy(createdAt = Clock.System.now()) + val now = Clock.System.now() + + val note = + note.copy( + id = UUID.randomUUID().toString(), + createdAt = now, + updatedAt = now, + ) return repo.createNote(note) } } diff --git a/domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DeleteNoteUseCase.kt similarity index 82% rename from domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/DeleteNoteUseCase.kt index 65e8b8a..4a287eb 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/DeleteNoteUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DeleteNoteUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.repository.NotesRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DeleteTagUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DeleteTagUseCase.kt new file mode 100644 index 0000000..0adeea5 --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DeleteTagUseCase.kt @@ -0,0 +1,25 @@ +package com.itlab.domain.usecase.noteusecase + +import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock + +class DeleteTagUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke( + noteId: String, + tagToDel: String, + ) { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found: $noteId") + + val updated = + note.copy( + tags = note.tags - tagToDel, + updatedAt = Clock.System.now(), + ) + + repo.updateNote(updated) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DuplicateNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DuplicateNoteUseCase.kt new file mode 100644 index 0000000..4225e5f --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/DuplicateNoteUseCase.kt @@ -0,0 +1,26 @@ +package com.itlab.domain.usecase.noteusecase + +import com.itlab.domain.repository.NotesRepository +import kotlinx.datetime.Clock +import java.util.UUID + +class DuplicateNoteUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke(noteId: String): String { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found: $noteId") + + val now = Clock.System.now() + val duplicated = + note.copy( + id = UUID.randomUUID().toString(), + title = if (note.title.isBlank()) "Copy" else "${note.title} Copy", + createdAt = now, + updatedAt = now, + ) + + return repo.createNote(duplicated) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/noteusecase/GetAllFavoritesUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/GetAllFavoritesUseCase.kt new file mode 100644 index 0000000..6008bea --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/GetAllFavoritesUseCase.kt @@ -0,0 +1,15 @@ +package com.itlab.domain.usecase.noteusecase + +import com.itlab.domain.model.Note +import com.itlab.domain.repository.NotesRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +class GetAllFavoritesUseCase( + private val repo: NotesRepository, +) { + operator fun invoke(): Flow> = + repo.observeNotes().map { notes -> + notes.filter { it.isFavorite } + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/GetNoteUseCase.kt similarity index 83% rename from domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/GetNoteUseCase.kt index bec0c5a..9901149 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/GetNoteUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/GetNoteUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.model.Note import com.itlab.domain.repository.NotesRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/MoveNoteToFolderUseCase.kt similarity index 91% rename from domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/MoveNoteToFolderUseCase.kt index c5f0265..ed711a1 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/MoveNoteToFolderUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/MoveNoteToFolderUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.repository.NotesRepository import kotlinx.datetime.Clock diff --git a/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ObserveNotesByFolderUseCase.kt similarity index 90% rename from domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/ObserveNotesByFolderUseCase.kt index 3634333..fa67715 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesByFolderUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ObserveNotesByFolderUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.model.Note import com.itlab.domain.repository.NotesRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ObserveNotesUseCase.kt similarity index 85% rename from domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/ObserveNotesUseCase.kt index 1fbfa3b..90c9c17 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/ObserveNotesUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/ObserveNotesUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.model.Note import com.itlab.domain.repository.NotesRepository diff --git a/domain/src/main/java/com/itlab/domain/usecase/noteusecase/SwitchFavoriteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/SwitchFavoriteUseCase.kt new file mode 100644 index 0000000..d0ec44c --- /dev/null +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/SwitchFavoriteUseCase.kt @@ -0,0 +1,20 @@ +package com.itlab.domain.usecase.noteusecase + +import com.itlab.domain.repository.NotesRepository + +class SwitchFavoriteUseCase( + private val repo: NotesRepository, +) { + suspend operator fun invoke(noteId: String) { + val note = + repo.getNoteById(noteId) + ?: throw IllegalArgumentException("Note not found") + + val updatedNote = + note.copy( + isFavorite = !note.isFavorite, + ) + + repo.updateNote(updatedNote) + } +} diff --git a/domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/UpdateNoteUseCase.kt similarity index 88% rename from domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt rename to domain/src/main/java/com/itlab/domain/usecase/noteusecase/UpdateNoteUseCase.kt index f7470ee..d7ccb50 100644 --- a/domain/src/main/java/com/itlab/domain/usecase/UpdateNoteUseCase.kt +++ b/domain/src/main/java/com/itlab/domain/usecase/noteusecase/UpdateNoteUseCase.kt @@ -1,4 +1,4 @@ -package com.itlab.domain.usecase +package com.itlab.domain.usecase.noteusecase import com.itlab.domain.model.Note import com.itlab.domain.repository.NotesRepository diff --git a/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt index 97d4c3b..19e53af 100644 --- a/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt +++ b/domain/src/test/java/com/itlab/domain/AIUseCasesTest.kt @@ -1,14 +1,14 @@ package com.itlab.domain import com.itlab.domain.ai.NoteAiService -import com.itlab.domain.aiusecase.ApplySummaryUseCase -import com.itlab.domain.aiusecase.ApplyTagsUseCase -import com.itlab.domain.aiusecase.SuggestSummaryUseCase -import com.itlab.domain.aiusecase.SuggestTagsUseCase import com.itlab.domain.model.ContentItem import com.itlab.domain.model.DataSource import com.itlab.domain.model.Note import com.itlab.domain.repository.NotesRepository +import com.itlab.domain.usecase.aiusecase.SuggestSummaryUseCase +import com.itlab.domain.usecase.aiusecase.SuggestTagsUseCase +import com.itlab.domain.usecase.noteusecase.ApplySummaryUseCase +import com.itlab.domain.usecase.noteusecase.ApplyTagsUseCase import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.map diff --git a/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt index fbe465b..8650a4e 100644 --- a/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt +++ b/domain/src/test/java/com/itlab/domain/FolderUseCasesTest.kt @@ -2,11 +2,11 @@ package com.itlab.domain import com.itlab.domain.model.NoteFolder import com.itlab.domain.repository.NoteFolderRepository -import com.itlab.domain.usecase.CreateFolderUseCase -import com.itlab.domain.usecase.DeleteFolderUseCase -import com.itlab.domain.usecase.GetFolderUseCase -import com.itlab.domain.usecase.ObserveFoldersUseCase -import com.itlab.domain.usecase.UpdateFolderUseCase +import com.itlab.domain.usecase.folderusecase.CreateFolderUseCase +import com.itlab.domain.usecase.folderusecase.DeleteFolderUseCase +import com.itlab.domain.usecase.folderusecase.GetFolderUseCase +import com.itlab.domain.usecase.folderusecase.ObserveFoldersUseCase +import com.itlab.domain.usecase.folderusecase.UpdateFolderUseCase import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking @@ -58,11 +58,11 @@ class FolderUseCasesTest { val create = CreateFolderUseCase(repo) val get = GetFolderUseCase(repo) - val folder = NoteFolder(id = "1", name = "Test") + val folder = NoteFolder(name = "Test") - create(folder) + val id = create(folder) - val result = get("1") + val result = get(id) assertEquals("Test", result?.name) } @@ -76,13 +76,16 @@ class FolderUseCasesTest { val update = UpdateFolderUseCase(repo) val get = GetFolderUseCase(repo) - val folder = NoteFolder(id = "1", name = "Old") - create(folder) + val folder = NoteFolder(name = "Old") - val updated = folder.copy(name = "New") + val id = create(folder) + + val created = get(id)!! + + val updated = created.copy(name = "New") update(updated) - val result = get("1") + val result = get(id) assertEquals("New", result?.name) } @@ -96,12 +99,13 @@ class FolderUseCasesTest { val delete = DeleteFolderUseCase(repo) val get = GetFolderUseCase(repo) - val folder = NoteFolder(id = "1", name = "Test") - create(folder) + val folder = NoteFolder(name = "Test") + + val id = create(folder) - delete("1") + delete(id) - val result = get("1") + val result = get(id) assertNull(result) } @@ -113,7 +117,7 @@ class FolderUseCasesTest { val create = CreateFolderUseCase(repo) val observe = ObserveFoldersUseCase(repo) - create(NoteFolder(id = "1", name = "A")) + create(NoteFolder(name = "A")) val list = observe().first() diff --git a/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt b/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt index be3d572..64f31ee 100644 --- a/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt +++ b/domain/src/test/java/com/itlab/domain/NoteUseCasesTest.kt @@ -4,17 +4,23 @@ import com.itlab.domain.model.Note import com.itlab.domain.model.NoteFolder import com.itlab.domain.repository.NoteFolderRepository import com.itlab.domain.repository.NotesRepository -import com.itlab.domain.usecase.CreateNoteUseCase -import com.itlab.domain.usecase.DeleteNoteUseCase -import com.itlab.domain.usecase.GetNoteUseCase -import com.itlab.domain.usecase.MoveNoteToFolderUseCase -import com.itlab.domain.usecase.ObserveNotesUseCase -import com.itlab.domain.usecase.UpdateNoteUseCase +import com.itlab.domain.usecase.noteusecase.AddTagUseCase +import com.itlab.domain.usecase.noteusecase.CreateNoteUseCase +import com.itlab.domain.usecase.noteusecase.DeleteNoteUseCase +import com.itlab.domain.usecase.noteusecase.DeleteTagUseCase +import com.itlab.domain.usecase.noteusecase.DuplicateNoteUseCase +import com.itlab.domain.usecase.noteusecase.GetAllFavoritesUseCase +import com.itlab.domain.usecase.noteusecase.GetNoteUseCase +import com.itlab.domain.usecase.noteusecase.MoveNoteToFolderUseCase +import com.itlab.domain.usecase.noteusecase.ObserveNotesUseCase +import com.itlab.domain.usecase.noteusecase.SwitchFavoriteUseCase +import com.itlab.domain.usecase.noteusecase.UpdateNoteUseCase import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import org.junit.Assert.assertEquals import org.junit.Assert.assertNull +import org.junit.Assert.fail import org.junit.Test class NoteUseCasesTest { @@ -77,19 +83,21 @@ class NoteUseCasesTest { val delete = DeleteNoteUseCase(repo) val get = GetNoteUseCase(repo) - val note = Note(id = "n1", title = "A") + val note = Note(title = "A") - create(note) + val id = create(note) - val updated = note.copy(title = "B") + val created = get(id)!! + + val updated = created.copy(title = "B") update(updated) - val result = get("n1") + val result = get(id) assertEquals("B", result?.title) - delete("n1") + delete(id) - val result2 = get("n1") + val result2 = get(id) assertNull(result2) } @@ -105,12 +113,13 @@ class NoteUseCasesTest { val folder = NoteFolder(id = "f1", name = "Folder") folderRepo.createFolder(folder) - val note = Note(id = "n1", title = "Note") - createNote(note) + val note = Note(title = "Note") + + val noteId = createNote(note) - move("f1", "n1") + move("f1", noteId) - val updated = notesRepo.getNoteById("n1") + val updated = notesRepo.getNoteById(noteId) assertEquals("f1", updated?.folderId) } @@ -122,10 +131,206 @@ class NoteUseCasesTest { val observe = ObserveNotesUseCase(repo) val create = CreateNoteUseCase(repo) - create(Note(id = "n1", title = "Test")) - + create(Note(title = "Test")) val list = observe().first() assertEquals(1, list.size) } + + @Test + fun addTag_addsTagToNote() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = AddTagUseCase(repo) + + val note = + Note( + id = "n1", + title = "Test", + tags = setOf("old"), + ) + repo.createNote(note) + + useCase("n1", "new-tag") + + val updated = repo.getNoteById("n1") + + assertEquals(setOf("old", "new-tag"), updated?.tags) + } + + @Test + fun addTag_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = AddTagUseCase(repo) + + try { + useCase("missing_id", "tag") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found: missing_id", e.message) + } + } + + @Test + fun deleteTag_removesTagFromNote() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = DeleteTagUseCase(repo) + + val note = + Note( + id = "n2", + title = "Test", + tags = setOf("old", "remove-me"), + ) + repo.createNote(note) + + useCase("n2", "remove-me") + + val updated = repo.getNoteById("n2") + + assertEquals(setOf("old"), updated?.tags) + } + + @Test + fun deleteTag_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = DeleteTagUseCase(repo) + + try { + useCase("missing_id", "tag") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found: missing_id", e.message) + } + } + + @Test + fun duplicateNote_createsCopyWithNewIdAndCopiedTitle() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = DuplicateNoteUseCase(repo) + + val original = + Note( + id = "n3", + title = "Hello", + tags = setOf("kotlin"), + isFavorite = true, + summary = "summary", + ) + repo.createNote(original) + + val newId = useCase("n3") + + val duplicated = repo.getNoteById(newId) + + assertEquals(true, duplicated != null) + assertEquals("Hello Copy", duplicated?.title) + assertEquals(setOf("kotlin"), duplicated?.tags) + assertEquals(true, duplicated?.isFavorite) + assertEquals("summary", duplicated?.summary) + assertEquals("n3", original.id) + assertEquals(false, original.id == newId) + } + + @Test + fun duplicateNote_usesCopyWhenTitleBlank() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = DuplicateNoteUseCase(repo) + + val original = + Note( + id = "n4", + title = " ", + ) + repo.createNote(original) + + val newId = useCase("n4") + + val duplicated = repo.getNoteById(newId) + + assertEquals("Copy", duplicated?.title) + } + + @Test + fun duplicateNote_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = DuplicateNoteUseCase(repo) + + try { + useCase("missing_id") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found: missing_id", e.message) + } + } + + @Test + fun getAllFavorites_returnsOnlyFavoriteNotes() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = GetAllFavoritesUseCase(repo) + + repo.createNote( + Note( + id = "n5", + title = "A", + isFavorite = true, + ), + ) + repo.createNote( + Note( + id = "n6", + title = "B", + isFavorite = false, + ), + ) + + val list = useCase().first() + + assertEquals(1, list.size) + assertEquals("n5", list.first().id) + } + + @Test + fun switchFavorite_turnsFavoriteOnAndOff() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = SwitchFavoriteUseCase(repo) + + val note = + Note( + id = "n7", + title = "Fav", + isFavorite = false, + ) + repo.createNote(note) + + useCase("n7") + val afterFirstSwitch = repo.getNoteById("n7") + assertEquals(true, afterFirstSwitch?.isFavorite) + + useCase("n7") + val afterSecondSwitch = repo.getNoteById("n7") + assertEquals(false, afterSecondSwitch?.isFavorite) + } + + @Test + fun switchFavorite_throwsIfNoteNotFound() = + runBlocking { + val repo = FakeNotesRepo() + val useCase = SwitchFavoriteUseCase(repo) + + try { + useCase("missing_id") + fail("Expected IllegalArgumentException") + } catch (e: IllegalArgumentException) { + assertEquals("Note not found", e.message) + } + } }