thoughtbot / json_matchers

Validate your JSON APIs
MIT License
384 stars 40 forks source link

Path must begin with a leading "/" #88

Closed Jesterovskiy closed 5 years ago

Jesterovskiy commented 6 years ago

After 0.10.0 update, get error for rspec tests:

Failure/Error: expect(response_body).to match_response_schema('users/show')

ArgumentError: Path must begin with a leading "/": #../user.json.

this is schema root path: JsonMatchers.schema_root = 'spec/support/json_schema'

Jesterovskiy commented 6 years ago

@seanpdoyle plz take a look, if you can)

mconiglio commented 6 years ago

I'm having this same issue

seanpdoyle commented 6 years ago

@Jesterovskiy @mconiglio could you share your schemata?

@Jesterovskiy is #../user.json. a value from spec/support/json_schema/users/show.json?

What is the structure of your spec/support/json_schema directory?

mconiglio commented 6 years ago

Hello @seanpdoyle, this is my directory tree:

spec/support/api/schemas
├── post.json
└── posts
    └── index.json

I have some schema in the post.json file and then I have the following in the posts/index.json file:

{
  "type": "object",
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "$ref": "../post.json"
      }
    }
  }
}

I tried this using the 0.9.0 version and it works correctly, but I get the ArgumentError: Path must begin with a leading "/" error if I use the 0.10.0 version.

seanpdoyle commented 6 years ago

@mconiglio thanks for the extra information!

Could you share a small snippet of post.json?

Also, could you share a JSON snippet that should we valid under the schema?

I'm working on creating a failing test and that data would be really helpful in doing so.

mconiglio commented 6 years ago

@seanpdoyle thanks to you for the help!

This is post.json

{
  "type": "object",
  "required": [
    "id",
    "type",
    "attributes"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "type": {
      "type": "string"
    },
    "attributes": {
      "type": "object",
      "required": [
        "id",
        "name",
        "kind",
        "species",
        "gender",
        "color",
        "description",
        "location",
        "latitude",
        "longitude",
        "created_at",
        "user"
      ],
      "properties": {
        "id": {
          "type": "integer"
        },
        "name": {
          "type": "string"
        },
        "kind": {
          "type": "string"
        },
        "species": {
          "type": "string"
        },
        "gender": {
          "type": "string"
        },
        "color": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "location": {
          "type": "string"
        },
        "latitude": {
          "type": "float"
        },
        "longitude": {
          "type": "float"
        },
        "created_at": {
          "type": "string",
          "format": "date-time"
        },
        "user": {
          "type": "object",
          "required": [
            "id",
            "phone_number",
            "created_at"
          ],
          "properties": {
            "id": {
              "type": "integer"
            },
            "phone_number": {
              "type": "string"
            },
            "created_at": {
              "type": "string",
              "format": "date-time"
            }
          }
        }
      }
    }
  }
}

And this is a response example of what would should match the posts/index schema:


{
    "data": [
        {
            "id": "1",
            "type": "post",
            "attributes": {
                "id": 1,
                "name": "Roxie",
                "kind": "lost",
                "species": "other",
                "gender": "unknown",
                "color": "Blue",
                "description": "Quia sint sapiente. Impedit velit voluptas. Harum facere suscipit.",
                "location": "Pocitos, Montevideo",
                "latitude": -34.913404,
                "longitude": -56.163182,
                "created_at": "2018-08-30T16:20:32.462Z",
                "user": {
                    "id": 19,
                    "phone_number": "92393459",
                    "created_at": "2018-08-30T16:20:32.448Z"
                }
            }
        },
        {
            "id": "2",
            "type": "post",
            "attributes": {
                "id": 2,
                "name": "Bubba",
                "kind": "lost",
                "species": "other",
                "gender": "male",
                "color": "Fuchsia",
                "description": "Non saepe optio. Nostrum aut doloribus. Ea animi facilis.",
                "location": "Pocitos, Montevideo",
                "latitude": -34.919485,
                "longitude": -56.166446,
                "created_at": "2018-08-30T16:20:35.079Z",
                "user": {
                    "id": 20,
                    "phone_number": "94431512",
                    "created_at": "2018-08-30T16:20:35.076Z"
                }
            }
        }
    ]
}
seanpdoyle commented 6 years ago

As a quick update, I'm working through a failing test that exercises this behavior.

As a temporary (hopefully helpful) bit of information, here's how we're building a JSON schema that references a sibling schema in our tests:

https://github.com/thoughtbot/json_matchers/blob/4ee7fac9982d3e1ef5bed349292cb7c18daba0c7/spec/factories.rb#L86-L106

And here's the schema it's referencing:

https://github.com/thoughtbot/json_matchers/blob/4ee7fac9982d3e1ef5bed349292cb7c18daba0c7/spec/factories.rb#L34-L50

To me, we should (do?) already support what you two are trying to do, but our documentation is lacking about what has changed during our switch from json-schema to json_schema as our underlying validator.

Could you try modifying your schemata to more closely resemble the above schemata and report back on what it took to get it working?

My instincts tell me that you'll need to introduce "definitions" keys and test out declaring "id" keys with "file:/ prefixes, but that's just a hunch.

mconiglio commented 6 years ago

@seanpdoyle thanks again for your help. I tried some things but it's still not working. Now it's not throwing an error, but I tried changing the post.json schema to make the tests fail and it seems that it's not being compared correctly.

I added this to the post.json file (I also had to change "type": "float" to "type": "number" to make it work):

{
  "id": "file:/post.json#",
  // ...
}

And changed the posts/index.json to this:

{
  "$schema": "https://json-schema.org/draft-04/schema#",
  "id": "file:/posts/index.json#",
  "type": "object",
  "required": [
    "data"
  ],
  "definitions": {
    "posts": {
      "type": "array",
      "items": {
        "$ref": "file:/post.json#"
      }
    }
  },
  "properties": {
    "data": {
      "$ref": "#/definitions/posts"
    }
  }
}

Maybe I'm doing something wrong as my data structure is a little different than the one you posted. But, as I said, now I'm not getting the Path must begin with a leading "/" error anymore, but it looks like changing the required schema in post.json doesn't make any actual changes when comparing it to the response with match_response_schema.

seanpdoyle commented 6 years ago

@mconiglio I've opened https://github.com/thoughtbot/json_matchers/pull/89.

I've lifted the JSON you've provided and added a test to exercise it. It's passing off the bat.

Please pull down that PR and modify that test so that it's in-line with your data. If you can produce a failing test, that would help me understand where the disconnect is.

Thanks!

Jesterovskiy commented 6 years ago

@mconiglio @seanpdoyle thank you for help. In my case, to use 0.10.0 I need change in each plural schema "$ref": "../user.json" -> "$ref": "file:/user.json#" and add in singular schema "id": "file:/user.json#"

This is a lot of changes) Thats why I`ll stay on previous version for now