From ea2ec4cc98b1669e048605dee379b2e2d9808f19 Mon Sep 17 00:00:00 2001
From: flaminiaScarciofolo <flaminia.scarciofolo@nttdata.com>
Date: Thu, 25 Jan 2024 15:47:39 +0100
Subject: [PATCH 1/5] [SELC-3962] Added method to validate a productRole given
 productId a Role

---
 libs/onboarding-sdk-product/pom.xml           |  4 ++++
 .../product/service/ProductService.java       |  3 +++
 .../service/ProductServiceCacheable.java      |  7 ++++++
 .../service/ProductServiceDefault.java        | 22 +++++++++++++++++++
 4 files changed, 36 insertions(+)

diff --git a/libs/onboarding-sdk-product/pom.xml b/libs/onboarding-sdk-product/pom.xml
index 9e8037771..ab944aa5f 100644
--- a/libs/onboarding-sdk-product/pom.xml
+++ b/libs/onboarding-sdk-product/pom.xml
@@ -49,6 +49,10 @@
             <version>8.6.6</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
 
     </dependencies>
 
diff --git a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductService.java b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductService.java
index 56ead812b..f0959af09 100644
--- a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductService.java
+++ b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductService.java
@@ -4,6 +4,7 @@
 import it.pagopa.selfcare.onboarding.common.InstitutionType;
 import it.pagopa.selfcare.onboarding.common.PartyRole;
 import it.pagopa.selfcare.product.entity.Product;
+import it.pagopa.selfcare.product.entity.ProductRole;
 import it.pagopa.selfcare.product.entity.ProductRoleInfo;
 
 import java.util.List;
@@ -19,4 +20,6 @@ public interface ProductService {
     void fillContractTemplatePathAndVersion(Product product, InstitutionType institutionType);
 
     Product getProductIsValid(String productId);
+
+    ProductRole validateProductRole(String productId, String productRole, PartyRole role);
 }
diff --git a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceCacheable.java b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceCacheable.java
index 11a3043b3..fd7d2bd00 100644
--- a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceCacheable.java
+++ b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceCacheable.java
@@ -6,6 +6,7 @@
 import it.pagopa.selfcare.onboarding.common.InstitutionType;
 import it.pagopa.selfcare.onboarding.common.PartyRole;
 import it.pagopa.selfcare.product.entity.Product;
+import it.pagopa.selfcare.product.entity.ProductRole;
 import it.pagopa.selfcare.product.entity.ProductRoleInfo;
 
 import java.time.LocalDateTime;
@@ -73,4 +74,10 @@ public Product getProductIsValid(String productId) {
         refreshProduct();
         return productService.getProductIsValid(productId);
     }
+
+    @Override
+    public ProductRole validateProductRole(String productId, String productRole, PartyRole role) {
+        refreshProduct();
+        return productService.validateProductRole(productId, productRole, role);
+    }
 }
diff --git a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
index add7cd8b3..883b5e77c 100644
--- a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
+++ b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
@@ -9,6 +9,7 @@
 import it.pagopa.selfcare.onboarding.common.InstitutionType;
 import it.pagopa.selfcare.onboarding.common.PartyRole;
 import it.pagopa.selfcare.product.entity.Product;
+import it.pagopa.selfcare.product.entity.ProductRole;
 import it.pagopa.selfcare.product.entity.ProductRoleInfo;
 import it.pagopa.selfcare.product.entity.ProductStatus;
 import it.pagopa.selfcare.product.exception.InvalidRoleMappingException;
@@ -154,6 +155,27 @@ public Product getProductIsValid(String productId) {
         return getProduct(productId, true);
     }
 
+    /**
+     * The validateProductRole function is used to validate a product role searching for it within the role map for a specific product
+     * given productId. It returns founded ProductRole object filtered by productRole code
+     */
+    @Override
+    public ProductRole validateProductRole(String productId, String productRole, PartyRole role) {
+        if (role == null) {
+            throw new IllegalArgumentException("Role is mandatory to check productRole");
+        }
+
+        Product product = getProduct(productId);
+        ProductRoleInfo productRoleInfo = product.getRoleMappings().get(productRole);
+        if (productRoleInfo == null) {
+            throw new IllegalArgumentException(String.format("Role %s not found", role));
+        }
+
+        return productRoleInfo.getRoles().stream().filter(prodRole -> prodRole.getCode().equals(productRole))
+                .findFirst()
+                .orElseThrow(() -> new IllegalArgumentException(String.format("ProductRole %s not found for role %s", productRole, role)));
+    }
+
     private static boolean statusIsNotValid(ProductStatus status) {
         return List.of(ProductStatus.INACTIVE, ProductStatus.PHASE_OUT).contains(status);
     }

From 52ad56d39de5c7d364a4b1d44d9f56504b3b0a74 Mon Sep 17 00:00:00 2001
From: flaminiaScarciofolo <flaminia.scarciofolo@nttdata.com>
Date: Thu, 25 Jan 2024 16:23:00 +0100
Subject: [PATCH 2/5] added tests in ProductServiceDefault

---
 .../service/ProductServiceDefault.java        |  2 +-
 .../test/java/ProductServiceDefaultTest.java  | 31 +++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
index 883b5e77c..c388d58ec 100644
--- a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
+++ b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
@@ -166,7 +166,7 @@ public ProductRole validateProductRole(String productId, String productRole, Par
         }
 
         Product product = getProduct(productId);
-        ProductRoleInfo productRoleInfo = product.getRoleMappings().get(productRole);
+        ProductRoleInfo productRoleInfo = product.getRoleMappings().get(role);
         if (productRoleInfo == null) {
             throw new IllegalArgumentException(String.format("Role %s not found", role));
         }
diff --git a/libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java b/libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java
index 84438221a..3da4f7af9 100644
--- a/libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java
+++ b/libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java
@@ -21,6 +21,10 @@ public class ProductServiceDefaultTest {
             "{\"id\":\"prod-test\", \"parentId\":\"prod-test-parent\",\"status\":\"ACTIVE\"}," +
             "{\"id\":\"prod-inactive\",\"status\":\"INACTIVE\"}]";
 
+    final private String PRODUCT_JSON_STRING_WITH_ROLEMAPPING = "[{\"id\":\"prod-test-parent\",\"status\":\"ACTIVE\"}," +
+            "{\"id\":\"prod-test\", \"parentId\":\"prod-test-parent\",\"status\":\"ACTIVE\", \"roleMappings\" : {\"MANAGER\":{\"roles\":[{\"code\":\"operatore\"}]}}}," +
+            "{\"id\":\"prod-inactive\",\"status\":\"INACTIVE\"}]";
+
     @Test
     void productServiceDefault_shouldThrowProductNotFoundExceptionIfJsonIsEmpty() {
         assertThrows(ProductNotFoundException.class, () -> new ProductServiceDefault(PRODUCT_JSON_STRING_EMPTY));
@@ -113,4 +117,31 @@ void getProductValid_shouldThrowProductNotFoundExceptionIfProductInactive() thro
         ProductServiceDefault productService = new ProductServiceDefault(PRODUCT_JSON_STRING);
         assertThrows(ProductNotFoundException.class, () -> productService.getProductIsValid("prod-inactive"));
     }
+
+    @Test
+    void validateProductRoleWithoutRole() throws JsonProcessingException {
+        ProductServiceDefault productService = new ProductServiceDefault(PRODUCT_JSON_STRING);
+        assertThrows(IllegalArgumentException.class, () -> productService.validateProductRole("prod-test", "productRole", null));
+    }
+
+
+    @Test
+    void validateProductRoleOk() throws JsonProcessingException {
+        ProductServiceDefault productService = new ProductServiceDefault(PRODUCT_JSON_STRING_WITH_ROLEMAPPING);
+        assertDoesNotThrow(() -> productService.validateProductRole("prod-test", "operatore", PartyRole.MANAGER));
+    }
+
+
+    @Test
+    void validateProductRoleWithProductRoleMappingNotFound() throws JsonProcessingException {
+        ProductServiceDefault productService = new ProductServiceDefault(PRODUCT_JSON_STRING_WITH_ROLEMAPPING);
+        assertThrows(IllegalArgumentException.class, () -> productService.validateProductRole("prod-test", "productRole", PartyRole.DELEGATE));
+    }
+
+
+    @Test
+    void validateProductRoleOkWithProductRoleNotFound() throws JsonProcessingException {
+        ProductServiceDefault productService = new ProductServiceDefault(PRODUCT_JSON_STRING_WITH_ROLEMAPPING);
+        assertThrows(IllegalArgumentException.class, () -> productService.validateProductRole("prod-test", "amministratore", PartyRole.MANAGER));
+    }
 }

From 2c589d204567206842005f5a6865ce93a8288b3f Mon Sep 17 00:00:00 2001
From: flaminiaScarciofolo <flaminia.scarciofolo@nttdata.com>
Date: Thu, 25 Jan 2024 16:32:12 +0100
Subject: [PATCH 3/5] upgrade versions in libs pom

---
 libs/onboarding-sdk-azure-storage/pom.xml | 2 +-
 libs/onboarding-sdk-common/pom.xml        | 2 +-
 libs/onboarding-sdk-crypto/pom.xml        | 2 +-
 libs/onboarding-sdk-pom/pom.xml           | 2 +-
 libs/onboarding-sdk-product/pom.xml       | 2 +-
 test-coverage/pom.xml                     | 8 ++++----
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libs/onboarding-sdk-azure-storage/pom.xml b/libs/onboarding-sdk-azure-storage/pom.xml
index f928ebd1c..57bc353df 100644
--- a/libs/onboarding-sdk-azure-storage/pom.xml
+++ b/libs/onboarding-sdk-azure-storage/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>it.pagopa.selfcare</groupId>
         <artifactId>onboarding-sdk-pom</artifactId>
-        <version>0.1.4</version>
+        <version>0.1.5</version>
         <relativePath>../onboarding-sdk-pom</relativePath>
     </parent>
 
diff --git a/libs/onboarding-sdk-common/pom.xml b/libs/onboarding-sdk-common/pom.xml
index f317f8ee1..2d8d6492e 100644
--- a/libs/onboarding-sdk-common/pom.xml
+++ b/libs/onboarding-sdk-common/pom.xml
@@ -4,7 +4,7 @@
     <parent>
         <groupId>it.pagopa.selfcare</groupId>
         <artifactId>onboarding-sdk-pom</artifactId>
-        <version>0.1.4</version>
+        <version>0.1.5</version>
         <relativePath>../onboarding-sdk-pom</relativePath>
     </parent>
     <artifactId>onboarding-sdk-common</artifactId>
diff --git a/libs/onboarding-sdk-crypto/pom.xml b/libs/onboarding-sdk-crypto/pom.xml
index 2e0756775..ca4ebf8e2 100644
--- a/libs/onboarding-sdk-crypto/pom.xml
+++ b/libs/onboarding-sdk-crypto/pom.xml
@@ -4,7 +4,7 @@
     <parent>
         <groupId>it.pagopa.selfcare</groupId>
         <artifactId>onboarding-sdk-pom</artifactId>
-        <version>0.1.4</version>
+        <version>0.1.5</version>
         <relativePath>../onboarding-sdk-pom</relativePath>
     </parent>
     <artifactId>onboarding-sdk-crypto</artifactId>
diff --git a/libs/onboarding-sdk-pom/pom.xml b/libs/onboarding-sdk-pom/pom.xml
index 17302dc41..d4c8c7ef1 100644
--- a/libs/onboarding-sdk-pom/pom.xml
+++ b/libs/onboarding-sdk-pom/pom.xml
@@ -6,7 +6,7 @@
     <artifactId>onboarding-sdk-pom</artifactId>
     <packaging>pom</packaging>
     <name>onboarding-sdk-pom</name>
-    <version>0.1.4</version>
+    <version>0.1.5</version>
 
     <properties>
         <maven.compiler.source>17</maven.compiler.source>
diff --git a/libs/onboarding-sdk-product/pom.xml b/libs/onboarding-sdk-product/pom.xml
index ab944aa5f..c40172f62 100644
--- a/libs/onboarding-sdk-product/pom.xml
+++ b/libs/onboarding-sdk-product/pom.xml
@@ -4,7 +4,7 @@
     <parent>
         <groupId>it.pagopa.selfcare</groupId>
         <artifactId>onboarding-sdk-pom</artifactId>
-        <version>0.1.4</version>
+        <version>0.1.5</version>
         <relativePath>../onboarding-sdk-pom</relativePath>
     </parent>
     <artifactId>onboarding-sdk-product</artifactId>
diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml
index 69e980397..c9339991c 100644
--- a/test-coverage/pom.xml
+++ b/test-coverage/pom.xml
@@ -77,22 +77,22 @@
                 <dependency>
                     <groupId>it.pagopa.selfcare</groupId>
                     <artifactId>onboarding-sdk-product</artifactId>
-                    <version>0.1.4</version>
+                    <version>0.1.5</version>
                 </dependency>
                 <dependency>
                     <groupId>it.pagopa.selfcare</groupId>
                     <artifactId>onboarding-sdk-common</artifactId>
-                    <version>0.1.4</version>
+                    <version>0.1.5</version>
                 </dependency>
                 <dependency>
                     <groupId>it.pagopa.selfcare</groupId>
                     <artifactId>onboarding-sdk-azure-storage</artifactId>
-                    <version>0.1.4</version>
+                    <version>0.1.5</version>
                 </dependency>
                 <dependency>
                     <groupId>it.pagopa.selfcare</groupId>
                     <artifactId>onboarding-sdk-crypto</artifactId>
-                    <version>0.1.4</version>
+                    <version>0.1.5</version>
                 </dependency>
             </dependencies>
 

From dd3b05c6a92f445ef7903d7ad1fb0e96030ffc0c Mon Sep 17 00:00:00 2001
From: flaminiaScarciofolo <flaminia.scarciofolo@nttdata.com>
Date: Thu, 25 Jan 2024 16:44:51 +0100
Subject: [PATCH 4/5] fix validateProductRole method

---
 .../service/ProductServiceDefault.java        | 47 +++++++++++++------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
index c388d58ec..16928b850 100644
--- a/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
+++ b/libs/onboarding-sdk-product/src/main/java/it/pagopa/selfcare/product/service/ProductServiceDefault.java
@@ -40,14 +40,17 @@ public ProductServiceDefault(String productString, ObjectMapper mapper) throws J
     }
 
     private Map<String, Product> constructProductsMap(String productString, ObjectMapper mapper) throws JsonProcessingException {
-        List<Product> productList = mapper.readValue(productString, new TypeReference<List<Product>>(){});
-        if(Objects.isNull(productList) || productList.isEmpty()) throw new ProductNotFoundException("json string is empty!");
+        List<Product> productList = mapper.readValue(productString, new TypeReference<List<Product>>() {
+        });
+        if (Objects.isNull(productList) || productList.isEmpty())
+            throw new ProductNotFoundException("json string is empty!");
         return productList.stream()
                 .collect(Collectors.toMap(Product::getId, Function.identity()));
     }
 
     /**
      * Returns the list of PagoPA products tree which are not INACTIVE
+     *
      * @param rootOnly if true only product that has parent is null are returned
      * @return List of PagoPA products
      */
@@ -55,11 +58,11 @@ private Map<String, Product> constructProductsMap(String productString, ObjectMa
     public List<Product> getProducts(boolean rootOnly, boolean valid) {
 
         return rootOnly
-            ? productsMap.values().stream()
+                ? productsMap.values().stream()
                 .filter(product -> Objects.isNull(product.getParentId()))
                 .filter(product -> !valid || !statusIsNotValid(product.getStatus()))
                 .collect(Collectors.toList())
-            : productsMap.values().stream()
+                : productsMap.values().stream()
                 .filter(product -> !valid || !statusIsNotValid(product.getStatus()))
                 .collect(Collectors.toList());
     }
@@ -67,19 +70,20 @@ public List<Product> getProducts(boolean rootOnly, boolean valid) {
     /**
      * Utility method for validating role mappings that contains associations between Selfcare role and Product role.
      * Each Selfcare role must be only one Product role except OPERATOR.
+     *
      * @param roleMappings
-     * @throws IllegalArgumentException roleMappings is null or empty
+     * @throws IllegalArgumentException    roleMappings is null or empty
      * @throws InvalidRoleMappingException Selfcare role have more than one Product role
      */
     @Override
     public void validateRoleMappings(Map<PartyRole, ? extends ProductRoleInfo> roleMappings) {
 
-        if(Objects.isNull(roleMappings) || roleMappings.isEmpty())
+        if (Objects.isNull(roleMappings) || roleMappings.isEmpty())
             throw new IllegalArgumentException("A product role mappings is required");
         roleMappings.forEach((partyRole, productRoleInfo) -> {
-            if(Objects.isNull(productRoleInfo))
+            if (Objects.isNull(productRoleInfo))
                 throw new IllegalArgumentException("A product role info is required");
-            if(Objects.isNull(productRoleInfo.getRoles()) || productRoleInfo.getRoles().isEmpty())
+            if (Objects.isNull(productRoleInfo.getRoles()) || productRoleInfo.getRoles().isEmpty())
                 throw new IllegalArgumentException("At least one Product role are required");
             if (productRoleInfo.getRoles().size() > 1 && !PartyRole.OPERATOR.equals(partyRole)) {
                 throw new InvalidRoleMappingException(String.format("Only '%s' Party-role can have more than one Product-role, %s",
@@ -92,11 +96,11 @@ public void validateRoleMappings(Map<PartyRole, ? extends ProductRoleInfo> roleM
     /**
      * Return a product by productId without any filter
      * retrieving data from institutionContractMappings map
+     *
      * @param productId
      * @return Product
      * @throws IllegalArgumentException if @param id is null
      * @throws ProductNotFoundException if product is not found
-     *
      */
     @Override
     public Product getProduct(String productId) {
@@ -105,7 +109,7 @@ public Product getProduct(String productId) {
 
     private Product getProduct(String productId, boolean filterValid) {
 
-        if(Objects.isNull(productId)) {
+        if (Objects.isNull(productId)) {
             throw new IllegalArgumentException(REQUIRED_PRODUCT_ID_MESSAGE);
         }
         Product product = Optional.ofNullable(productsMap.get(productId))
@@ -131,7 +135,8 @@ private Product getProduct(String productId, boolean filterValid) {
      * Fills contractTemplatePath and ContractTemplateVersion based on @param institutionType.
      * If institutionContractMappings contains institutionType, it take value from that setting inside
      * contractTemplatePath and contractTemplateVersion of product
-     * @param product Product
+     *
+     * @param product         Product
      * @param institutionType InstitutionType
      */
     @Override
@@ -145,6 +150,7 @@ public void fillContractTemplatePathAndVersion(Product product, InstitutionType
 
     /**
      * Returns the information for a single product if it has not PHASE_OUT,INACTIVE status and its parent has not PHASE_OUT,INACTIVE status
+     *
      * @param productId
      * @return Product if it is valid or null if it has PHASE_OUT,INACTIVE status
      * @throws IllegalArgumentException product id is null
@@ -166,14 +172,25 @@ public ProductRole validateProductRole(String productId, String productRole, Par
         }
 
         Product product = getProduct(productId);
+        return Optional.ofNullable(product.getRoleMappings())
+                .map(partyRoleProductRoleInfoMap -> getProductRole(productRole, role, product))
+                .orElseThrow(() -> new IllegalArgumentException(String.format("RoleMappings map for product %s not found", productId)));
+    }
+
+    /**
+     * The getProductRole function takes a productRole, role, and product as parameters.
+     * It returns the ProductRole object that matches the given role and product.
+     */
+    private static ProductRole getProductRole(String productRole, PartyRole role, Product product) {
         ProductRoleInfo productRoleInfo = product.getRoleMappings().get(role);
         if (productRoleInfo == null) {
             throw new IllegalArgumentException(String.format("Role %s not found", role));
         }
-
-        return productRoleInfo.getRoles().stream().filter(prodRole -> prodRole.getCode().equals(productRole))
-                .findFirst()
-                .orElseThrow(() -> new IllegalArgumentException(String.format("ProductRole %s not found for role %s", productRole, role)));
+        return Optional.ofNullable(productRoleInfo.getRoles())
+                .map(productRoles -> productRoles.stream().filter(prodRole -> prodRole.getCode().equals(productRole))
+                        .findFirst()
+                        .orElseThrow(() -> new IllegalArgumentException(String.format("ProductRole %s not found for role %s", productRole, role))))
+                .orElseThrow(() -> new IllegalArgumentException(String.format("Roles of ProductRoleInfo related to role %s not found", role)));
     }
 
     private static boolean statusIsNotValid(ProductStatus status) {

From b1c731084cd1144af15896caf6bceab47a1f1e25 Mon Sep 17 00:00:00 2001
From: flaminiaScarciofolo <flaminia.scarciofolo@nttdata.com>
Date: Thu, 25 Jan 2024 16:47:23 +0100
Subject: [PATCH 5/5] add other unit tests for ProductServiceCacheable

---
 .../service/ProductServiceCacheableTest.java  | 37 +++++++++++++++++++
 .../service}/ProductServiceDefaultTest.java   |  2 +
 2 files changed, 39 insertions(+)
 rename libs/onboarding-sdk-product/src/test/java/{ => it/pagopa/selfcare/product/service}/ProductServiceDefaultTest.java (99%)

diff --git a/libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceCacheableTest.java b/libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceCacheableTest.java
index 68509b120..3199c31a8 100644
--- a/libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceCacheableTest.java
+++ b/libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceCacheableTest.java
@@ -1,6 +1,7 @@
 package it.pagopa.selfcare.product.service;
 
 import com.azure.storage.blob.models.BlobProperties;
+import com.fasterxml.jackson.core.JsonProcessingException;
 import it.pagopa.selfcare.azurestorage.AzureBlobClient;
 import it.pagopa.selfcare.onboarding.common.PartyRole;
 import it.pagopa.selfcare.product.entity.Product;
@@ -26,6 +27,11 @@ class ProductServiceCacheableTest {
             "{\"id\":\"prod-test\", \"parentId\":\"prod-test-parent\",\"status\":\"ACTIVE\"}," +
             "{\"id\":\"prod-inactive\",\"status\":\"INACTIVE\"}]";
 
+    final private String PRODUCT_JSON_STRING_WITH_ROLEMAPPING = "[{\"id\":\"prod-test-parent\",\"status\":\"ACTIVE\"}," +
+            "{\"id\":\"prod-test\", \"parentId\":\"prod-test-parent\",\"status\":\"ACTIVE\", \"roleMappings\" : {\"MANAGER\":{\"roles\":[{\"code\":\"operatore\"}]}}}," +
+            "{\"id\":\"prod-inactive\",\"status\":\"INACTIVE\"}]";
+
+
     final private String PRODUCT_JSON_STRING_EMPTY = "[]";
 
     @Test
@@ -176,6 +182,37 @@ void getProduct_notFoundInactive() {
         assertThrows(ProductNotFoundException.class, executable);
     }
 
+    @Test
+    void validateProductRoleWithoutRole()  {
+        final String filePath = "filePath";
+        ProductServiceCacheable productServiceCacheable = mockProductService(PRODUCT_JSON_STRING, filePath);
+        assertThrows(IllegalArgumentException.class, () -> productServiceCacheable.validateProductRole("prod-test", "productRole", null));
+    }
+
+
+    @Test
+    void validateProductRoleOk() {
+        final String filePath = "filePath";
+        ProductServiceCacheable productServiceCacheable = mockProductService(PRODUCT_JSON_STRING_WITH_ROLEMAPPING, filePath);
+        assertDoesNotThrow(() -> productServiceCacheable.validateProductRole("prod-test", "operatore", PartyRole.MANAGER));
+    }
+
+
+    @Test
+    void validateProductRoleWithProductRoleMappingNotFound() {
+        final String filePath = "filePath";
+        ProductServiceCacheable productServiceCacheable = mockProductService(PRODUCT_JSON_STRING_WITH_ROLEMAPPING, filePath);
+        assertThrows(IllegalArgumentException.class, () -> productServiceCacheable.validateProductRole("prod-test", "productRole", PartyRole.DELEGATE));
+    }
+
+
+    @Test
+    void validateProductRoleOkWithProductRoleNotFound() {
+        final String filePath = "filePath";
+        ProductServiceCacheable productServiceCacheable = mockProductService(PRODUCT_JSON_STRING_WITH_ROLEMAPPING, filePath);
+        assertThrows(IllegalArgumentException.class, () -> productServiceCacheable.validateProductRole("prod-test", "amministratore", PartyRole.MANAGER));
+    }
+
     private ProductServiceCacheable mockProductService(String productJson, String filePath) {
         AzureBlobClient azureBlobClient = mock(AzureBlobClient.class);
         BlobProperties blobPropertiesMock = mock(BlobProperties.class);
diff --git a/libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java b/libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceDefaultTest.java
similarity index 99%
rename from libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java
rename to libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceDefaultTest.java
index 3da4f7af9..ce1b11631 100644
--- a/libs/onboarding-sdk-product/src/test/java/ProductServiceDefaultTest.java
+++ b/libs/onboarding-sdk-product/src/test/java/it/pagopa/selfcare/product/service/ProductServiceDefaultTest.java
@@ -1,3 +1,5 @@
+package it.pagopa.selfcare.product.service;
+
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import it.pagopa.selfcare.onboarding.common.PartyRole;