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

Proposal: Create assert_response_schema test helper #1270

Closed
wants to merge 1 commit into from

Conversation

maurogeorge
Copy link
Member

It is a common pattern to use JSON Schema to validate a API response 1, 2
and 3.

This patch creates the assert_response_schema test helper that helps people do
this kind of validation easily on the controller tests.

This makes sense to you guys? If make sense I can continue with CHANGELOG, Docs and so on.

@bf4
Copy link
Member

bf4 commented Oct 14, 2015

Wow, this is awesome! I think I made a issue to add this.. specifically for json-api, but in general is also great!

I have a few comments on implementation, but am generally wow!

@maurogeorge
Copy link
Member Author

Hi @bf4 great to hear that 😃
I added some docs, now waiting for your review.

module ActiveModel
class Serializer
module Assertions
def assert_response_schema(schema_path = nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be under a test namespace if it's for tests, e.g. ActiveModelSerializers::Test::Schema

And would be good for the method not to be dependent on where it's included

e.g.

module Schema
  module_function

  def validate!(schema_full_path, json, strict = true)
    JSON::Validator.validate!(schema_full_path, json, strict: strict) # is this keyword args? we can't support that yet
  end

  def validate_response_schema!(response, schema_path = nil)
    validate!(schema_full_path_for(response.body, schema_path))
  end

  def schema_full_path_for(response, schema_path = nil)
        controller_path = response.request.filtered_parameters[:controller]
        action = response.request.filtered_parameters[:action]
        schema_directory = ActiveModel::Serializer.config.schema_path
        schema_path ||= "#{controller_path}/#{action}.json"
        "#{schema_directory}/#{schema_path}"
  end

@bf4
Copy link
Member

bf4 commented Oct 26, 2015

Sorry for delay in review this. There'll be a good rebase ...

@bf4
Copy link
Member

bf4 commented Oct 26, 2015

ref: #1162

@maurogeorge
Copy link
Member Author

Thanks for the review, I think it is better hold the working on this until the #1291 be merged, since both define instrumentation and the last one is more mature.

First I will work on the #1291 until the merge and later I back to this one.

@bf4
Copy link
Member

bf4 commented Nov 10, 2015

wanna take another look at this? I like this PR

@maurogeorge
Copy link
Member Author

I think it is better hold the working on this until the #1322 be merged, since both define instrumentation and the last one is more mature.

@bf4
Copy link
Member

bf4 commented Nov 24, 2015

instrumentation PR is merged!

@malandrina
Copy link

This is a cool idea!

I wanted to chime in and share some thoughts about compatibility with other JSON Schema-based tools. Something we discovered recently with json_matchers at thoughtbot is that json_matchers currently isn’t compatible with Heroku’s JSON Schema-based tools, e.g. prmd and committee, because it makes different assumptions about the organization and structure of the schemata.

It’s likely you’ll run into the same issue with the implementation you have here. If you’re interested in ensuring compatibility with Heroku’s tooling you should consider using json_schema to parse and validate schemata and organize the schemata according to Heroku’s conventions.

@maurogeorge
Copy link
Member Author

@malandrina thanks a lot for you thoughts here ❤️

I missed this on README of json-schema is said that this does not handle any JSON Hyper-Schema and prmd uses JSON Hyper-Schema.
The json_schema you recommended handle this. So yes I will change this to use json_schema.

When you said it makes different assumptions about the organization and structure of the schemata, the recommended way to organize the individual resource schema is under docs/schema/schemata. I created a option to define the path here so if we change this to ActiveModel::Serializer.config.schema_path = 'docs/schema/schemata' we can use the same json files to the prmd and comittee right?

Thanks

@malandrina
Copy link

@maurogeorge no problem!

Based on my experience with this json_matchers issue (apologies for not having referenced it directly in my previous comment), I'm not confident that making the root path for the schemata configurable is enough to achieve compatibility with Heroku's tools. I believe users of ActiveModelSerializers will have to structure their schemata according to Heroku's conventions (e.g. including required metadata and links) in addition to storing the schema files in docs/schema/schemata.

@maurogeorge
Copy link
Member Author

@malandrina I updated to use the json_schema. To test the heroku integration I create a hyper-schema using the prmd and test against it. So now it is possible to do some simple validation using a simple json or using the hyper-schema format.

With this I think the users can structure their schemata according to Heroku's conventions and storing the schema files in docs/schema/schemata. You think this is ok or I miss something.

Thanks

@malandrina
Copy link

@maurogeorge your process seems solid. 👍 The only other I thing I would suggest thinking about is use of the $ref keyword and JSON Pointers in the simple (i.e. non-hyper) schemata.

If you would like for users of the matcher to be able to use JSON Pointers in non-hyper schemata, I'd suggesting writing a test or two to validate your assumptions about how JSON Pointers should be formatted and how json_schema dereferences them. This could be as simple as adding a couple $refs to test/support/schemas/custom/show.json.

If you don't expect users to include JSON Pointers in non-hyper schemata, I'd recommend including that information in the documentation.

@bf4
Copy link
Member

bf4 commented Dec 2, 2015

@@ -0,0 +1,78 @@
# How to test

## Test helpers
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an end-user's guide to testing, right? (vs. in CONTRIBUTING.md how to develop on AMS).

In any case, this is 💯

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bf4 thanks! Yes, this is the idea.

@maurogeorge
Copy link
Member Author

@malandrina thanks for the tip, I updated the code maurogeorge@0852b49 do you think this is enough?

Thanks

@bf4
Copy link
Member

bf4 commented Dec 3, 2015

@maurogeorge Looks like CI wants you to rebase off of master and force push

This PR is so awesome. I love looking at it!

@maurogeorge
Copy link
Member Author

@bf4 Thanks for the review.

I updated the code following your comments. We are back to green after drop Ruby 1.9 on Travis.

The AppVeyor is broken because we are running Ruby 1.9.3 on it, I can't found a dot file to change this, I imagine this can be managed via some interface, so we need to change this.

Thanks

@maurogeorge
Copy link
Member Author

@bf4 I sent a PR to fix AppVeyor the #1395 I found for a dot file, but it is not a dot file is appveyor.yml only 😄

@maurogeorge
Copy link
Member Author

@bf4 I updated the code following your last comments and rebased against the master.

We are good to :shipit: ?

Thanks

@bf4
Copy link
Member

bf4 commented Jan 6, 2016

Looks good but I'm tired right now and want to review more carefully. Did I miss why json_schema is a runtime dependency instead of development?

@malandrina thoughts?

cc @rails-api/ams this is a good one to look at

@maurogeorge
Copy link
Member Author

@bf4 thanks, no problem take a rest 😃

I think if we keep the json_schema as a development dependency we will need to ask for people to install this, before use the test helper.

@bf4
Copy link
Member

bf4 commented Jan 6, 2016

Oh right. We could warn inside a method like rails attr_encrypted so rails doesn't need to specify bcrypt

B mobile phone

On Jan 6, 2016, at 3:09 PM, Mauro George [email protected] wrote:

@bf4 thanks, no problem take a rest

I think if we keep the json_schema as a development dependency we will need to ask for people to install this, before use the test helper.


Reply to this email directly or view it on GitHub.


ActiveModelSerializers provides a `assert_response_schema` method to be used on your controller tests to
assert the response against a [JSON Schema](http://json-schema.org/). Let's take
a look in a example.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grammar: "a example" => "an example"

@malandrina
Copy link

I left some comments with suggested improvements to the documentation but overall this seems reasonable to me. It's great that this will be compatible with Heroku's tooling. 👍

@maurogeorge
Copy link
Member Author

@bf4 Liked the idea, I update the code following the same idea Rails does.

@malandrina thanks for the review, I updated the docs accordingly.

@bf4
Copy link
Member

bf4 commented Jan 13, 2016

@maurogeorge rebase and good to merge, I think. Wanna join the commiters team?

@bf4 bf4 added the S: LGTM label Jan 13, 2016
@bf4 bf4 mentioned this pull request Jan 13, 2016
It is a common pattern to use JSON Schema to validate a API response[1], [2]
and [3].

This patch creates the `assert_response_schema` test helper that helps people do
this kind of validation easily on the controller tests.

[1]: https://robots.thoughtbot.com/validating-json-schemas-with-an-rspec-matcher
[2]: https://github.com/sharethrough/json-schema-rspec
[3]: rails-api#1011 (comment)
@maurogeorge
Copy link
Member Author

@bf4 rebased, :shipit:

😊 Yeah, I like the idea to join the commiters team. Probably I will leave the open source world for a while, but later I can continue working on the project.

@bf4
Copy link
Member

bf4 commented Jan 14, 2016

@maurogeorge awesome. I'll have @joaomdmoura add you. (I thought I could, but I guess not.)

@joaomdmoura
Copy link
Member

@maurogeorge You are invited! ❤️ would be nice to have you on slack so that I can add you on the maintainer channel 😄

@maurogeorge
Copy link
Member Author

@bf4 @joaomdmoura thanks ❤️

João as I said in the #1270 (comment), I will leave the open source world for a while, but later I can continue working on the project and help more the project.

@bf4 :shipit: ?

@bf4
Copy link
Member

bf4 commented Jan 15, 2016

Merged by ac13053

@bf4 bf4 closed this Jan 15, 2016
@maurogeorge
Copy link
Member Author

Thanks for the merge 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants