Skip to content

Commit

Permalink
Merge branch 'main' into feature/SELC-3903
Browse files Browse the repository at this point in the history
# Conflicts:
#	apps/user-ms/src/main/java/it/pagopa/selfcare/user/controller/UserController.java
#	apps/user-ms/src/main/java/it/pagopa/selfcare/user/service/UserInstitutionService.java
#	apps/user-ms/src/main/java/it/pagopa/selfcare/user/service/UserInstitutionServiceDefault.java
#	apps/user-ms/src/main/java/it/pagopa/selfcare/user/service/UserService.java
#	apps/user-ms/src/main/java/it/pagopa/selfcare/user/service/UserServiceImpl.java
#	apps/user-ms/src/main/java/it/pagopa/selfcare/user/util/UserUtils.java
#	apps/user-ms/src/test/java/it/pagopa/selfcare/user/controller/UserControllerTest.java
#	apps/user-ms/src/test/java/it/pagopa/selfcare/user/service/UserInstitutionServiceTest.java
#	apps/user-ms/src/test/java/it/pagopa/selfcare/user/service/UserServiceTest.java
  • Loading branch information
flaminiaScarciofolo committed Jan 29, 2024
2 parents 1a4e157 + 5e9aad8 commit ffedad9
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ public Uni<UserResponse> getUserInfo(@PathParam(value = "id") String userId,
.map(user -> userMapper.toUserResponse(user, institutionId));
}

/**
* The deleteProducts function is used to delete logically the association institution and product.
*
* @param userId String
* @param institutionId String
* @param productId String
*
* @return A uni&lt;void&gt;
*/
@Operation(summary = "Delete logically the association institution and product")
@DELETE
@Path(value = "/{userId}/institutions/{institutionId}/products/{productId}")
public Uni<Void> deleteProducts(@PathParam(value = "userId") String userId,
@PathParam(value = "institutionId") String institutionId,
@PathParam(value = "productId") String productId) {
return userService.deleteUserInstitutionProduct(userId, institutionId, productId);
}

/**
* The updateUserStatus function updates the status of a user's product.
*
Expand Down Expand Up @@ -86,6 +104,5 @@ public Uni<Response> updateUserStatus(@PathParam(value = "id") String userId,
.status(HttpStatus.SC_NO_CONTENT)
.build());
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ public interface UserInstitutionService {

Uni<UserInstitution> retrieveFirstFilteredUserInstitution(Map<String, Object> queryParameter);

Uni<Long> deleteUserInstitutionProduct(String userId, String institutionId, String productId);

Uni<Long> updateUserStatusWithOptionalFilterByInstitutionAndProduct(String userId, String institutionId, String productId, PartyRole role, String productRole, OnboardedProductState status);
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,20 @@ public Uni<UserInstitution> retrieveFirstFilteredUserInstitution(Map<String, Obj
return runUserInstitutionFindQuery(query, null).firstResult();
}

@Override
public Uni<Long> deleteUserInstitutionProduct(String userId, String institutionId, String productId) {
OnboardedProductFilter onboardedProductFilter = OnboardedProductFilter.builder().productId(productId).build();
UserInstitutionFilter userInstitutionFilter = UserInstitutionFilter.builder().userId(userId).institutionId(institutionId).build();
Map<String, Object> filterMap = userUtils.retrieveMapForFilter(onboardedProductFilter.constructMap(), userInstitutionFilter.constructMap());
return updateUserStatusDao(filterMap, OnboardedProductState.DELETED);
}

@Override
public Uni<Long> updateUserStatusWithOptionalFilterByInstitutionAndProduct(String userId, String institutionId, String productId, PartyRole role, String productRole, OnboardedProductState status) {
Map<String, Object> onboardedProductFilterMap = OnboardedProductFilter.builder().productId(productId).role(role).productRole(productRole).build().constructMap();
Map<String, Object> userInstitutionFilterMap = UserInstitutionFilter.builder().userId(userId).institutionId(institutionId).build().constructMap();
Map<String, Object> filterMap = userUtils.retrieveMapForFilter(onboardedProductFilterMap, userInstitutionFilterMap);
return updateUserStatus(filterMap, status);
return updateUserStatusDao(filterMap, status);
}

@Override
Expand All @@ -84,7 +92,7 @@ public Multi<UserInstitution> findAllWithFilter(Map<String, Object> queryParamet
return runUserInstitutionFindQuery(query, null).stream();
}

private Uni<Long> updateUserStatus(Map<String, Object> filterMap, OnboardedProductState status) {
private Uni<Long> updateUserStatusDao(Map<String, Object> filterMap, OnboardedProductState status) {

Map<String, Object> fieldToUpdateMap = new HashMap<>();
if(productFilterIsEmpty(filterMap)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@

import java.util.List;

import it.pagopa.selfcare.onboarding.common.PartyRole;
import it.pagopa.selfcare.user.constant.OnboardedProductState;

public interface UserService {
Uni<List<String>> getUsersEmails(String institutionId, String productId);
Multi<UserProductResponse> getUserProductsByInstitution(String institutionId);
Uni<UserResource> retrievePerson(String userId, String productId, String institutionId);
Uni<Void> updateUserStatusWithOptionalFilter(String userId, String institutionId, String productId, PartyRole role, String productRole, OnboardedProductState status);
Multi<UserInstitutionResponse> findAllUserInstitutions(String institutionId, String userId, List<String> roles, List<String> states, List<String> products, List<String> productRoles);
Uni<Void> deleteUserInstitutionProduct(String userId, String institutionId, String productId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,15 @@ public Multi<UserInstitutionResponse> findAllUserInstitutions(String institution
return userInstitutions.onItem().transform(userInstitutionMapper::toResponse);
}

@Override
public Uni<Void> deleteUserInstitutionProduct(String userId, String institutionId, String productId) {
return userInstitutionService.deleteUserInstitutionProduct(userId, institutionId, productId)
.onItem().transformToUni(aLong -> {
if (aLong < 1) {
return Uni.createFrom().failure(new ResourceNotFoundException(USER_TO_UPDATE_NOT_FOUND.getMessage()));
}
return Uni.createFrom().nullItem();
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,23 @@
import java.util.HashMap;
import java.util.Map;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@ApplicationScoped
@RequiredArgsConstructor
@Slf4j
public class UserUtils {

private final ProductService productService;

@SafeVarargs
public final Map<String, Object> retrieveMapForFilter(Map<String, Object>... maps) {
Map<String, Object> map = new HashMap<>();
Arrays.stream(maps).forEach(map::putAll);
return map;
}

public void checkProductRole(String productId, PartyRole role, String productRole) {
if(StringUtils.isNotBlank(productRole) && StringUtils.isNotBlank(productId)) {
Expand All @@ -34,14 +44,6 @@ public void checkProductRole(String productId, PartyRole role, String productRol
}
}

@SafeVarargs
public final Map<String, Object> retrieveMapForFilter(Map<String, Object>... maps) {
Map<String, Object> map = new HashMap<>();
Arrays.stream(maps).forEach(map::putAll);
return map;
}


public static boolean checkIfNotFoundException(Throwable throwable) {
if(throwable instanceof WebClientApplicationException wex) {
return wex.getResponse().getStatus() == HttpStatus.SC_NOT_FOUND;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import io.restassured.http.ContentType;
import io.smallrye.mutiny.Uni;
import it.pagopa.selfcare.user.constant.OnboardedProductState;
import it.pagopa.selfcare.user.exception.InvalidRequestException;
import it.pagopa.selfcare.user.exception.ResourceNotFoundException;
import it.pagopa.selfcare.user.service.UserService;
import org.apache.http.HttpStatus;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.openapi.quarkus.user_registry_json.model.CertifiableFieldResourceOfLocalDate;
Expand Down Expand Up @@ -170,4 +172,62 @@ void updateUserStatusError() {
.statusCode(404);
}

/**
* Method under test:
* {@link UserController#deleteProducts(String, String, String)}
*/
@Test
@TestSecurity(user = "userJwt")
void deleteDeleteProductsErrorTest() {
String PATH_USER_ID = "userId";
String PATH_INSTITUTION_ID = "institutionId";
String PATH_PRODUCT_ID = "productId";
String PATH_DELETE_PRODUCT = "{userId}/institutions/{institutionId}/products/{productId}";

var user = "user1";
var institution = "institution1";
var product = "product1";
Mockito.when(userService.deleteUserInstitutionProduct("user1","institution1", "product1"))
.thenThrow(InvalidRequestException.class);

given()
.when()
.pathParam(PATH_USER_ID, user)
.pathParam(PATH_INSTITUTION_ID, institution)
.pathParam(PATH_PRODUCT_ID, product)
.delete(PATH_DELETE_PRODUCT)
.then()
.statusCode(HttpStatus.SC_BAD_REQUEST);
}

/**
* Method under test:
* {@link UserController#deleteProducts(String, String, String)}
*/
@Test
@TestSecurity(user = "userJwt")
void deleteDeleteProductsOKTest() {

String PATH_USER_ID = "userId";
String PATH_INSTITUTION_ID = "institutionId";
String PATH_PRODUCT_ID = "productId";
String PATH_DELETE_PRODUCT = "{userId}/institutions/{institutionId}/products/{productId}";

var user = "user123";
var institution = "institution123";
var product = "prod-pagopa";

Mockito.when(userService.deleteUserInstitutionProduct("user123", "institution123", "prod-pagopa"))
.thenReturn(Uni.createFrom().voidItem());

given()
.when()
.pathParam(PATH_USER_ID, user)
.pathParam(PATH_INSTITUTION_ID, institution)
.pathParam(PATH_PRODUCT_ID, product)
.delete(PATH_DELETE_PRODUCT)
.then()
.statusCode(HttpStatus.SC_NO_CONTENT);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,20 @@ void updateUserStatusWithInstitutionFilter() {
subscriber.assertCompleted().assertItem(1L);
}

@Test
void deleteUserInstitutionProduct(){
final String userId = "userId";
String institutionId = "institutionId";
PanacheMock.mock(UserInstitution.class);
ReactivePanacheUpdate update = Mockito.mock(ReactivePanacheUpdate.class);
when(UserInstitution.update(any(Document.class)))
.thenReturn(update);
when(update.where(any())).thenReturn(Uni.createFrom().item(1L));
UniAssertSubscriber<Long> subscriber = userInstitutionService.deleteUserInstitutionProduct(userId, institutionId, "productID")
.subscribe().withSubscriber(UniAssertSubscriber.create());
subscriber.assertCompleted().assertItem(1L);
}

private UserInstitution createDummyUserInstitution() {
UserInstitution userInstitution = new UserInstitution();
userInstitution.setId(ObjectId.get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,5 +224,27 @@ void retrieveUsersTest() {
assertEquals(userInstitution.getUserId(), actual.get(0).getUserId());
}

@Test
void deleteUserInstitutionProductFound(){
when(userInstitutionService.deleteUserInstitutionProduct("userId", "institutionId", "productId")).thenReturn(Uni.createFrom().item(1L));
UniAssertSubscriber<Void> subscriber = userService
.deleteUserInstitutionProduct("userId", "institutionId", "productId")
.subscribe()
.withSubscriber(UniAssertSubscriber.create());

subscriber.assertCompleted();


}

@Test
void deleteUserInstitutionProductNotFound(){
when(userInstitutionService.deleteUserInstitutionProduct("userId", "institutionId", "productId")).thenReturn(Uni.createFrom().item(0L));
UniAssertSubscriber<Void> subscriber = userService
.deleteUserInstitutionProduct("userId", "institutionId", "productId")
.subscribe()
.withSubscriber(UniAssertSubscriber.create());

subscriber.assertFailedWith(ResourceNotFoundException.class, USER_TO_UPDATE_NOT_FOUND.getMessage());
}
}
25 changes: 25 additions & 0 deletions infra/mongo/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions infra/mongo/env/dev/backend.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
subscription=DEV-SelfCare
4 changes: 4 additions & 0 deletions infra/mongo/env/dev/backend.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource_group_name = "terraform-state-rg"
storage_account_name = "tfappdevselfcare"
container_name = "terraform-state"
key = "selfcare-user.mongo.tfstate"
10 changes: 10 additions & 0 deletions infra/mongo/env/dev/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix = "selc"
env_short = "d"

tags = {
CreatedBy = "Terraform"
Environment = "Dev"
Owner = "SelfCare"
Source = "https://github.com/pagopa/selfcare-user"
CostCenter = "TS310 - PAGAMENTI & SERVIZI"
}
1 change: 1 addition & 0 deletions infra/mongo/env/uat/backend.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
subscription=UAT-SelfCare
4 changes: 4 additions & 0 deletions infra/mongo/env/uat/backend.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
resource_group_name = "terraform-state-rg"
storage_account_name = "tfappuatselfcare"
container_name = "terraform-state"
key = "selfcare-user.mongo.tfstate"
10 changes: 10 additions & 0 deletions infra/mongo/env/uat/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
prefix = "selc"
env_short = "u"

tags = {
CreatedBy = "Terraform"
Environment = "Uat"
Owner = "SelfCare"
Source = "https://github.com/pagopa/selfcare-user"
CostCenter = "TS310 - PAGAMENTI & SERVIZI"
}
8 changes: 8 additions & 0 deletions infra/mongo/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
locals {
prefix = "selc"

mongo_db = {
mongodb_rg_name = "${local.prefix}-${var.env_short}-cosmosdb-mongodb-rg",
cosmosdb_account_mongodb_name = "${local.prefix}-${var.env_short}-cosmosdb-mongodb-account"
}
}
20 changes: 20 additions & 0 deletions infra/mongo/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
terraform {
required_version = ">=1.6.0"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "<= 3.86.0"
}
}

backend "azurerm" {}
}

provider "azurerm" {
features {}
}

data "azurerm_client_config" "current" {}

data "azurerm_subscription" "current" {}
Loading

0 comments on commit ffedad9

Please sign in to comment.