From 4bf052bc3c47ff8fe9e110aab9fdfd9ca6d85559 Mon Sep 17 00:00:00 2001 From: ThaminduDilshan Date: Fri, 3 Jan 2025 15:05:39 +0530 Subject: [PATCH] Add unit tests --- .../scim2/common/DAO/GroupDAOTest.java | 96 ++++++++++++++ .../common/group/SCIMGroupHandlerTest.java | 13 ++ .../common/impl/SCIMUserManagerTest.java | 119 ++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 4 files changed, 229 insertions(+) create mode 100644 components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/DAO/GroupDAOTest.java diff --git a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/DAO/GroupDAOTest.java b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/DAO/GroupDAOTest.java new file mode 100644 index 000000000..fc15caeff --- /dev/null +++ b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/DAO/GroupDAOTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.scim2.common.DAO; + +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; +import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; +import static org.mockito.MockitoAnnotations.initMocks; + +public class GroupDAOTest { + + @Mock + private Connection connection; + + @Mock + private PreparedStatement mockedPreparedStatement; + + @Mock + private ResultSet resultSet; + + private MockedStatic identityDatabaseUtil; + private MockedStatic scimCommonUtils; + + @BeforeMethod + public void setUp() { + + initMocks(this); + identityDatabaseUtil = mockStatic(IdentityDatabaseUtil.class); + scimCommonUtils = mockStatic(SCIMCommonUtils.class); + } + + @AfterMethod + public void tearDown() { + + identityDatabaseUtil.close(); + scimCommonUtils.close(); + } + + @Test + public void testUpdateSCIMGroupAttributesWithUpdatedColumn() throws Exception { + + Map attributes = new HashMap<>(); + attributes.put("urn:ietf:params:scim:schemas:core:2.0:meta.created", "2017-10-10T10:10:10Z"); + attributes.put("urn:ietf:params:scim:schemas:core:2.0:meta.lastModified", "2017-10-10T10:10:10Z"); + + when(IdentityDatabaseUtil.getDBConnection(true)).thenReturn(connection); + when(connection.prepareStatement(anyString())).thenReturn(mockedPreparedStatement); + when(mockedPreparedStatement.executeBatch()).thenReturn(new int[]{1}); + when(resultSet.next()).thenReturn(true); + when(SCIMCommonUtils.getGroupNameWithDomain(anyString())).thenReturn("PRIMARY/GROUP_NAME"); + + Connection mockedConnection2 = mock(Connection.class); + PreparedStatement mockedPreparedStatement2 = mock(PreparedStatement.class); + ResultSet mockedResultSet2 = mock(ResultSet.class); + when(IdentityDatabaseUtil.getDBConnection()).thenReturn(mockedConnection2); + when(mockedConnection2.prepareStatement(anyString())).thenReturn(mockedPreparedStatement2); + when(mockedPreparedStatement2.executeQuery()).thenReturn(mockedResultSet2); + when(mockedResultSet2.next()).thenReturn(true); + + GroupDAO groupDAO = spy(new GroupDAO()); + doReturn(true).when(groupDAO).isExistingGroup(anyString(), anyInt()); + + groupDAO.updateSCIMGroupAttributesWithUpdatedColumn(1, "GROUP_NAME", attributes); + verify(mockedPreparedStatement, times(1)).executeBatch(); + } +} diff --git a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/group/SCIMGroupHandlerTest.java b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/group/SCIMGroupHandlerTest.java index ec8cabee0..f17bbd2a8 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/group/SCIMGroupHandlerTest.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/group/SCIMGroupHandlerTest.java @@ -337,4 +337,17 @@ public void testListSCIMRoles() throws Exception { assertNotNull(new SCIMGroupHandler(1).listSCIMRoles()); } + @Test + public void testUpdateSCIMAttributes() throws IdentitySCIMException { + + Map attributes = new HashMap(); + attributes.put("urn:ietf:params:scim:schemas:core:2.0:meta.created", "2017-10-10T10:10:10Z"); + attributes.put("urn:ietf:params:scim:schemas:core:2.0:meta.lastModified", "2017-10-10T10:10:10Z"); + + try (MockedConstruction mockedConstruction = Mockito.mockConstruction(GroupDAO.class)) { + new SCIMGroupHandler(1).updateSCIMAttributes("GROUP_NAME", attributes); + verify(mockedConstruction.constructed().get(0)) + .updateSCIMGroupAttributesWithUpdatedColumn(1, "GROUP_NAME", attributes); + } + } } diff --git a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java index 5c6cd4c45..3e9f5da09 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManagerTest.java @@ -31,6 +31,7 @@ import org.testng.annotations.Test; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.base.MultitenantConstants; +import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException; import org.wso2.carbon.identity.application.common.model.InboundProvisioningConfig; import org.wso2.carbon.identity.application.common.model.ServiceProvider; import org.wso2.carbon.identity.application.mgt.ApplicationManagementService; @@ -91,6 +92,7 @@ import org.wso2.charon3.core.utils.codeutils.ExpressionNode; import org.wso2.charon3.core.utils.codeutils.FilterTreeManager; import org.wso2.charon3.core.utils.codeutils.Node; +import org.wso2.charon3.core.utils.codeutils.PatchOperation; import org.wso2.charon3.core.utils.codeutils.SearchRequest; import org.wso2.carbon.identity.configuration.mgt.core.model.Resource; @@ -119,6 +121,8 @@ import static org.mockito.Mockito.mockConstruction; import static org.mockito.Mockito.mockStatic; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static org.testng.Assert.assertEquals; @@ -1694,6 +1698,121 @@ public void testCreateUserWithConflictingLoginIdentifier() throws Exception { // This method is for testing of throwing BadRequestException, hence no assertion. } + @DataProvider(name = "patchGroupDataProvider") + public Object[][] patchGroupDataProvider() { + + String currentGroupName = "CurrentGroupName"; + String updatedGroupName = "UpdatedGroupName"; + String userName = "user1"; + String userId = "1234"; + + Map> patchOperations1 = new HashMap<>(); + Map> patchOperations2 = new HashMap<>(); + Map> patchOperations3 = new HashMap<>(); + Map> patchOperations4 = new HashMap<>(); + + PatchOperation patchOperation1 = new PatchOperation(); + patchOperation1.setOperation("add"); + patchOperation1.setValues(updatedGroupName); + patchOperation1.setAttributeName("displayName"); + patchOperation1.setExecutionOrder(1); + patchOperations1.put("add", new ArrayList() {{ + add(patchOperation1); + }}); + patchOperations3.put("add", new ArrayList() {{ + add(patchOperation1); + }}); + + // Update with the same display name. + PatchOperation patchOperation2 = new PatchOperation(); + patchOperation2.setOperation("add"); + patchOperation2.setValues(currentGroupName); + patchOperation2.setAttributeName("displayName"); + patchOperation2.setExecutionOrder(1); + patchOperations2.put("add", new ArrayList() {{ + add(patchOperation2); + }}); + + PatchOperation patchOperation3 = new PatchOperation(); + patchOperation3.setOperation("remove"); + HashMap groupUsers = new HashMap<>(); + groupUsers.put("display", userName); + groupUsers.put("value", userId); + patchOperation3.setValues(groupUsers); + patchOperation3.setAttributeName("members"); + patchOperation3.setExecutionOrder(2); + patchOperation3.setPath("members[display eq \"" + userName + "\"]"); + patchOperations1.put("remove", new ArrayList() {{ + add(patchOperation3); + }}); + patchOperations2.put("remove", new ArrayList() {{ + add(patchOperation3); + }}); + patchOperations4.put("remove", new ArrayList() {{ + add(patchOperation3); + }}); + + return new Object[][]{ + {true, currentGroupName, updatedGroupName, patchOperations1}, + {false, currentGroupName, updatedGroupName, patchOperations1}, + {false, currentGroupName, currentGroupName, patchOperations2}, + {false, currentGroupName, updatedGroupName, patchOperations3}, + {false, currentGroupName, currentGroupName, patchOperations4}, + }; + } + + @Test(dataProvider = "patchGroupDataProvider") + public void testPatchGroup(boolean isUniqueGroupIdEnabled, String currentGroupName, String updatedGroupName, + Map> patchOperations) + throws NotImplementedException, BadRequestException, NotFoundException, CharonException, + IdentityApplicationManagementException, UserStoreException { + + String currentGroupNameWithDomain = "PRIMARY/" + currentGroupName; + String updatedGroupNameWithDomain = "PRIMARY/" + updatedGroupName; + + scimCommonUtils.when(() -> SCIMCommonUtils.getGroupNameWithDomain(currentGroupName)) + .thenReturn(currentGroupNameWithDomain); + scimCommonUtils.when(() -> SCIMCommonUtils.getGroupNameWithDomain(updatedGroupName)) + .thenReturn(updatedGroupNameWithDomain); + when(IdentityUtil.extractDomainFromName(anyString())).thenReturn("PRIMARY"); + + InboundProvisioningConfig inboundProvisioningConfig = new InboundProvisioningConfig(); + inboundProvisioningConfig.setProvisioningUserStore("PRIMARY"); + ServiceProvider serviceProvider = new ServiceProvider(); + serviceProvider.setInboundProvisioningConfig(inboundProvisioningConfig); + when(ApplicationManagementService.getInstance()).thenReturn(applicationManagementService); + when(applicationManagementService.getServiceProvider(anyString(), anyString())).thenReturn(serviceProvider); + + mockedUserStoreManager = mock(AbstractUserStoreManager.class); + when(mockedUserStoreManager.getSecondaryUserStoreManager(anyString())).thenReturn(secondaryUserStoreManager); + when(mockedUserStoreManager.isUniqueGroupIdEnabled()).thenReturn(isUniqueGroupIdEnabled); + when(secondaryUserStoreManager.getUserIDFromProperties(USERNAME_LOCAL_CLAIM, "user1", "default")) + .thenReturn("1234"); + + try (MockedConstruction mockedGroupHandler = mockConstruction(SCIMGroupHandler.class)) { + SCIMUserManager scimUserManager = new SCIMUserManager(mockedUserStoreManager, + mockClaimMetadataManagementService, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + scimUserManager.patchGroup("123456", currentGroupName, patchOperations); + + // Assert if mocks are called as expected. + if (currentGroupName.equals(updatedGroupName) || !patchOperations.containsKey("add")) { + verify(mockedUserStoreManager, times(0)).renameGroup("123456", updatedGroupNameWithDomain); + } else { + verify(mockedUserStoreManager, times(1)).renameGroup("123456", updatedGroupNameWithDomain); + } + if (patchOperations.containsKey("remove")) { + verify(mockedUserStoreManager, times(1)).updateUserListOfRoleWithID(anyString(), any(), any()); + } + verify(mockedUserStoreManager, times(1)).updateGroupName(currentGroupName, updatedGroupName); + + if (isUniqueGroupIdEnabled) { + assertEquals(mockedGroupHandler.constructed().size(), 0); + } else { + assertEquals(mockedGroupHandler.constructed().size(), 1); + } + } + } + /** * Build a group object with the given params to mock the userstore response. * diff --git a/components/org.wso2.carbon.identity.scim2.common/src/test/resources/testng.xml b/components/org.wso2.carbon.identity.scim2.common/src/test/resources/testng.xml index e9b0cdcfd..7a75706d3 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/test/resources/testng.xml +++ b/components/org.wso2.carbon.identity.scim2.common/src/test/resources/testng.xml @@ -35,6 +35,7 @@ +