Skip to content

Commit

Permalink
feat: add support for multipart/form
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Aug 6, 2018
1 parent 4baa075 commit 8ed4332
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 5 deletions.
4 changes: 4 additions & 0 deletions lib/pact/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
require 'pact/matchers/embedded_diff_formatter'
require 'pact/matchers/unix_diff_formatter'
require 'pact/matchers/list_diff_formatter'
require 'pact/matchers/multipart_form_diff_formatter'
require 'pact/shared/json_differ'
require 'pact/shared/text_differ'
require 'pact/shared/form_differ'
require 'pact/shared/multipart_form_differ'


module Pact
Expand All @@ -24,13 +26,15 @@ def self.=~ other
end

DIFF_FORMATTER_REGISTRATIONS = [
[/multipart\/form-data/, Pact::Matchers::MultipartFormDiffFormatter],
[/.*/, Pact::Matchers::UnixDiffFormatter],
[NilMatcher, Pact::Matchers::UnixDiffFormatter]
]

DIFFERS = [
[/json/, Pact::JsonDiffer],
[/application\/x\-www\-form\-urlencoded/, Pact::FormDiffer],
[/multipart\/form-data/, Pact::MultipartFormDiffer],
[NilMatcher, Pact::TextDiffer],
[/.*/, Pact::TextDiffer]
]
Expand Down
6 changes: 1 addition & 5 deletions lib/pact/consumer_contract/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
require 'pact/shared/null_expectation'

module Pact

module Request

class Expected < Pact::Request::Base

DEFAULT_OPTIONS = {:allow_unexpected_keys => false}.freeze
Expand Down Expand Up @@ -80,8 +78,6 @@ def body_diff(actual_body)
def body_differ
Pact.configuration.body_differ_for_content_type content_type
end

end

end
end
end
41 changes: 41 additions & 0 deletions lib/pact/matchers/multipart_form_diff_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'pact/matchers/unix_diff_formatter'
require 'pact/matchers/differ'

module Pact
module Matchers
class MultipartFormDiffFormatter

def initialize diff, options = {}
@options = options
@body_diff = diff[:body]
@non_body_diff = diff.reject{ |k, v| k == :body }
@colour = options.fetch(:colour, false)
@differ = Pact::Matchers::Differ.new(@colour)
end

def self.call diff, options = {}
new(diff, options).call
end

def call
Pact::Matchers::UnixDiffFormatter::MESSAGES_TITLE + "\n" + non_body_diff_string + "\n" + body_diff_string
end

def non_body_diff_string
if @non_body_diff.any?
Pact::Matchers::ExtractDiffMessages.call(@non_body_diff).collect{ | message| "* #{message}" }.join("\n")
else
""
end
end

def body_diff_string
if @body_diff
@differ.diff_as_string(@body_diff.expected, @body_diff.actual)
else
""
end
end
end
end
end
14 changes: 14 additions & 0 deletions lib/pact/shared/multipart_form_differ.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'uri'
require 'pact/shared/text_differ'

module Pact
class MultipartFormDiffer
def self.call expected, actual, options = {}
require 'pact/matchers' # avoid recursive loop between this file and pact/matchers
expected_boundary = expected.split.first
actual_boundary = actual.split.first
actual_with_hardcoded_boundary = actual.gsub(actual_boundary, expected_boundary)
TextDiffer.call(expected, actual_with_hardcoded_boundary, options)
end
end
end
9 changes: 9 additions & 0 deletions spec/fixtures/multipart-form-diff.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@


Description of differences
--------------------------------------
* Wrong header

@@ -1,2 +1,2 @@
-bar
+foo
36 changes: 36 additions & 0 deletions spec/lib/pact/matchers/multipart_form_diff_formatter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'pact/matchers/multipart_form_diff_formatter'

module Pact
module Matchers
describe MultipartFormDiffFormatter do
describe ".call" do
subject { MultipartFormDiffFormatter.call(diff, options)}

let(:diff) do
{
headers: header_diff,
body: body_diff
}
end

let(:header_diff) do
{
"Content-Type" => Difference.new("foo", "bar", "Wrong header")
}
end

let(:body_diff) do
Difference.new("foo", "bar", "A message")
end

let(:options) { {} }

let(:expected_output) { File.read("spec/fixtures/multipart-form-diff.txt")}

it "formats the diff" do
expect(subject).to eq expected_output
end
end
end
end
end
39 changes: 39 additions & 0 deletions spec/lib/pact/shared/multipart_form_differ_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'pact/shared/multipart_form_differ'

module Pact
describe MultipartFormDiffer do

describe ".call" do

let(:expected_body) do
"-------------RubyMultipartPost-1e4912957c7bb64de3c444568326663b\r\nContent-Disposition: form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 14\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nThis is a file\r\n-------------RubyMultipartPost-1e4912957c7bb64de3c444568326663b--\r\n\r\n"
end

let(:actual_body) do
"-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX\r\nContent-Disposition: form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 14\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nThis is a file\r\n-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX--\r\n\r\n"
end

let(:options) do
{}
end

subject { MultipartFormDiffer.call(expected_body, actual_body, options) }

context "when the bodies are the same apart from the boundary" do
it "returns an empty diff" do
expect(subject).to eq({})
end
end

context "when the bodies are not the same" do
let(:actual_body) do
"-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX\r\nContent-Disposition: form-data; name=\"file\"; filename=\"bar.txt\"\r\nContent-Length: 14\r\nContent-Type: text/plain\r\nContent-Transfer-Encoding: binary\r\n\r\nThis is a file\r\n-------------RubyMultipartPost-1e4912957c7bb64de3c4445683266XXX--\r\n\r\n"
end

it "returns a text diff" do
expect(subject).to_not eq({})
end
end
end
end
end

0 comments on commit 8ed4332

Please sign in to comment.