diff --git a/Gemfile.lock b/Gemfile.lock index 60d9c8b..5afb841 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,7 @@ PATH remote: ./rswag-specs specs: rswag-specs (1.2.0) + json (~> 1.8) json-schema (~> 2.2) rails (>= 3.1, < 5.1) rspec-rails (>= 2.14, < 4) diff --git a/README.md b/README.md index f6db531..be69bbb 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,17 @@ If you've used [Swagger](http://swagger.io/specification) before, then the synta Take special note of the __run_test!__ method that's called within each response block. This tells rswag to create and execute a corresponding example. It builds and submits a request based on parameter descriptions and corresponding values that have been provided using the rspec "let" syntax. For example, the "post" description in the example above specifies a "body" parameter called "blog". It also lists 2 different responses. For the success case (i.e. the 201 response), notice how "let" is used to set the blog parameter to a value that matches the provided schema. For the failure case (i.e. the 422 response), notice how it's set to a value that does not match the provided schema. When the test is executed, rswag also validates the actual response code and, where applicable, the response body against the provided [JSON Schema](http://json-schema.org/documentation.html). +If you want to do additional validation on the response, pass a block to the __run_test!__ method: + +```ruby +response '201', 'blog created' do + run_test! do |response| + data = JSON.parse(response.body) + expect(data['title']).to eq('foo') + end +end +``` + If you'd like your specs to be a little more explicit about what's going on here, you can replace the call to __run_test!__ with equivalent "before" and "it" blocks: ```ruby diff --git a/rswag-specs/lib/rswag/specs/example_group_helpers.rb b/rswag-specs/lib/rswag/specs/example_group_helpers.rb index cb96e71..ed7b20f 100644 --- a/rswag-specs/lib/rswag/specs/example_group_helpers.rb +++ b/rswag-specs/lib/rswag/specs/example_group_helpers.rb @@ -69,7 +69,7 @@ module Rswag metadata[:response][:examples] = example end - def run_test! + def run_test!(&block) # NOTE: rspec 2.x support if RSPEC_VERSION < 3 before do @@ -77,7 +77,7 @@ module Rswag end it "returns a #{metadata[:response][:code]} response" do - assert_response_matches_metadata(example.metadata) + assert_response_matches_metadata(example.metadata, &block) end else before do |example| @@ -85,7 +85,7 @@ module Rswag end it "returns a #{metadata[:response][:code]} response" do |example| - assert_response_matches_metadata(example.metadata) + assert_response_matches_metadata(example.metadata, &block) end end end diff --git a/rswag-specs/lib/rswag/specs/example_helpers.rb b/rswag-specs/lib/rswag/specs/example_helpers.rb index b9850ce..b7185fb 100644 --- a/rswag-specs/lib/rswag/specs/example_helpers.rb +++ b/rswag-specs/lib/rswag/specs/example_helpers.rb @@ -28,10 +28,10 @@ module Rswag end end - def assert_response_matches_metadata(api_metadata) + def assert_response_matches_metadata(api_metadata, &block) global_metadata = rswag_config.get_swagger_doc(api_metadata[:swagger_doc]) validator = ResponseValidator.new(api_metadata, global_metadata) - validator.validate!(response) + validator.validate!(response, &block) end private diff --git a/rswag-specs/lib/rswag/specs/response_validator.rb b/rswag-specs/lib/rswag/specs/response_validator.rb index 7212a3f..7194953 100644 --- a/rswag-specs/lib/rswag/specs/response_validator.rb +++ b/rswag-specs/lib/rswag/specs/response_validator.rb @@ -1,5 +1,6 @@ require 'active_support/core_ext/hash/slice' require 'json-schema' +require 'json' require 'rswag/specs/extended_schema' module Rswag @@ -11,10 +12,11 @@ module Rswag @global_metadata = global_metadata end - def validate!(response) + def validate!(response, &block) validate_code!(response.code) validate_headers!(response.headers) - validate_body!(response.body) + validate_body!(response.body, &block) + block.call(response) if block_given? end private diff --git a/rswag-specs/rswag-specs.gemspec b/rswag-specs/rswag-specs.gemspec index 6bfd38b..6e866a6 100644 --- a/rswag-specs/rswag-specs.gemspec +++ b/rswag-specs/rswag-specs.gemspec @@ -16,7 +16,8 @@ Gem::Specification.new do |s| s.files = Dir["{lib}/**/*"] + ["MIT-LICENSE", "Rakefile" ] - s.add_dependency "rails", ">= 3.1", "< 5.1" + s.add_dependency "rails", ">= 3.1", "< 5.1" + s.add_dependency 'json', '~> 1.8' s.add_dependency 'json-schema', '~> 2.2' s.add_dependency 'rspec-rails', '>= 2.14', '< 4' end diff --git a/rswag-specs/spec/rswag/specs/response_validator_spec.rb b/rswag-specs/spec/rswag/specs/response_validator_spec.rb index 286940d..cb95996 100644 --- a/rswag-specs/spec/rswag/specs/response_validator_spec.rb +++ b/rswag-specs/spec/rswag/specs/response_validator_spec.rb @@ -29,7 +29,7 @@ module Rswag api_metadata[:response][:schema] = { type: 'object', properties: { text: { type: 'string' } }, - required: [ 'text' ] + required: ['text'] } end @@ -42,6 +42,25 @@ module Rswag let(:response) { OpenStruct.new(code: 200, body: "{\"foo\":\"Some comment\"}") } it { expect { call }.to raise_error UnexpectedResponse } end + + context "'block' provided" do + let(:call) do + subject.validate!(response) do |response| + data = JSON.parse(response.body) + expect(data['text']).to eq('Some comment') + end + end + + context 'the block validation passes' do + let(:response) { OpenStruct.new(code: 200, body: "{\"text\":\"Some comment\"}") } + it { expect { call }.to_not raise_error } + end + + context 'the block validation fails' do + let(:response) { OpenStruct.new(code: 200, body: "{\"text\":\"Some other comment\"}") } + it { expect { call }.to raise_error(RSpec::Expectations::ExpectationNotMetError) } + end + end end context "referenced 'schema' provided" do @@ -51,7 +70,7 @@ module Rswag author: { type: 'object', properties: { name: { type: 'string' } }, - required: [ 'name' ] + required: ['name'] } } end