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 6861e59a3..bf3cf2e95 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 @@ -47,6 +47,7 @@ import org.wso2.carbon.identity.scim2.common.extenstion.SCIMUserStoreErrorResolver; import org.wso2.carbon.identity.scim2.common.group.SCIMGroupHandler; import org.wso2.carbon.identity.scim2.common.internal.SCIMCommonComponentHolder; +import org.wso2.charon3.core.objects.plainobjects.Cursor; import org.wso2.charon3.core.objects.plainobjects.UsersGetResponse; import org.wso2.carbon.identity.scim2.common.test.utils.CommonTestUtils; import org.wso2.carbon.identity.scim2.common.utils.AttributeMapper; @@ -111,9 +112,9 @@ import static org.powermock.api.mockito.PowerMockito.spy; import static org.powermock.api.mockito.PowerMockito.when; import static org.powermock.api.mockito.PowerMockito.whenNew; -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertTrue; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; /* * Unit tests for SCIMUserManager @@ -469,7 +470,201 @@ public void testListUsersWithGET(List use requiredClaimsMap.put("urn:ietf:params:scim:schemas:core:2.0:User:userName", false); SCIMUserManager scimUserManager = new SCIMUserManager(mockedUserStoreManager, mockedClaimManager); UsersGetResponse result = scimUserManager.listUsersWithGET(null, 1, 0, null, null, requiredClaimsMap); - assertEquals(expectedResultCount, result.getUsers().size()); + assertEquals(result.getUsers().size(), expectedResultCount); + } + + @Test(dataProvider = "userInfoForCursorFiltering") + public void testCursorFilteringUsersWithGET(String filter, int expectedResultCount, Object cursor, Integer count, + List filteredUsers) + throws Exception { + + Map scimToLocalClaimMap = new HashMap<>(); + scimToLocalClaimMap.put("urn:ietf:params:scim:schemas:core:2.0:User:userName", + "http://wso2.org/claims/username"); + scimToLocalClaimMap.put("urn:ietf:params:scim:schemas:core:2.0:id", "http://wso2.org/claims/userid"); + scimToLocalClaimMap.put("urn:ietf:params:scim:schemas:core:2.0:User:emails", + "http://wso2.org/claims/emailaddress"); + scimToLocalClaimMap.put("urn:ietf:params:scim:schemas:core:2.0:User:name.givenName", + "http://wso2.org/claims/givenname"); + + mockStatic(SCIMCommonUtils.class); + when(SCIMCommonUtils.getSCIMtoLocalMappings()).thenReturn(scimToLocalClaimMap); + when(SCIMCommonUtils.convertLocalToSCIMDialect(anyMap(), anyMap())).thenReturn(new HashMap() {{ + put(SCIMConstants.CommonSchemaConstants.ID_URI, "1f70378a-69bb-49cf-aa51-a0493c09110c"); + }}); + + mockedUserStoreManager = PowerMockito.mock(AbstractUserStoreManager.class); + + //Cursor filtering + when(mockedUserStoreManager.getUserListWithID(any(Condition.class), anyString(), anyString(), anyInt(), + anyString(), anyString(), anyString(), anyString())).thenReturn(filteredUsers); + + whenNew(GroupDAO.class).withAnyArguments().thenReturn(mockedGroupDAO); + when(mockedGroupDAO.listSCIMGroups(anyInt())).thenReturn(anySet()); + when(mockedUserStoreManager.getSecondaryUserStoreManager("PRIMARY")).thenReturn(mockedUserStoreManager); + when(mockedUserStoreManager.isSCIMEnabled()).thenReturn(true); + when(mockedUserStoreManager.getSecondaryUserStoreManager("SECONDARY")).thenReturn(secondaryUserStoreManager); + when(secondaryUserStoreManager.isSCIMEnabled()).thenReturn(true); + + when(mockedUserStoreManager.getRealmConfiguration()).thenReturn(mockedRealmConfig); + when(mockedRealmConfig.getUserStoreProperty(UserCoreConstants.RealmConfig.PROPERTY_MAX_USER_LIST)) + .thenReturn("100"); + + mockStatic(IdentityTenantUtil.class); + when(IdentityTenantUtil.getRealmService()).thenReturn(mockRealmService); + when(mockRealmService.getBootstrapRealmConfiguration()).thenReturn(mockedRealmConfig); + mockStatic(IdentityUtil.class); + when(IdentityUtil.isGroupsVsRolesSeparationImprovementsEnabled()).thenReturn(false); + + ClaimMapping[] claimMappings = getTestClaimMappings(); + when(mockedClaimManager.getAllClaimMappings(anyString())).thenReturn(claimMappings); + + HashMap requiredClaimsMap = new HashMap<>(); + requiredClaimsMap.put("urn:ietf:params:scim:schemas:core:2.0:User:userName", false); + SCIMUserManager scimUserManager = new SCIMUserManager(mockedUserStoreManager, mockedClaimManager); + + Node node = null; + if (StringUtils.isNotBlank(filter)) { + SCIMResourceTypeSchema schema = SCIMResourceSchemaManager.getInstance().getUserResourceSchema(); + FilterTreeManager filterTreeManager = new FilterTreeManager(filter, schema); + node = filterTreeManager.buildTree(); + } + + UsersGetResponse result = scimUserManager.listUsersWithGET(node, (Cursor) cursor, count, null, null, null, + requiredClaimsMap); + assertEquals(result.getUsers().size(), expectedResultCount); + } + + @DataProvider(name = "userInfoForCursorFiltering") + public Object[][] userInfoForCursorFiltering() { + + + org.wso2.carbon.user.core.common.User testUser1 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "testUser1", "testUser1"); + Map testUser1Attributes = new HashMap<>(); + testUser1Attributes.put("http://wso2.org/claims/givenname", "testUser"); + testUser1Attributes.put("http://wso2.org/claims/emailaddress", "testUser1@gmail.com"); + testUser1.setAttributes(testUser1Attributes); + + org.wso2.carbon.user.core.common.User testUser2 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "testUser2", "testUser2"); + Map testUser2Attributes = new HashMap<>(); + testUser2Attributes.put("http://wso2.org/claims/givenname", "testUser"); + testUser2Attributes.put("http://wso2.org/claims/emailaddress", "testUser2@wso2.com"); + testUser2.setAttributes(testUser2Attributes); + + org.wso2.carbon.user.core.common.User testUser3 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "testUser3", "testUser3"); + Map testUser3Attributes = new HashMap<>(); + testUser3Attributes.put("http://wso2.org/claims/givenname", "testUser"); + testUser3Attributes.put("http://wso2.org/claims/emailaddress", "testUser3@gmail.com"); + testUser3.setAttributes(testUser3Attributes); + + org.wso2.carbon.user.core.common.User testUser4 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "testUser4", "testUser4"); + Map testUser4Attributes = new HashMap<>(); + testUser4Attributes.put("http://wso2.org/claims/givenname", "testUser"); + testUser4Attributes.put("http://wso2.org/claims/emailaddress", "testUser4@wso2.com"); + testUser4.setAttributes(testUser4Attributes); + + org.wso2.carbon.user.core.common.User fakeUser5 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "fakeUser5", "fakeUser5"); + Map testUser5Attributes = new HashMap<>(); + testUser5Attributes.put("http://wso2.org/claims/givenname", "fakeUser"); + testUser5Attributes.put("http://wso2.org/claims/emailaddress", "fakeUser5@gmail.com"); + fakeUser5.setAttributes(testUser5Attributes); + + org.wso2.carbon.user.core.common.User fakeUser6 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "fakeUser6", "fakeUser6"); + Map testUser6Attributes = new HashMap<>(); + testUser6Attributes.put("http://wso2.org/claims/givenname", "fakeUser"); + testUser6Attributes.put("http://wso2.org/claims/emailaddress", "fakeUser6@wso2.com"); + fakeUser6.setAttributes(testUser6Attributes); + + org.wso2.carbon.user.core.common.User fakeUser7 = new org.wso2.carbon.user.core.common.User(UUID.randomUUID() + .toString(), "fakeUser7", "fakeUser7"); + Map testUser7Attributes = new HashMap<>(); + testUser7Attributes.put("http://wso2.org/claims/givenname", "fakeUser"); + testUser7Attributes.put("http://wso2.org/claims/emailaddress", "fakeUser7@gmail.com"); + fakeUser7.setAttributes(testUser7Attributes); + + return new Object[][]{ + // Forwards pagination initial request + {"name.givenName eq testUser", 4, new Cursor("", "NEXT"), 5, + new ArrayList() {{ + add(testUser1); + add(testUser2); + add(testUser3); + add(testUser4); + }}}, + + // Forwards pagination without filtering + {null, 5, new Cursor("fakeUser6", "NEXT"), 5, + new ArrayList() {{ + add(fakeUser7); + add(testUser1); + add(testUser2); + add(testUser3); + add(testUser4); + }}}, + + // Backwards pagination without filter + {null, 4, new Cursor("testUser2", "PREVIOUS"), 5, + new ArrayList() {{ + add(fakeUser5); + add(fakeUser6); + add(fakeUser7); + add(testUser1); + }}}, + + // Forwards pagination with a filter + {"name.givenName eq testUser", 2, new Cursor("testUser2", "NEXT"), 5, + new ArrayList() {{ + add(testUser3); + add(testUser4); + }}}, + + // Backwards pagination with a filter + {"name.givenName eq testUser", 2, new Cursor("testUser3", "PREVIOUS"), 5, + new ArrayList() {{ + add(testUser1); + add(testUser2); + }}}, + + // Multi-attribute filtering - Forwards pagination - With a count + {"name.givenName eq testUser and emails co gmail", 2, new Cursor("", "NEXT"), 5, + new ArrayList() {{ + add(testUser1); + add(testUser3); + }}}, + + // Multi-attribute filtering - Backwards pagination + {"name.givenName eq fakeUser and emails co wso2.com", 1, + new Cursor("fakeUser7", "PREVIOUS"), 5, + new ArrayList() {{ + add(fakeUser6); + }}}, + + // Multi-attribute filtering - Forwards pagination - Without maxLimit calls + // getMultiAttributeFilteredUsersWithMaxLimit + {"name.givenName eq testUser and emails co gmail", 2, new Cursor("", "NEXT"), null, + new ArrayList() {{ + add(testUser1); + add(testUser3); + }}}, + + // Return empty list when count == 0 + {"", 0, new Cursor("", "NEXT"), 0, + new ArrayList() {{ + }}}, + + // Single attribute group filtering + {"groups eq Manager", 2, new Cursor("", "NEXT"), 5, + new ArrayList() {{ + add(testUser1); + add(testUser3); + }}}, + }; } @DataProvider(name = "listUser") @@ -491,18 +686,18 @@ public Object[][] listUser() throws Exception { // If SCIM is enabled for both primary and secondary, result should contain a total of 4 entries, // including the metadata in index position. - {users, true, true, 4}, + {users, true, true, 3}, // If SCIM is enabled for primary but not for secondary, result should contain 3 entries including // the metadata in index position and 2 users [testUser1, testUser2] from primary user-store domain. - {users, true, false, 3}, + {users, true, false, 2}, // If SCIM is enabled for secondary but not for primary, result should contain 2 entries including // the metadata in index position and 1 users [SECONDARY/testUser3] from secondary user-store domain. - {users, false, true, 2}, + {users, false, true, 1}, // If no users are present in user-stores, result should contain a single entry for metadata. - {Collections.EMPTY_LIST, true, true, 1} + {Collections.EMPTY_LIST, true, true, 0} }; } @@ -567,7 +762,7 @@ public void testFilteringUsersWithGET(List() {{ add(testUser1); add(testUser2); }}}, - {users, "name.givenName eq testUser and emails eq testUser1@wso2.com", 2, + {users, "name.givenName eq testUser and emails eq testUser1@wso2.com", 1, new ArrayList() {{ add(testUser1); }}} @@ -678,8 +873,8 @@ public void testListApplicationRolesWithDomainParam(Map require List roleList = scimUserManager .listGroupsWithGET(null, 1, null, null, null, "Application", requiredAttributes); roleList.remove(0); //The first entry is the count of roles. - assertEquals("Application/Apple", ((Group) roleList.get(0)).getDisplayName()); - assertEquals("Application/MyApp", ((Group) roleList.get(1)).getDisplayName()); + assertEquals(((Group) roleList.get(0)).getDisplayName(), "Application/Apple"); + assertEquals(((Group) roleList.get(1)).getDisplayName(), "Application/MyApp"); assertEquals(roleList.size(), 2); } @@ -735,7 +930,7 @@ public void testFilterApplicationRolesWithDomainParam(String filter, String[] ro List roleList = scimUserManager .listGroupsWithGET(node, 1, null, null, null, "Application", requiredAttributes); roleList.remove(0); //The first entry is the count of roles. - assertEquals("Application/MyApp", ((Group) roleList.get(0)).getDisplayName()); + assertEquals(((Group) roleList.get(0)).getDisplayName(), "Application/MyApp"); assertEquals(roleList.size(), 1); } @@ -854,7 +1049,7 @@ public void testUpdateUserWithUsernameChange() throws Exception { } } - assertTrue("UserName claim update is not properly handled.", hasExpectedBehaviour); + assertTrue(hasExpectedBehaviour, "UserName claim update is not properly handled."); } @Test @@ -888,7 +1083,7 @@ public void testGetUserSchema() throws Exception { SCIMUserManager scimUserManager = new SCIMUserManager(mockedUserStoreManager, mockClaimMetadataManagementService, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); List list = scimUserManager.getUserSchema(); - assertEquals(3, list.size()); + assertEquals(list.size(), 3); } @Test(dataProvider = "groupPermission") @@ -901,7 +1096,7 @@ public void testGetGroupPermissions(String roleName, String[] permission, Object .thenReturn(mockedRolePermissionManagementService); when(mockedRolePermissionManagementService.getRolePermissions(anyString(), anyInt())).thenReturn(permission); String[] actual = scimUserManager.getGroupPermissions(roleName); - assertEquals(expected, actual); + assertEquals(actual, expected); } @DataProvider(name = "groupPermission") @@ -1092,13 +1287,13 @@ public Group answer(InvocationOnMock invocation) throws Throwable { mockStatic(IdentityTenantUtil.class); when(IdentityTenantUtil.getTenantId("carbon.super")).thenReturn(-1234); User scimUser = scimUserManager.getUser(userId, requiredAttributes); - assertEquals(expectedNoOfAttributes, scimUser.getAttributeList().size()); + assertEquals(scimUser.getAttributeList().size(), expectedNoOfAttributes); // Check whether the added multi valued attributes for the addresses attribute are contained. - assertEquals(2, - ((MultiValuedAttribute) scimUser.getAttribute("addresses")).getAttributeValues().size()); - assertEquals(expectedUserName, scimUser.getUserName()); - assertEquals(expectedNoOfGroups, scimUser.getGroups().size()); - assertEquals(expectedNoOfRoles, scimUser.getRoles().size()); + assertEquals( + ((MultiValuedAttribute) scimUser.getAttribute("addresses")).getAttributeValues().size(), 2); + assertEquals(scimUser.getUserName(), expectedUserName); + assertEquals(scimUser.getGroups().size(), expectedNoOfGroups); + assertEquals(scimUser.getRoles().size(), expectedNoOfRoles); } @DataProvider(name = "exceptionHandlingConfigurations") @@ -1161,15 +1356,14 @@ public void testGetUserWhenSCIMisDisabled() throws Exception { public void testListUsersWithPost() throws Exception { SearchRequest searchRequest = new SearchRequest(); - List listOfUsers = new ArrayList<>(); - + UsersGetResponse usersGetResponse = new UsersGetResponse(0, Collections.emptyList()); Map requiredAttributes = new HashMap<>(); SCIMUserManager scimUserManager = spy(new SCIMUserManager(mockedUserStoreManager, mockClaimMetadataManagementService, MultitenantConstants.SUPER_TENANT_DOMAIN_NAME)); - doReturn(listOfUsers).when(scimUserManager) + doReturn(usersGetResponse).when(scimUserManager) .listUsersWithGET(any(), (Integer) any(), any(), anyString(), anyString(), anyString(), anyMap()); UsersGetResponse users = scimUserManager.listUsersWithPost(searchRequest, requiredAttributes); - assertEquals(listOfUsers, users); + assertEquals(users, usersGetResponse); } @Test(expectedExceptions = NotFoundException.class)