pact 1.1.1 → 1.2.1.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +42 -39
- data/README.md +2 -0
- data/documentation/configuration.md +2 -2
- data/documentation/faq.md +5 -7
- data/documentation/provider-states.md +2 -10
- data/example/animal-service/spec/service_consumers/pact_helper.rb +0 -4
- data/lib/pact/consumer/configuration/mock_service.rb +2 -0
- data/lib/pact/consumer/consumer_contract_builder.rb +58 -58
- data/lib/pact/consumer/mock_service/app.rb +4 -1
- data/lib/pact/consumer/mock_service/interaction_replay.rb +11 -3
- data/lib/pact/consumer/mock_service/missing_interactions_get.rb +2 -2
- data/lib/pact/consumer/mock_service/pact_post.rb +33 -0
- data/lib/pact/consumer/mock_service/verification_get.rb +1 -2
- data/lib/pact/consumer/mock_service_client.rb +14 -5
- data/lib/pact/consumer/mock_service_interaction_expectation.rb +1 -1
- data/lib/pact/consumer/spec_hooks.rb +2 -0
- data/lib/pact/consumer/world.rb +25 -0
- data/lib/pact/consumer_contract/consumer_contract.rb +1 -1
- data/lib/pact/consumer_contract/consumer_contract_writer.rb +84 -0
- data/lib/pact/consumer_contract/file_name.rb +7 -1
- data/lib/pact/provider/pact_helper_locator.rb +1 -1
- data/lib/pact/provider/pact_spec_runner.rb +3 -9
- data/lib/pact/provider/rspec/{formatter.rb → formatter_rspec_2.rb} +2 -2
- data/lib/pact/provider/rspec/formatter_rspec_3.rb +96 -0
- data/lib/pact/provider/rspec/matchers.rb +79 -19
- data/lib/pact/provider/rspec.rb +3 -1
- data/lib/pact/provider/state/provider_state_configured_modules.rb +6 -0
- data/lib/pact/provider/state/provider_state_manager.rb +3 -3
- data/lib/pact/provider/world.rb +2 -8
- data/lib/pact/rspec.rb +32 -0
- data/lib/pact/version.rb +1 -1
- data/pact.gemspec +3 -3
- data/spec/features/consumption_spec.rb +6 -1
- data/spec/integration/consumer_spec.rb +16 -9
- data/spec/integration/pact/consumer_configuration_spec.rb +7 -22
- data/spec/lib/pact/app_spec.rb +5 -5
- data/spec/lib/pact/configuration_spec.rb +1 -1
- data/spec/lib/pact/consumer/app_manager_spec.rb +3 -3
- data/spec/lib/pact/consumer/configuration_spec.rb +11 -8
- data/spec/lib/pact/consumer/consumer_contract_builder_spec.rb +3 -101
- data/spec/lib/pact/consumer/interaction_builder_spec.rb +8 -8
- data/spec/lib/pact/consumer/mock_service/app_spec.rb +2 -2
- data/spec/lib/pact/consumer/mock_service/interaction_mismatch_spec.rb +2 -2
- data/spec/lib/pact/consumer/mock_service/interaction_replay_spec.rb +12 -0
- data/spec/lib/pact/consumer/mock_service/verification_get_spec.rb +2 -2
- data/spec/lib/pact/consumer/mock_service_client_spec.rb +88 -0
- data/spec/lib/pact/consumer/mock_service_interaction_expectation_spec.rb +4 -4
- data/spec/lib/pact/consumer_contract/consumer_contract_spec.rb +18 -18
- data/spec/lib/pact/consumer_contract/consumer_contract_writer_spec.rb +111 -0
- data/spec/lib/pact/provider/configuration/pact_verification_spec.rb +1 -1
- data/spec/lib/pact/provider/pact_helper_locator_spec.rb +2 -2
- data/spec/lib/pact/provider/rspec/{formatter_spec.rb → formatter_rspec_2_spec.rb} +14 -4
- data/spec/lib/pact/provider/rspec/formatter_rspec_3_spec.rb +72 -0
- data/spec/lib/pact/provider/rspec_spec.rb +3 -0
- data/spec/lib/pact/provider/state/provider_state_manager_spec.rb +1 -1
- data/spec/lib/pact/provider/state/provider_state_proxy_spec.rb +4 -4
- data/spec/lib/pact/provider/state/provider_state_spec.rb +7 -7
- data/spec/lib/pact/provider/world_spec.rb +8 -8
- data/spec/lib/pact/tasks/verification_task_spec.rb +2 -2
- data/spec/spec_helper.rb +2 -4
- data/spec/support/factories.rb +13 -13
- data/spec/support/spec_support.rb +10 -0
- data/spec/support/stubbing_using_allow.rb +0 -4
- data/tasks/pact-test.rake +12 -8
- metadata +27 -24
- data/bethtest.rb +0 -30
- data/lib/pact/provider/rspec/silent_json_formatter.rb +0 -18
- data/spec/support/stubbing.rb +0 -26
@@ -10,12 +10,14 @@ describe "consumer side" do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
let(:application) { double("App")}
|
13
|
+
let(:world) { Pact::Consumer::World.new }
|
13
14
|
|
14
15
|
before do
|
15
16
|
Pact.clear_configuration
|
16
17
|
Pact::Consumer::AppManager.instance.clear_all
|
17
|
-
#Don't want processes actually spawning
|
18
|
-
Pact::Consumer::AppRegistration.
|
18
|
+
# Don't want processes actually spawning
|
19
|
+
allow_any_instance_of(Pact::Consumer::AppRegistration).to receive(:spawn)
|
20
|
+
allow(Pact).to receive(:consumer_world).and_return(world)
|
19
21
|
|
20
22
|
my_app = application
|
21
23
|
|
@@ -40,40 +42,23 @@ describe "consumer side" do
|
|
40
42
|
|
41
43
|
end
|
42
44
|
|
43
|
-
describe "consumer" do
|
44
|
-
|
45
|
-
subject { TestHelper.new.my_service.consumer_contract.consumer }
|
46
|
-
|
47
|
-
it "should be configured" do
|
48
|
-
expect(subject).to be_instance_of Pact::ServiceConsumer
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should have the right name" do
|
52
|
-
expect(subject.name).to eq "My Consumer"
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should have registered the app" do
|
56
|
-
Pact::Consumer::AppManager.instance.app_registered_on?(1111).should be true
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
45
|
describe "providers" do
|
61
46
|
|
62
47
|
subject { TestHelper.new.my_service }
|
63
48
|
|
64
49
|
it "should have defined methods in MockServices for the providers" do
|
65
|
-
subject.
|
50
|
+
expect(subject).to be_instance_of(Pact::Consumer::ConsumerContractBuilder)
|
66
51
|
end
|
67
52
|
|
68
53
|
context "when standalone is true" do
|
69
54
|
it "is not registerd with the AppManager" do
|
70
|
-
Pact::Consumer::AppManager.instance.app_registered_on?(1234).
|
55
|
+
expect(Pact::Consumer::AppManager.instance.app_registered_on?(1234)).to eq false
|
71
56
|
end
|
72
57
|
end
|
73
58
|
|
74
59
|
context "when standalone is false" do
|
75
60
|
it "should register the MockServices on their given ports if they are not" do
|
76
|
-
Pact::Consumer::AppManager.instance.app_registered_on?(1235).
|
61
|
+
expect(Pact::Consumer::AppManager.instance.app_registered_on?(1235)).to eq true
|
77
62
|
end
|
78
63
|
end
|
79
64
|
end
|
data/spec/lib/pact/app_spec.rb
CHANGED
@@ -16,9 +16,9 @@ module Pact
|
|
16
16
|
|
17
17
|
context "when ENV variables are defined" do
|
18
18
|
before do
|
19
|
-
ENV.
|
20
|
-
ENV.
|
21
|
-
ENV.
|
19
|
+
allow(ENV).to receive(:[])
|
20
|
+
allow(ENV).to receive(:[]).with("PACT_DESCRIPTION").and_return(env_description)
|
21
|
+
allow(ENV).to receive(:[]).with("PACT_PROVIDER_STATE").and_return(env_provider_state)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "returns the env vars as regexes" do
|
@@ -34,8 +34,8 @@ module Pact
|
|
34
34
|
|
35
35
|
context "when provider state is an empty string" do
|
36
36
|
before do
|
37
|
-
ENV.
|
38
|
-
ENV.
|
37
|
+
allow(ENV).to receive(:[]).with(anything).and_return(nil)
|
38
|
+
allow(ENV).to receive(:[]).with("PACT_PROVIDER_STATE").and_return('')
|
39
39
|
end
|
40
40
|
|
41
41
|
it "returns a nil provider state so that it matches a nil provider state on the interaction" do
|
@@ -143,7 +143,7 @@ describe Pact do
|
|
143
143
|
context "when @pactfile_write_mode is :smart" do
|
144
144
|
before do
|
145
145
|
configuration.pactfile_write_mode = :smart
|
146
|
-
configuration.
|
146
|
+
expect(configuration).to receive(:is_rake_running?).and_return(is_rake_running)
|
147
147
|
end
|
148
148
|
context "when rake is running" do
|
149
149
|
let(:is_rake_running) { true }
|
@@ -8,20 +8,20 @@ module Pact::Consumer
|
|
8
8
|
|
9
9
|
describe "start_service_for" do
|
10
10
|
before do
|
11
|
-
AppRegistration.
|
11
|
+
allow_any_instance_of(AppRegistration).to receive(:spawn) # Don't want process actually spawning during the tests
|
12
12
|
end
|
13
13
|
let(:name) { 'some_service'}
|
14
14
|
context "for http://localhost" do
|
15
15
|
let(:url) { 'http://localhost:1234'}
|
16
16
|
it "starts a mock service at the given port on localhost" do
|
17
|
-
AppRegistration.
|
17
|
+
expect_any_instance_of(AppRegistration).to receive(:spawn)
|
18
18
|
AppManager.instance.register_mock_service_for name, url
|
19
19
|
AppManager.instance.spawn_all
|
20
20
|
end
|
21
21
|
|
22
22
|
it "registers the mock service as running on the given port" do
|
23
23
|
AppManager.instance.register_mock_service_for name, url
|
24
|
-
AppManager.instance.app_registered_on?(1234).
|
24
|
+
expect(AppManager.instance.app_registered_on?(1234)).to eq true
|
25
25
|
end
|
26
26
|
end
|
27
27
|
context "for https://" do
|
@@ -4,9 +4,12 @@ require 'pact/consumer/configuration'
|
|
4
4
|
module Pact::Consumer::Configuration
|
5
5
|
|
6
6
|
describe MockService do
|
7
|
+
|
8
|
+
let(:world) { Pact::Consumer::World.new }
|
7
9
|
before do
|
8
10
|
Pact.clear_configuration
|
9
|
-
Pact::Consumer::AppManager.instance.
|
11
|
+
allow(Pact::Consumer::AppManager.instance).to receive(:register_mock_service_for)
|
12
|
+
allow(Pact).to receive(:consumer_world).and_return(world)
|
10
13
|
end
|
11
14
|
|
12
15
|
describe "configure_consumer_contract_builder" do
|
@@ -19,20 +22,20 @@ module Pact::Consumer::Configuration
|
|
19
22
|
end
|
20
23
|
}
|
21
24
|
|
22
|
-
let(:provider_name) { 'Mock Provider'}
|
23
|
-
let(:consumer_contract_builder) { instance_double('Pact::Consumer::ConsumerContractBuilder')}
|
24
|
-
let(:url) { "http://localhost:1234"}
|
25
|
+
let(:provider_name) { 'Mock Provider' }
|
26
|
+
let(:consumer_contract_builder) { instance_double('Pact::Consumer::ConsumerContractBuilder') }
|
27
|
+
let(:url) { "http://localhost:1234" }
|
25
28
|
|
26
29
|
it "adds a verification to the Pact configuration" do
|
27
|
-
Pact::Consumer::ConsumerContractBuilder.
|
30
|
+
allow(Pact::Consumer::ConsumerContractBuilder).to receive(:new).and_return(consumer_contract_builder)
|
28
31
|
subject.finalize
|
29
|
-
consumer_contract_builder.
|
32
|
+
expect(consumer_contract_builder).to receive(:verify)
|
30
33
|
Pact.configuration.provider_verifications.first.call
|
31
34
|
end
|
32
35
|
|
33
36
|
context "when standalone" do
|
34
37
|
it "does not register the app with the AppManager" do
|
35
|
-
Pact::Consumer::AppManager.instance.
|
38
|
+
expect(Pact::Consumer::AppManager.instance).to_not receive(:register_mock_service_for)
|
36
39
|
subject.finalize
|
37
40
|
end
|
38
41
|
end
|
@@ -45,7 +48,7 @@ module Pact::Consumer::Configuration
|
|
45
48
|
end
|
46
49
|
}
|
47
50
|
it "registers the app with the AppManager" do
|
48
|
-
Pact::Consumer::AppManager.instance.
|
51
|
+
expect(Pact::Consumer::AppManager.instance).to receive(:register_mock_service_for).with(provider_name, url)
|
49
52
|
subject.finalize
|
50
53
|
end
|
51
54
|
end
|
@@ -9,98 +9,10 @@ module Pact
|
|
9
9
|
let(:consumer_name) { 'a consumer' }
|
10
10
|
let(:provider_name) { 'a provider' }
|
11
11
|
|
12
|
-
describe "initialize" do
|
13
|
-
SUPPORT_PACT_FILE = './spec/support/a_consumer-a_provider.json'
|
14
|
-
before do
|
15
|
-
Pact.clear_configuration
|
16
|
-
Pact.configuration.stub(:pact_dir).and_return(File.expand_path(tmp_pact_dir))
|
17
|
-
FileUtils.rm_rf tmp_pact_dir
|
18
|
-
FileUtils.mkdir_p tmp_pact_dir
|
19
|
-
FileUtils.cp SUPPORT_PACT_FILE, "#{tmp_pact_dir}/a_consumer-a_provider.json"
|
20
|
-
end
|
21
|
-
|
22
|
-
let(:expected_interactions) { ConsumerContract.from_json(File.read(SUPPORT_PACT_FILE)).interactions }
|
23
|
-
|
24
|
-
let(:tmp_pact_dir) {"./tmp/pacts"}
|
25
|
-
|
26
|
-
let(:consumer_contract_builder) {
|
27
|
-
Pact::Consumer::ConsumerContractBuilder.new(
|
28
|
-
:pactfile_write_mode => pactfile_write_mode,
|
29
|
-
:consumer_name => consumer_name,
|
30
|
-
:provider_name => provider_name,
|
31
|
-
:port => 1234)}
|
32
|
-
|
33
|
-
context "when overwriting pact" do
|
34
|
-
let(:pactfile_write_mode) {:overwrite}
|
35
|
-
it "it overwrites the existing pact file" do
|
36
|
-
expect(consumer_contract_builder.consumer_contract.interactions).to eq []
|
37
|
-
end
|
38
|
-
|
39
|
-
it "uses an DistinctInteractionsFilter to handle new interactions" do
|
40
|
-
Pact::Consumer::DistinctInteractionsFilter.should_receive(:new).with([])
|
41
|
-
consumer_contract_builder
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "when updating pact" do
|
46
|
-
before do
|
47
|
-
|
48
|
-
end
|
49
|
-
let(:pactfile_write_mode) {:update}
|
50
|
-
it "loads the interactions from the existing pact file" do
|
51
|
-
ConsumerContractBuilder.any_instance.stub(:info_and_puts)
|
52
|
-
expect(consumer_contract_builder.consumer_contract.interactions).to eq expected_interactions
|
53
|
-
end
|
54
|
-
|
55
|
-
it "uses an UpdatableInteractionsFilter to handle new interactions" do
|
56
|
-
ConsumerContractBuilder.any_instance.stub(:info_and_puts)
|
57
|
-
Pact::Consumer::UpdatableInteractionsFilter.should_receive(:new).with(expected_interactions)
|
58
|
-
consumer_contract_builder
|
59
|
-
end
|
60
|
-
|
61
|
-
let(:line0) { /\*/ }
|
62
|
-
let(:line1) { /Updating existing file/ }
|
63
|
-
let(:line2) { /Only interactions defined in this test run will be updated/ }
|
64
|
-
let(:line3) { /As interactions are identified by description and provider state/ }
|
65
|
-
it "logs a description message" do
|
66
|
-
$stdout.should_receive(:puts).with(line0).twice
|
67
|
-
$stdout.should_receive(:puts).with(line1)
|
68
|
-
$stdout.should_receive(:puts).with(line2)
|
69
|
-
$stdout.should_receive(:puts).with(line3)
|
70
|
-
Pact.configuration.logger.should_receive(:info).with(line0).twice
|
71
|
-
Pact.configuration.logger.should_receive(:info).with(line1)
|
72
|
-
Pact.configuration.logger.should_receive(:info).with(line2)
|
73
|
-
Pact.configuration.logger.should_receive(:info).with(line3)
|
74
|
-
consumer_contract_builder
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context "when an error occurs deserializing the existing pactfile" do
|
79
|
-
let(:pactfile_write_mode) {:update}
|
80
|
-
let(:error) { RuntimeError.new('some error')}
|
81
|
-
let(:line1) { /Could not load existing consumer contract from .* due to some error/ }
|
82
|
-
let(:line2) {'Creating a new file.'}
|
83
|
-
before do
|
84
|
-
ConsumerContract.stub(:from_json).and_raise(error)
|
85
|
-
$stderr.should_receive(:puts).with(line1)
|
86
|
-
$stderr.should_receive(:puts).with(line2)
|
87
|
-
Pact.configuration.logger.should_receive(:warn).with(line1)
|
88
|
-
Pact.configuration.logger.should_receive(:warn).with(line2)
|
89
|
-
end
|
90
|
-
it "logs the error" do
|
91
|
-
consumer_contract_builder
|
92
|
-
end
|
93
|
-
|
94
|
-
it "continues with a new file" do
|
95
|
-
expect(consumer_contract_builder.consumer_contract.interactions).to eq []
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
12
|
describe "handle_interaction_fully_defined" do
|
101
13
|
|
102
14
|
subject {
|
103
|
-
Pact::Consumer::ConsumerContractBuilder.new(
|
15
|
+
Pact::Consumer::ConsumerContractBuilder.new(:consumer_name => 'blah', :provider_name => 'blah', :port => 2222)
|
104
16
|
}
|
105
17
|
|
106
18
|
let(:interaction_hash) {
|
@@ -130,21 +42,11 @@ module Pact
|
|
130
42
|
|
131
43
|
it "posts the interaction with generated response to the mock service" do
|
132
44
|
subject.handle_interaction_fully_defined interaction
|
133
|
-
WebMock.
|
134
|
-
end
|
135
|
-
|
136
|
-
it "adds the interaction to the consumer contract" do
|
137
|
-
subject.handle_interaction_fully_defined interaction
|
138
|
-
expect(subject.consumer_contract.interactions).to eq [interaction]
|
139
|
-
end
|
140
|
-
|
141
|
-
it "updates the provider's pactfile" do
|
142
|
-
subject.consumer_contract.should_receive(:update_pactfile)
|
143
|
-
subject.handle_interaction_fully_defined interaction
|
45
|
+
expect(WebMock).to have_requested(:post, 'localhost:2222/interactions').with(body: interaction_json)
|
144
46
|
end
|
145
47
|
|
146
48
|
it "resets the interaction_builder to nil" do
|
147
|
-
subject.
|
49
|
+
expect(subject).to receive(:interaction_builder=).with(nil)
|
148
50
|
subject.handle_interaction_fully_defined interaction
|
149
51
|
end
|
150
52
|
end
|
@@ -9,20 +9,20 @@ module Pact
|
|
9
9
|
let(:interaction) { double('Interaction').as_null_object}
|
10
10
|
|
11
11
|
before do
|
12
|
-
Interaction.
|
12
|
+
expect(Interaction).to receive(:new).and_return(interaction)
|
13
13
|
end
|
14
14
|
|
15
15
|
describe "given" do
|
16
16
|
context "with a string provider state" do
|
17
17
|
it "sets the provider_state on the interaction" do
|
18
|
-
interaction.
|
18
|
+
expect(interaction).to receive(:provider_state=).with('blah')
|
19
19
|
subject.given('blah')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
context "with a symbol provider state" do
|
24
24
|
it "sets the provider_state on the interaction as a string" do
|
25
|
-
interaction.
|
25
|
+
expect(interaction).to receive(:provider_state=).with('some_symbol')
|
26
26
|
subject.given(:some_symbol)
|
27
27
|
end
|
28
28
|
end
|
@@ -34,7 +34,7 @@ module Pact
|
|
34
34
|
|
35
35
|
describe "upon_receiving" do
|
36
36
|
it "sets the description on the interaction" do
|
37
|
-
interaction.
|
37
|
+
expect(interaction).to receive(:description=).with('blah')
|
38
38
|
subject.upon_receiving('blah')
|
39
39
|
end
|
40
40
|
|
@@ -49,8 +49,8 @@ module Pact
|
|
49
49
|
let(:expected_request) { {an: 'expected_request'} }
|
50
50
|
|
51
51
|
it "sets the request on the interaction as a instance of Request::Expected" do
|
52
|
-
Pact::Request::Expected.
|
53
|
-
interaction.
|
52
|
+
expect(Pact::Request::Expected).to receive(:from_hash).with(request).and_return(expected_request)
|
53
|
+
expect(interaction).to receive(:request=).with(expected_request)
|
54
54
|
subject.with(request)
|
55
55
|
end
|
56
56
|
|
@@ -73,7 +73,7 @@ module Pact
|
|
73
73
|
end
|
74
74
|
|
75
75
|
it "sets the response on the interaction" do
|
76
|
-
interaction.
|
76
|
+
expect(interaction).to receive(:response=).with(response)
|
77
77
|
subject.will_respond_with(response)
|
78
78
|
end
|
79
79
|
|
@@ -82,7 +82,7 @@ module Pact
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it "invokes the 'on_interaction_fully_defined' callback" do
|
85
|
-
provider.
|
85
|
+
expect(provider).to receive(:callback).with(interaction)
|
86
86
|
subject.will_respond_with response
|
87
87
|
end
|
88
88
|
end
|
@@ -25,8 +25,8 @@ module Pact
|
|
25
25
|
let(:interaction_replay) { double(InteractionReplay, :match? => true)}
|
26
26
|
|
27
27
|
before do
|
28
|
-
InteractionReplay.
|
29
|
-
interaction_replay.
|
28
|
+
expect(InteractionReplay).to receive(:new).and_return(interaction_replay)
|
29
|
+
expect(interaction_replay).to receive(:respond).and_raise("an error")
|
30
30
|
end
|
31
31
|
|
32
32
|
subject { get "/" }
|
@@ -15,8 +15,8 @@ module Pact
|
|
15
15
|
let(:diff_2) { {} }
|
16
16
|
|
17
17
|
before do
|
18
|
-
expected_request_1.
|
19
|
-
expected_request_2.
|
18
|
+
allow(expected_request_1).to receive(:difference).with(actual_request).and_return(diff_1)
|
19
|
+
allow(expected_request_2).to receive(:difference).with(actual_request).and_return(diff_2)
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "short_summary" do
|
@@ -12,8 +12,8 @@ module Pact
|
|
12
12
|
subject { VerificationGet.new('VerificationGet', logger, interaction_list, log_description) }
|
13
13
|
|
14
14
|
describe "request_path" do
|
15
|
-
it "is /
|
16
|
-
expect(subject.request_path).to eq '/
|
15
|
+
it "is /interactions/verification" do
|
16
|
+
expect(subject.request_path).to eq '/interactions/verification'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -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
|
+
|
@@ -3,6 +3,7 @@ require 'pact/consumer/mock_service_interaction_expectation'
|
|
3
3
|
|
4
4
|
describe Pact::Consumer::MockServiceInteractionExpectation do
|
5
5
|
describe "as_json" do
|
6
|
+
|
6
7
|
let(:options ) { {} }
|
7
8
|
let(:request_as_json) { {a: 'request'} }
|
8
9
|
let(:request) { instance_double('Pact::Request::Expected', :as_json => request_as_json, :options => options)}
|
@@ -13,12 +14,11 @@ describe Pact::Consumer::MockServiceInteractionExpectation do
|
|
13
14
|
let(:expected_hash) { {:response => generated_response, :request => as_json_with_options, :description => '' } }
|
14
15
|
|
15
16
|
before do
|
16
|
-
Pact::Reification.
|
17
|
+
allow(Pact::Reification).to receive(:from_term).with(response).and_return(generated_response)
|
17
18
|
end
|
18
19
|
|
19
|
-
it "
|
20
|
-
|
21
|
-
expect(subject.as_json[:response]).to eq generated_response
|
20
|
+
it "includes the response" do
|
21
|
+
expect(subject.as_json[:response]).to eq response
|
22
22
|
end
|
23
23
|
|
24
24
|
it "includes the options in the request" do
|
@@ -12,7 +12,7 @@ module Pact
|
|
12
12
|
end
|
13
13
|
|
14
14
|
before do
|
15
|
-
DateTime.
|
15
|
+
allow(DateTime).to receive(:now).and_return(DateTime.strptime("2013-08-15T13:27:13+10:00"))
|
16
16
|
end
|
17
17
|
|
18
18
|
let(:service_consumer) { double('ServiceConsumer', :as_json => {:a => 'consumer'}) }
|
@@ -21,7 +21,7 @@ module Pact
|
|
21
21
|
let(:expected_as_json) { {:provider=>{:a=>"provider"}, :consumer=>{:a=>"consumer"}, :interactions=>[{:mock=>"interaction"}], :metadata=>{:pactSpecificationVersion=> "1.0.0" }} }
|
22
22
|
|
23
23
|
it "should return a hash representation of the Pact" do
|
24
|
-
pact.as_json.
|
24
|
+
expect(pact.as_json).to eq expected_as_json
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -32,43 +32,43 @@ module Pact
|
|
32
32
|
let(:string) { '{"interactions":[{"request": {"path":"/path", "method" : "get"}}], "consumer": {"name" : "Bob"} , "provider": {"name" : "Mary"} }' }
|
33
33
|
|
34
34
|
it "should create a Pact" do
|
35
|
-
loaded_pact.
|
35
|
+
expect(loaded_pact).to be_instance_of ConsumerContract
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should have interactions" do
|
39
|
-
loaded_pact.interactions.
|
39
|
+
expect(loaded_pact.interactions).to be_instance_of Array
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should have a consumer" do
|
43
|
-
loaded_pact.consumer.
|
43
|
+
expect(loaded_pact.consumer).to be_instance_of Pact::ServiceConsumer
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should have a provider" do
|
47
|
-
loaded_pact.provider.
|
47
|
+
expect(loaded_pact.provider).to be_instance_of Pact::ServiceProvider
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
context "with old 'producer' key" do
|
52
52
|
let(:string) { File.read('./spec/support/a_consumer-a_producer.json')}
|
53
53
|
it "should create a Pact" do
|
54
|
-
loaded_pact.
|
54
|
+
expect(loaded_pact).to be_instance_of ConsumerContract
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should have interactions" do
|
58
|
-
loaded_pact.interactions.
|
58
|
+
expect(loaded_pact.interactions).to be_instance_of Array
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should have a consumer" do
|
62
|
-
loaded_pact.consumer.
|
62
|
+
expect(loaded_pact.consumer).to be_instance_of Pact::ServiceConsumer
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should have a provider" do
|
66
|
-
loaded_pact.provider.
|
67
|
-
loaded_pact.provider.name.
|
66
|
+
expect(loaded_pact.provider).to be_instance_of Pact::ServiceProvider
|
67
|
+
expect(loaded_pact.provider.name).to eq "an old producer"
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should have a provider_state" do
|
71
|
-
loaded_pact.interactions.first.provider_state.
|
71
|
+
expect(loaded_pact.interactions.first.provider_state).to eq 'state one'
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -80,7 +80,7 @@ module Pact
|
|
80
80
|
subject { ConsumerContract.new(:interactions => [interaction], :consumer => consumer, :provider => provider) }
|
81
81
|
let(:criteria) { {:description => /blah/} }
|
82
82
|
before do
|
83
|
-
interaction.
|
83
|
+
expect(interaction).to receive(:matches_criteria?).with(criteria).and_return(matches)
|
84
84
|
end
|
85
85
|
context "by description" do
|
86
86
|
context "when no interactions are found" do
|
@@ -106,8 +106,8 @@ module Pact
|
|
106
106
|
let(:criteria) { {:description => /blah/} }
|
107
107
|
|
108
108
|
before do
|
109
|
-
interaction1.
|
110
|
-
interaction2.
|
109
|
+
expect(interaction1).to receive(:matches_criteria?).with(criteria).and_return(matches1)
|
110
|
+
expect(interaction2).to receive(:matches_criteria?).with(criteria).and_return(matches2)
|
111
111
|
end
|
112
112
|
|
113
113
|
subject { ConsumerContract.new(:interactions => [interaction1, interaction2], :consumer => consumer, :provider => provider) }
|
@@ -162,18 +162,18 @@ eos
|
|
162
162
|
let(:interactions) { [double("interaction", as_json: "something")]}
|
163
163
|
subject { ConsumerContract.new(:consumer => consumer, :provider => provider, :interactions => interactions) }
|
164
164
|
before do
|
165
|
-
Pact.configuration.
|
165
|
+
allow(Pact.configuration).to receive(:pact_dir).and_return(Pathname.new("./tmp/pactfiles"))
|
166
166
|
FileUtils.rm_rf pacts_dir
|
167
167
|
FileUtils.mkdir_p pacts_dir
|
168
168
|
subject.update_pactfile
|
169
169
|
end
|
170
170
|
|
171
171
|
it "should write to a file specified by the consumer and provider name" do
|
172
|
-
File.exist?(expected_pact_path).
|
172
|
+
expect(File.exist?(expected_pact_path)).to eq true
|
173
173
|
end
|
174
174
|
|
175
175
|
it "should write the interactions to the file" do
|
176
|
-
File.read(expected_pact_path).
|
176
|
+
expect(File.read(expected_pact_path)).to eql expected_pact_string.strip
|
177
177
|
end
|
178
178
|
end
|
179
179
|
end
|