fix: merge pdf pipeline validation (#5799)

Co-authored-by: RenzoMXD <RenzoMXD@users.noreply.github.com>
This commit is contained in:
Renzo
2026-03-05 16:14:30 -08:00
committed by GitHub
parent 30b0924d6b
commit c77242d943
3 changed files with 101 additions and 3 deletions

View File

@@ -25,8 +25,9 @@ public class ApiEndpoint {
}
public boolean areParametersValid(Map<String, Object> providedParams) {
for (String requiredParam : parameters.keySet()) {
if (!providedParams.containsKey(requiredParam)) {
for (Map.Entry<String, JsonNode> entry : parameters.entrySet()) {
boolean isRequired = entry.getValue().path("required").asBoolean(false);
if (isRequired && !providedParams.containsKey(entry.getKey())) {
return false;
}
}

View File

@@ -18,6 +18,11 @@ class ApiEndpointTest {
private final ObjectMapper mapper = JsonMapper.builder().build();
private JsonNode postNodeWithParams(String description, String... names) {
return postNodeWithParams(description, true, names);
}
private JsonNode postNodeWithParams(
String description, boolean required, String... names) {
ObjectNode post = mapper.createObjectNode();
post.put("description", description);
ArrayNode params = mapper.createArrayNode();
@@ -26,6 +31,7 @@ class ApiEndpointTest {
if (n != null) {
p.put("name", n);
}
p.put("required", required);
params.add(p);
}
post.set("parameters", params);
@@ -92,6 +98,75 @@ class ApiEndpointTest {
assertTrue(endpoint.areParametersValid(Map.of("", 42)));
}
@Test
void optional_parameters_can_be_omitted() {
JsonNode post = postNodeWithParams("desc", false, "fileOrder");
ApiEndpoint endpoint = new ApiEndpoint("merge", post);
assertTrue(
endpoint.areParametersValid(Map.of()),
"Should be valid when optional param is omitted");
}
@Test
void mixed_required_and_optional_validates_only_required() {
ObjectNode post = mapper.createObjectNode();
post.put("description", "merge pdfs");
ArrayNode params = mapper.createArrayNode();
ObjectNode required = mapper.createObjectNode();
required.put("name", "sortType");
required.put("required", true);
params.add(required);
ObjectNode optional = mapper.createObjectNode();
optional.put("name", "fileOrder");
optional.put("required", false);
params.add(optional);
post.set("parameters", params);
ApiEndpoint endpoint = new ApiEndpoint("/api/v1/general/merge-pdfs", post);
Map<String, Object> provided = new HashMap<>();
provided.put("sortType", "byFileName");
assertTrue(
endpoint.areParametersValid(provided),
"Should pass when required params present and optional omitted");
provided.put("fileOrder", "0,1,2");
assertTrue(
endpoint.areParametersValid(provided),
"Should also pass when optional param is provided");
}
@Test
void missing_required_param_with_optional_present_still_fails() {
ObjectNode post = mapper.createObjectNode();
post.put("description", "desc");
ArrayNode params = mapper.createArrayNode();
ObjectNode required = mapper.createObjectNode();
required.put("name", "file");
required.put("required", true);
params.add(required);
ObjectNode optional = mapper.createObjectNode();
optional.put("name", "fileOrder");
optional.put("required", false);
params.add(optional);
post.set("parameters", params);
ApiEndpoint endpoint = new ApiEndpoint("x", post);
Map<String, Object> provided = new HashMap<>();
provided.put("fileOrder", "0,1");
assertFalse(
endpoint.areParametersValid(provided),
"Should fail when required param is missing even if optional is present");
}
@Test
void toString_contains_name_and_parameter_names() {
JsonNode post = postNodeWithParams("desc", "file", "mode");

View File

@@ -74,15 +74,37 @@ class ApiDocServiceTest {
@Test
void isValidOperationChecksRequiredParameters() throws Exception {
String json =
"{\"description\": \"desc\", \"parameters\": [{\"name\":\"param1\"}, {\"name\":\"param2\"}]}";
"{\"description\": \"desc\", \"parameters\": [{\"name\":\"param1\", \"required\": true}, {\"name\":\"param2\", \"required\": true}]}";
JsonNode postNode = mapper.readTree(json);
ApiEndpoint endpoint = new ApiEndpoint("/op", postNode);
setApiDocumentation(Map.of("/op", endpoint));
setApiDocsJsonRootNode();
// All required params provided - valid
assertTrue(apiDocService.isValidOperation("/op", Map.of("param1", "a", "param2", "b")));
// Missing required param2 - invalid
assertFalse(apiDocService.isValidOperation("/op", Map.of("param1", "a")));
// Missing required param1 - invalid
assertFalse(apiDocService.isValidOperation("/op", Map.of("param2", "b")));
}
@Test
void isValidOperationAllowsOptionalParameters() throws Exception {
String json =
"{\"description\": \"desc\", \"parameters\": [{\"name\":\"param1\", \"required\": false}, {\"name\":\"param2\", \"required\": false}]}";
JsonNode postNode = mapper.readTree(json);
ApiEndpoint endpoint = new ApiEndpoint("/op", postNode);
setApiDocumentation(Map.of("/op", endpoint));
setApiDocsJsonRootNode();
// All optional params provided - valid
assertTrue(apiDocService.isValidOperation("/op", Map.of("param1", "a", "param2", "b")));
// Only one optional param provided - valid
assertTrue(apiDocService.isValidOperation("/op", Map.of("param1", "a")));
// No optional params provided - valid
assertTrue(apiDocService.isValidOperation("/op", Map.of()));
}
@Test