Skip to content

Commit

Permalink
Merge pull request #24 from virtualidentityag/develop
Browse files Browse the repository at this point in the history
Update staging
  • Loading branch information
tkuzynow authored Jun 13, 2024
2 parents f7f28a8 + ea80f0a commit a4b41fd
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 32 deletions.
4 changes: 4 additions & 0 deletions api/userservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2589,6 +2589,10 @@ components:
description: "Datetime stamp when the user accepted data privacy"
emailNotifications:
$ref: "#/components/schemas/EmailNotificationsDTO"
sessions:
type: array
items:
$ref: "#/components/schemas/SessionDTO"

PatchUserDTO:
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,6 @@ public class UserDataResponseDTO {
private Boolean available;

private EmailNotificationsDTO emailNotifications;

private Set<SessionDTO> sessions;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import de.caritas.cob.userservice.api.adapters.web.dto.AgencyDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.LanguageCode;
import de.caritas.cob.userservice.api.adapters.web.dto.UserDataResponseDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.UserDataResponseDTO.UserDataResponseDTOBuilder;
import de.caritas.cob.userservice.api.helper.AuthenticatedUser;
import de.caritas.cob.userservice.api.helper.SessionDataProvider;
import de.caritas.cob.userservice.api.manager.consultingtype.ConsultingTypeManager;
Expand All @@ -11,6 +12,8 @@
import de.caritas.cob.userservice.api.model.UserAgency;
import de.caritas.cob.userservice.api.port.out.IdentityClientConfig;
import de.caritas.cob.userservice.api.service.agency.AgencyService;
import de.caritas.cob.userservice.api.service.session.SessionMapper;
import de.caritas.cob.userservice.api.service.session.SessionService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
Expand All @@ -37,6 +40,8 @@ public class AskerDataProvider {
private final @NonNull ConsultingTypeManager consultingTypeManager;
private final @NonNull IdentityClientConfig identityClientConfig;

private final @NonNull SessionService sessionService;

private final @NonNull EmailNotificationMapper emailNotificationMapper;

/**
Expand All @@ -46,24 +51,39 @@ public class AskerDataProvider {
* @return the user data
*/
public UserDataResponseDTO retrieveData(User user) {
return UserDataResponseDTO.builder()
.userId(user.getUserId())
.userName(user.getUsername())
.email(observeUserEmailAddress(user))
.isAbsent(false)
.encourage2fa(user.getEncourage2fa())
.isFormalLanguage(user.isLanguageFormal())
.preferredLanguage(LanguageCode.fromValue(user.getLanguageCode().toString()))
.isInTeamAgency(false)
.userRoles(authenticatedUser.getRoles())
.grantedAuthorities(authenticatedUser.getGrantedAuthorities())
.consultingTypes(getConsultingTypes(user))
.hasAnonymousConversations(false)
.hasArchive(false)
.dataPrivacyConfirmation(user.getDataPrivacyConfirmation())
.termsAndConditionsConfirmation(user.getTermsAndConditionsConfirmation())
.emailNotifications(emailNotificationMapper.toEmailNotificationsDTO(user))
.build();
var userDataResponseDTOBuilder =
UserDataResponseDTO.builder()
.userId(user.getUserId())
.userName(user.getUsername())
.email(observeUserEmailAddress(user))
.isAbsent(false)
.encourage2fa(user.getEncourage2fa())
.isFormalLanguage(user.isLanguageFormal())
.preferredLanguage(LanguageCode.fromValue(user.getLanguageCode().toString()))
.isInTeamAgency(false)
.userRoles(authenticatedUser.getRoles())
.grantedAuthorities(authenticatedUser.getGrantedAuthorities())
.consultingTypes(getConsultingTypes(user))
.hasAnonymousConversations(false)
.hasArchive(false)
.dataPrivacyConfirmation(user.getDataPrivacyConfirmation())
.termsAndConditionsConfirmation(user.getTermsAndConditionsConfirmation())
.emailNotifications(emailNotificationMapper.toEmailNotificationsDTO(user));

enrichWithUserSessions(user, userDataResponseDTOBuilder);
return userDataResponseDTOBuilder.build();
}

private void enrichWithUserSessions(
User user, UserDataResponseDTOBuilder userDataResponseDTOBuilder) {
List<Session> sessionsByUser = sessionService.findSessionsByUser(user);
if (CollectionUtils.isNotEmpty(sessionsByUser)) {
SessionMapper sessionMapper = new SessionMapper();
userDataResponseDTOBuilder.sessions(
sessionsByUser.stream()
.map(sessionMapper::convertToSessionDTO)
.collect(Collectors.toSet()));
}
}

private String observeUserEmailAddress(User user) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,13 @@ public Optional<Session> findSessionByConsultantAndUserAndConsultingType(
return Optional.empty();
}

public List<Session> findSessionsByUser(User user) {
if (nonNull(user)) {
return sessionRepository.findByUser(user);
}
return emptyList();
}

public String findGroupIdByConsultantAndUser(String consultantId, String askerId) {

Optional<Consultant> consultant = consultantService.getConsultant(consultantId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ public class DeleteInactiveSessionsAndUserService {
private final @NonNull SessionRepository sessionRepository;
private final @NonNull DeleteUserAccountService deleteUserAccountService;
private final @NonNull WorkflowErrorMailService workflowErrorMailService;
private final @NonNull WorkflowErrorLogService workflowErrorLogService;
private final @NonNull DeleteSessionService deleteSessionService;
private final @NonNull InactivePrivateGroupsProvider inactivePrivateGroupsProvider;

private static final String USER_NOT_FOUND_REASON = "User could not be found.";
private static final String RC_SESSION_GROUP_NOT_FOUND_REASON =
"Session with rc group id could not be found.";

/**
* Deletes all inactive sessions and even the asker accounts, if there are no more active
* sessions.
Expand All @@ -49,15 +54,28 @@ public void deleteInactiveSessionsAndUsers() {
.flatMap(Collection::stream)
.collect(Collectors.toList());

sendWorkflowErrorsMail(workflowErrors);
findWorkflowErrorByReason(workflowErrors);
}

private void sendWorkflowErrorsMail(List<DeletionWorkflowError> workflowErrors) {
private void findWorkflowErrorByReason(List<DeletionWorkflowError> workflowErrors) {
if (isNotEmpty(workflowErrors)) {
this.workflowErrorMailService.buildAndSendErrorMail(workflowErrors);
List<DeletionWorkflowError> rcSessionGroupNotFoundWorkflowErrors =
getSameReasonWorkflowErrors(workflowErrors, RC_SESSION_GROUP_NOT_FOUND_REASON);
List<DeletionWorkflowError> workflowErrorsExceptSessionGroupNotFound =
new ArrayList<>(workflowErrors);
workflowErrorsExceptSessionGroupNotFound.removeAll(rcSessionGroupNotFoundWorkflowErrors);
this.workflowErrorLogService.logWorkflowErrors(rcSessionGroupNotFoundWorkflowErrors);
this.workflowErrorMailService.buildAndSendErrorMail(workflowErrorsExceptSessionGroupNotFound);
}
}

private static List<DeletionWorkflowError> getSameReasonWorkflowErrors(
List<DeletionWorkflowError> workflowErrors, String reason) {
return workflowErrors.stream()
.filter(error -> reason.equals(error.getReason()))
.collect(Collectors.toList());
}

private List<DeletionWorkflowError> performDeletionWorkflow(
Entry<String, List<String>> userInactiveGroupEntry) {

Expand All @@ -73,7 +91,7 @@ private List<DeletionWorkflowError> performDeletionWorkflow(
.deletionSourceType(ASKER)
.deletionTargetType(ALL)
.identifier(userInactiveGroupEntry.getKey())
.reason("User could not be found.")
.reason(USER_NOT_FOUND_REASON)
.timestamp(nowInUtc())
.build()));

Expand Down Expand Up @@ -115,7 +133,7 @@ private List<DeletionWorkflowError> performSessionDeletion(
.deletionSourceType(ASKER)
.deletionTargetType(ALL)
.identifier(rcGroupId)
.reason("Session with rc group id could not be found.")
.reason(RC_SESSION_GROUP_NOT_FOUND_REASON)
.timestamp(nowInUtc())
.build()));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package de.caritas.cob.userservice.api.workflow.delete.service;

import static org.apache.commons.collections4.CollectionUtils.isNotEmpty;

import de.caritas.cob.userservice.api.workflow.delete.model.DeletionWorkflowError;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/** Service class to log all deletion workflow errors. */
@Slf4j
@Service
@RequiredArgsConstructor
public class WorkflowErrorLogService {

public void logWorkflowErrors(List<DeletionWorkflowError> workflowErrors) {
if (isNotEmpty(workflowErrors)) {
workflowErrors.forEach(
workflowError ->
log.warn(
"Errors during deletion workflow:"
+ " SourceType = {}; "
+ "TargetType = {}; "
+ "Identifier = {}; "
+ "Reason = {}; "
+ "Timestamp = {}.",
workflowError.getDeletionSourceType(),
workflowError.getDeletionTargetType(),
workflowError.getIdentifier(),
workflowError.getReason(),
workflowError.getTimestamp()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,26 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.api.client.util.Sets;
import com.google.common.collect.Lists;
import com.neovisionaries.i18n.LanguageCode;
import de.caritas.cob.userservice.api.adapters.web.dto.AgencyDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.SessionDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.UserDataResponseDTO;
import de.caritas.cob.userservice.api.config.auth.UserRole;
import de.caritas.cob.userservice.api.exception.httpresponses.InternalServerErrorException;
import de.caritas.cob.userservice.api.helper.AuthenticatedUser;
import de.caritas.cob.userservice.api.helper.SessionDataProvider;
import de.caritas.cob.userservice.api.manager.consultingtype.ConsultingTypeManager;
import de.caritas.cob.userservice.api.model.Session;
import de.caritas.cob.userservice.api.model.Session.RegistrationType;
import de.caritas.cob.userservice.api.model.Session.SessionStatus;
import de.caritas.cob.userservice.api.model.User;
import de.caritas.cob.userservice.api.port.out.IdentityClientConfig;
import de.caritas.cob.userservice.api.service.agency.AgencyService;
import de.caritas.cob.userservice.api.service.session.SessionService;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
Expand Down Expand Up @@ -61,6 +69,8 @@ public class AskerDataProviderTest {

@Mock EmailNotificationMapper emailNotificationMapper;

@Mock SessionService sessionService;

@Test
public void
retrieveData_Should_ReturnUserDataWithAgency_When_ProvidedWithUserWithAgencyInSession() {
Expand Down Expand Up @@ -104,6 +114,39 @@ public void retrieveData_Should_ReturnUserDataWithAgency_When_ProvidedWithUserWi
assertEquals(AGENCY_DTO_KREUZBUND, agency);
}

@Test
public void retrieveData_Should_ReturnUserDataWithSessions_When_ProvidedWithUserWithSessions() {
givenAnEmailDummySuffixConfig();
when(authenticatedUser.getRoles()).thenReturn(asSet(UserRole.USER.getValue()));
ArrayList<Session> inputSessions =
Lists.newArrayList(
Session.builder()
.id(1L)
.registrationType(RegistrationType.ANONYMOUS)
.languageCode(LanguageCode.de)
.postcode("12111")
.status(SessionStatus.NEW)
.createDate(LocalDateTime.now())
.build(),
Session.builder()
.id(2L)
.registrationType(RegistrationType.REGISTERED)
.languageCode(LanguageCode.de)
.postcode("11111")
.createDate(LocalDateTime.now())
.status(SessionStatus.NEW)
.build());
when(sessionService.findSessionsByUser(Mockito.any(User.class))).thenReturn(inputSessions);
Set<SessionDTO> sessions = askerDataProvider.retrieveData(USER).getSessions();

assertEquals(sessions.size(), 2);
var expectedSessionsIds = Sets.newHashSet();
expectedSessionsIds.add(1L);
expectedSessionsIds.add(2L);
var sessionIds = sessions.stream().map(SessionDTO::getId).collect(Collectors.toSet());
assertEquals(sessionIds, expectedSessionsIds);
}

@Test(expected = InternalServerErrorException.class)
public void
retrieveData_GetConsultingTypes_Should_ThrowInternalServerErrorException_When_AgencyServiceHelperFails() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package de.caritas.cob.userservice.api.workflow.delete.service;

import static org.mockito.ArgumentMatchers.any;
import static de.caritas.cob.userservice.api.helper.CustomLocalDateTime.nowInUtc;
import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionSourceType.ASKER;
import static de.caritas.cob.userservice.api.workflow.delete.model.DeletionTargetType.ALL;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

Expand Down Expand Up @@ -31,14 +34,16 @@ public class DeleteInactiveSessionsAndUserServiceTest {
@InjectMocks private DeleteInactiveSessionsAndUserService deleteInactiveSessionsAndUserService;

@Mock private WorkflowErrorMailService workflowErrorMailService;
@Mock private WorkflowErrorLogService workflowErrorLogService;
@Mock private UserRepository userRepository;
@Mock private SessionRepository sessionRepository;
@Mock private DeleteUserAccountService deleteUserAccountService;
@Mock private DeleteSessionService deleteSessionService;
@Mock private InactivePrivateGroupsProvider inactivePrivateGroupsProvider;

@Test
public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() {
public void
deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail_When_userNotFoundReason() {

EasyRandom easyRandom = new EasyRandom();
User user = easyRandom.nextObject(User.class);
Expand All @@ -60,7 +65,9 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() {

deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers();

verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any());
verify(workflowErrorLogService, Mockito.times(1)).logWorkflowErrors(Collections.emptyList());
verify(workflowErrorMailService, Mockito.times(1))
.buildAndSendErrorMail(argThat(list -> !list.isEmpty()));
}

@Test
Expand Down Expand Up @@ -115,7 +122,7 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() {

@Test
public void
deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorMail_WhenUserHasActiveAndInactiveSessionsAndHasErrors() {
deleteInactiveSessionsAndUsers_Should_logWorkflowErrorMail_WhenUserHasActiveAndInactiveSessionsAndHasErrors() {

EasyRandom easyRandom = new EasyRandom();
User user = easyRandom.nextObject(User.class);
Expand All @@ -132,18 +139,28 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() {
when(userRepository.findByRcUserIdAndDeleteDateIsNull(anyString()))
.thenReturn(Optional.of(user));
when(sessionRepository.findByUser(user)).thenReturn(Arrays.asList(session1, session2));
DeletionWorkflowError deletionWorkflowError = Mockito.mock(DeletionWorkflowError.class);
DeletionWorkflowError deletionWorkflowError =
DeletionWorkflowError.builder()
.deletionSourceType(ASKER)
.deletionTargetType(ALL)
.identifier(null)
.reason("Session with rc group id could not be found.")
.timestamp(nowInUtc())
.build();
when(deleteSessionService.performSessionDeletion(session1))
.thenReturn(Collections.singletonList(deletionWorkflowError));

deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers();

verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any());
verify(workflowErrorLogService, Mockito.times(1))
.logWorkflowErrors(argThat(list -> !list.isEmpty()));
verify(workflowErrorMailService, Mockito.times(1))
.buildAndSendErrorMail(Collections.emptyList());
}

@Test
public void
deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorMail_WhenSessionCouldNotBeFound() {
deleteInactiveSessionsAndUsers_Should_logWorkflowErrorMail_WhenSessionCouldNotBeFound() {

EasyRandom easyRandom = new EasyRandom();
User user = easyRandom.nextObject(User.class);
Expand All @@ -164,7 +181,10 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() {

deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers();

verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any());
verify(workflowErrorLogService, Mockito.times(1))
.logWorkflowErrors(argThat(list -> !list.isEmpty()));
verify(workflowErrorMailService, Mockito.times(1))
.buildAndSendErrorMail(Collections.emptyList());
}

@Test
Expand All @@ -187,6 +207,8 @@ public void deleteInactiveSessionsAndUsers_Should_SendWorkflowErrorsMail() {

deleteInactiveSessionsAndUserService.deleteInactiveSessionsAndUsers();

verify(workflowErrorMailService, Mockito.times(1)).buildAndSendErrorMail(any());
verify(workflowErrorLogService, Mockito.times(1)).logWorkflowErrors(Collections.emptyList());
verify(workflowErrorMailService, Mockito.times(1))
.buildAndSendErrorMail(argThat(list -> !list.isEmpty()));
}
}
Loading

0 comments on commit a4b41fd

Please sign in to comment.