Skip to content

Commit b125b52

Browse files
committed
Merge branch 'dev-innovation-full-info' into dev
2 parents 4ccb849 + d1d29f3 commit b125b52

File tree

7 files changed

+138
-7
lines changed

7 files changed

+138
-7
lines changed

src/main/java/com/example/demo/modules/innovationcomments/adapters/infrastructure/persistence/InnovationCatalogCommentJpaRepository.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.example.demo.modules.innovationcomments.adapters.infrastructure.persistence;
22

33
import com.example.demo.modules.innovationcomments.domain.model.InnovationCatalogComment;
4+
import org.springframework.data.domain.Pageable;
45
import org.springframework.data.jpa.repository.JpaRepository;
56
import org.springframework.data.jpa.repository.Modifying;
67
import org.springframework.data.jpa.repository.Query;
@@ -81,6 +82,16 @@ public interface InnovationCatalogCommentJpaRepository extends JpaRepository<Inn
8182
"ORDER BY c.activeSince DESC")
8283
List<InnovationCatalogComment> findAllCommentsByInnovationId(@Param("innovationId") Long innovationId);
8384

85+
/**
86+
* Finds all comments ordered by active since descending.
87+
*/
88+
List<InnovationCatalogComment> findAllByOrderByActiveSinceDesc();
89+
90+
/**
91+
* Finds comments ordered by active since descending limited by pageable.
92+
*/
93+
List<InnovationCatalogComment> findAllByOrderByActiveSinceDesc(Pageable pageable);
94+
8495
/**
8596
* Soft delete - marks comment as inactive instead of deleting it
8697
* Note: For update queries, we need @Modifying annotation
@@ -92,4 +103,4 @@ public interface InnovationCatalogCommentJpaRepository extends JpaRepository<Inn
92103
"SET c.isActive = false, c.activeSince = CURRENT_TIMESTAMP " +
93104
"WHERE c.id = :commentId")
94105
int softDeleteComment(@Param("commentId") Long commentId);
95-
}
106+
}

src/main/java/com/example/demo/modules/innovationcomments/adapters/infrastructure/persistence/InnovationCommentRepositoryAdapter.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.example.demo.modules.innovationcomments.domain.model.InnovationCatalogComment;
44
import com.example.demo.modules.innovationcomments.domain.port.out.InnovationCommentRepository;
5+
import org.springframework.data.domain.PageRequest;
56
import org.springframework.stereotype.Repository;
67
import org.springframework.transaction.annotation.Transactional;
78

@@ -62,6 +63,14 @@ public List<InnovationCatalogComment> findAllCommentsByInnovationId(Long innovat
6263
return jpaRepository.findAllCommentsByInnovationId(innovationId);
6364
}
6465

66+
@Override
67+
public List<InnovationCatalogComment> findAllCommentsOrderByActiveSinceDesc(Integer limit) {
68+
if (limit == null || limit <= 0) {
69+
return jpaRepository.findAllByOrderByActiveSinceDesc();
70+
}
71+
return jpaRepository.findAllByOrderByActiveSinceDesc(PageRequest.of(0, limit));
72+
}
73+
6574
@Override
6675
@Transactional
6776
public int softDeleteComment(Long commentId) {
@@ -73,4 +82,4 @@ public boolean existsActiveComment(Long commentId) {
7382
Optional<InnovationCatalogComment> comment = jpaRepository.findById(commentId);
7483
return comment.isPresent() && comment.get().getIsActive();
7584
}
76-
}
85+
}

src/main/java/com/example/demo/modules/innovationcomments/adapters/web/controller/InnovationCommentController.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,40 @@ public InnovationCommentController(InnovationCommentUseCase commentUseCase,
3838
this.commentMapper = commentMapper;
3939
}
4040

41+
@Operation(
42+
summary = "Get all comments",
43+
description = "Retrieves all comments ordered by most recent first. Optionally limit the number of comments returned."
44+
)
45+
@ApiResponses(value = {
46+
@ApiResponse(responseCode = "200", description = "Successfully retrieved comments"),
47+
@ApiResponse(responseCode = "400", description = "Invalid limit parameter"),
48+
@ApiResponse(responseCode = "503", description = "Comments table unavailable"),
49+
@ApiResponse(responseCode = "500", description = "Internal server error")
50+
})
51+
@GetMapping
52+
public ResponseEntity<List<InnovationCommentResponseDto>> getAllComments(
53+
@Parameter(description = "Maximum number of comments to return", required = false, example = "10")
54+
@RequestParam(value = "limit", required = false) Integer limit) {
55+
56+
try {
57+
List<InnovationCatalogComment> comments = commentUseCase.getAllComments(limit);
58+
return ResponseEntity.ok(commentMapper.toResponseDtoList(comments));
59+
} catch (IllegalArgumentException e) {
60+
logger.warn("Invalid limit parameter provided: {}", e.getMessage());
61+
return ResponseEntity.badRequest().build();
62+
} catch (RuntimeException e) {
63+
if (e.getMessage() != null && e.getMessage().contains("table not found")) {
64+
logger.error("Database table not found: {}", e.getMessage());
65+
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).build();
66+
}
67+
logger.error("Error fetching comments: {}", e.getMessage());
68+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
69+
} catch (Exception e) {
70+
logger.error("Unexpected error fetching comments: {}", e.getMessage());
71+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
72+
}
73+
}
74+
4175
@Operation(
4276
summary = "Get active comments by innovation ID",
4377
description = "Retrieves all active comments for a specific innovation, ordered by creation date descending"
@@ -213,4 +247,4 @@ public ResponseEntity<Void> deactivateComment(
213247

214248

215249

216-
}
250+
}

src/main/java/com/example/demo/modules/innovationcomments/application/service/InnovationCommentService.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,29 @@ public List<InnovationCatalogComment> getActiveCommentsByUserEmail(String userEm
149149
}
150150
}
151151

152+
@Override
153+
@Transactional(readOnly = true)
154+
public List<InnovationCatalogComment> getAllComments(Integer limit) {
155+
Integer sanitizedLimit = null;
156+
if (limit != null) {
157+
if (limit <= 0) {
158+
throw new IllegalArgumentException("Limit must be greater than zero");
159+
}
160+
sanitizedLimit = limit;
161+
}
162+
163+
try {
164+
return commentRepository.findAllCommentsOrderByActiveSinceDesc(sanitizedLimit);
165+
} catch (DataAccessException e) {
166+
logger.error("Database error while fetching comments: {}", e.getMessage());
167+
if (isTableNotExistsError(e)) {
168+
logger.warn("Table 'innovation_catalog_comments' does not exist in database");
169+
throw new RuntimeException("Comments table not found. Please ensure the database schema is properly initialized.", e);
170+
}
171+
throw new RuntimeException("Database error occurred while fetching comments", e);
172+
}
173+
}
174+
152175
@Override
153176
@Transactional(readOnly = true)
154177
public List<InnovationCatalogComment> getRecentActiveCommentsByInnovationId(Long innovationId) {
@@ -266,4 +289,4 @@ private boolean isTableNotExistsError(DataAccessException e) {
266289
lowerCaseMessage.contains("unknown table") ||
267290
lowerCaseMessage.contains("innovation_catalog_comments"));
268291
}
269-
}
292+
}

src/main/java/com/example/demo/modules/innovationcomments/domain/port/in/InnovationCommentUseCase.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ InnovationCatalogComment createCommentWithAudit(Long innovationId, String userNa
7070
*/
7171
List<InnovationCatalogComment> getRecentActiveCommentsByInnovationId(Long innovationId);
7272

73+
/**
74+
* Get all comments ordered by newest first, optionally limited.
75+
* @param limit Maximum number of comments to return. Null means all.
76+
* @return List of comments ordered by activeSince descending.
77+
*/
78+
List<InnovationCatalogComment> getAllComments(Integer limit);
79+
7380
/**
7481
* Soft delete a comment (mark as inactive)
7582
* @param commentId The comment ID to deactivate
@@ -83,4 +90,4 @@ InnovationCatalogComment createCommentWithAudit(Long innovationId, String userNa
8390
* @return true if comment exists and is active
8491
*/
8592
boolean isCommentActive(Long commentId);
86-
}
93+
}

src/main/java/com/example/demo/modules/innovationcomments/domain/port/out/InnovationCommentRepository.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ public interface InnovationCommentRepository {
6767
*/
6868
List<InnovationCatalogComment> findAllCommentsByInnovationId(Long innovationId);
6969

70+
/**
71+
* Find all comments ordered by activeSince descending, optionally limited.
72+
* @param limit Maximum number of comments to return. If null, returns all.
73+
* @return List of comments ordered by newest first.
74+
*/
75+
List<InnovationCatalogComment> findAllCommentsOrderByActiveSinceDesc(Integer limit);
76+
7077
/**
7178
* Soft delete a comment by marking it as inactive
7279
* @param commentId The comment ID to deactivate
@@ -80,4 +87,4 @@ public interface InnovationCommentRepository {
8087
* @return true if comment exists and is active
8188
*/
8289
boolean existsActiveComment(Long commentId);
83-
}
90+
}

src/test/java/com/example/demo/modules/innovationcomments/application/service/InnovationCommentServiceTest.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import static org.junit.jupiter.api.Assertions.*;
1717
import static org.mockito.ArgumentMatchers.any;
1818
import static org.mockito.ArgumentMatchers.anyLong;
19+
import static org.mockito.ArgumentMatchers.isNull;
1920
import static org.mockito.Mockito.*;
2021

2122
/**
@@ -229,6 +230,45 @@ void getRecentActiveCommentsByInnovationId_Success() {
229230
verify(commentRepository, times(1)).findRecentActiveCommentsByInnovationId(testInnovationId);
230231
}
231232

233+
@Test
234+
void getAllComments_NoLimit_ReturnsAll() {
235+
// Arrange
236+
List<InnovationCatalogComment> expectedComments = Arrays.asList(testCommentEntity);
237+
when(commentRepository.findAllCommentsOrderByActiveSinceDesc(isNull())).thenReturn(expectedComments);
238+
239+
// Act
240+
List<InnovationCatalogComment> result = commentService.getAllComments(null);
241+
242+
// Assert
243+
assertNotNull(result);
244+
assertEquals(1, result.size());
245+
verify(commentRepository, times(1)).findAllCommentsOrderByActiveSinceDesc(isNull());
246+
}
247+
248+
@Test
249+
void getAllComments_WithLimit_ReturnsLimited() {
250+
// Arrange
251+
List<InnovationCatalogComment> expectedComments = Arrays.asList(testCommentEntity);
252+
when(commentRepository.findAllCommentsOrderByActiveSinceDesc(5)).thenReturn(expectedComments);
253+
254+
// Act
255+
List<InnovationCatalogComment> result = commentService.getAllComments(5);
256+
257+
// Assert
258+
assertNotNull(result);
259+
verify(commentRepository, times(1)).findAllCommentsOrderByActiveSinceDesc(5);
260+
}
261+
262+
@Test
263+
void getAllComments_InvalidLimit_ThrowsException() {
264+
// Act & Assert
265+
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
266+
() -> commentService.getAllComments(0));
267+
268+
assertEquals("Limit must be greater than zero", exception.getMessage());
269+
verify(commentRepository, never()).findAllCommentsOrderByActiveSinceDesc(any());
270+
}
271+
232272
@Test
233273
void deactivateComment_Success() {
234274
// Arrange
@@ -308,4 +348,4 @@ void isCommentActive_NullCommentId_ReturnsFalse() {
308348
assertFalse(result);
309349
verify(commentRepository, never()).existsActiveComment(any());
310350
}
311-
}
351+
}

0 commit comments

Comments
 (0)