Skip to content

Commit 8ed4332

Browse files
committed
feat: add support for multipart/form
1 parent 4baa075 commit 8ed4332

File tree

7 files changed

+144
-5
lines changed

7 files changed

+144
-5
lines changed

lib/pact/configuration.rb

+4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
require 'pact/matchers/embedded_diff_formatter'
22
require 'pact/matchers/unix_diff_formatter'
33
require 'pact/matchers/list_diff_formatter'
4+
require 'pact/matchers/multipart_form_diff_formatter'
45
require 'pact/shared/json_differ'
56
require 'pact/shared/text_differ'
67
require 'pact/shared/form_differ'
8+
require 'pact/shared/multipart_form_differ'
79

810

911
module Pact
@@ -24,13 +26,15 @@ def self.=~ other
2426
end
2527

2628
DIFF_FORMATTER_REGISTRATIONS = [
29+
[/multipart\/form-data/, Pact::Matchers::MultipartFormDiffFormatter],
2730
[/.*/, Pact::Matchers::UnixDiffFormatter],
2831
[NilMatcher, Pact::Matchers::UnixDiffFormatter]
2932
]
3033

3134
DIFFERS = [
3235
[/json/, Pact::JsonDiffer],
3336
[/application\/x\-www\-form\-urlencoded/, Pact::FormDiffer],
37+
[/multipart\/form-data/, Pact::MultipartFormDiffer],
3438
[NilMatcher, Pact::TextDiffer],
3539
[/.*/, Pact::TextDiffer]
3640
]

lib/pact/consumer_contract/request.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
require 'pact/shared/null_expectation'
33

44
module Pact
5-
65
module Request
7-
86
class Expected < Pact::Request::Base
97

108
DEFAULT_OPTIONS = {:allow_unexpected_keys => false}.freeze
@@ -80,8 +78,6 @@ def body_diff(actual_body)
8078
def body_differ
8179
Pact.configuration.body_differ_for_content_type content_type
8280
end
83-
8481
end
85-
8682
end
87-
end
83+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
require 'pact/matchers/unix_diff_formatter'
2+
require 'pact/matchers/differ'
3+
4+
module Pact
5+
module Matchers
6+
class MultipartFormDiffFormatter
7+
8+
def initialize diff, options = {}
9+
@options = options
10+
@body_diff = diff[:body]
11+
@non_body_diff = diff.reject{ |k, v| k == :body }
12+
@colour = options.fetch(:colour, false)
13+
@differ = Pact::Matchers::Differ.new(@colour)
14+
end
15+
16+
def self.call diff, options = {}
17+
new(diff, options).call
18+
end
19+
20+
def call
21+
Pact::Matchers::UnixDiffFormatter::MESSAGES_TITLE + "\n" + non_body_diff_string + "\n" + body_diff_string
22+
end
23+
24+
def non_body_diff_string
25+
if @non_body_diff.any?
26+
Pact::Matchers::ExtractDiffMessages.call(@non_body_diff).collect{ | message| "* #{message}" }.join("\n")
27+
else
28+
""
29+
end
30+
end
31+
32+
def body_diff_string
33+
if @body_diff
34+
@differ.diff_as_string(@body_diff.expected, @body_diff.actual)
35+
else
36+
""
37+
end
38+
end
39+
end
40+
end
41+
end
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require 'uri'
2+
require 'pact/shared/text_differ'
3+
4+
module Pact
5+
class MultipartFormDiffer
6+
def self.call expected, actual, options = {}
7+
require 'pact/matchers' # avoid recursive loop between this file and pact/matchers
8+
expected_boundary = expected.split.first
9+
actual_boundary = actual.split.first
10+
actual_with_hardcoded_boundary = actual.gsub(actual_boundary, expected_boundary)
11+
TextDiffer.call(expected, actual_with_hardcoded_boundary, options)
12+
end
13+
end
14+
end

spec/fixtures/multipart-form-diff.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
3+
Description of differences
4+
--------------------------------------
5+
* Wrong header
6+
7+
@@ -1,2 +1,2 @@
8+
-bar
9+
+foo
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
require 'pact/matchers/multipart_form_diff_formatter'
2+
3+
module Pact
4+
module Matchers
5+
describe MultipartFormDiffFormatter do
6+
describe ".call" do
7+
subject { MultipartFormDiffFormatter.call(diff, options)}
8+
9+
let(:diff) do
10+
{
11+
headers: header_diff,
12+
body: body_diff
13+
}
14+
end
15+
16+
let(:header_diff) do
17+
{
18+
"Content-Type" => Difference.new("foo", "bar", "Wrong header")
19+
}
20+
end
21+
22+
let(:body_diff) do
23+
Difference.new("foo", "bar", "A message")
24+
end
25+
26+
let(:options) { {} }
27+
28+
let(:expected_output) { File.read("spec/fixtures/multipart-form-diff.txt")}
29+
30+
it "formats the diff" do
31+
expect(subject).to eq expected_output
32+
end
33+
end
34+
end
35+
end
36+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
require 'pact/shared/multipart_form_differ'
2+
3+
module Pact
4+
describe MultipartFormDiffer do
5+
6+
describe ".call" do
7+
8+
let(:expected_body) do
9+
"-------------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"
10+
end
11+
12+
let(:actual_body) do
13+
"-------------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"
14+
end
15+
16+
let(:options) do
17+
{}
18+
end
19+
20+
subject { MultipartFormDiffer.call(expected_body, actual_body, options) }
21+
22+
context "when the bodies are the same apart from the boundary" do
23+
it "returns an empty diff" do
24+
expect(subject).to eq({})
25+
end
26+
end
27+
28+
context "when the bodies are not the same" do
29+
let(:actual_body) do
30+
"-------------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"
31+
end
32+
33+
it "returns a text diff" do
34+
expect(subject).to_not eq({})
35+
end
36+
end
37+
end
38+
end
39+
end

0 commit comments

Comments
 (0)