friendsofgo / killgrave

Simple way to generate mock servers written in Go
https://friendsofgo.github.io/killgrave/
MIT License
498 stars 94 forks source link

schemaFile with array producing false positives #160

Closed silverskater closed 3 months ago

silverskater commented 3 months ago

Trying to mock some ElasticSearch requests containing arrays, many of them with mixed type:

  "sort": [
    {
      "date": "desc"
    },
    "_score"
  ],
  "query": {   }

With a schemaFile like this or similar variations:

{
  "type": "object",
  "properties": {
    "sort": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "date": {
              "const": "desc"
            }
          }
        }
      ]
    }
  },
  "required": [
    "sort"
  ]
}

Any simple request like:

  "sort": [
    {
      "date": "desc"
    }
  ]

or changing to dateINVALID": "desc" they are always a match, array contents don't make a difference at all https://json-schema.org/understanding-json-schema/reference/array#items

Same with prefixItems https://json-schema.org/understanding-json-schema/reference/array#tupleValidation

How can we use a schemaFile to filter by array contents?

joanlopez commented 3 months ago

Hi @silverskater,

I'm not a great expert with JSON Schema, but here are the few ideas that come to my mind:

Maybe if you have a little but specific example, I can try to write the imposters for you.

I hope that helps!

silverskater commented 3 months ago

Thank you @joanlopez, in the end it was a different issue, docker build caching wasn't reliably turned off and I was sometimes testing against outdated schemas files :(

But here's a basic working example: Imposter xyz.imp.json:

[
  {
    "request": {
      "method": "POST",
      "endpoint": "/xyz",
      "schemaFile": "schemas/xyz.json",
      "headers": {
        "Content-Type": "application/json"
      }
    },
    "response": {
      "status": 200,
      "body": "Request matches with the json schema!"
    }
  },
  {
    "request": {
      "method": "POST",
      "endpoint": "/xyz"
    },
    "response": {
      "status": 200,
      "body": "Fallback, no match found."
    }
  }
]

Schema file schemas/xyz.json:

{
  "type": "object",
  "properties": {
    "sort": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "date": {
              "const": "desc"
            }
          }
        }
      ]
    }
  },
  "required": [
    "sort"
  ]
}

Request:

curl -XPOST http://localhost:9201/xyz -H "Content-Type: application/json" -d '{
  "sort": [
    {
      "date": "desc"
    },
    "_score"
  ],
  "query": { }
}'

The above returns 'Request matches with the json schema!' as expected, while a request with { "date": "asc" } properly responds with 'Fallback, no match found.'.