Riyas
Riyas

Reputation: 327

Validate jsonschema against a json array having multiple elements using postman and tv4

Below is my JSON schema

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array",
  "items": [
    {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "stations": {
          "type": "array",
          "items": [
            {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "serial_number": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "serial_number",
                "name"
              ]
            }
          ]
        }
      },
      "required": [
        "id",
        "name",
        "stations"
      ]
    }
  ]
}

Below is the json to validate

[
    {
        "id": 1,
        "name": "Test location",       
        "stations": [
            {
                "id": 1,
                "serial_number": "TEST001",
                "name": "TEST-STN!"                
            }
        ]

    },
    {
        "id": 2,
        "name": "Test location2"    
    }

]

Here the element "stations" is marked as required in schema, but it is missing in the second Item of json. still tv4 validation is passed.

What we really required is, it should fail the validation because the station element is missing in the second Item

The observation is IF station element is NOT present in any of the JSON Item, then validation is failing. But if the station element is present in one of the item then validation is passed

pm.test("Login Validation", function() { pm.expect(tv4.validate(pm.response.json(), pm.environment.get('schema.json'), true, true), tv4.error).to.be.true;});

I tried tv4 option "checkRecursive" with value both true and false...Still it passing the validation

Any help is appreciated

Upvotes: 3

Views: 1674

Answers (2)

Danny Dainton
Danny Dainton

Reputation: 25921

I think something like this would work for you and show the issue:

let schema = {
    "type": "array",
    "items": {
        "type": "object",
        "required": [
            "id",
            "name",
            "stations"
        ],
        "properties": {
            "id": {
                "type": "integer"
            },
            "name": {
                "type": "string"
            },
            "stations": {
                "type": "array",
                "items": {
                    "type": "object",
                    "required": [
                        "id",
                        "serial_number",
                        "name"
                    ],
                    "properties": {
                        "id": {
                            "type": "integer"
                        },
                        "serial_number": {
                            "type": "string"
                        },
                        "name": {
                            "type": "string"
                        }
                    }
                }
            }
        }
    }
}

pm.test("Check Schemat", () => {
    pm.response.to.have.jsonSchema(schema)
}) 

I've included the jsonSchema() Postman function as this uses AJV rather than the older and not currently maintained tv4 module.

Upvotes: 4

Jason Desrosiers
Jason Desrosiers

Reputation: 24489

The items keyword can take a schema, or an array of schemas and it has different semantics depending on which version is being used.

When items takes a single schema, it's describing an array where all items in the array must conform to the given schema.

{
  "type": "array".
  "items": { "type": "string" }
}

["a", "b", "c"]

When items takes an array of schemas, it's describing a tuple where each schema in items is compared with the corresponding item in the instance array.

{
  "type": "array",
  "items": [{ "type": "string" }, { "type": "integer" }, { "type": "boolean }]
}

["a", 1, false]

You are confused because you are using the wrong form of items. Because you used the array form, only the first element in your array is being validated. The validator ignores the rest of the items.

Upvotes: 2

Related Questions