Skip to content

Commit 4166463

Browse files
committed
Add edit button for comments
1 parent e0aac08 commit 4166463

File tree

5 files changed

+81
-8
lines changed

5 files changed

+81
-8
lines changed

src/main/java/com/yandex/blog/controllers/PostController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,12 @@ public ResponseEntity<Void> addComment(@RequestParam("postId") long postId,
8686
postService.saveComment(new Comment(null, postId, content));
8787
return ResponseEntity.ok().build();
8888
}
89+
90+
@PostMapping("/comments/edit")
91+
@ResponseBody
92+
public ResponseEntity<Void> editComment(@RequestParam("id") long id,
93+
@RequestParam("content") String content) {
94+
postService.updateComment(id, content);
95+
return ResponseEntity.ok().build();
96+
}
8997
}

src/main/java/com/yandex/blog/services/PostService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ public void saveComment(Comment comment) {
8282
commentRepository.saveComment(comment);
8383
}
8484

85+
public void updateComment(Long commentId, String content) {
86+
commentRepository.updateComment(new Comment(commentId, null, content));
87+
}
88+
8589
public void deleteById(Long id) {
8690
postRepository.deleteById(id);
8791
tagRepository.deleteTagsForPost(id);

src/main/resources/templates/post.html

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,17 @@ <h1 th:text="${post.title}">Title</h1>
2222
</div>
2323
<div>
2424
<h3>Комментарии</h3>
25-
<ul id="comment-list" th:each="comment : ${post.comments}">
26-
<li th:text="${comment.content}"></li>
25+
<ul id="comment-list">
26+
<li th:each="comment : ${post.comments}" th:attr="data-id=${comment.id}">
27+
<span class="comment-content" th:text="${comment.content}"></span>
28+
<button class="edit-btn" type="button">Редактировать</button>
29+
</li>
2730
</ul>
2831
<form id="comment-form">
2932
<input type="hidden" name="postId" th:value="${post.id}">
3033
<input type="text" name="content" placeholder="Комментарий" required>
3134
<button type="submit">Добавить комментарий</button>
3235
</form>
33-
<script src="/MyPersonalBlog/js/createComment.js"></script>
3436
</div>
3537
<form th:action="@{/post/edit/{id}(id=${post.id})}" method="get">
3638
<button type="submit" class="btn btn-warning">Редактировать пост</button>
@@ -39,5 +41,7 @@ <h3>Комментарии</h3>
3941
<button type="submit" class="btn btn-danger">Удалить пост</button>
4042
</form>
4143
<a href="/MyPersonalBlog/feed">Назад к ленте</a>
44+
<script src="/MyPersonalBlog/js/createComment.js"></script>
45+
<script src="/MyPersonalBlog/js/editComment.js"></script>
4246
</body>
4347
</html>

src/main/webapp/js/editComment.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
document.querySelectorAll('.edit-btn').forEach(button => {
2+
button.addEventListener('click', function () {
3+
const li = button.closest('li');
4+
const span = li.querySelector('.comment-content');
5+
const oldText = span.textContent;
6+
const textArea = document.createElement('textarea');
7+
textArea.value = oldText;
8+
textArea.className = 'comment-edit';
9+
10+
span.replaceWith(textArea);
11+
textArea.focus();
12+
13+
textArea.addEventListener('keydown', async function (e) {
14+
if (e.ctrlKey && e.key === 'Enter') {
15+
const newText = textArea.value;
16+
const commentId = li.getAttribute('data-id');
17+
18+
const response = await fetch('/MyPersonalBlog/post/comments/edit', {
19+
method: 'POST',
20+
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
21+
body: `id=${commentId}&content=${encodeURIComponent(newText)}`
22+
});
23+
24+
if (response.ok) {
25+
const updatedSpan = document.createElement('span');
26+
updatedSpan.className = 'comment-content';
27+
updatedSpan.textContent = newText;
28+
29+
textArea.replaceWith(updatedSpan);
30+
} else {
31+
alert('Непредвиденная ошибка при сохранении коммента');
32+
}
33+
}
34+
});
35+
});
36+
});

src/test/java/com/yandex/blog/test/unit/PostServiceUnitTest.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.yandex.blog.test.unit;
22

33

4+
import com.yandex.blog.model.Comment;
45
import com.yandex.blog.model.Post;
56
import com.yandex.blog.repository.CommentRepository;
67
import com.yandex.blog.repository.PostRepository;
@@ -17,6 +18,8 @@
1718

1819
import static org.junit.jupiter.api.Assertions.assertEquals;
1920
import static org.junit.jupiter.api.Assertions.assertNotNull;
21+
import static org.mockito.ArgumentMatchers.any;
22+
import static org.mockito.ArgumentMatchers.eq;
2023
import static org.mockito.Mockito.mock;
2124
import static org.mockito.Mockito.times;
2225
import static org.mockito.Mockito.verify;
@@ -42,7 +45,7 @@ void setUp() {
4245
}
4346

4447
@Test
45-
void findById_shouldReturnPostWhenExists() {
48+
void findById_shouldCallPostRepositoryFindByIdAndTagRepositoryFindAllTags() {
4649
Post post = new Post(1L, "title1", "desc1", "content1", 0, null);
4750

4851
when(postRepository.findById(1L)).thenReturn(post);
@@ -58,7 +61,7 @@ void findById_shouldReturnPostWhenExists() {
5861
}
5962

6063
@Test
61-
void findById_shouldReturnNullWhenPostDoesNotExist() {
64+
void findById_shouldCallRepositoryFindById() {
6265
when(postRepository.findById(1L)).thenReturn(null);
6366

6467
postService.findById(1L);
@@ -67,7 +70,7 @@ void findById_shouldReturnNullWhenPostDoesNotExist() {
6770
}
6871

6972
@Test
70-
void save_shouldSavePost() {
73+
void save_shouldCallSave() {
7174
MultipartFile file = mock(MultipartFile.class);
7275
when(file.isEmpty()).thenReturn(true);
7376
Post post = new Post(1L, "title1", "desc1", "content1", 0, null);
@@ -77,7 +80,7 @@ void save_shouldSavePost() {
7780
}
7881

7982
@Test
80-
void deleteById_shouldDeletePost() {
83+
void deleteById_shouldCallPostAndTagRepositoriesDelete() {
8184
postService.deleteById(1L);
8285
verify(postRepository, times(1)).deleteById(1L);
8386
verify(tagRepository, times(1)).deleteTagsForPost(1L);
@@ -94,7 +97,7 @@ void splitToParagraphs_shouldSplitIntoParagraphs() {
9497
}
9598

9699
@Test
97-
void update_shouldUpdatePost() {
100+
void update_shouldCallRepositoryUpdate() {
98101
Post post = new Post(1L, "title1", "desc1", "content1", 0, null);
99102

100103
when(postRepository.findById(1L)).thenReturn(post);
@@ -124,4 +127,22 @@ void saveTags_shouldDeleteCurrentTagsAndCreateTagsIfNotExistsAndAttachNewTags()
124127
verify(tagRepository, times(1)).findTagIdsByNames(tags);
125128
verify(tagRepository, times(1)).attachTags(1L, List.of(1L));
126129
}
130+
131+
@Test
132+
void saveComments_shouldCallRepositorySave() {
133+
Comment comment = new Comment(1L, 1L, "comment1");
134+
135+
postService.saveComment(comment);
136+
137+
verify(commentRepository).saveComment(comment);
138+
}
139+
140+
@Test
141+
void updateComment_shouldCallRepositoryUpdateComment() {
142+
String updatedContent = "updatedContent";
143+
144+
postService.updateComment(1L, updatedContent);
145+
146+
verify(commentRepository).updateComment(any(Comment.class));
147+
}
127148
}

0 commit comments

Comments
 (0)