Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate array only the first elemet #926

Closed
r-alto opened this issue Jan 22, 2024 Discussed in #925 · 2 comments
Closed

Validate array only the first elemet #926

r-alto opened this issue Jan 22, 2024 Discussed in #925 · 2 comments

Comments

@r-alto
Copy link

r-alto commented Jan 22, 2024

Only the first element of an array is validated, see "isInValidNotOk".

package json;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersionDetector;
import com.networknt.schema.ValidationMessage;
import java.util.Set;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

class TestValidator {
  private static String jsonschema = "";
  private static String jsonValid = "";
  private static String jsonInValidOk = "";
  private static String jsonInValidNotOk = "";
  
  @BeforeAll
  static void init() {
    jsonschema =
        "{"
            + "  \"$schema\": \"http://json-schema.org/draft-04/schema#\","
            + "  \"type\": \"object\","
            + "  \"properties\": {"
            + "    \"items\": {"
            + "      \"type\": \"array\","
            + "      \"items\": ["
            + "        {"
            + "          \"type\": \"object\","
            + "          \"properties\": {"
            + "            \"name\": {"
            + "              \"type\": \"string\""
            + "            },"
            + "            \"city\": {"
            + "              \"type\": \"string\""
            + "            }"
            + "          },"
            + "          \"required\": ["
            + "            \"name\","
            + "            \"city\""
            + "          ]"
            + "        }"
            + "      ]"
            + "    }"
            + "  },"
            + "  \"required\": ["
            + "    \"items\""
            + "  ]"
            + "}";

    jsonValid =
        "{"
            + "  \"items\":["
            + "    { "
            + "      \"name\" : \"Test1\","
            + "      \"city\" : \"city1\""
            + "    },"
            + "    { "
            + "      \"name\" : \"Test2\","
            + "      \"city\" : \"city2\""
            + "    }"
            + "  ]"
            + "}";

    jsonInValidOk =
        "{"
            + "  \"items\":["
            + "    { "
            + "      \"name\" : \"Test1\""
            + "    },"
            + "    { "
            + "      \"name\" : \"Test2\","
            + "      \"city\" : \"city2\""
            + "    }"
            + "  ]"
            + "}";

    jsonInValidNotOk = "{"
        + "  \"items\":["
        + "    { "
        + "      \"name\" : \"Test1\","
        + "      \"city\" : \"city1\""
        + "    },"
        + "    { "
        + "      \"name\" : \"Test2\""
        + "    }"
        + "  ]"
        + "}";
  }

  @Test
  void isValid() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    JsonNode schema = mapper.readTree( jsonschema );
    JsonNode json = mapper.readTree( jsonValid );
    JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(schema));
    Set<ValidationMessage> errors = factory.getSchema(schema).validate( json );
    Assertions.assertTrue( errors.isEmpty() );
  }

  @Test
  void isInValidOk() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    JsonNode schema = mapper.readTree( jsonschema );
    JsonNode json = mapper.readTree( jsonInValidOk ); // "city" is defined as required
    JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(schema));
    Set<ValidationMessage> errors = factory.getSchema(schema).validate( json );
    Assertions.assertFalse( errors.isEmpty() );
  }

  @Test
  void isInValidNotOk() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    JsonNode schema = mapper.readTree( jsonschema );
    JsonNode json = mapper.readTree( jsonInValidNotOk ); // "city" is defined as required
    JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(schema));
    Set<ValidationMessage> errors = factory.getSchema(schema).validate( json );
    Assertions.assertFalse( errors.isEmpty() );
  }
}
@justin-tay
Copy link
Contributor

If your intent is for all the items to be validated with the same schema, then your schema is incorrect as your items is configured using a tuple validation schema which will validate the array on a position basis.

Instead of "items": [] in your schema you should be using "items": {}.

@r-alto
Copy link
Author

r-alto commented Jan 23, 2024

Thanks a lot, you are right. If I change the schema its works fine.

jsonschema =
    "{"
        + "  \"$schema\": \"http://json-schema.org/draft-04/schema#\","
        + "  \"type\": \"object\","
        + "  \"properties\": {"
        + "    \"items\": {"
        + "      \"type\": \"array\","
        + "      \"uniqueItems\": true,"
        + "      \"unevaluatedItems\": false,"
        + "      \"items\": "
        + "        {"
        + "          \"type\": \"object\","
        + "          \"properties\": {"
        + "            \"name\": {"
        + "              \"type\": \"string\""
        + "            },"
        + "            \"city\": {"
        + "              \"type\": \"string\""
        + "            }"
        + "          },"
        + "          \"required\": ["
        + "            \"name\","
        + "            \"city\""
        + "          ]"
        + "        }"
        + "    }"
        + "  },"
        + "  \"required\": ["
        + "    \"items\""
        + "  ]"
        + "}";

@r-alto r-alto closed this as completed Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants