You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by lf...@apache.org on 2026/08/19 07:57:31 UTC
(ofbiz-framework) 02/02: Improved: Refactored rest-api tests to be simpler. All tests that test against a real endpoint are now found in RestTestHttpRequest.java
This is an automated email from the ASF dual-hosted git repository.
Lukas-Finster pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
commit a48c8fcbb5a3b7070b46244f1345050d0741497a
Author: Lukas Finster <lu...@ecomify.de>
AuthorDate: Tue Aug 18 13:21:59 2026 +0200
Improved: Refactored rest-api tests to be simpler. All tests that test
against a real endpoint are now found in RestTestHttpRequest.java
---
.../apache/ofbiz/ws/rs/test/RestServicesTests.java | 243 --------------
.../ofbiz/ws/rs/test/RestTestHttpRequest.java | 368 ++++++++++++---------
framework/rest-api/testdef/rest-apiTests.xml | 3 -
3 files changed, 203 insertions(+), 411 deletions(-)
diff --git a/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestServicesTests.java b/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestServicesTests.java
deleted file mode 100644
index 018d8f9ca5..0000000000
--- a/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestServicesTests.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*******************************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF 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.apache.ofbiz.ws.rs.test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Map;
-
-import org.apache.ofbiz.base.util.UtilMisc;
-import org.apache.ofbiz.entity.GenericValue;
-import org.apache.ofbiz.service.ModelService;
-import org.apache.ofbiz.service.ServiceUtil;
-import org.apache.ofbiz.testtools.JunitJupiterTest;
-import org.apache.ofbiz.testtools.JupiterTestHelper;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-@JunitJupiterTest
-public class RestServicesTests implements JupiterTestHelper {
-
- /**
- * Verifies that the {@code generateAuthTokenService} returns a success response
- * when called with a valid {@code userLogin} in the service context.
- *
- * <p>This is the happy-path test — it confirms the service completes without
- * error and that {@link ServiceUtil#isSuccess(Map)} returns {@code true}.</p>
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly
- */
- @Test
- @Order(1)
- public void testGenerateAuthTokenReturnsSuccess() throws Exception {
- GenericValue userLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
- assertNotNull(userLogin, "admin userLogin must exist in demo data");
-
- Map<String, Object> ctx = UtilMisc.toMap("userLogin", (Object) userLogin);
- Map<String, Object> result = getDispatcher().runSync("generateAuthTokenService", ctx);
-
- assertTrue(ServiceUtil.isSuccess(result), "Service should return success");
- }
-
- /**
- * Verifies that the {@code access_token} output attribute is present and non-empty
- * in the service response.
- *
- * <p>A null or empty token would indicate that {@code JWTManager.createJwt()}
- * failed silently or returned an unexpected value.</p>
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly
- */
- @Test
- @Order(2)
- public void testGenerateAuthTokenAccessTokenPresent() throws Exception {
- GenericValue userLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
-
- Map<String, Object> result = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) userLogin));
-
- String accessToken = (String) result.get("access_token");
- assertNotNull(accessToken, "access_token should not be null");
- assertFalse(accessToken.isEmpty(), "access_token should not be empty");
- }
-
- /**
- * Verifies that the {@code token_type} output attribute is exactly {@code "Bearer"}.
- *
- * <p>REST clients rely on this value to correctly construct the
- * {@code Authorization: Bearer <token>} header. Any deviation would break
- * standard OAuth2 / JWT bearer token flows.</p>
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly
- */
- @Test
- @Order(3)
- public void testGenerateAuthTokenTokenTypeIsBearer() throws Exception {
- GenericValue userLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
-
- Map<String, Object> result = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) userLogin));
-
- assertEquals("Bearer", result.get("token_type"), "token_type should be Bearer");
- }
-
- /**
- * Verifies that the {@code expires_in} output attribute is present and represents
- * a valid positive integer (in seconds).
- *
- * <p>The value is read from the {@code security.jwt.token.expireTime} property
- * in {@code security.properties}. This test guards against a missing property
- * file entry or a non-numeric value being returned.</p>
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly,
- * or if {@code expires_in} cannot be parsed as an integer
- */
- @Test
- @Order(4)
- public void testGenerateAuthTokenExpiresInIsValid() throws Exception {
- GenericValue userLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
-
- Map<String, Object> result = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) userLogin));
-
- String expiresIn = (String) result.get("expires_in");
- assertNotNull(expiresIn, "expires_in should not be null");
-
- int expiresCurrent = Integer.parseInt(expiresIn);
- assertTrue(expiresCurrent > 0, "expires_in should be a positive number");
-
- int expiresTarget = 1800;
- assertTrue(expiresCurrent == expiresTarget, "expires_in should match the configured amount");
- }
-
- /**
- * Verifies that the {@code access_token} is a well-formed JWT by checking
- * it consists of exactly three Base64-encoded parts separated by dots
- * ({@code header.payload.signature}).
- *
- * <p>This does not validate the cryptographic signature — it confirms that
- * {@code JWTManager.createJwt()} produced a structurally valid token that
- * JWT libraries and API clients will be able to parse.</p>
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly
- */
- @Test
- @Order(5)
- public void testGenerateAuthTokenTokenIsValidJwtFormat() throws Exception {
- GenericValue userLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
-
- Map<String, Object> result = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) userLogin));
-
- String accessToken = (String) result.get("access_token");
- String[] parts = accessToken.split("\\.");
- assertEquals(3, parts.length, "JWT should have 3 parts (header.payload.signature)");
- }
-
- /**
- * Verifies that two different users receive different tokens.
- *
- * <p>Since the {@code userLoginId} is embedded in the JWT payload, tokens
- * generated for different users must not be identical. Identical tokens would
- * indicate that the {@code userLogin} is not being read from context correctly,
- * allowing one user to authenticate as another.</p>
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly
- */
- @Test
- @Order(6)
- public void testGenerateAuthTokenDifferentUsersGetDifferentTokens() throws Exception {
- GenericValue adminLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
- GenericValue systemLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "system"), false);
-
- assertNotNull(adminLogin, "admin userLogin must exist");
- assertNotNull(systemLogin, "system userLogin must exist");
-
- Map<String, Object> adminResult = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) adminLogin));
-
- Map<String, Object> systemResult = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) systemLogin));
-
- assertFalse(
- adminResult.get("access_token").equals(systemResult.get("access_token")),
- "Different users should receive different tokens");
- }
-
- /**
- * Verifies JWT payload hast correct issuer and userLoginId.
- *
- * @throws Exception if the service call or entity lookup fails unexpectedly
- */
- @Test
- @Order(7)
- public void testGenerateAuthTokenIssuerAndUserLoginIdInPayload() throws Exception {
- GenericValue adminLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
- Map<String, Object> adminResult = getDispatcher().runSync(
- "generateAuthTokenService",
- UtilMisc.toMap("userLogin", (Object) adminLogin));
- String jwt = (String) adminResult.get("access_token");
-
- String[] parts = jwt.split("\\.");
- String payloadSegment = parts[1];
- byte[] decodedBytes = Base64.getUrlDecoder().decode(padBase64(payloadSegment));
- String jwtDecoded = new String(decodedBytes, StandardCharsets.UTF_8);
-
- ObjectMapper mapper = new ObjectMapper();
- JsonNode claims = mapper.readTree(jwtDecoded);
-
- String iss = claims.path("iss").asText(null);
- String userLoginId = claims.path("userLoginId").asText(null);
-
- assertTrue(iss.equals("ApacheOFBiz"), "Issuer is ApacheOFBiz");
- assertTrue(userLoginId.equals("admin"), "UserLoginId is admin");
- }
-
- private static String padBase64(String input) {
- int padding = (4 - input.length() % 4) % 4;
- StringBuilder sb = new StringBuilder(input);
- for (int i = 0; i < padding; i++) sb.append('=');
- return sb.toString();
- }
-
- @Test
- public void testReturnCustomErrorCode() throws Exception {
- GenericValue adminLogin = getDelegator().findOne("UserLogin", UtilMisc.toMap("userLoginId", "admin"), false);
- Map<String, Object> result = getDispatcher().runSync(
- "returnCustomErrorTest",
- UtilMisc.toMap("userLogin", (Object) adminLogin));
- String errorCode = (String) result.get(ModelService.ERROR_CODE);
- assertTrue(errorCode.equals("999"));
- }
-}
diff --git a/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestTestHttpRequest.java b/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestTestHttpRequest.java
index b7c60ec79e..5cdb3be86c 100644
--- a/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestTestHttpRequest.java
+++ b/framework/rest-api/src/test/java/org/apache/ofbiz/ws/rs/test/RestTestHttpRequest.java
@@ -18,11 +18,15 @@
*******************************************************************************/
package org.apache.ofbiz.ws.rs.test;
-import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
@@ -35,18 +39,22 @@ import org.apache.ofbiz.base.util.SSLUtil;
import org.apache.ofbiz.testtools.JunitJupiterTest;
import org.apache.ofbiz.testtools.JupiterTestHelper;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
+
+import jakarta.ws.rs.HttpMethod;
+
@JunitJupiterTest
class RestTestHttpRequest implements JupiterTestHelper {
private static final String MODULE = RestTestHttpRequest.class.getName();
private static final String BASE_URL = "https://localhost:8443/rest";
+ private static final ObjectMapper MAPPER = new ObjectMapper();
private static String accessToken;
- private static ObjectMapper mapper = new ObjectMapper();
private static HttpClient initHttpClient() {
HttpClient http = new HttpClient();
@@ -56,225 +64,255 @@ class RestTestHttpRequest implements JupiterTestHelper {
return http;
}
- @BeforeAll
- public static void init() {
- String creds = Base64.getEncoder().encodeToString(("admin:ofbiz").getBytes());
+ private static HttpClient createAuthorizedClient(String path) {
+ HttpClient client = initHttpClient();
+ client.setHeader("Content-Type", "application/json");
+ client.setHeader("Authorization", "Bearer " + accessToken);
+ client.setUrl(BASE_URL + path);
+ return client;
+ }
- HttpClient fetchClient = initHttpClient();
- fetchClient.setUrl(BASE_URL + "/auth/token");
- fetchClient.setHeader("Authorization", "Basic " + creds);
- fetchClient.setHeader("Accept", "application/json");
+ private static JsonNode requestForJson(HttpClient client, String errorContext, String verb) {
String response = "";
try {
- response = fetchClient.post();
+ response = switch (verb) {
+ case "GET" -> client.get();
+ case "POST" -> client.post();
+ default -> "";
+ };
} catch (HttpClientException e) {
- Debug.logError(e, "Error returning rest access token", MODULE);
- return;
+ Debug.logError(e, "Error during rest POST to " + errorContext, MODULE);
+ fail("HTTP POST failed for " + errorContext + ": " + e.getMessage());
}
-
try {
- JsonNode root = mapper.readTree(response);
- accessToken = root.get("data").get("access_token").asText();
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
+ return MAPPER.readTree(response);
+ } catch (JsonProcessingException e) {
+ Debug.logError(e, "Error parsing rest response for " + errorContext, MODULE);
+ fail("Error parsing rest response: " + e.getMessage());
+ return null;
}
}
- @Test
- void returnSuccessreturnsExpectedStatusCode() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setUrl(BASE_URL + "/exampleApi/returnSuccess");
+ private static byte[] postRawBytes(HttpClient client) throws Exception {
+ try (InputStream responseStream = client.postStream()) {
+ return responseStream.readAllBytes();
+ }
+ }
- String response = "";
- try {
- response = client.post();
- } catch (HttpClientException e) {
- Debug.logError(e, "Error during rest POST to /exampleApi/returnSuccess", MODULE);
+ private static String padBase64(String input) {
+ int padding = (4 - input.length() % 4) % 4;
+ StringBuilder sb = new StringBuilder(input);
+ for (int i = 0; i < padding; i++) {
+ sb.append('=');
}
- int statusCode = 0;
+ return sb.toString();
+ }
+
+ private static JsonNode decodeJwtPayload(String jwt) {
+ String[] parts = jwt.split("\\.");
+ assertEquals(3, parts.length, "JWT should have 3 parts (header.payload.signature)");
+
+ byte[] decodedBytes = Base64.getUrlDecoder().decode(padBase64(parts[1]));
+ String payloadJson = new String(decodedBytes, StandardCharsets.UTF_8);
try {
- JsonNode root = mapper.readTree(response);
- statusCode = root.get("statusCode").asInt(999999999);
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
+ return MAPPER.readTree(payloadJson);
+ } catch (JsonProcessingException e) {
+ fail("Error parsing JWT payload: " + e.getMessage());
+ return null;
}
+ }
+
+ private static JsonNode decompress(byte[] rawBytes, String encoding) throws Exception {
+ InputStream decompressStream = "gzip".equals(encoding)
+ ? new GZIPInputStream(new ByteArrayInputStream(rawBytes))
+ : new InflaterInputStream(new ByteArrayInputStream(rawBytes));
- assertEquals(200, statusCode);
+ try (InputStream is = decompressStream) {
+ return MAPPER.readTree(is);
+ } catch (JsonProcessingException | ZipException e) {
+ fail("Error parsing " + encoding + " response: " + e.getMessage());
+ return null;
+ }
}
- //Corresponding service overwrites statusCode with 201
- @Test
- void returnSuccessOverwriteStatusCode() throws Exception {
+ private static JsonNode requestAuthToken(String username, String password) {
+ String creds = Base64.getEncoder().encodeToString((username + ":" + password).getBytes(StandardCharsets.UTF_8));
+
HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setUrl(BASE_URL + "/exampleApi/returnSuccessButOverwriteStatusCode");
+ client.setUrl(BASE_URL + "/auth/token");
+ client.setHeader("Authorization", "Basic " + creds);
+ client.setHeader("Accept", "application/json");
- String response = "";
- try {
- response = client.post();
- } catch (HttpClientException e) {
- Debug.logError(e, "Error during rest POST to /exampleApi/returnSuccessButOverwriteStatusCode", MODULE);
- }
- int statusCode = 0;
- try {
- JsonNode root = mapper.readTree(response);
- statusCode = root.get("statusCode").asInt(999999999);
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
- }
+ return requestForJson(client, "/auth/token (" + username + ")", HttpMethod.POST);
+ }
- assertEquals(201, statusCode);
+ private static JsonNode requestAuthTokenAsAdmin() {
+ return requestAuthToken("admin", "ofbiz");
}
+ @BeforeAll
+ public static void init() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ accessToken = root.path("data").path("access_token").asText();
+ }
+
+ // ---- auth token tests ----
+
@Test
- void useCustomHeaderAsServiceParameter() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setHeader("x-custom-header", "Foo");
- client.setUrl(BASE_URL + "/exampleApi/useCustomHeaderAsServiceParameter");
+ @Order(1)
+ void testGenerateAuthTokenReturnsSuccess() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ assertEquals(200, root.path("statusCode").asInt(), "Endpoint should return success status code");
+ }
- String response = "";
- try {
- response = client.post();
- } catch (HttpClientException e) {
- Debug.logError(e, "Error during rest POST to /exampleApi/useCustomHeaderAsServiceParameter", MODULE);
- }
- String customHeaderValue = "";
- try {
- JsonNode root = mapper.readTree(response);
- customHeaderValue = root.get("data").get("x-custom-header").asText();
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
- }
+ @Test
+ @Order(2)
+ void testGenerateAuthTokenAccessTokenPresent() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ String token = root.path("data").path("access_token").asText(null);
- assertEquals("Foo", customHeaderValue);
+ assertNotNull(token, "access_token should not be null");
+ assertFalse(token.isEmpty(), "access_token should not be empty");
}
@Test
- void testUseLocaleSetInRequestHeader() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setHeader("Accept-Language", "fr");
- client.setUrl(BASE_URL + "/exampleApi/useLocaleSetInRequestHeader");
+ @Order(3)
+ void testGenerateAuthTokenTokenTypeIsBearer() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ assertEquals("Bearer", root.path("data").path("token_type").asText(null), "token_type should be Bearer");
+ }
- String response = "";
- try {
- response = client.post();
- } catch (HttpClientException e) {
- Debug.logError(e, "Error during rest POST to /exampleApi/useLocaleSetInRequestHeader", MODULE);
- }
- String localeSentViaAcceptLanguageHeader = "";
- try {
- JsonNode root = mapper.readTree(response);
- localeSentViaAcceptLanguageHeader = root.get("data").get("localeAsString").asText();
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
- }
+ @Test
+ @Order(4)
+ void testGenerateAuthTokenExpiresInIsValid() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ JsonNode expiresInNode = root.path("data").path("expires_in");
- assertEquals("fr", localeSentViaAcceptLanguageHeader);
+ assertFalse(expiresInNode.isMissingNode(), "expires_in should be present");
+
+ int expiresCurrent = expiresInNode.asInt();
+ assertTrue(expiresCurrent > 0, "expires_in should be a positive number");
+ assertEquals(1800, expiresCurrent, "expires_in should match the configured amount");
}
@Test
- void testGZipCompression() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
+ @Order(5)
+ void testGenerateAuthTokenTokenIsValidJwtFormat() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ String token = root.path("data").path("access_token").asText(null);
+
+ String[] parts = token.split("\\.");
+ assertEquals(3, parts.length, "JWT should have 3 parts (header.payload.signature)");
+ }
+
+ @Test
+ @Order(6)
+ void testGenerateAuthTokenDifferentUsersGetDifferentTokens() {
+ JsonNode adminRoot = requestAuthToken("admin", "ofbiz");
+ JsonNode systemRoot = requestAuthToken("REST_API_TEST_USER", "ofbiz");
+
+ String adminToken = adminRoot.path("data").path("access_token").asText(null);
+ String systemToken = systemRoot.path("data").path("access_token").asText(null);
+
+ assertNotNull(adminToken, "admin access_token should not be null");
+ assertNotNull(systemToken, "REST_API_TEST_USER access_token should not be null");
+ assertFalse(adminToken.equals(systemToken), "Different users should receive different tokens");
+ }
+
+ @Test
+ @Order(7)
+ void testGenerateAuthTokenIssuerAndUserLoginIdInPayload() {
+ JsonNode root = requestAuthTokenAsAdmin();
+ String token = root.path("data").path("access_token").asText(null);
+
+ JsonNode claims = decodeJwtPayload(token);
+
+ assertEquals("ApacheOFBiz", claims.path("iss").asText(null), "Issuer should be ApacheOFBiz");
+ assertEquals("admin", claims.path("userLoginId").asText(null), "userLoginId should be admin");
+ }
+
+ @Test
+ @Order(8)
+ void testGenerateAuthTokenInvalidCredentialsFail() {
+ JsonNode root = requestAuthToken("admin", "wrong-password");
+ int statusCode = root.path("statusCode").asInt(200);
+ assertFalse(statusCode == 200, "Invalid credentials should not return a success status code");
+ }
+
+ /* ========= generall tests - these rely on the Endpoints
+ specified via exampleApiDefinition.rest.xml ============ */
+
+ @Test
+ void returnSuccessReturnsExpectedStatusCode() throws Exception {
+ HttpClient client = createAuthorizedClient("/exampleApi/returnSuccess");
+ JsonNode root = requestForJson(client, "/exampleApi/returnSuccess", HttpMethod.POST);
+ assertEquals(200, root.path("statusCode").asInt());
+ }
+
+ // Corresponding service overwrites statusCode with 201
+ @Test
+ void returnSuccessOverwriteStatusCode() throws Exception {
+ HttpClient client = createAuthorizedClient("/exampleApi/returnSuccessButOverwriteStatusCode");
+ JsonNode root = requestForJson(client, "/exampleApi/returnSuccessButOverwriteStatusCode", HttpMethod.POST);
+ assertEquals(201, root.path("statusCode").asInt());
+ }
+
+ @Test
+ void useCustomHeaderAsServiceParameter() throws Exception {
+ HttpClient client = createAuthorizedClient("/exampleApi/useCustomHeaderAsServiceParameter");
+ client.setHeader("x-custom-header", "Foo");
+ JsonNode root = requestForJson(client, "/exampleApi/useCustomHeaderAsServiceParameter", HttpMethod.POST);
+ assertEquals("Foo", root.path("data").path("x-custom-header").asText());
+ }
+
+ @Test
+ void testUseLocaleSetInRequestHeader() throws Exception {
+ HttpClient client = createAuthorizedClient("/exampleApi/useLocaleSetInRequestHeader");
client.setHeader("Accept-Language", "fr");
+ JsonNode root = requestForJson(client, "/exampleApi/useLocaleSetInRequestHeader", HttpMethod.POST);
+ assertEquals("fr", root.path("data").path("localeAsString").asText());
+ }
+
+ @Test
+ void testGZipCompression() throws Exception {
+ HttpClient client = createAuthorizedClient("/exampleApi/returnSuccess");
client.setHeader("Accept-Encoding", "gzip");
- client.setUrl(BASE_URL + "/exampleApi/returnSuccess");
- byte[] rawBytes;
- try (InputStream responseStream = client.postStream()) {
- rawBytes = responseStream.readAllBytes();
- }
+ byte[] rawBytes = postRawBytes(client);
- // magic bytes for gzip
+ // gzip magic bytes
assertEquals((byte) 0x1f, rawBytes[0]);
assertEquals((byte) 0x8b, rawBytes[1]);
- try (GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(rawBytes))) {
- JsonNode root = mapper.readTree(gis);
- assertEquals(200, root.path("statusCode").asInt());
- } catch (JsonProcessingException e) {
- fail("Error parsing rest auth response: " + e.getMessage());
- }
+ JsonNode root = decompress(rawBytes, "gzip");
+ assertEquals(200, root.path("statusCode").asInt());
}
@Test
void testDeflateCompression() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setHeader("Accept-Language", "fr");
+ HttpClient client = createAuthorizedClient("/exampleApi/returnSuccess");
client.setHeader("Accept-Encoding", "deflate");
- client.setUrl(BASE_URL + "/exampleApi/returnSuccess");
- byte[] rawBytes;
- try (InputStream responseStream = client.postStream()) {
- rawBytes = responseStream.readAllBytes();
- }
+ byte[] rawBytes = postRawBytes(client);
- try (InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(rawBytes))) {
- JsonNode root = mapper.readTree(iis);
- assertEquals(200, root.path("statusCode").asInt());
- } catch (JsonProcessingException | ZipException e) {
- fail("Error parsing rest auth response: " + e.getMessage());
- }
+ JsonNode root = decompress(rawBytes, "deflate");
+ assertEquals(200, root.path("statusCode").asInt());
}
@Test
void testServiceInputParametersAsPath() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setHeader("Accept-Language", "fr");
- client.setUrl(BASE_URL + "/exampleApi/foo/testServiceInputParametersAsPath/");
+ HttpClient client = createAuthorizedClient("/exampleApi/foo/testServiceInputParametersAsPath/");
- String response = "";
- try {
- response = client.get();
- } catch (HttpClientException e) {
- Debug.logError(e, "Error during rest GET to /exampleApi/foo/testServiceInputParametersAsPath/", MODULE);
- }
- String serviceInputParameter = "";
- try {
- JsonNode root = mapper.readTree(response);
- serviceInputParameter = root.get("data").get("myInput").asText();
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
- }
-
- assertEquals("foo", serviceInputParameter);
+ JsonNode root = requestForJson(client, "/exampleApi/foo/testServiceInputParametersAsPath/", HttpMethod.GET);
+ assertEquals("foo", root.path("data").path("myInput").asText());
}
@Test
void testServiceInputParametersAsQueryParam() throws Exception {
- HttpClient client = initHttpClient();
- client.setHeader("Content-Type", "application/json");
- client.setHeader("Authorization", "Bearer " + accessToken);
- client.setHeader("Accept-Language", "fr");
- client.setUrl(BASE_URL + "/exampleApi/testServiceInputParametersAsQueryParam");
+ HttpClient client = createAuthorizedClient("/exampleApi/testServiceInputParametersAsQueryParam/");
client.setParameter("myInput", "foo");
- String response = "";
- try {
- response = client.get();
- } catch (HttpClientException e) {
- Debug.logError(e, "Error during rest GET to /exampleApi/testServiceInputParametersAsQueryParam", MODULE);
- }
- String serviceInputParameter = "";
- try {
- JsonNode root = mapper.readTree(response);
- serviceInputParameter = root.get("data").get("myInput").asText();
- } catch (JsonProcessingException | NullPointerException e) {
- Debug.logError(e, "Error parsing rest auth response", MODULE);
- }
-
- assertEquals("foo", serviceInputParameter);
+ JsonNode root = requestForJson(client, "/exampleApi/testServiceInputParametersAsQueryParam/", HttpMethod.GET);
+ assertEquals("foo", root.path("data").path("myInput").asText());
}
}
diff --git a/framework/rest-api/testdef/rest-apiTests.xml b/framework/rest-api/testdef/rest-apiTests.xml
index 393a7bd642..e94804364f 100644
--- a/framework/rest-api/testdef/rest-apiTests.xml
+++ b/framework/rest-api/testdef/rest-apiTests.xml
@@ -21,9 +21,6 @@ under the License.
<test-suite suite-name="rest-api-tests"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://ofbiz.apache.org/dtds/test-suite.xsd">
- <test-case case-name="rest-api-services-tests">
- <jupiter-test-suite class-name="org.apache.ofbiz.ws.rs.test.RestServicesTests"/>
- </test-case>
<test-case case-name="rest-api-http-requests">
<jupiter-test-suite class-name="org.apache.ofbiz.ws.rs.test.RestTestHttpRequest"/>
</test-case>