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 <[email protected]> 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>

