Skip to content

Commit

Permalink
CB-5270 gql tests refactoring (#2713)
Browse files Browse the repository at this point in the history
  • Loading branch information
yagudin10 authored Jun 20, 2024
1 parent cdd3a35 commit b46dd9b
Show file tree
Hide file tree
Showing 18 changed files with 325 additions and 330 deletions.
1 change: 1 addition & 0 deletions server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Export-Package: io.cloudbeaver,
io.cloudbeaver.service.admin,
io.cloudbeaver.service.security,
io.cloudbeaver.service.sql,
io.cloudbeaver.test,
io.cloudbeaver.utils,
io.cloudbeaver.utils.file
Automatic-Module-Name: io.cloudbeaver.model
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 DBeaver Corp and others
*
* Licensed 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 io.cloudbeaver.test;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* GraphQL client for tests.
*/
public class WebGQLClient {
private static final Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
public static final String GQL_AUTHENTICATE = """
query authLogin($provider: ID!, $configuration: ID, $credentials: Object, $linkUser: Boolean, $forceSessionsLogout: Boolean) {
result: authLogin(
provider: $provider
configuration: $configuration
credentials: $credentials
linkUser: $linkUser
forceSessionsLogout: $forceSessionsLogout
) {
authId
authStatus
}
}""";

@NotNull
private final HttpClient httpClient;
@NotNull
private final String apiUrl;

public WebGQLClient(@NotNull HttpClient httpClient, @NotNull String apiUrl) {
this.httpClient = httpClient;
this.apiUrl = apiUrl;
}

/**
* Sends GraphQL request without additional headers
*
* @param query GraphQL query
* @param variables GraphQL query variables
* @return GraphQL response
*/
@NotNull
public <T> T sendQuery(@NotNull String query, @Nullable Map<String, Object> variables) throws Exception {
return sendQueryWithHeaders(query, variables, List.of());
}

/**
* Sends GraphQL request without additional headers
*
* @param query GraphQL query
* @param variables GraphQL query variables
* @param headers HTTP request headers
* @return GraphQL response
*/
@NotNull
public <T> T sendQueryWithHeaders(
@NotNull String query,
@Nullable Map<String, Object> variables,
@NotNull List<String> headers
) throws Exception {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.POST(HttpRequest.BodyPublishers.ofString(makeGQLRequest(query, variables)))
.setHeader("TE-Client-Version", GeneralUtils.getMajorVersion())
.header("Content-Type", "application/json");
if (!headers.isEmpty()) {
requestBuilder.headers(headers.toArray(String[]::new));
}
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Map<String, Object> body = gson.fromJson(
response.body(),
JSONUtils.MAP_TYPE_TOKEN
);
if (body.containsKey("errors")) {
String message = JSONUtils.getString(JSONUtils.getObjectList(body, "errors").get(0), "message");
throw new DBException(message);
}
// graphql response will be in "data" key
return (T) JSONUtils.getObject(body, "data").get("result");
}

@NotNull
private String makeGQLRequest(@NotNull String text, @Nullable Map<String, Object> variables) {
Map<String, Object> request = new LinkedHashMap<>();
request.put("query", text);
if (variables != null && !variables.isEmpty()) {
request.put("variables", variables);
}

return gson.toJson(request, Map.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,62 +17,15 @@

package io.cloudbeaver.utils;

import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;

import java.io.File;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class WebTestUtils {

public static final String GQL_TEMPLATE_AUTH_LOGIN = "authLogin.json";

public static String readScriptTemplate(String templateName, Path scriptsPath) throws Exception {
Path templatePath = new File(String.valueOf(scriptsPath), templateName).toPath();
return Files.readString(templatePath);
}


public static Map<String, Object> doPost(String apiUrl, String input, HttpClient client) throws Exception {
return doPostWithHeaders(apiUrl, input, client, List.of());
}

public static Map<String, Object> doPostWithHeaders(
String apiUrl,
String input,
HttpClient client,
List<String> headers
) throws Exception {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.POST(HttpRequest.BodyPublishers.ofString(input))
.setHeader("TE-Client-Version", GeneralUtils.getMajorVersion())
.header("Content-Type", "application/json");

if (!headers.isEmpty()) {
requestBuilder.headers(headers.toArray(String[]::new));
}
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());

return new GsonBuilder().create().fromJson(
response.body(),
new TypeToken<Map<String, Object>>() {
}.getType()
);
}

public static boolean getServerStatus(HttpClient client, String apiUrl) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
Expand All @@ -86,14 +39,4 @@ public static boolean getServerStatus(HttpClient client, String apiUrl) {
return false;
}
}

public static Map<String, Object> authenticateUser(HttpClient client, Path scriptsPath, String apiUrl) throws Exception {
String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_AUTH_LOGIN, scriptsPath);
Map<String, Object> map = WebTestUtils.doPost(apiUrl, input, client);
Map<String, Object> data = JSONUtils.getObjectOrNull(map, "data");
if (data != null) {
return JSONUtils.getObjectOrNull(data, "authInfo");
}
return Collections.emptyMap();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import io.cloudbeaver.service.rm.nio.RMNIOFileSystem;
import io.cloudbeaver.service.rm.nio.RMNIOFileSystemProvider;
import io.cloudbeaver.service.rm.nio.RMPath;
import io.cloudbeaver.test.WebGQLClient;
import io.cloudbeaver.test.platform.CEServerTestSuite;
import io.cloudbeaver.utils.WebTestUtils;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
Expand Down Expand Up @@ -53,12 +53,12 @@ public class RMNIOTest {
@BeforeClass
public static void init() throws Exception {
var cookieManager = new CookieManager();
var client = HttpClient.newBuilder()
var httpClient = HttpClient.newBuilder()
.cookieHandler(cookieManager)
.version(HttpClient.Version.HTTP_2)
.build();
Map<String, Object> authInfo = WebTestUtils.authenticateUser(
client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL);
WebGQLClient client = CEServerTestSuite.createClient(httpClient);
Map<String, Object> authInfo = CEServerTestSuite.authenticateTestUser(client);
Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));

String sessionId = cookieManager.getCookieStore().getCookies()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,64 +1,61 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2024 DBeaver Corp and others
*
* Licensed 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 io.cloudbeaver.test.platform;

import io.cloudbeaver.auth.provider.rp.RPAuthProvider;
import io.cloudbeaver.utils.WebTestUtils;
import io.cloudbeaver.test.WebGQLClient;
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class AuthenticationTest {
public static final String GQL_TEMPLATE_OPEN_SESSION = "openSession.json";
public static final String GQL_TEMPLATE_ACTIVE_USER = "activeUser.json";
public static final String REVERSE_PROXY_TEST_USER = "reverseProxyTestUser";
private static final String GQL_OPEN_SESSION = """
mutation openSession($defaultLocale: String) {
result: openSession(defaultLocale: $defaultLocale) {
valid
}
}""";
private static final String GQL_ACTIVE_USER = """
query activeUser {
result: activeUser {
userId
}
}""";

@Test
public void testLoginUser() throws Exception {
HttpClient client = CEServerTestSuite.createClient();
Map<String, Object> authInfo = WebTestUtils.authenticateUser(
client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL);
WebGQLClient client = CEServerTestSuite.createClient();
Map<String, Object> authInfo = CEServerTestSuite.authenticateTestUser(client);
Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));
}

@Test
public void testReverseProxyAnonymousModeLogin() throws Exception {
HttpClient client = CEServerTestSuite.createClient();
Map<String, Object> sessionInfo = openSession(client);
WebGQLClient client = CEServerTestSuite.createClient();
String testUserId = "reverseProxyTestUser";
List<String> headers = List.of(RPAuthProvider.X_USER, testUserId, RPAuthProvider.X_TEAM, "user");
Map<String, Object> sessionInfo = client.sendQueryWithHeaders(GQL_OPEN_SESSION, null, headers);
Assert.assertTrue(JSONUtils.getBoolean(sessionInfo, "valid"));
Map<String, Object> activeUser = getActiveUser(client);
Assert.assertEquals(REVERSE_PROXY_TEST_USER, JSONUtils.getString(activeUser, "userId"));
}

private Map<String, Object> openSession(HttpClient client) throws Exception {
Map<String, Object> data = doPostQuery(client, GQL_TEMPLATE_OPEN_SESSION);
if (data != null) {
return JSONUtils.getObject(data, "session");
}
return Collections.emptyMap();
}

private Map<String, Object> getActiveUser(HttpClient client) throws Exception {
Map<String, Object> data = doPostQuery(client, GQL_TEMPLATE_ACTIVE_USER);
if (data != null) {
return JSONUtils.getObject(data, "user");
}
return Collections.emptyMap();
Map<String, Object> activeUser = client.sendQuery(GQL_ACTIVE_USER, null);
Assert.assertEquals(testUserId, JSONUtils.getString(activeUser, "userId"));
}

private Map<String, Object> doPostQuery(HttpClient client, String gqlScript) throws Exception {
String input = WebTestUtils.readScriptTemplate(gqlScript, CEServerTestSuite.getScriptsPath());
List<String> headers = List.of(RPAuthProvider.X_USER, REVERSE_PROXY_TEST_USER, RPAuthProvider.X_TEAM, "user");
Map<String, Object> map = WebTestUtils.doPostWithHeaders(CEServerTestSuite.GQL_API_URL, input, client, headers);
return JSONUtils.getObjectOrNull(map, "data");
}


}
Loading

0 comments on commit b46dd9b

Please sign in to comment.