Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@

---

### ☑️ 메모 수정 기능
### 메모 수정 기능

- 저장된 메모의 content를 수정할 수 있어야 한다.

### ⚠️ 메모 수정 기능 예외 상황

- 수정할 메모가 없다면 아무 수행도 해선 안된다.

---

### ☑️ 메모 추출 기능
Expand Down
18 changes: 18 additions & 0 deletions src/main/kotlin/com/github/yeoli/devlog/domain/memo/domain/Memo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,22 @@ class Memo(
visibleStart = this.visibleStart,
visibleEnd = this.visibleEnd
)

fun update(
content: String = this.content
): Memo {
return Memo(
id = this.id,
createdAt = this.createdAt,
updatedAt = LocalDateTime.now(),
content = content,
commitHash = this.commitHash,
filePath = this.filePath,
selectedCodeSnippet = this.selectedCodeSnippet,
selectionStart = this.selectionStart,
selectionEnd = this.selectionEnd,
visibleStart = this.visibleStart,
visibleEnd = this.visibleEnd
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ class MemoRepository : PersistentStateComponent<MemoStorageState> {
state.memos.add(memo.toState())
}

fun findMemoById(memoId: Long): Memo? {
val memoState = state.memos.find { it.id == memoId }
return memoState?.toDomain()
}

fun getAll(): List<Memo> {
return state.memos.map { it.toDomain() }
}

private fun removeMemoById(memoId: Long) {
fun removeMemoById(memoId: Long) {
state.memos.removeIf { it.id == memoId }
}

Expand All @@ -37,4 +42,5 @@ class MemoRepository : PersistentStateComponent<MemoStorageState> {
removeMemoById(memoId)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,15 @@ class MemoService(private val project: Project) {
logger.warn("[removeMemos] 메모 삭제 중 알 수 없는 에러가 발생했습니다. ${e.message}", e)
}
}

fun updateMemo(memoId: Long, newContent: String) {
try {
val memo: Memo = memoRepository.findMemoById(memoId) ?: return
val updated = memo.update(newContent)
memoRepository.removeMemoById(memoId)
memoRepository.save(updated)
} catch (e: Exception) {
logger.warn("[updateMemo] 메모 수정 중 알 수 없는 에러가 발생했습니다. ${e.message}", e)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ class MemoServiceTest : BasePlatformTestCase() {
// given
val memo1 = Memo(
id = System.currentTimeMillis(),
createdAt = java.time.LocalDateTime.now(),
updatedAt = java.time.LocalDateTime.now(),
createdAt = LocalDateTime.now(),
updatedAt = LocalDateTime.now(),
content = "메모1",
commitHash = null,
filePath = "/path/to/file1",
Expand All @@ -205,8 +205,8 @@ class MemoServiceTest : BasePlatformTestCase() {

val memo2 = Memo(
id = System.currentTimeMillis() + 1,
createdAt = java.time.LocalDateTime.now(),
updatedAt = java.time.LocalDateTime.now(),
createdAt = LocalDateTime.now(),
updatedAt = LocalDateTime.now(),
content = "메모2",
commitHash = null,
filePath = "/path/to/file2",
Expand Down Expand Up @@ -243,7 +243,7 @@ class MemoServiceTest : BasePlatformTestCase() {

// ========= 메모 삭제 기능 =========
fun `test 메모 삭제 기능 - 정상 삭제`() {
val now = java.time.LocalDateTime.now()
val now = LocalDateTime.now()
val memo1 = Memo(
id = 1L,
createdAt = now,
Expand Down Expand Up @@ -310,5 +310,90 @@ class MemoServiceTest : BasePlatformTestCase() {
}
assertTrue(result.isSuccess, "예외가 발생하면 안 됩니다.")
}
}

// ========= 메모 수정 기능 =========
fun `test 메모 수정 성공`() {
// given
val now = LocalDateTime.now()
val original = Memo(
id = 1L,
createdAt = now,
updatedAt = now,
content = "old",
commitHash = null,
filePath = "/path/file",
selectedCodeSnippet = "snippet",
selectionStart = 0,
selectionEnd = 5,
visibleStart = 1,
visibleEnd = 3
)
whenever(memoRepository.findMemoById(1L)).thenReturn(original)

val updated = original.update(content = "new")
whenever(memoRepository.save(updated)).thenAnswer {}

// when
MemoService(project).updateMemo(1L, "new")

// then
org.mockito.kotlin.verify(memoRepository).removeMemoById(1L)
org.mockito.kotlin.verify(memoRepository).save(org.mockito.kotlin.check {
assertEquals("new", it.content)
})
}

fun `test 조회 실패 시 아무 것도 하지 않음`() {
// given
whenever(memoRepository.findMemoById(999L)).thenReturn(null)

// when
MemoService(project).updateMemo(999L, "new")

// then
org.mockito.kotlin.verify(memoRepository, org.mockito.kotlin.never())
.removeMemoById(org.mockito.kotlin.any())
org.mockito.kotlin.verify(memoRepository, org.mockito.kotlin.never())
.save(org.mockito.kotlin.any())
}

fun `test udpate 적용된 필드 검증`() {
// given
val createdAt = LocalDateTime.now().minusDays(1)
val original = Memo(
id = 1L,
createdAt = createdAt,
updatedAt = createdAt,
content = "before",
commitHash = "abc",
filePath = "/path",
selectedCodeSnippet = "code",
selectionStart = 10,
selectionEnd = 20,
visibleStart = 5,
visibleEnd = 15
)
whenever(memoRepository.findMemoById(1L)).thenReturn(original)

val service = MemoService(project)

// when
service.updateMemo(1L, "after")

// then
org.mockito.kotlin.verify(memoRepository).save(org.mockito.kotlin.check { updated ->
assertEquals(1L, updated.id)
assertEquals("after", updated.content)

assertEquals(original.createdAt, updated.createdAt)
assertEquals(original.commitHash, updated.commitHash)
assertEquals(original.filePath, updated.filePath)
assertEquals(original.selectedCodeSnippet, updated.selectedCodeSnippet)
assertEquals(original.selectionStart, updated.selectionStart)
assertEquals(original.selectionEnd, updated.selectionEnd)
assertEquals(original.visibleStart, updated.visibleStart)
assertEquals(original.visibleEnd, updated.visibleEnd)
})
}

}
Loading