Skip to content

Commit

Permalink
CCMSPUI-453: NotificationServiceTest and additional JavaDoc
Browse files Browse the repository at this point in the history
Signed-off-by: Jamie Briggs <jamie.briggs@digital.justice.gov.uk>
  • Loading branch information
JamieBriggs-MoJ committed Dec 17, 2024
1 parent 57805eb commit c9b4646
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,22 @@
import uk.gov.laa.ccms.data.entity.Notification;


/**
* Repository interface for accessing {@link Notification} entities.
*
* <p>This repository extends the {@link ReadOnlyRepository} interface,
* it supports read-only operations for the {@link Notification} entity.
* This repository also extends {@link JpaSpecificationExecutor}, which
* allows the use of ${@link org.springframework.data.jpa.domain.Specification}
* to filter easier.</p>
*
* @author Jamie Briggs
* @see Notification
* @see ReadOnlyRepository
* @see org.springframework.data.jpa.domain.Specification
*/
@Repository
public interface NotificationRepository extends ReadOnlyRepository<Notification, Long>,
JpaSpecificationExecutor<Notification> {


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,75 @@
import org.springframework.data.jpa.domain.Specification;
import uk.gov.laa.ccms.data.entity.Notification;

/**
* A utility class for creating specifications to filter and query notifications.
*
* <p>The {@link NotificationSpecification} class provides mechanisms to construct dynamic
* query criteria using the JPA Specification API. It allows filtering of
* {@link Notification} entities based on various attributes such as case reference number,
* provider case reference, assigned user, client surname, and more.</p>
*
* <p>The filters include:</p>
* <ul>
* <li>Case reference number (partial matching support).</li>
* <li>Provider case reference (partial matching support).</li>
* <li>Assigned user ID.</li>
* <li>Client surname (partial matching support).</li>
* <li>Fee earner ID.</li>
* <li>Should include closed notifications.</li>
* <li>Notification type.</li>
* <li>Date range (start and end dates).</li>
* </ul>
*
* <p>This allows querying for notifications based on multiple combinations of these filters,
* with all specified conditions combined.</p>
*
* @see Notification
* @see Specification
* @see uk.gov.laa.ccms.data.repository.NotificationRepository
* @author Jamie Briggs
*/
public class NotificationSpecification {

/**
* Private constructor to prevent instantiation of the NotificationSpecification class.
*/
private NotificationSpecification() {}

/**
* Builds a {@link Specification} for filtering {@link Notification} entities based
* on various criteria. The method dynamically constructs filter
* conditions for the provided filter parameters.
*
* @param caseReferenceNumber the case reference number to filter by (optional).
* @param providerCaseReference the provider case reference to filter by (optional).
* @param assignedToUserId the user ID assigned to the notification (optional).
* @param clientSurname the client's surname to filter by (optional).
* @param feeEarnerId the ID of the fee earner to filter by (optional).
* @param includeClosed a flag to include closed notifications in the result set.
* @param notificationType the type of notification to filter by (optional).
* @param dateFrom the starting date for filtering notifications by the date assigned (inclusive).
* @param dateTo the ending date for filtering notifications by the date assigned (inclusive).
* @return a {@link Specification} object encapsulating the
* filtering logic for {@link Notification} entities.
*/
public static Specification<Notification> withFilters(
String caseReferenceNumber,
String providerCaseReference, String assignedToUserId, String clientSurname,
Integer feeEarnerId, boolean includeClosed, String notificationType, LocalDate dateFrom,
LocalDate dateTo
){
) {
return (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();

// Add predicates for each filter only if they are non-null
if (caseReferenceNumber != null) {
predicates.add(criteriaBuilder.like(root.get("lscCaseRefReference"), "%" + caseReferenceNumber + "%"));
predicates.add(criteriaBuilder.like(root.get("lscCaseRefReference"),
"%" + caseReferenceNumber + "%"));
}
if (providerCaseReference != null) {
predicates.add(criteriaBuilder.like(root.get("providerCaseReference"), "%" + providerCaseReference + "%"));
predicates.add(criteriaBuilder.like(root.get("providerCaseReference"),
"%" + providerCaseReference + "%"));
}
if (assignedToUserId != null) {
predicates.add(criteriaBuilder.equal(root.get("assignedTo"), assignedToUserId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,19 @@ public Optional<NotificationSummary> getUserNotificationSummary(String userId) {
}

/**
* Retrieves a paginated list of notifications assigned to a specific user.
* Retrieves a paginated list of notifications.
*
* @param pageable the pagination and sorting information for retrieving notifications
* @return an Optional containing a Notifications object if
* notifications are found, or an empty Optional otherwise
* @param caseReferenceNumber the case reference number to filter by (optional).
* @param providerCaseReference the provider case reference to filter by (optional).
* @param assignedToUserId the user ID assigned to the notification (optional).
* @param clientSurname the client's surname to filter by (optional).
* @param feeEarnerId the ID of the fee earner to filter by (optional).
* @param includeClosed a flag to include closed notifications in the result set.
* @param notificationType the type of notification to filter by (optional).
* @param dateFrom the starting date for filtering notifications by the date assigned (inclusive).
* @param dateTo the ending date for filtering notifications by the date assigned (inclusive).
* @param pageable the pageable to describe the requested pagination format.
* @return a paginated list of notifications.
*/
public Optional<Notifications> getNotifications(String caseReferenceNumber,
String providerCaseReference, String assignedToUserId, String clientSurname,
Expand All @@ -80,7 +88,6 @@ public Optional<Notifications> getNotifications(String caseReferenceNumber,
dateFrom,
dateTo),
pageable);
//Page<Notification> byAll = notificationRepository.findAll(Pageable.ofSize(100));
Notifications notifications = notificationsMapper.mapToNotificationsList(byAssignedTo);
return Optional.ofNullable(notifications);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package uk.gov.laa.ccms.data.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import uk.gov.laa.ccms.data.entity.Notification;
import uk.gov.laa.ccms.data.entity.NotificationCount;
import uk.gov.laa.ccms.data.mapper.NotificationSummaryMapper;
import uk.gov.laa.ccms.data.mapper.NotificationsMapper;
import uk.gov.laa.ccms.data.model.NotificationSummary;
import uk.gov.laa.ccms.data.model.Notifications;
import uk.gov.laa.ccms.data.model.UserDetail;
import uk.gov.laa.ccms.data.repository.NotificationCountRepository;
import uk.gov.laa.ccms.data.repository.NotificationRepository;

@ExtendWith(MockitoExtension.class)
@DisplayName("Notification service test")
class NotificationServiceTest {

private NotificationService notificationService;
@Mock
private NotificationCountRepository notificationCountRepository;
@Mock
private NotificationSummaryMapper notificationSummaryMapper;
@Mock
private NotificationRepository notificationRepository;
@Mock
private NotificationsMapper notificationsMapper;
@Mock
private UserService userService;


@BeforeEach
void setup() {
notificationService = new NotificationService(notificationCountRepository,
notificationSummaryMapper, notificationRepository, notificationsMapper, userService);
}

@Test
@DisplayName("getUserNotificationSummary(): Returns notification summary")
void getUserNotificationSummary_returnsNotificationSummary() {
// Given
String userId = "123456";
when(userService.getUser(userId)).thenReturn(Optional.of(new UserDetail()));
List<NotificationCount> notificationCounts = List.of(new NotificationCount());
when(notificationCountRepository.findAllByIdUserLoginId(userId)).thenReturn(notificationCounts);
NotificationSummary expected = new NotificationSummary();
when(notificationSummaryMapper.toNotificationSummary(notificationCounts)).thenReturn(expected);
// When
Optional<NotificationSummary> userNotificationSummary = notificationService.getUserNotificationSummary(
userId);
// Then
assertEquals(expected, userNotificationSummary.get());
}

@Test
@DisplayName("getUserNotificationSummary(): User not found")
void getUserNotificationSummary_userNotFound() {
// Given
String userId = "123456";
// When
Optional<NotificationSummary> userNotificationSummary = notificationService.getUserNotificationSummary(
userId);
// Then
assertFalse(userNotificationSummary.isPresent());
}

@Test
@DisplayName("getNotifications(): Returns data")
void getNotifications_returnsData() {
// Given
PageImpl<Notification> repositoryResult = new PageImpl<>(Collections.singletonList(new Notification()));
when(notificationRepository.findAll(any(Specification.class), any(Pageable.class)))
.thenReturn(
repositoryResult);
Notifications expected = new Notifications().size(1);
when(notificationsMapper.mapToNotificationsList(repositoryResult)).thenReturn(
expected
);
// When
Optional<Notifications> result = notificationService.getNotifications(
"Case Ref",
"Prov case ref",
"Assigned user id",
"surname",
123,
true,
"type",
LocalDate.of(2000, 1, 1),
LocalDate.of(2024, 1 ,1), Pageable.unpaged());
// Then
assertTrue(result.isPresent());
assertEquals(expected, result.get());
}

@Test
@DisplayName("getNotifications(): No data found")
void getNotifications_noDataFound() {
// Given
// When
Optional<Notifications> result = notificationService.getNotifications(
"Case Ref",
"Prov case ref",
"Assigned user id",
"surname",
123,
true,
"type",
LocalDate.of(2000, 1, 1),
LocalDate.of(2024, 1 ,1), Pageable.unpaged());
// Then
assertFalse(result.isPresent());
}
}

0 comments on commit c9b4646

Please sign in to comment.