Skip to content

Integration Tests for Conditional View Access in Discoverable Applications within MyAccount feature #23725

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0eba98e
create test base for the discoverable applications
DilshanSenarath Feb 12, 2025
904275c
improve the test base
DilshanSenarath Feb 15, 2025
aa09630
add integrations for discoverable apps
DilshanSenarath Feb 16, 2025
52a6fdf
update application payload with discoverability
DilshanSenarath Feb 16, 2025
8f54847
Merge branch 'master' into discoverable-apps-integration
DilshanSenarath Feb 21, 2025
63e1292
add logic to remove the test resources
DilshanSenarath Feb 23, 2025
5da2655
add integration for discoverable groups property in application mgt api
DilshanSenarath Feb 25, 2025
ba5cf81
add test data
DilshanSenarath Feb 25, 2025
716d668
add integrations for the group met endpoint
DilshanSenarath Mar 1, 2025
5e1daf6
bump console version
DilshanSenarath Mar 1, 2025
a820658
fix the formatting issues
DilshanSenarath Mar 1, 2025
83c56a7
Merge branch 'master' into discoverable-apps-integration
DilshanSenarath Mar 1, 2025
8497c3a
update api server version
DilshanSenarath Mar 1, 2025
7ee6b1b
fix the group count issue
DilshanSenarath Mar 1, 2025
6dc5650
revert the api user version
DilshanSenarath Mar 2, 2025
4cf2b4e
Merge branch 'master' into discoverable-apps-integration
DilshanSenarath Mar 2, 2025
c0869a5
revert scim version
DilshanSenarath Mar 2, 2025
c14c225
Merge branch 'master' into discoverable-apps-integration
DilshanSenarath Mar 3, 2025
2be6872
Merge branch 'wso2:master' into discoverable-apps-integration
DilshanSenarath Mar 6, 2025
af3e40e
change the client init logic
DilshanSenarath Mar 9, 2025
e7b41ee
close the http clients
DilshanSenarath Mar 16, 2025
a0c4b03
fix the issue of client closing order
DilshanSenarath Mar 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,24 @@ protected Response getResponseOfGetWithOAuth2(String endpointURL, String accessT
.get(endpointURL);
}

/**
* Invoke given endpointURL with params for GET with OAuth2 authentication, using the provided token.
*
* @param endpointURL Endpoint to be invoked.
* @param accessToken OAuth2 access token.
* @param queryParams request query parameters
* @return Response.
*/
protected Response getResponseOfGetWithOAuth2(String endpointURL, String accessToken,
Map<String, Object> queryParams) {

return given().auth().preemptive().oauth2(accessToken)
.header(HttpHeaders.ACCEPT, ContentType.JSON)
.queryParams(queryParams)
.when()
.get(endpointURL);
}

/**
* Invoke given endpointUri for GET without authentication.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
/*
* Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2019-2025, WSO2 LLC. (https://www.wso2.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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
* 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.
* 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.identity.integration.test.rest.api.server.application.management.v1;

import io.restassured.RestAssured;
import io.restassured.response.Response;

import java.io.IOException;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
Expand All @@ -28,9 +37,8 @@
import org.testng.annotations.DataProvider;
import org.wso2.carbon.automation.engine.context.TestUserMode;
import org.wso2.identity.integration.test.rest.api.server.common.RESTAPIServerTestBase;

import java.io.IOException;
import java.util.Set;
import org.wso2.identity.integration.test.rest.api.user.common.model.GroupRequestObject;
import org.wso2.identity.integration.test.restclients.SCIM2RestClient;

/**
* Base test class for Application Management REST APIs.
Expand All @@ -45,9 +53,11 @@ public class ApplicationManagementBaseTest extends RESTAPIServerTestBase {
static final String RESIDENT_APP_API_BASE_PATH = APPLICATION_MANAGEMENT_API_BASE_PATH + "/resident";
static final String APPLICATION_TEMPLATE_MANAGEMENT_API_BASE_PATH = APPLICATION_MANAGEMENT_API_BASE_PATH +
"/templates";
static final String GROUPS_METADATA_PATH = METADATA_API_BASE_PATH + "/groups";
static final String PATH_SEPARATOR = "/";

protected static String swaggerDefinition;
private SCIM2RestClient scim2RestClient;

static {
String API_PACKAGE_NAME = "org.wso2.carbon.identity.api.server.application.management.v1";
Expand All @@ -72,12 +82,14 @@ public ApplicationManagementBaseTest(TestUserMode userMode) throws Exception {
public void init() throws IOException {

super.testInit(API_VERSION, swaggerDefinition, tenant);
scim2RestClient = new SCIM2RestClient(serverURL, tenantInfo);
}

@AfterClass(alwaysRun = true)
public void testConclude() throws Exception {

super.conclude();
scim2RestClient.closeHttpClient();
}

@BeforeMethod(alwaysRun = true)
Expand Down Expand Up @@ -116,4 +128,85 @@ protected void cleanUpApplications(Set<String> appsToCleanUp) {
getResponseOfGet(applicationPath).then().assertThat().statusCode(HttpStatus.SC_NOT_FOUND);
});
}

/**
* Create a set of groups and return the group IDs.
*
* @param groupCount The number of groups to be created.
* @param groupNamePrefix The prefix of the group name.
* @return The group IDs.
* @throws Exception If an error occurs while creating the groups.
*/
protected String[] createGroups(int groupCount, String groupNamePrefix) throws Exception {

String[] groupIDs = new String[groupCount];
for (int i = 0; i < groupCount; i++) {
String groupName = groupNamePrefix + i;
groupIDs[i] = scim2RestClient.createGroup(new GroupRequestObject().displayName(groupName));
}
return groupIDs;
}

/**
* Delete the groups with the given group IDs.
*
* @param groupIDs The group IDs.
* @throws Exception If an error occurs while deleting the groups.
*/
protected void deleteGroups(String[] groupIDs) throws Exception {

for (String groupID : groupIDs) {
scim2RestClient.deleteGroup(groupID);
}
}

/**
* Add discoverable groups to the application payload.
*
* @param payload Application payload.
* @param userStore User store.
* @param groupIDs Group IDs.
* @throws JSONException If an error occurs while adding discoverable groups to the payload.
*/
protected JSONObject addDiscoverableGroupsToApplicationPayload(JSONObject payload, String userStore,
String[] groupIDs)
throws JSONException {

JSONObject discoverableGroup = new JSONObject();
discoverableGroup.put("userStore", userStore);
JSONArray groups = new JSONArray();
for (String groupID : groupIDs) {
JSONObject group = new JSONObject();
group.put("id", groupID);
groups.put(group);
}
discoverableGroup.put("groups", groups);
JSONArray discoverableGroups = new JSONArray();
discoverableGroups.put(discoverableGroup);
JSONObject advancedConfigs = payload.getJSONObject("advancedConfigurations");
advancedConfigs.put("discoverableGroups", discoverableGroups);
return payload;
}

/**
* Verify the discoverable groups in the response.
*
* @param response The response.
* @param userStore User store.
* @param groupIDs Group IDs.
* @throws JSONException If an error occurs while verifying the discoverable groups.
*/
protected void verifyDiscoverableGroups(JSONObject response, String userStore, String[] groupIDs)
throws JSONException {

JSONArray discoverableGroups = response.getJSONArray("discoverableGroups");
Assert.assertEquals(discoverableGroups.length(), 1, "Discoverable groups count mismatched.");
JSONObject discoverableGroup = discoverableGroups.getJSONObject(0);
Assert.assertEquals(discoverableGroup.getString("userStore"), userStore, "User store mismatched.");
JSONArray groups = discoverableGroup.getJSONArray("groups");
Assert.assertEquals(groups.length(), groupIDs.length, "Group count mismatched.");
for (String groupID : groupIDs) {
Assert.assertTrue(groups.toString().contains(groupID), "Group ID not found in the response.");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
/*
* Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
* Copyright (c) 2019-2025, WSO2 LLC. (https://www.wso2.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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
* 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.
* 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.identity.integration.test.rest.api.server.application.management.v1;

import io.restassured.response.Response;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.hamcrest.Matchers;
import org.json.JSONException;
import org.json.JSONObject;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import org.wso2.carbon.automation.engine.context.TestUserMode;
import org.wso2.carbon.identity.application.mgt.ApplicationConstants;

import java.util.HashSet;
import java.util.Set;

import static org.hamcrest.core.IsNull.notNullValue;
import static org.wso2.identity.integration.test.rest.api.server.application.management.v1.Utils.assertNotBlank;
import static org.wso2.identity.integration.test.rest.api.server.application.management.v1.Utils.extractApplicationIdFromLocationHeader;
Expand Down Expand Up @@ -203,6 +211,32 @@ public void testCreateDiscoverableAppWithoutAccessUrl() throws Exception {
validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "APP-60001");
}

@Test(description = "Test configuring invalid discoverable groups for an application.")
public void testAddInvalidDiscoverableGroups() throws Exception {

String payload = readResource("invalid-discoverable-groups.json");
Response response = getResponseOfPost(APPLICATION_MANAGEMENT_API_BASE_PATH, payload);
validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "APP-60001");
response.then()
.body("description", Matchers.equalTo(String.format(
"Invalid application configuration for application: 'Test Invalid App' of tenantDomain: %s." +
" No group found for the given group ID: 'invalid-id-1'. No group found for the" +
" given group ID: 'invalid-id-2'. The provided user store: 'INVALID_USER_STORE_1'" +
" is not found.",
tenant)));
JSONObject applicationPayload = new JSONObject(payload);
JSONObject advancedConfigs = applicationPayload.getJSONObject("advancedConfigurations");
advancedConfigs.put("discoverableByEndUsers", false);
payload = applicationPayload.toString();
response = getResponseOfPost(APPLICATION_MANAGEMENT_API_BASE_PATH, payload);
validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "APP-60001");
response.then()
.body("description", Matchers.equalTo(String.format(
"Invalid application configuration for application: 'Test Invalid App' of tenantDomain: %s." +
" Discoverable groups are defined for a non-discoverable application.",
tenant)));
}

@Test(description = "Tests whether inbound unique key is validated during application creation.")
public void testCreateApplicationsWithConflictingInboundKeys() throws Exception {

Expand Down Expand Up @@ -233,6 +267,36 @@ public void testCreateApplicationsWithInvalidAllowedOrigins() throws Exception {
validateErrorResponse(createAppResponse, HttpStatus.SC_BAD_REQUEST, "APP-60001");
}

@Test(description = "Test groups metadata endpoint with an invalid domain.")
public void testGetGroupsMetadataWithInvalidDomain() {

Map<String, Object> queryParam = new HashMap<>();
queryParam.put("domain", "invalid");
Response response = getResponseOfGetWithQueryParams(GROUPS_METADATA_PATH, queryParam);
validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "APP-60001");
}

@DataProvider(name = "testGetGroupsMetadataWithInvalidFilters")
public Object[][] testGetGroupsMetadataWithInvalidFilters() {

return new Object[][]{
{ "name eq Group_1_1" },
{ "name sw Gro" },
{ "name ew _1" },
{ "id co 12" }
};
}

@Test(description = "Test groups metadata endpoint with invalid filters.",
dataProvider = "testGetGroupsMetadataWithInvalidFilters")
public void testGetGroupsMetadataWithInvalidFilters(String filter) {

Map<String, Object> queryParam = new HashMap<>();
queryParam.put("filter", filter);
Response response = getResponseOfGetWithQueryParams(GROUPS_METADATA_PATH, queryParam);
validateErrorResponse(response, HttpStatus.SC_BAD_REQUEST, "APP-60004");
}

private String getApplicationId(Response createFirstAppResponse) {

String location = createFirstAppResponse.getHeader(HttpHeaders.LOCATION);
Expand Down
Loading