2

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

Nilanka Manoj
  • 3,527
  • 4
  • 17
  • 48
Riyas
  • 299
  • 4
  • 15

2 Answers2

3

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.

Danny Dainton
  • 23,069
  • 6
  • 67
  • 80
2

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.

Jason Desrosiers
  • 22,479
  • 5
  • 47
  • 53
  • How mark one of Items element as ''required' in above example – Riyas Apr 01 '20 at 15:12
  • Not sure I understand your question. You were using `required` correctly. Once you remove the `[` `]` in your `items`, everything should work as you expect. – Jason Desrosiers Apr 01 '20 at 15:32
  • I tried this, my data is ignoring . It is an collection of dictionaries instead of array of Items. ( I used 'items' since, the number of dictionaries are varying ) . I implemeted like this but, all the data are ignoring in the validation. – Vineesh TP Dec 03 '21 at 08:08
  • @VineeshTP I suggest you open a new question with more detail or stop by the JSON Schema slack https://json-schema.org/slack. I'd be happy to help, but don't think I can in an SO comment. – Jason Desrosiers Dec 03 '21 at 23:17
  • @JasonDesrosiers : https://stackoverflow.com/questions/70212520/optional-json-validation-using-tv4-javascript could you please have a look. Thanks – Vineesh TP Dec 06 '21 at 04:37