Skip to content

Commit

Permalink
[SELC-5856] Fix add user product Role to allowed multirole (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
flaminiaScarciofolo authored Oct 28, 2024
1 parent bcefe5c commit deb015e
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -480,23 +480,36 @@ private Uni<UserInstitution> updateOrCreateUserInstitution(AddUserRoleDto userDt
}

log.info(USER_INSTITUTION_FOUNDED, userId, userDto.getInstitutionId());
//Verify if productRole already exists
if(Optional.ofNullable(userInstitution.getProducts())
.orElse(Collections.emptyList())
.stream()
.filter(onboardedProduct -> onboardedProduct.getStatus().equals(ACTIVE))
.filter(onboardedProduct -> userDto.getProduct().getProductId().equals(onboardedProduct.getProductId()))
.anyMatch(onboardedProduct -> userDto.getProduct().getProductRoles().contains(onboardedProduct.getProductRole()))){
return Uni.createFrom().nullItem();

if(checkAlreadyOnboardedRole(userDto.getProduct(), userInstitution)){
throw new InvalidRequestException(String.format("User already has different role on Product %s", userDto.getProduct().getProductId()));
}

List<String> productRoleToAdd = checkAlreadyOnboardedProdcutRole(userDto.getProduct().getProductId(), userDto.getProduct().getProductRoles(), userInstitution);
List<String> productRoleToAdd = checkAlreadyOnboardedProductRole(userDto.getProduct().getProductId(), userDto.getProduct().getProductRoles(), userInstitution);
userDto.getProduct().setProductRoles(productRoleToAdd);

productRoleToAdd.forEach(productRole -> userInstitution.getProducts().add(onboardedProductMapper.toNewOnboardedProduct(userDto.getProduct(), productRole)));
return Uni.createFrom().item(userInstitution);
}

private boolean checkAlreadyOnboardedRole(AddUserRoleDto.Product product, UserInstitution userInstitution) {
return Optional.ofNullable(userInstitution.getProducts())
.orElse(Collections.emptyList())
.stream()
.filter(onboardedProduct -> onboardedProduct.getStatus().equals(ACTIVE))
.filter(onboardedProduct -> onboardedProduct.getProductId().equalsIgnoreCase(product.getProductId()))
.anyMatch(onboardedProduct -> !onboardedProduct.getRole().name().equalsIgnoreCase(product.getRole()));
}

private boolean checkAlreadyOnboardedRole(CreateUserDto.Product product, UserInstitution userInstitution) {
return Optional.ofNullable(userInstitution.getProducts())
.orElse(Collections.emptyList())
.stream()
.filter(onboardedProduct -> onboardedProduct.getStatus().equals(ACTIVE))
.filter(onboardedProduct -> onboardedProduct.getProductId().equalsIgnoreCase(product.getProductId()))
.anyMatch(onboardedProduct -> !onboardedProduct.getRole().name().equalsIgnoreCase(product.getRole()));
}

/**
* Updates or creates a UserInstitution based on the provided data.
* Return null value if UserInstitution exists in ACTIVE with the same productRole
Expand All @@ -514,17 +527,13 @@ private Uni<UserInstitution> updateOrCreateUserInstitution(CreateUserDto userDto
}

log.info(USER_INSTITUTION_FOUNDED, userId, userDto.getInstitutionId());
//Verify if productRole already exists
if(Optional.ofNullable(userInstitution.getProducts())
.orElse(Collections.emptyList())
.stream()
.filter(onboardedProduct -> onboardedProduct.getStatus().equals(ACTIVE))
.filter(onboardedProduct -> userDto.getProduct().getProductId().equals(onboardedProduct.getProductId()))
.anyMatch(onboardedProduct -> userDto.getProduct().getProductRoles().contains(onboardedProduct.getProductRole()))){
return Uni.createFrom().nullItem();
log.info(USER_INSTITUTION_FOUNDED, userId, userDto.getInstitutionId());

if(checkAlreadyOnboardedRole(userDto.getProduct(), userInstitution)){
throw new InvalidRequestException(String.format("User already has different role on Product %s", userDto.getProduct().getProductId()));
}

List<String> productRoleToAdd = checkAlreadyOnboardedProdcutRole(userDto.getProduct().getProductId(), userDto.getProduct().getProductRoles(), userInstitution);
List<String> productRoleToAdd = checkAlreadyOnboardedProductRole(userDto.getProduct().getProductId(), userDto.getProduct().getProductRoles(), userInstitution);
userDto.getProduct().setProductRoles(productRoleToAdd);

userInstitution.setUserMailUuid(mailUuid);
Expand All @@ -533,20 +542,24 @@ private Uni<UserInstitution> updateOrCreateUserInstitution(CreateUserDto userDto
return Uni.createFrom().item(userInstitution);
}

private List<String> checkAlreadyOnboardedProdcutRole(String productId, List<String> productRole, UserInstitution userInstitution) {
List<String> productAlreadyOnboarded = Optional.ofNullable(userInstitution.getProducts())
private List<String> checkAlreadyOnboardedProductRole(String productId, List<String> productRole, UserInstitution userInstitution) {

List<String> productAlreadyOnboarded = new ArrayList<>(Optional.ofNullable(userInstitution.getProducts())
.orElse(Collections.emptyList())
.stream()
.filter(onboardedProduct -> onboardedProduct.getProductId().equals(productId))
//.filter(onboardedProduct -> productRole.contains(onboardedProduct.getProductRole()))
.filter(onboardedProduct -> productRole.contains(onboardedProduct.getProductRole()))
.filter(onboardedProduct -> onboardedProduct.getStatus().equals(ACTIVE))
.map(OnboardedProduct::getProductRole)
.toList();
.toList());

List<String> productRoleFinal = new ArrayList<>(productRole);
productRoleFinal.removeIf(productAlreadyOnboarded::contains);

if (!productAlreadyOnboarded.isEmpty()) {
if (!productAlreadyOnboarded.isEmpty() && CollectionUtils.isNullOrEmpty(productRoleFinal)) {
throw new InvalidRequestException(String.format("User already has roles on Product %s", productId));
}
return productRole;
return productRoleFinal;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.helpers.test.AssertSubscriber;
import io.smallrye.mutiny.helpers.test.UniAssertSubscriber;
import it.pagopa.selfcare.onboarding.common.PartyRole;
import it.pagopa.selfcare.product.entity.Product;
import it.pagopa.selfcare.product.service.ProductService;
import it.pagopa.selfcare.user.controller.request.AddUserRoleDto;
Expand Down Expand Up @@ -58,10 +59,12 @@
import java.util.*;

import static it.pagopa.selfcare.onboarding.common.PartyRole.MANAGER;
import static it.pagopa.selfcare.onboarding.common.PartyRole.OPERATOR;
import static it.pagopa.selfcare.user.constant.CustomError.*;
import static it.pagopa.selfcare.user.model.constants.EventsMetric.EVENTS_USER_INSTITUTION_SUCCESS;
import static it.pagopa.selfcare.user.model.constants.EventsName.EVENT_USER_MS_NAME;
import static it.pagopa.selfcare.user.model.constants.OnboardedProductState.ACTIVE;
import static it.pagopa.selfcare.user.model.constants.OnboardedProductState.DELETED;
import static it.pagopa.selfcare.user.service.UserServiceImpl.USERS_FIELD_LIST_WITHOUT_FISCAL_CODE;
import static it.pagopa.selfcare.user.service.UserServiceImpl.USERS_WORKS_FIELD_LIST;
import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -141,6 +144,7 @@ private UserInstitution createUserInstitution(){
OnboardedProduct productTest = new OnboardedProduct();
productTest.setProductId("prod-test");
productTest.setProductRole("operator");
productTest.setRole(PartyRole.OPERATOR);
productTest.setStatus(OnboardedProductState.DELETED);
List<OnboardedProduct> products = new ArrayList<>();
products.add(product);
Expand Down Expand Up @@ -807,7 +811,8 @@ void testCreateOrUpdateUser_UpdateUser_SuccessByFiscalCode_with2role() {
CreateUserDto.User user = new CreateUserDto.User();
user.setFiscalCode("fiscalCode");
CreateUserDto.Product createUserProduct = new CreateUserDto.Product();
createUserProduct.setProductId("prod-io");
createUserProduct.setProductId("test");
createUserProduct.setRole(MANAGER.name());
createUserProduct.setProductRoles(List.of("admin2","admin3"));
createUserDto.setUser(user);
createUserDto.setProduct(createUserProduct);
Expand Down Expand Up @@ -847,6 +852,96 @@ void testCreateOrUpdateUser_UpdateUser_SuccessByFiscalCode_with2role() {
verify(userNotificationService).sendCreateUserNotification(any(), any(), any(), any(), any(),any());
}

@Test
void testCreateOrUpdateUser_UpdateUser_SuccessByFiscalCode_with2role_oneAlreadyOnboarded() {
UserInstitution userInstitution = createUserInstitution();
// Prepare test data
CreateUserDto createUserDto = new CreateUserDto();
CreateUserDto.User user = new CreateUserDto.User();
user.setFiscalCode("fiscalCode");
CreateUserDto.Product createUserProduct = new CreateUserDto.Product();
createUserProduct.setProductId("test");
createUserProduct.setRole(MANAGER.name());
createUserProduct.setProductRoles(List.of("admin","admin3"));
createUserDto.setUser(user);
createUserDto.setProduct(createUserProduct);
LoggedUser loggedUser = LoggedUser.builder().build();

Product product = new Product();
product.setDescription("description");

UserToNotify userToNotify = new UserToNotify();
userToNotify.setUserId(userId.toString());

UserNotificationToSend userNotificationToSend = new UserNotificationToSend();
userNotificationToSend.setUser(userToNotify);

// Mock external dependencies
when(userRegistryApi.searchUsingPOST(any(), any())).thenReturn(Uni.createFrom().item(userResource));
when(userInstitutionService.findByUserIdAndInstitutionId(any(), any())).thenReturn(Uni.createFrom().item(userInstitution));
when(userRegistryApi.updateUsingPATCH(any(), any())).thenReturn(Uni.createFrom().item(Response.ok().build()));
when(userInstitutionService.persistOrUpdate(any())).thenReturn(Uni.createFrom().item(userInstitution));
when(productService.getProduct(any())).thenReturn(product);
when(userNotificationService.sendCreateUserNotification(any(), any(), any(), any(), any(),any())).thenReturn(Uni.createFrom().voidItem());
when(userUtils.buildUsersNotificationResponse(any(), any())).thenReturn(List.of(userNotificationToSend));

// Call the method
UniAssertSubscriber<CreateOrUpdateUserByFiscalCodeResponse> subscriber = userService.createOrUpdateUserByFiscalCode(createUserDto, loggedUser)
.subscribe().withSubscriber(UniAssertSubscriber.create());

Assertions.assertEquals(3, userInstitution.getProducts().size());
// Verify the result

CreateOrUpdateUserByFiscalCodeResponse response = subscriber.awaitItem().getItem();

assertEquals(userId.toString(),response.getUserId());
verify(userRegistryApi).updateUsingPATCH(any(), any());
verify(userInstitutionService).persistOrUpdate(any());
verify(userInstitutionService).findByUserIdAndInstitutionId(any(), any());
verify(userNotificationService).sendCreateUserNotification(any(), any(), any(), any(), any(),any());
}

@Test
void testCreateOrUpdateUser_UpdateUser_SuccessByFiscalCode_with2role_oneAlreadyOnboarded_withDifferentSelcRole() {
UserInstitution userInstitution = createUserInstitution();
// Prepare test data
CreateUserDto createUserDto = new CreateUserDto();
CreateUserDto.User user = new CreateUserDto.User();
user.setFiscalCode("fiscalCode");
CreateUserDto.Product createUserProduct = new CreateUserDto.Product();
createUserProduct.setProductId("test");
createUserProduct.setRole(PartyRole.OPERATOR.name());
createUserProduct.setProductRoles(List.of("admin","admin3"));
createUserDto.setUser(user);
createUserDto.setProduct(createUserProduct);
LoggedUser loggedUser = LoggedUser.builder().build();

Product product = new Product();
product.setDescription("description");

UserToNotify userToNotify = new UserToNotify();
userToNotify.setUserId(userId.toString());

UserNotificationToSend userNotificationToSend = new UserNotificationToSend();
userNotificationToSend.setUser(userToNotify);

// Mock external dependencies
when(userRegistryApi.searchUsingPOST(any(), any())).thenReturn(Uni.createFrom().item(userResource));
when(userInstitutionService.findByUserIdAndInstitutionId(any(), any())).thenReturn(Uni.createFrom().item(userInstitution));
when(userRegistryApi.updateUsingPATCH(any(), any())).thenReturn(Uni.createFrom().item(Response.ok().build()));
when(userInstitutionService.persistOrUpdate(any())).thenReturn(Uni.createFrom().item(userInstitution));
when(productService.getProduct(any())).thenReturn(product);
when(userNotificationService.sendCreateUserNotification(any(), any(), any(), any(), any(),any())).thenReturn(Uni.createFrom().voidItem());
when(userUtils.buildUsersNotificationResponse(any(), any())).thenReturn(List.of(userNotificationToSend));

userService.createOrUpdateUserByFiscalCode(createUserDto, loggedUser)
.subscribe().withSubscriber(UniAssertSubscriber.create())
.assertFailedWith(InvalidRequestException.class, "User already has different role on Product test");

Assertions.assertEquals(2, userInstitution.getProducts().size());
}


@Test
void testCreateOrUpdateUser_CreateUser_SuccessByFiscalCode() {
// Prepare test data
Expand Down Expand Up @@ -959,20 +1054,87 @@ void testCreateOrUpdateUser_UpdateUser_ProductAlreadyOnboarded() {
AddUserRoleDto.Product addUserRoleProduct = new AddUserRoleDto.Product();
addUserRoleProduct.setProductId("test");
addUserRoleProduct.setDelegationId("delegationId");
addUserRoleDto.setProduct(addUserRoleProduct);
addUserRoleProduct.setRole(MANAGER.name());
addUserRoleProduct.setProductRoles(List.of("admin"));
addUserRoleDto.setProduct(addUserRoleProduct);
LoggedUser loggedUser = LoggedUser.builder().build();

when(userRegistryApi.findByIdUsingGET(any(), eq("userId"))).thenReturn(Uni.createFrom().item(userResource));
when(userInstitutionService.findByUserIdAndInstitutionId(userResource.getId().toString(), addUserRoleDto.getInstitutionId())).thenReturn(Uni.createFrom().item(createUserInstitution()));

userService.createOrUpdateUserByUserId(addUserRoleDto, "userId", loggedUser)
.subscribe().withSubscriber(UniAssertSubscriber.create())
.assertFailedWith(InvalidRequestException.class, "User already has roles on Product test");
}

@Test
void testCreateOrUpdateUser_UpdateUser_ProductAlreadyOnboardedWithAnotherRole() {
// Prepare test data
AddUserRoleDto addUserRoleDto = new AddUserRoleDto();
addUserRoleDto.setInstitutionId("institutionId");
AddUserRoleDto.Product addUserRoleProduct = new AddUserRoleDto.Product();
addUserRoleProduct.setProductId("test");
addUserRoleProduct.setRole(OPERATOR.name());
addUserRoleProduct.setDelegationId("delegationId");
addUserRoleDto.setProduct(addUserRoleProduct);
addUserRoleProduct.setProductRoles(List.of("operatore api"));
LoggedUser loggedUser = LoggedUser.builder().build();

when(userRegistryApi.findByIdUsingGET(any(), eq("userId"))).thenReturn(Uni.createFrom().item(userResource));
when(userInstitutionService.findByUserIdAndInstitutionId(userResource.getId().toString(), addUserRoleDto.getInstitutionId())).thenReturn(Uni.createFrom().item(createUserInstitution()));


userService.createOrUpdateUserByUserId(addUserRoleDto, "userId", loggedUser)
.subscribe().withSubscriber(UniAssertSubscriber.create())
.assertFailedWith(InvalidRequestException.class, "User already has different role on Product test");

}

@Test
void testCreateOrUpdateUser_UpdateUser_ProductAlreadyOnboardedWithAnotherProductRole() {
// Prepare test data
AddUserRoleDto addUserRoleDto = new AddUserRoleDto();
addUserRoleDto.setInstitutionId("institutionId");
AddUserRoleDto.Product addUserRoleProduct = new AddUserRoleDto.Product();
addUserRoleProduct.setProductId("test");
addUserRoleProduct.setRole(OPERATOR.name());
addUserRoleProduct.setDelegationId("delegationId");
addUserRoleDto.setProduct(addUserRoleProduct);
addUserRoleProduct.setProductRoles(List.of("security"));
LoggedUser loggedUser = LoggedUser.builder().build();
UserInstitution userInstitution = createUserInstitution();
userInstitution.getProducts().get(0).setStatus(DELETED);
userInstitution.getProducts().get(1).setStatus(ACTIVE);
userInstitution.getProducts().get(1).setProductId("test");

UserToNotify userToNotify = new UserToNotify();
userToNotify.setUserId(userId.toString());

UserNotificationToSend userNotificationToSend = new UserNotificationToSend();
userNotificationToSend.setUser(userToNotify);

Product product = new Product();
product.setDescription("description");

// Mock external dependencies
when(userRegistryApi.findByIdUsingGET(any(), eq("userId"))).thenReturn(Uni.createFrom().item(userResource));
when(userInstitutionService.findByUserIdAndInstitutionId(userResource.getId().toString(), addUserRoleDto.getInstitutionId())).thenReturn(Uni.createFrom().item((userInstitution)));
when(userInstitutionService.persistOrUpdate(any())).thenReturn(Uni.createFrom().item(createUserInstitution()));
when(productService.getProduct(any())).thenReturn(product);
when(userNotificationService.sendCreateUserNotification(any(), any(), any(), any(), any(),any())).thenReturn(Uni.createFrom().voidItem());
when(userUtils.buildUsersNotificationResponse(any(), any())).thenReturn(List.of(userNotificationToSend));
when(userNotificationService.sendKafkaNotification(any())).thenReturn(Uni.createFrom().item(userNotificationToSend));


// Call the method
UniAssertSubscriber<String> subscriber = userService.createOrUpdateUserByUserId(addUserRoleDto, "userId", loggedUser)
.subscribe().withSubscriber(UniAssertSubscriber.create());

// Verify the result
assertNull(subscriber.awaitItem().getItem());
subscriber.awaitItem().assertCompleted();
verify(userRegistryApi).findByIdUsingGET(any(), eq("userId"));
verify(userInstitutionService).persistOrUpdate(any());

}

@Test
Expand All @@ -982,6 +1144,7 @@ void testCreateOrUpdateUser_UpdateUser_OneOfProductRoleAlreadyOnboarded() {
addUserRoleDto.setInstitutionId("institutionId");
AddUserRoleDto.Product addUserRoleProduct = new AddUserRoleDto.Product();
addUserRoleProduct.setProductId("test");
addUserRoleProduct.setRole(MANAGER.name());
addUserRoleDto.setProduct(addUserRoleProduct);
addUserRoleProduct.setProductRoles(List.of("admin", "admin2"));
LoggedUser loggedUser = LoggedUser.builder().build();
Expand Down

0 comments on commit deb015e

Please sign in to comment.