diff --git a/rswag-specs/lib/rswag/specs/example_helpers.rb b/rswag-specs/lib/rswag/specs/example_helpers.rb index 302a84a..1b62bb8 100644 --- a/rswag-specs/lib/rswag/specs/example_helpers.rb +++ b/rswag-specs/lib/rswag/specs/example_helpers.rb @@ -12,15 +12,15 @@ module Rswag send( request[:verb], request[:path], - request[:body], - rackify_headers(request[:headers]) # Rails test infrastructure requires Rack headers + request[:payload], + request[:headers] ) else send( request[:verb], request[:path], { - params: request[:body], + params: request[:payload], headers: request[:headers] } ) @@ -30,24 +30,6 @@ module Rswag def assert_response_matches_metadata(metadata, &block) ResponseValidator.new.validate!(metadata, response, &block) end - - private - - def rackify_headers(headers) - name_value_pairs = headers.map do |name, value| - [ - case name - when 'Accept' then 'HTTP_ACCEPT' - when 'Content-Type' then 'CONTENT_TYPE' - when 'Authorization' then 'HTTP_AUTHORIZATION' - else name - end, - value - ] - end - - Hash[ name_value_pairs ] - end end end end diff --git a/rswag-specs/lib/rswag/specs/request_factory.rb b/rswag-specs/lib/rswag/specs/request_factory.rb index ac5a6b3..dcb18db 100644 --- a/rswag-specs/lib/rswag/specs/request_factory.rb +++ b/rswag-specs/lib/rswag/specs/request_factory.rb @@ -1,4 +1,5 @@ require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/hash/conversions' require 'json' module Rswag @@ -16,8 +17,8 @@ module Rswag {}.tap do |request| add_verb(request, metadata) add_path(request, metadata, swagger_doc, parameters, example) - add_headers(request, parameters, example) - add_content(request, metadata, swagger_doc, parameters, example) + add_headers(request, metadata, swagger_doc, parameters, example) + add_payload(request, parameters, example) end end @@ -91,34 +92,60 @@ module Rswag end end - def add_headers(request, parameters, example) - name_value_pairs = parameters + def add_headers(request, metadata, swagger_doc, parameters, example) + tuples = parameters .select { |p| p[:in] == :header } .map { |p| [ p[:name], example.send(p[:name]).to_s ] } - request[:headers] = Hash[ name_value_pairs ] - end - - def add_content(request, metadata, swagger_doc, parameters, example) # Accept header produces = metadata[:operation][:produces] || swagger_doc[:produces] if produces accept = example.respond_to?(:'Accept') ? example.send(:'Accept') : produces.first - request[:headers]['Accept'] = accept + tuples << [ 'Accept', accept ] end - # Content-Type and body + # Content-Type header consumes = metadata[:operation][:consumes] || swagger_doc[:consumes] - return if consumes.nil? - - content_type = example.respond_to?(:'Content-Type') ? example.send(:'Content-Type') : consumes.first - request[:headers]['Content-Type'] = content_type - - if content_type.include?('json') - body_param = parameters.select { |p| p[:in] == :body }.first - return if body_param.nil? - request[:body] = example.send(body_param[:name]).to_json + if consumes + content_type = example.respond_to?(:'Content-Type') ? example.send(:'Content-Type') : consumes.first + tuples << [ 'Content-Type', content_type ] end + + # Rails test infrastructure requires rackified headers + rackified_tuples = tuples.map do |pair| + [ + case pair[0] + when 'Accept' then 'HTTP_ACCEPT' + when 'Content-Type' then 'CONTENT_TYPE' + when 'Authorization' then 'HTTP_AUTHORIZATION' + else pair[0] + end, + pair[1] + ] + end + + request[:headers] = Hash[ rackified_tuples ] + end + + def add_payload(request, parameters, example) + content_type = request[:headers]['CONTENT_TYPE'] + return if content_type.nil? + + if [ 'application/x-www-form-urlencoded', 'multipart/form-data' ].include?(content_type) + request[:payload] = build_form_payload(parameters, example) + else + request[:payload] = build_json_payload(parameters, example) + end + end + + def build_json_payload(parameters, example) + body_param = parameters.select { |p| p[:in] == :body }.first + body_param ? example.send(body_param[:name]).to_json : nil + end + + def build_form_payload(parameters, example) + nil + # TODO: end end end diff --git a/rswag-specs/spec/rswag/specs/request_factory_spec.rb b/rswag-specs/spec/rswag/specs/request_factory_spec.rb index 423272f..a22b0d4 100644 --- a/rswag-specs/spec/rswag/specs/request_factory_spec.rb +++ b/rswag-specs/spec/rswag/specs/request_factory_spec.rb @@ -133,8 +133,8 @@ module Rswag end context "no 'Content-Type' provided" do - it "sets 'Content-Type' header to first in list" do - expect(request[:headers]).to eq('Content-Type' => 'application/json') + it "sets 'CONTENT_TYPE' header to first in list" do + expect(request[:headers]).to eq('CONTENT_TYPE' => 'application/json') end end @@ -143,19 +143,19 @@ module Rswag allow(example).to receive(:'Content-Type').and_return('application/xml') end - it "sets 'Content-Type' header to example value" do - expect(request[:headers]).to eq('Content-Type' => 'application/xml') + it "sets 'CONTENT_TYPE' header to example value" do + expect(request[:headers]).to eq('CONTENT_TYPE' => 'application/xml') end end - context 'JSON body' do + context 'JSON payload' do before do metadata[:operation][:parameters] = [ { name: 'comment', in: :body, schema: { type: 'object' } } ] allow(example).to receive(:comment).and_return(text: 'Some comment') end - it 'sets body to example value as JSON string' do - expect(request[:body]).to eq("{\"text\":\"Some comment\"}") + it "serializes first 'body' parameter to JSON string" do + expect(request[:payload]).to eq("{\"text\":\"Some comment\"}") end end end @@ -166,8 +166,8 @@ module Rswag end context "no 'Accept' value provided" do - it "sets 'Accept' header to first in list" do - expect(request[:headers]).to eq('Accept' => 'application/json') + it "sets 'HTTP_ACCEPT' header to first in list" do + expect(request[:headers]).to eq('HTTP_ACCEPT' => 'application/json') end end @@ -176,8 +176,8 @@ module Rswag allow(example).to receive(:'Accept').and_return('application/xml') end - it "sets 'Accept' header to example value" do - expect(request[:headers]).to eq('Accept' => 'application/xml') + it "sets 'HTTP_ACCEPT' header to example value" do + expect(request[:headers]).to eq('HTTP_ACCEPT' => 'application/xml') end end end @@ -213,8 +213,8 @@ module Rswag allow(example).to receive(:Authorization).and_return('Basic foobar') end - it "sets 'Authorization' header to example value" do - expect(request[:headers]).to eq('Authorization' => 'Basic foobar') + it "sets 'HTTP_AUTHORIZATION' header to example value" do + expect(request[:headers]).to eq('HTTP_AUTHORIZATION' => 'Basic foobar') end end @@ -225,8 +225,8 @@ module Rswag allow(example).to receive(:Authorization).and_return('Bearer foobar') end - it "sets 'Authorization' header to example value" do - expect(request[:headers]).to eq('Authorization' => 'Bearer foobar') + it "sets 'HTTP_AUTHORIZATION' header to example value" do + expect(request[:headers]).to eq('HTTP_AUTHORIZATION' => 'Bearer foobar') end end @@ -266,8 +266,8 @@ module Rswag context "global consumes" do before { swagger_doc[:consumes] = [ 'application/xml' ] } - it "defaults 'Content-Type' to global value(s)" do - expect(request[:headers]).to eq('Content-Type' => 'application/xml') + it "defaults 'CONTENT_TYPE' to global value(s)" do + expect(request[:headers]).to eq('CONTENT_TYPE' => 'application/xml') end end