pact-mock_service 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +29 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/CHANGELOG.md +4 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +100 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +314 -0
  10. data/Rakefile +6 -0
  11. data/bin/pact-mock-service +3 -0
  12. data/lib/pact/consumer/app_manager.rb +159 -0
  13. data/lib/pact/consumer/interactions_filter.rb +48 -0
  14. data/lib/pact/consumer/mock_service/app.rb +84 -0
  15. data/lib/pact/consumer/mock_service/interaction_delete.rb +33 -0
  16. data/lib/pact/consumer/mock_service/interaction_list.rb +76 -0
  17. data/lib/pact/consumer/mock_service/interaction_mismatch.rb +73 -0
  18. data/lib/pact/consumer/mock_service/interaction_post.rb +31 -0
  19. data/lib/pact/consumer/mock_service/interaction_replay.rb +139 -0
  20. data/lib/pact/consumer/mock_service/log_get.rb +28 -0
  21. data/lib/pact/consumer/mock_service/missing_interactions_get.rb +30 -0
  22. data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +31 -0
  23. data/lib/pact/consumer/mock_service/pact_post.rb +33 -0
  24. data/lib/pact/consumer/mock_service/rack_request_helper.rb +51 -0
  25. data/lib/pact/consumer/mock_service/verification_get.rb +68 -0
  26. data/lib/pact/consumer/mock_service.rb +2 -0
  27. data/lib/pact/consumer/mock_service_client.rb +65 -0
  28. data/lib/pact/consumer/mock_service_interaction_expectation.rb +37 -0
  29. data/lib/pact/consumer/request.rb +27 -0
  30. data/lib/pact/consumer/server.rb +90 -0
  31. data/lib/pact/consumer_contract/consumer_contract_writer.rb +84 -0
  32. data/lib/pact/mock_service/cli.rb +49 -0
  33. data/lib/pact/mock_service/version.rb +5 -0
  34. data/lib/pact/mock_service.rb +1 -0
  35. data/pact-mock-service.gemspec +41 -0
  36. data/spec/lib/pact/consumer/app_manager_spec.rb +42 -0
  37. data/spec/lib/pact/consumer/mock_service/app_spec.rb +52 -0
  38. data/spec/lib/pact/consumer/mock_service/interaction_list_spec.rb +78 -0
  39. data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +70 -0
  40. data/spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb +12 -0
  41. data/spec/lib/pact/consumer/mock_service/rack_request_helper_spec.rb +88 -0
  42. data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +142 -0
  43. data/spec/lib/pact/consumer/mock_service_client_spec.rb +88 -0
  44. data/spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb +54 -0
  45. data/spec/lib/pact/consumer/service_consumer_spec.rb +11 -0
  46. data/spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb +111 -0
  47. data/spec/spec_helper.rb +16 -0
  48. data/spec/support/a_consumer-a_producer.json +32 -0
  49. data/spec/support/a_consumer-a_provider.json +32 -0
  50. data/spec/support/active_support_if_configured.rb +6 -0
  51. data/spec/support/app_for_config_ru.rb +4 -0
  52. data/spec/support/case-insensitive-response-header-matching.json +21 -0
  53. data/spec/support/case-insensitive-response-header-matching.rb +15 -0
  54. data/spec/support/consumer_contract_template.json +24 -0
  55. data/spec/support/dsl_spec_support.rb +7 -0
  56. data/spec/support/factories.rb +82 -0
  57. data/spec/support/generated_index.md +4 -0
  58. data/spec/support/generated_markdown.md +55 -0
  59. data/spec/support/interaction_view_model.json +63 -0
  60. data/spec/support/interaction_view_model_with_terms.json +50 -0
  61. data/spec/support/markdown_pact.json +48 -0
  62. data/spec/support/missing_provider_states_output.txt +25 -0
  63. data/spec/support/options.json +21 -0
  64. data/spec/support/options_app.rb +15 -0
  65. data/spec/support/pact_helper.rb +57 -0
  66. data/spec/support/shared_examples_for_request.rb +94 -0
  67. data/spec/support/spec_support.rb +20 -0
  68. data/spec/support/stubbing.json +22 -0
  69. data/spec/support/stubbing_using_allow.rb +29 -0
  70. data/spec/support/term.json +48 -0
  71. data/spec/support/test_app_fail.json +61 -0
  72. data/spec/support/test_app_pass.json +38 -0
  73. data/spec/support/test_app_with_right_content_type_differ.json +23 -0
  74. data/tasks/spec.rake +6 -0
  75. metadata +388 -0
@@ -0,0 +1,70 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service/interaction_mismatch'
3
+
4
+ module Pact
5
+ module Consumer
6
+ describe InteractionMismatch do
7
+ let(:content_type) { 'some/content' }
8
+ let(:actual_request) { instance_double('Pact::Consumer::Request::Actual', :method_and_path => 'GET /path') }
9
+ let(:expected_request_1) { instance_double('Pact::Request::Expected', :content_type => content_type) }
10
+ let(:expected_request_2) { instance_double('Pact::Request::Expected', :content_type => content_type) }
11
+ let(:candidate_1) { instance_double('Pact::Interaction', request: expected_request_1, description_with_provider_state_quoted: "desc 1") }
12
+ let(:candidate_2) { instance_double('Pact::Interaction', request: expected_request_2, description_with_provider_state_quoted: "desc 2") }
13
+ let(:candidate_interactions) { [candidate_1, candidate_2] }
14
+ subject { InteractionMismatch.new(candidate_interactions, actual_request) }
15
+ let(:diff_1) { {body: 'diff'} }
16
+ let(:diff_2) { {} }
17
+
18
+ before do
19
+ allow(expected_request_1).to receive(:difference).with(actual_request).and_return(diff_1)
20
+ allow(expected_request_2).to receive(:difference).with(actual_request).and_return(diff_2)
21
+ end
22
+
23
+ describe "short_summary" do
24
+ it "includes the method and path" do
25
+ expect(subject.short_summary).to match /GET \/path \(.*\)/
26
+ end
27
+ context "when the body does not match" do
28
+ let(:diff_1) { {body: nil} }
29
+
30
+ it "returns a message indicating that the body does not match" do
31
+ expect(subject.short_summary).to include "(request body did not match)"
32
+ end
33
+ end
34
+ context "when the headers do not match" do
35
+ let(:diff_1) { {headers: nil} }
36
+ it "returns a message indicating that the body does not match" do
37
+ expect(subject.short_summary).to include "(request headers did not match)"
38
+ end
39
+ end
40
+ context "when the headers and body do not match" do
41
+ let(:diff_1) { {body: nil, headers: nil} }
42
+ let(:diff_2) { {body: nil, headers: nil} }
43
+ it "returns a message indicating that the headers and body do not match" do
44
+ expect(subject.short_summary).to include "(request body and headers did not match)"
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "to_s" do
50
+ let(:expected_message) { "Diff with interaction: desc 1\ndiff 1\nDiff with interaction: desc 2\ndiff 2" }
51
+
52
+ let(:diff_formatter) { double("diff_formatter")}
53
+ before do
54
+ allow(Pact.configuration).to receive(:diff_formatter_for_content_type).with(content_type).and_return(diff_formatter)
55
+ allow(diff_formatter).to receive(:call).and_return("diff 1", "diff 2")
56
+ end
57
+
58
+ it "creates diff output using the configured diff_formatter" do
59
+ expect(diff_formatter).to receive(:call).with(diff_1, colour: false)
60
+ expect(diff_formatter).to receive(:call).with(diff_2, colour: false)
61
+ subject.to_s
62
+ end
63
+
64
+ it "includes a diff output in the string output" do
65
+ expect(subject.to_s).to eq expected_message
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service/interaction_replay'
3
+
4
+ module Pact
5
+ module Consumer
6
+
7
+ describe InteractionReplay do
8
+
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service/rack_request_helper'
3
+
4
+ module Pact::Consumer
5
+
6
+ describe RackRequestHelper do
7
+ class TestSubject
8
+ include RackRequestHelper
9
+ end
10
+
11
+ let(:rack_env) {
12
+ {
13
+ "CONTENT_LENGTH" => "16",
14
+ "CONTENT_TYPE" => content_type,
15
+ "GATEWAY_INTERFACE" => "CGI/1.1",
16
+ "PATH_INFO" => "/donuts",
17
+ "QUERY_STRING" => "",
18
+ "REMOTE_ADDR" => "127.0.0.1",
19
+ "REMOTE_HOST" => "localhost",
20
+ "REQUEST_METHOD" => "POST",
21
+ "REQUEST_URI" => "http://localhost:4321/donuts",
22
+ "SCRIPT_NAME" => "",
23
+ "SERVER_NAME" => "localhost",
24
+ "SERVER_PORT" => "4321",
25
+ "SERVER_PROTOCOL" => "HTTP/1.1",
26
+ "SERVER_SOFTWARE" => "WEBrick/1.3.1 (Ruby/1.9.3/2013-02-22)",
27
+ "HTTP_ACCEPT" => "text/plain",
28
+ "HTTP_USER_AGENT" => "Ruby",
29
+ "HTTP_HOST" => "localhost:4321",
30
+ "HTTP_X_SOMETHING" => "1, 2",
31
+ "rack.version" => [1, 2 ],
32
+ "rack.input" => StringIO.new(body),
33
+ "rack.errors" => nil,
34
+ "rack.multithread" => true,
35
+ "rack.multiprocess" => false,
36
+ "rack.run_once" => false,
37
+ "rack.url_scheme" => "http",
38
+ "HTTP_VERSION" => "HTTP/1.1",
39
+ "REQUEST_PATH" => "/donuts"
40
+ }
41
+ }
42
+
43
+ let(:content_type) { "" }
44
+ let(:body) { '' }
45
+
46
+ subject { TestSubject.new }
47
+
48
+ let(:expected_request) {
49
+ {
50
+ :query => "",
51
+ :method => "post",
52
+ :body => expected_body,
53
+ :path => "/donuts",
54
+ :headers => {
55
+ "Content-Type" => content_type,
56
+ "Content-Length" => "16",
57
+ "Accept" => "text/plain",
58
+ "User-Agent" => "Ruby",
59
+ "Host" => "localhost:4321",
60
+ "Version" => "HTTP/1.1",
61
+ "X-Something" => "1, 2"
62
+ }
63
+ }
64
+ }
65
+
66
+ context "with a text body" do
67
+ let(:content_type) { "application/x-www-form-urlencoded" }
68
+ let(:body) { 'this is the body' }
69
+ let(:expected_body) { body }
70
+
71
+ it "extracts the body" do
72
+ expect(subject.request_as_hash_from(rack_env)).to eq expected_request
73
+ end
74
+ end
75
+
76
+ context "with a json body" do
77
+ let(:content_type) { "application/json" }
78
+ let(:body) { '{"a" : "body" }' }
79
+ let(:expected_body) { {"a" => "body"} }
80
+
81
+ it "extracts the body" do
82
+ expect(subject.request_as_hash_from(rack_env)).to eq expected_request
83
+ end
84
+ end
85
+
86
+
87
+ end
88
+ end
@@ -0,0 +1,142 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service/verification_get'
3
+
4
+ module Pact
5
+ module Consumer
6
+ describe VerificationGet do
7
+
8
+ let(:interaction_list) { instance_double("Pact::Consumer::InteractionList")}
9
+ let(:logger) { double("Logger").as_null_object }
10
+ let(:log_description) { "/log/pact.log" }
11
+
12
+ subject { VerificationGet.new('VerificationGet', logger, interaction_list, log_description) }
13
+
14
+ describe "request_path" do
15
+ it "is /interactions/verification" do
16
+ expect(subject.request_path).to eq '/interactions/verification'
17
+ end
18
+ end
19
+
20
+ describe "request_method" do
21
+ it "is GET" do
22
+ expect(subject.request_method).to eq 'GET'
23
+ end
24
+ end
25
+
26
+ describe "#respond" do
27
+ let(:env) { {
28
+ "QUERY_STRING" => "example_description=a description"
29
+ } }
30
+
31
+ before do
32
+ allow(interaction_list).to receive(:all_matched?).and_return(all_matched)
33
+ end
34
+
35
+ let(:response) { subject.respond env }
36
+
37
+ context "when all interactions have been matched" do
38
+ let(:all_matched) { true }
39
+
40
+ it "returns a 200 status" do
41
+ expect(response.first).to eq 200
42
+ end
43
+
44
+ it "returns a Content-Type of text/plain" do
45
+ expect(response[1]).to eq 'Content-Type' => 'text/plain'
46
+ end
47
+
48
+ it "returns a nice message" do
49
+ expect(response.last).to eq ['Interactions matched']
50
+ end
51
+
52
+ it "logs the success" do
53
+ expect(logger).to receive(:info).with(/Verifying - interactions matched.*a description/)
54
+ response
55
+ end
56
+ end
57
+
58
+ context "when all interactions not been matched" do
59
+ let(:all_matched) { false }
60
+ let(:failure_message) { "this is a failure message"}
61
+
62
+ before do
63
+ allow_any_instance_of(VerificationGet::FailureMessage).to receive(:to_s).and_return(failure_message)
64
+ end
65
+
66
+ it "returns a 500 status" do
67
+ expect(response.first).to eq 500
68
+ end
69
+
70
+ it "returns a Content-Type of text/plain" do
71
+ expect(response[1]).to eq 'Content-Type' => 'text/plain'
72
+ end
73
+
74
+ it "returns a message" do
75
+ expect(response.last.first).to include "Actual interactions do not match"
76
+ expect(response.last.first).to include failure_message
77
+ expect(response.last.first).to include log_description
78
+ end
79
+
80
+ it "logs the failure message" do
81
+ expect(logger).to receive(:warn).with(/Verifying - actual interactions do not match/)
82
+ expect(logger).to receive(:warn).with(failure_message)
83
+ response
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ describe "FailureMessage" do
91
+ let(:missing_interactions_summaries) { ["Blah", "Thing"]}
92
+ let(:interaction_mismatches_summaries) { []}
93
+ let(:unexpected_requests_summaries) { []}
94
+ let(:interaction_list) { instance_double("Pact::Consumer::InteractionList") }
95
+ subject { VerificationGet::FailureMessage.new(interaction_list).to_s }
96
+
97
+ before do
98
+ allow(interaction_list).to receive(:missing_interactions_summaries).and_return(missing_interactions_summaries)
99
+ allow(interaction_list).to receive(:interaction_mismatches_summaries).and_return(interaction_mismatches_summaries)
100
+ allow(interaction_list).to receive(:unexpected_requests_summaries).and_return(unexpected_requests_summaries)
101
+ end
102
+
103
+ context "with only a missing interactions" do
104
+
105
+ let(:expected_string) { <<-EOS
106
+ Missing requests:
107
+ \tBlah
108
+ \tThing
109
+
110
+ EOS
111
+ }
112
+ it "only includes missing interactions" do
113
+ expect(subject).to eq expected_string
114
+ end
115
+ end
116
+
117
+ context "with missing, mismatches and unexpected interactions" do
118
+
119
+ let(:interaction_mismatches_summaries) { ["wiffle"]}
120
+ let(:unexpected_requests_summaries) { ["moose"]}
121
+
122
+ let(:expected_string) { <<-EOS
123
+ Incorrect requests:
124
+ \twiffle
125
+
126
+ Missing requests:
127
+ \tBlah
128
+ \tThing
129
+
130
+ Unexpected requests:
131
+ \tmoose
132
+
133
+ EOS
134
+ }
135
+ it "includes all the things" do
136
+ expect(subject).to eq expected_string
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service_client'
3
+
4
+ module Pact
5
+ module Consumer
6
+ describe MockServiceClient do
7
+
8
+ subject { MockServiceClient.new(4444) }
9
+
10
+ let(:administration_headers) { {'X-Pact-Mock-Service' => 'true'} }
11
+
12
+ describe "#add_expected_interaction" do
13
+ let(:interaction) { InteractionFactory.create }
14
+ let(:request_body) { MockServiceInteractionExpectation.new(interaction).to_json }
15
+
16
+ context "when successful" do
17
+ let!(:post_interaction) do
18
+ stub_request(:post, "localhost:4444/interactions").
19
+ with(body: request_body, headers: administration_headers.merge('Content-Type' => "application/json")).
20
+ to_return(status: 200)
21
+ end
22
+
23
+ it "sets up the expected interaction on the mock server" do
24
+ subject.add_expected_interaction interaction
25
+ expect(post_interaction).to have_been_made
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ describe "#verify" do
32
+
33
+ context "when all interactions are successfully verified" do
34
+
35
+ let!(:get_verification) do
36
+ stub_request(:get, "localhost:4444/interactions/verification?example_description=some%20example").
37
+ with(headers: administration_headers).
38
+ to_return(status: 200)
39
+ end
40
+
41
+ it "does not throw an error" do
42
+ subject.verify "some example"
43
+ expect(get_verification).to have_been_made
44
+ end
45
+ end
46
+ end
47
+
48
+ describe ".clear_interactions" do
49
+ let!(:delete_verifications) do
50
+ stub_request(:delete, "localhost:4444/interactions?example_description=some%20example").
51
+ with(headers: administration_headers).
52
+ to_return(status: 200)
53
+ end
54
+
55
+ it "deletes the interactions" do
56
+ MockServiceClient.clear_interactions 4444, "some example"
57
+ expect(delete_verifications).to have_been_made
58
+ end
59
+ end
60
+
61
+ describe "#write_pact" do
62
+ let(:consumer_contract_details) { {consumer: {name: 'Consumer'}, provider: {name: 'Provider'}, pactfile_write_mode: 'update'} }
63
+ let(:pact) { {a: 'pact'}.to_json }
64
+
65
+ let!(:post_pact) do
66
+ stub_request(:post, "localhost:4444/pact").
67
+ with(headers: administration_headers.merge('Content-Type' => "application/json"), body: consumer_contract_details).
68
+ to_return(status: 200, body: pact)
69
+ end
70
+
71
+ it "deletes the interactions" do
72
+ expect(subject.write_pact(consumer_contract_details)).to eq pact
73
+ expect(post_pact).to have_been_made
74
+ end
75
+
76
+ end
77
+
78
+ describe "#log" do
79
+ it "sends a log request to the mock server"
80
+ end
81
+
82
+ describe "#wait_for_interactions" do
83
+ it "waits until there are no missing interactions"
84
+ end
85
+ end
86
+ end
87
+ end
88
+
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer/mock_service_interaction_expectation'
3
+
4
+ describe Pact::Consumer::MockServiceInteractionExpectation do
5
+ describe "as_json" do
6
+
7
+ let(:options ) { {} }
8
+ let(:request_as_json) { {a: 'request'} }
9
+ let(:request) { instance_double('Pact::Request::Expected', :as_json => request_as_json, :options => options)}
10
+ let(:response) { double('response') }
11
+ let(:generated_response ) { double('generated_response', :to_json => 'generated_response') }
12
+ let(:interaction) { instance_double('Pact::Interaction', :description => 'description', :request => request, :response => response, :provider_state => 'some state') }
13
+ subject { described_class.new(interaction)}
14
+ let(:expected_hash) { {:response => generated_response, :request => as_json_with_options, :description => '' } }
15
+
16
+ before do
17
+ allow(Pact::Reification).to receive(:from_term).with(response).and_return(generated_response)
18
+ end
19
+
20
+ it "includes the response" do
21
+ expect(subject.as_json[:response]).to eq response
22
+ end
23
+
24
+ it "includes the options in the request" do
25
+ expect(subject.as_json[:request]).to eq request_as_json
26
+ end
27
+
28
+ it "includes the provider state" do
29
+ expect(subject.as_json[:provider_state]).to eq 'some state'
30
+ end
31
+
32
+ it "includes the description" do
33
+ expect(subject.as_json[:description]).to eq 'description'
34
+ end
35
+
36
+ it "doesn't have any other keys" do
37
+ expect(subject.as_json.keys).to eq [:description, :provider_state, :request, :response]
38
+ end
39
+
40
+ context "without options" do
41
+ it "does not include the options key" do
42
+ expect(subject.as_json.key?(:options)).to be false
43
+ end
44
+ end
45
+
46
+ context "with options" do
47
+ let(:options) { {:opts => 'blah'} }
48
+ it "includes the options in the request hash" do
49
+ expect(subject.as_json[:request][:options]).to eq options
50
+ end
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ module Pact
4
+ describe ServiceConsumer do
5
+ describe "as_json" do
6
+ it "returns a hash representation of the object" do
7
+ expect(ServiceConsumer.new(:name => "Bob").as_json).to eq :name => "Bob"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+ require 'pact/consumer_contract/consumer_contract_writer'
3
+
4
+ module Pact
5
+
6
+ describe ConsumerContractWriter do
7
+
8
+ let(:support_pact_file) { './spec/support/a_consumer-a_provider.json' }
9
+ let(:consumer_name) { 'a consumer' }
10
+ let(:provider_name) { 'a provider' }
11
+
12
+ before do
13
+ Pact.clear_configuration
14
+ allow(Pact.configuration).to receive(:pact_dir).and_return(File.expand_path(tmp_pact_dir))
15
+ FileUtils.rm_rf tmp_pact_dir
16
+ FileUtils.mkdir_p tmp_pact_dir
17
+ FileUtils.cp support_pact_file, "#{tmp_pact_dir}/a_consumer-a_provider.json"
18
+ end
19
+
20
+ let(:existing_interactions) { ConsumerContract.from_json(File.read(support_pact_file)).interactions }
21
+ let(:new_interactions) { [InteractionFactory.create] }
22
+ let(:tmp_pact_dir) {"./tmp/pacts"}
23
+ let(:logger) { double("logger").as_null_object }
24
+ let(:pactfile_write_mode) {:overwrite}
25
+ let(:consumer_contract_details) {
26
+ {
27
+ consumer: {name: consumer_name},
28
+ provider: {name: provider_name},
29
+ pactfile_write_mode: pactfile_write_mode,
30
+ interactions: new_interactions
31
+ }
32
+ }
33
+
34
+ let(:consumer_contract_writer) { ConsumerContractWriter.new(consumer_contract_details, logger) }
35
+
36
+ describe "consumer_contract" do
37
+
38
+ let(:subject) { consumer_contract_writer.consumer_contract }
39
+
40
+ context "when overwriting pact" do
41
+
42
+ it "it uses only the interactions from the current test run" do
43
+ expect(consumer_contract_writer.consumer_contract.interactions).to eq new_interactions
44
+ end
45
+
46
+ end
47
+
48
+ context "when updating pact" do
49
+
50
+ let(:pactfile_write_mode) {:update}
51
+
52
+ it "merges the interactions from the current test run with the interactions from the existing file" do
53
+ allow_any_instance_of(ConsumerContractWriter).to receive(:info_and_puts)
54
+ expect(consumer_contract_writer.consumer_contract.interactions).to eq existing_interactions + new_interactions
55
+ end
56
+
57
+ let(:line0) { /\*/ }
58
+ let(:line1) { /Updating existing file/ }
59
+ let(:line2) { /Only interactions defined in this test run will be updated/ }
60
+ let(:line3) { /As interactions are identified by description and provider state/ }
61
+
62
+ it "logs a description message" do
63
+ expect($stdout).to receive(:puts).with(line0).twice
64
+ expect($stdout).to receive(:puts).with(line1)
65
+ expect($stdout).to receive(:puts).with(line2)
66
+ expect($stdout).to receive(:puts).with(line3)
67
+ expect(logger).to receive(:info).with(line0).twice
68
+ expect(logger).to receive(:info).with(line1)
69
+ expect(logger).to receive(:info).with(line2)
70
+ expect(logger).to receive(:info).with(line3)
71
+ consumer_contract_writer.consumer_contract
72
+ end
73
+ end
74
+
75
+ context "when an error occurs deserializing the existing pactfile" do
76
+
77
+ let(:pactfile_write_mode) {:update}
78
+ let(:error) { RuntimeError.new('some error')}
79
+ let(:line1) { /Could not load existing consumer contract from .* due to some error/ }
80
+ let(:line2) {'Creating a new file.'}
81
+
82
+ before do
83
+ allow(ConsumerContract).to receive(:from_json).and_raise(error)
84
+ allow($stderr).to receive(:puts)
85
+ allow(logger).to receive(:puts)
86
+ end
87
+
88
+ it "logs the error" do
89
+ expect($stderr).to receive(:puts).with(line1)
90
+ expect($stderr).to receive(:puts).with(line2)
91
+ expect(logger).to receive(:warn).with(line1)
92
+ expect(logger).to receive(:warn).with(line2)
93
+ consumer_contract_writer.consumer_contract
94
+ end
95
+
96
+ it "uses the new interactions" do
97
+ expect(consumer_contract_writer.consumer_contract.interactions).to eq new_interactions
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "write" do
103
+ it "writes the pact file" do
104
+ expect_any_instance_of(ConsumerContract).to receive(:update_pactfile)
105
+ consumer_contract_writer.write
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end
@@ -0,0 +1,16 @@
1
+ require 'rspec'
2
+ require 'fakefs/spec_helpers'
3
+ require 'rspec'
4
+ require 'pact/support'
5
+ require 'webmock/rspec'
6
+ require 'support/factories'
7
+ require 'support/spec_support'
8
+
9
+ WebMock.disable_net_connect!(allow_localhost: true)
10
+
11
+ require './spec/support/active_support_if_configured'
12
+
13
+ RSpec.configure do | config |
14
+ config.include(FakeFS::SpecHelpers, :fakefs => true)
15
+ end
16
+
@@ -0,0 +1,32 @@
1
+ {
2
+ "producer": {
3
+ "name": "an old producer"
4
+ },
5
+ "consumer": {
6
+ "name": "a consumer"
7
+ },
8
+ "interactions": [
9
+ {
10
+ "description": "request one",
11
+ "request": {
12
+ "method": "get",
13
+ "path": "/path_one"
14
+ },
15
+ "response": {
16
+ },
17
+ "producer_state": "state one"
18
+ },
19
+ {
20
+ "description": "request two",
21
+ "request": {
22
+ "method": "get",
23
+ "path": "/path_two"
24
+ },
25
+ "response": {
26
+ }
27
+ }
28
+ ],
29
+ "metadata": {
30
+ "pactSpecificationVersion": "1.0"
31
+ }
32
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "provider": {
3
+ "name": "a provider"
4
+ },
5
+ "consumer": {
6
+ "name": "a consumer"
7
+ },
8
+ "interactions": [
9
+ {
10
+ "description": "request one",
11
+ "request": {
12
+ "method": "get",
13
+ "path": "/path_one"
14
+ },
15
+ "response": {
16
+ },
17
+ "provider_state": "state one"
18
+ },
19
+ {
20
+ "description": "request two",
21
+ "request": {
22
+ "method": "get",
23
+ "path": "/path_two"
24
+ },
25
+ "response": {
26
+ }
27
+ }
28
+ ],
29
+ "metadata": {
30
+ "pactSpecificationVersion": "1.0"
31
+ }
32
+ }
@@ -0,0 +1,6 @@
1
+ if ENV['LOAD_ACTIVE_SUPPORT']
2
+ puts 'LOADING ACTIVE SUPPORT!!!! Hopefully it all still works'
3
+ require 'active_support/all'
4
+ require 'active_support'
5
+ require 'active_support/json'
6
+ end
@@ -0,0 +1,4 @@
1
+ class AppForConfigRu
2
+ def call env
3
+ end
4
+ end