From b46dd9b8a8cc272577f453cece1f10bfd80ac204 Mon Sep 17 00:00:00 2001 From: Ainur <59531286+yagudin10@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:59:57 +0200 Subject: [PATCH] CB-5270 gql tests refactoring (#2713) --- .../io.cloudbeaver.model/META-INF/MANIFEST.MF | 1 + .../src/io/cloudbeaver/test/WebGQLClient.java | 124 ++++++++++++++++++ .../io/cloudbeaver/utils/WebTestUtils.java | 57 -------- .../io/cloudbeaver/model/rm/RMNIOTest.java | 8 +- .../test/platform/AuthenticationTest.java | 77 ++++++----- .../test/platform/CEServerTestSuite.java | 88 +++++++------ .../test/platform/ConnectionsTest.java | 94 +++++++------ .../test/platform/ResourceManagerTest.java | 117 ++++++++++------- .../workspace/gql_scripts/activeUser.json | 4 - .../workspace/gql_scripts/authLogin.json | 12 -- .../gql_scripts/createConnection.json | 22 ---- .../gql_scripts/deleteConnection.json | 8 -- .../workspace/gql_scripts/navDeleteNode.json | 9 -- .../workspace/gql_scripts/openSession.json | 7 - .../gql_scripts/rmDeleteResource.json | 9 -- .../rmReadEmptyProjectIdResources.json | 3 - .../gql_scripts/rmWriteResource.json | 10 -- .../gql_scripts/userConnections.json | 5 - 18 files changed, 325 insertions(+), 330 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/test/WebGQLClient.java delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/authLogin.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/createConnection.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/deleteConnection.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/navDeleteNode.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmDeleteResource.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmReadEmptyProjectIdResources.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmWriteResource.json delete mode 100644 server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/userConnections.json diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index f9ae5108fd..c265424b51 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -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 diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/test/WebGQLClient.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/test/WebGQLClient.java new file mode 100644 index 0000000000..93d0ab37ca --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/test/WebGQLClient.java @@ -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 sendQuery(@NotNull String query, @Nullable Map 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 sendQueryWithHeaders( + @NotNull String query, + @Nullable Map variables, + @NotNull List 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 response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + Map 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 variables) { + Map request = new LinkedHashMap<>(); + request.put("query", text); + if (variables != null && !variables.isEmpty()) { + request.put("variables", variables); + } + + return gson.toJson(request, Map.class); + } +} diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java index 65956cfcf5..b4c131f815 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebTestUtils.java @@ -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 doPost(String apiUrl, String input, HttpClient client) throws Exception { - return doPostWithHeaders(apiUrl, input, client, List.of()); - } - - public static Map doPostWithHeaders( - String apiUrl, - String input, - HttpClient client, - List 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 response = client.send(request, - HttpResponse.BodyHandlers.ofString()); - - return new GsonBuilder().create().fromJson( - response.body(), - new TypeToken>() { - }.getType() - ); - } - public static boolean getServerStatus(HttpClient client, String apiUrl) { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) @@ -86,14 +39,4 @@ public static boolean getServerStatus(HttpClient client, String apiUrl) { return false; } } - - public static Map authenticateUser(HttpClient client, Path scriptsPath, String apiUrl) throws Exception { - String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_AUTH_LOGIN, scriptsPath); - Map map = WebTestUtils.doPost(apiUrl, input, client); - Map data = JSONUtils.getObjectOrNull(map, "data"); - if (data != null) { - return JSONUtils.getObjectOrNull(data, "authInfo"); - } - return Collections.emptyMap(); - } } diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/rm/RMNIOTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/rm/RMNIOTest.java index da6eceae9b..ab4f65bcc8 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/rm/RMNIOTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/model/rm/RMNIOTest.java @@ -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; @@ -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 authInfo = WebTestUtils.authenticateUser( - client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL); + WebGQLClient client = CEServerTestSuite.createClient(httpClient); + Map authInfo = CEServerTestSuite.authenticateTestUser(client); Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus")); String sessionId = cookieManager.getCookieStore().getCookies() diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java index e279eb9c0b..d642b44e34 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/AuthenticationTest.java @@ -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 authInfo = WebTestUtils.authenticateUser( - client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL); + WebGQLClient client = CEServerTestSuite.createClient(); + Map authInfo = CEServerTestSuite.authenticateTestUser(client); Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus")); } @Test public void testReverseProxyAnonymousModeLogin() throws Exception { - HttpClient client = CEServerTestSuite.createClient(); - Map sessionInfo = openSession(client); + WebGQLClient client = CEServerTestSuite.createClient(); + String testUserId = "reverseProxyTestUser"; + List headers = List.of(RPAuthProvider.X_USER, testUserId, RPAuthProvider.X_TEAM, "user"); + Map sessionInfo = client.sendQueryWithHeaders(GQL_OPEN_SESSION, null, headers); Assert.assertTrue(JSONUtils.getBoolean(sessionInfo, "valid")); - Map activeUser = getActiveUser(client); - Assert.assertEquals(REVERSE_PROXY_TEST_USER, JSONUtils.getString(activeUser, "userId")); - } - - private Map openSession(HttpClient client) throws Exception { - Map data = doPostQuery(client, GQL_TEMPLATE_OPEN_SESSION); - if (data != null) { - return JSONUtils.getObject(data, "session"); - } - return Collections.emptyMap(); - } - private Map getActiveUser(HttpClient client) throws Exception { - Map data = doPostQuery(client, GQL_TEMPLATE_ACTIVE_USER); - if (data != null) { - return JSONUtils.getObject(data, "user"); - } - return Collections.emptyMap(); + Map activeUser = client.sendQuery(GQL_ACTIVE_USER, null); + Assert.assertEquals(testUserId, JSONUtils.getString(activeUser, "userId")); } - - private Map doPostQuery(HttpClient client, String gqlScript) throws Exception { - String input = WebTestUtils.readScriptTemplate(gqlScript, CEServerTestSuite.getScriptsPath()); - List headers = List.of(RPAuthProvider.X_USER, REVERSE_PROXY_TEST_USER, RPAuthProvider.X_TEAM, "user"); - Map map = WebTestUtils.doPostWithHeaders(CEServerTestSuite.GQL_API_URL, input, client, headers); - return JSONUtils.getObjectOrNull(map, "data"); - } - - } diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java index f922f67b2f..3ca615b5ea 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/CEServerTestSuite.java @@ -17,11 +17,15 @@ package io.cloudbeaver.test.platform; +import io.cloudbeaver.auth.provider.local.LocalAuthProvider; import io.cloudbeaver.model.rm.RMNIOTest; import io.cloudbeaver.model.rm.lock.RMLockTest; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBApplicationCE; +import io.cloudbeaver.test.WebGQLClient; import io.cloudbeaver.utils.WebTestUtils; +import org.jkiss.code.NotNull; +import org.jkiss.utils.SecurityUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.runner.RunWith; @@ -29,7 +33,7 @@ import java.net.CookieManager; import java.net.http.HttpClient; -import java.nio.file.Path; +import java.util.Map; @RunWith(Suite.class) @Suite.SuiteClasses( @@ -44,43 +48,34 @@ ) public class CEServerTestSuite { - public static final String GQL_API_URL = "http://localhost:18978/api/gql"; - public static final String SERVER_STATUS_URL = "http://localhost:18978/status"; + private static final String GQL_API_URL = "http://localhost:18978/api/gql"; + private static final String SERVER_STATUS_URL = "http://localhost:18978/status"; + private static final Map TEST_CREDENTIALS = Map.of( + LocalAuthProvider.CRED_USER, "test", + LocalAuthProvider.CRED_PASSWORD, SecurityUtils.makeDigest("test") + ); - private static boolean setUpIsDone = false; - private static boolean testFinished = false; - - private static CBApplication testApp; - private static HttpClient client; - private static Path scriptsPath; - private static Thread thread; + private static CBApplication testApp; @BeforeClass public static void startServer() throws Exception { - if (setUpIsDone) { - return; - } else { - System.out.println("Start CBApplication"); - testApp = new CBApplicationCE(); - thread = new Thread(() -> { - testApp.start(null); - }); - thread.start(); - client = createClient(); - long startTime = System.currentTimeMillis(); - long endTime = 0; - while (true) { - setUpIsDone = WebTestUtils.getServerStatus(client, SERVER_STATUS_URL); - endTime = System.currentTimeMillis() - startTime; - if (setUpIsDone || endTime > 300000) { - break; - } - } - if (!setUpIsDone) { - throw new Exception("Server is not running"); - } - scriptsPath = Path.of(testApp.getHomeDirectory().toString(), "/workspace/gql_scripts") - .toAbsolutePath(); + System.out.println("Start CBApplication"); + testApp = new CBApplicationCE(); + Thread thread = new Thread(() -> testApp.start(null)); + thread.start(); + HttpClient httpClient = HttpClient.newBuilder() + .cookieHandler(new CookieManager()) + .version(HttpClient.Version.HTTP_2) + .build(); + long startTime = System.currentTimeMillis(); + long endTime = 0; + boolean setUpIsDone = false; + while (!setUpIsDone && endTime < 300000) { + setUpIsDone = WebTestUtils.getServerStatus(httpClient, SERVER_STATUS_URL); + endTime = System.currentTimeMillis() - startTime; + } + if (!setUpIsDone) { + throw new Exception("Server is not running"); } } @@ -89,22 +84,29 @@ public static void shutdownServer() { testApp.stop(); } - public static CBApplication getTestApp() { + public static CBApplication getTestApp() { return testApp; } - public static HttpClient getClient() { - return client; - } - - public static HttpClient createClient() { - return HttpClient.newBuilder() + public static WebGQLClient createClient() { + HttpClient httpClient = HttpClient.newBuilder() .cookieHandler(new CookieManager()) .version(HttpClient.Version.HTTP_2) .build(); + return createClient(httpClient); + } + + public static WebGQLClient createClient(@NotNull HttpClient httpClient) { + return new WebGQLClient(httpClient, GQL_API_URL); } - public static Path getScriptsPath() { - return scriptsPath; + public static Map authenticateTestUser(@NotNull WebGQLClient client) throws Exception { + return client.sendQuery( + WebGQLClient.GQL_AUTHENTICATE, + Map.of( + "provider", LocalAuthProvider.PROVIDER_ID, + "credentials", TEST_CREDENTIALS + ) + ); } } diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ConnectionsTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ConnectionsTest.java index f780e0897e..1a59389d65 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ConnectionsTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ConnectionsTest.java @@ -17,24 +17,36 @@ package io.cloudbeaver.test.platform; -import io.cloudbeaver.utils.WebTestUtils; +import io.cloudbeaver.test.WebGQLClient; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.data.json.JSONUtils; import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.dbeaver.utils.GeneralUtils; -import org.jkiss.utils.CommonUtils; +import org.junit.Assert; import org.junit.Test; -import java.net.http.HttpClient; import java.nio.file.Path; -import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class ConnectionsTest { - - public static final String GQL_TEMPLATE_CREATE_CONNECTION = "createConnection.json"; - public static final String GQL_TEMPLATE_DELETE_CONNECTION = "deleteConnection.json"; - public static final String GQL_TEMPLATE_USER_CONNECTIONS = "userConnections.json"; + private static final String GQL_CONNECTIONS_GET = """ + query userConnections { + result: userConnections { + id + } + }"""; + private static final String GQL_CONNECTIONS_CREATE = """ + mutation createConnection($config: ConnectionConfig!, $projectId: ID) { + result: createConnection(config: $config, projectId: $projectId) { + id + } + }"""; + private static final String GQL_CONNECTIONS_DELETE = """ + mutation deleteConnection($id: ID!, $projectId: ID) { + result: deleteConnection(id: $id, projectId: $projectId) + }"""; @Test public void testAPlatformPresence() { @@ -52,50 +64,34 @@ public void testAPlatformPresence() { @Test public void testBCreateConnection() throws Exception { - HttpClient client = CEServerTestSuite.createClient(); - WebTestUtils.authenticateUser( - client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL); - - List> connections = getUserConnections(client); - Map addedConnection = createConnection(client); - if (!getUserConnections(client).contains(addedConnection)) { - throw new Exception("The new connection was not added"); - } + WebGQLClient client = CEServerTestSuite.createClient(); + CEServerTestSuite.authenticateTestUser(client); - boolean deleteConnection = deleteConnection(client, CommonUtils.toString(addedConnection.get("id"))); - if (!deleteConnection) { - throw new Exception("The new connection was not deleted"); - } - } + Map configuration = new LinkedHashMap<>(); + Map variables = new LinkedHashMap<>(); + variables.put("config", configuration); + Assert.assertThrows( + "Template connection or driver must be specified", + DBException.class, + () -> client.sendQuery(GQL_CONNECTIONS_CREATE, variables) + ); + String templateId = "test_template"; + configuration.put("templateId", templateId); + Assert.assertThrows( + "Template connection '" + templateId + "' not found", + DBException.class, + () -> client.sendQuery(GQL_CONNECTIONS_CREATE, variables) + ); - private List> getUserConnections(HttpClient client) throws Exception { - String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_USER_CONNECTIONS, CEServerTestSuite.getScriptsPath()); - Map map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client); - Map data = JSONUtils.getObjectOrNull(map, "data"); - if (data != null) { - return JSONUtils.getObjectList(data, "userConnections"); - } - return Collections.emptyList(); - } + configuration.remove("templateId"); + configuration.put("driverId", "postgresql:postgres-jdbc"); - private Map createConnection(HttpClient client) throws Exception { - String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_CREATE_CONNECTION, CEServerTestSuite.getScriptsPath()); - Map map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client); - Map data = JSONUtils.getObjectOrNull(map, "data"); - if (data != null) { - return JSONUtils.getObjectOrNull(data, "createConnection"); - } - return Collections.emptyMap(); - } + Map addedConnection = client.sendQuery(GQL_CONNECTIONS_CREATE, variables); - private boolean deleteConnection(HttpClient client, String connectionId) throws Exception { - String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_DELETE_CONNECTION, CEServerTestSuite.getScriptsPath()) - .replace("${connectionId}", connectionId); - Map map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client); - Map data = JSONUtils.getObjectOrNull(map, "data"); - if (data != null) { - return JSONUtils.getBoolean(data, "deleteConnection"); - } - return false; + List> connections = client.sendQuery(GQL_CONNECTIONS_GET, null); + Assert.assertTrue(connections.contains(addedConnection)); + String connectionId = JSONUtils.getString(addedConnection, "id"); + Assert.assertNotNull(connectionId); + Assert.assertTrue(client.sendQuery(GQL_CONNECTIONS_DELETE, Map.of("id", connectionId))); } } diff --git a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ResourceManagerTest.java b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ResourceManagerTest.java index 221a9f4a0c..e4bdfebdf3 100644 --- a/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ResourceManagerTest.java +++ b/server/test/io.cloudbeaver.test.platform/src/io/cloudbeaver/test/platform/ResourceManagerTest.java @@ -19,81 +19,102 @@ import io.cloudbeaver.model.rm.local.LocalResourceController; import io.cloudbeaver.server.CBApplication; -import io.cloudbeaver.utils.WebTestUtils; +import io.cloudbeaver.test.WebGQLClient; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.auth.SMAuthStatus; import org.jkiss.dbeaver.model.data.json.JSONUtils; -import org.jkiss.utils.CommonUtils; +import org.jkiss.utils.IOUtils; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; -import java.net.CookieManager; -import java.net.http.HttpClient; +import java.nio.file.Path; import java.util.Map; public class ResourceManagerTest { - public static final String GQL_TEMPLATE_RM_WRITE_RESOURCE = "rmWriteResource.json"; - public static final String GQL_TEMPLATE_RM_DELETE_RESOURCE = "rmDeleteResource.json"; - public static final String GQL_READ_EMPTY_PROJECT_ID_RESOURCES = "rmReadEmptyProjectIdResources.json"; - - private static HttpClient client; + private static WebGQLClient client; + private static final String GQL_RESOURCES_CREATE = """ + mutation rmWriteResourceStringContent($projectId: String!, $resourcePath: String!, $data: String!, $forceOverwrite: Boolean!) { + result: rmWriteResourceStringContent( + projectId: $projectId + resourcePath: $resourcePath + data: $data + forceOverwrite: $forceOverwrite + ) + }"""; + private static final String GQL_RESOURCES_DELETE = """ + mutation rmDeleteResource($projectId: String!, $resourcePath: String!, $recursive: Boolean!) { + result: rmDeleteResource( + projectId: $projectId + resourcePath: $resourcePath + recursive: $recursive + ) + }"""; + private static final String GQL_RESOURCES_LIST = """ + query rmListResources($projectId: String!, $folder: String, $nameMask: String, $readProperties: Boolean, $readHistory: Boolean) { + result: rmListResources( + projectId: $projectId + folder: $folder + nameMask: $nameMask + readProperties: $readProperties + readHistory: $readHistory + ) { + name + folder + } + }"""; @BeforeClass public static void init() throws Exception { Assert.assertTrue(CBApplication.getInstance().getAppConfiguration().isResourceManagerEnabled()); - client = HttpClient.newBuilder() - .cookieHandler(new CookieManager()) - .version(HttpClient.Version.HTTP_2) - .build(); - Map authInfo = WebTestUtils.authenticateUser( - client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL); + client = CEServerTestSuite.createClient(); + Map authInfo = CEServerTestSuite.authenticateTestUser(client); Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus")); - } @Test public void createDeleteResourceTest() throws Exception { - Assert.assertTrue(createResource(client, false)); - Assert.assertFalse(createResource(client, false)); - Assert.assertTrue(createResource(client, true)); - Assert.assertTrue(deleteResource(client)); + String projectId = "u_test"; + String resourcePath = "testScript.sql"; + Assert.assertTrue(createResource(projectId, resourcePath, false)); + Assert.assertThrows( + "Resource '" + IOUtils.getFileNameWithoutExtension(Path.of(resourcePath)) + "' already exists", + DBException.class, + () -> createResource(projectId, resourcePath, false) + ); + Assert.assertTrue(createResource(projectId, resourcePath, true)); + Assert.assertTrue(deleteResource(projectId, resourcePath)); } @Test public void listResourcesWithInvalidProjectId() throws Exception { - String input = WebTestUtils.readScriptTemplate(GQL_READ_EMPTY_PROJECT_ID_RESOURCES, CEServerTestSuite.getScriptsPath()); - Map map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client); - var errors = JSONUtils.getObjectList(map, "errors"); - Assert.assertFalse("No errors happened with empty project id request", errors.isEmpty()); - var rmError = errors.get(0); - //FIXME stupid way to validate error - Assert.assertTrue(JSONUtils.getString(rmError, "message", "").contains("Project id is empty")); + Assert.assertThrows( + "Project id is empty", + DBException.class, + () -> client.sendQuery(GQL_RESOURCES_LIST, Map.of("projectId", "")) + ); } - private boolean createResource(HttpClient client, boolean forceOverwrite) throws Exception { - String input = WebTestUtils.readScriptTemplate( - GQL_TEMPLATE_RM_WRITE_RESOURCE, CEServerTestSuite.getScriptsPath() - ).replaceAll("\\{forceOverwrite}", CommonUtils.toString(forceOverwrite)); - Map map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client); - Map data = JSONUtils.getObjectOrNull(map, "data"); - if (data != null) { - return LocalResourceController.DEFAULT_CHANGE_ID.equals(JSONUtils.getString(data, "rmWriteResourceStringContent")); - } - return false; + private boolean createResource(@NotNull String projectId, @NotNull String resourcePath, boolean forceOverwrite) throws Exception { + Map variables = Map.of( + "projectId", projectId, + "resourcePath", resourcePath, + "data", "TEST SCRIPT", + "forceOverwrite", forceOverwrite + ); + String data = client.sendQuery(GQL_RESOURCES_CREATE, variables); + return LocalResourceController.DEFAULT_CHANGE_ID.equals(data); } - private boolean deleteResource(HttpClient client) throws Exception { - String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_RM_DELETE_RESOURCE, CEServerTestSuite.getScriptsPath()); - Map map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client); - Map data = JSONUtils.getObjectOrNull(map, "data"); - if (map.containsKey("errors")) { - return false; - } - if (data != null) { - return data.containsKey("rmDeleteResource"); - } - return false; + private boolean deleteResource(@NotNull String projectId, @NotNull String resourcePath) throws Exception { + Map variables = Map.of( + "projectId", projectId, + "resourcePath", resourcePath, + "recursive", false + ); + return client.sendQuery(GQL_RESOURCES_DELETE, variables); } } diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json deleted file mode 100644 index 97b079675a..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/activeUser.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "query": "\n query activeUser {\n user: activeUser {\n userId\n }\n}\n ", - "operationName": "activeUser" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/authLogin.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/authLogin.json deleted file mode 100644 index c0d1796e74..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/authLogin.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "query": "\n query authLogin($provider: ID!, $configuration: ID, $credentials: Object, $linkUser: Boolean) {\n authInfo: authLogin(\n provider: $provider\n configuration: $configuration\n credentials: $credentials\n linkUser: $linkUser\n ) {\n authStatus\n }\n}\n ", - "variables": { - "provider": "local", - "credentials": { - "user": "test", - "password": "098F6BCD4621D373CADE4E832627B4F6" - }, - "linkUser": true - }, - "operationName": "authLogin" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/createConnection.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/createConnection.json deleted file mode 100644 index a9340bb121..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/createConnection.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "query": "\n mutation createConnection($projectId:ID!, $config: ConnectionConfig!) {\n createConnection(projectId:$projectId, config: $config) {\n id\n }\n} ", - "variables": { - "projectId": "u_test", - "config": { - "name": "PostgreSQL@localhost (1)", - "driverId": "postgresql:postgres-jdbc", - "host": "localhost", - "port": "5432", - "databaseName": "postgres", - "authModelId": "native", - "saveCredentials": true, - "credentials": { - "userName": "postgres", - "userPassword": "postgres" - }, - "providerProperties": {}, - "properties": {} - } - }, - "operationName": "createConnection" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/deleteConnection.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/deleteConnection.json deleted file mode 100644 index 21837ecdc6..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/deleteConnection.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "query": "mutation deleteConnection($projectId:ID!, $id: ID!) {deleteConnection(projectId:$projectId, id: $id)}", - "variables": { - "projectId": "u_test", - "id": "${connectionId}" - }, - "operationName": "deleteConnection" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/navDeleteNode.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/navDeleteNode.json deleted file mode 100644 index 7302133c3d..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/navDeleteNode.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "query": "\n mutation navDeleteNodes($nodePaths: [ID!]!) {\n navDeleteNodes(nodePaths: $nodePaths)\n}\n ", - "variables": { - "nodePaths": [ - "ext://resources/u_test/testScript.sql" - ] - }, - "operationName": "navDeleteNodes" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json deleted file mode 100644 index eff24dcf81..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/openSession.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "query": "\n mutation openSession($defaultLocale: String) {\n session: openSession(defaultLocale: $defaultLocale) {\n valid\n }\n}\n ", - "variables": { - "defaultLocale": "en" - }, - "operationName": "openSession" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmDeleteResource.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmDeleteResource.json deleted file mode 100644 index f820b6222c..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmDeleteResource.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "query": "\n mutation rmDeleteResource($projectId: String!, $resourcePath: String!, $recursive: Boolean!) {\n rmDeleteResource(\n projectId: $projectId\n resourcePath: $resourcePath\n recursive: $recursive\n )\n}\n ", - "variables": { - "projectId": "u_test", - "resourcePath": "testScript.sql", - "recursive": false - }, - "operationName": "rmDeleteResource" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmReadEmptyProjectIdResources.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmReadEmptyProjectIdResources.json deleted file mode 100644 index 114f2ea64c..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmReadEmptyProjectIdResources.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "query": "query {\n rmListResources(projectId: \"\") {\n name\n folder\n}\n}" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmWriteResource.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmWriteResource.json deleted file mode 100644 index 1652331d3b..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/rmWriteResource.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "query": "\n mutation writeContent($projectId: String!, $resourcePath: String!, $data: String!, $forceOverwrite: Boolean!) {\n rmWriteResourceStringContent(\n projectId: $projectId\n resourcePath: $resourcePath\n data: $data\n forceOverwrite: $forceOverwrite\n )\n}\n ", - "variables": { - "projectId": "u_test", - "resourcePath": "testScript.sql", - "data": "TEST SCRIPT;", - "forceOverwrite": {forceOverwrite} - }, - "operationName": "writeContent" -} \ No newline at end of file diff --git a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/userConnections.json b/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/userConnections.json deleted file mode 100644 index 5859aa23a7..0000000000 --- a/server/test/io.cloudbeaver.test.platform/workspace/gql_scripts/userConnections.json +++ /dev/null @@ -1,5 +0,0 @@ -{"query": "query userConnections($id: ID) {userConnections(id: $id) { id}}", -"variables": { - "id" : null -}, -"operationName":"userConnections"} \ No newline at end of file