pact-mock_service 0.2.4 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/pact/consumer/mock_service/set_location.rb +28 -0
- data/lib/pact/consumer_contract/consumer_contract_writer.rb +2 -2
- data/lib/pact/mock_service/app.rb +56 -0
- data/lib/pact/{consumer → mock_service}/app_manager.rb +4 -4
- data/lib/pact/{consumer/mock_service_client.rb → mock_service/client.rb} +2 -2
- data/lib/pact/mock_service/control_server/delegator.rb +1 -12
- data/lib/pact/mock_service/control_server/mock_service_creator.rb +1 -1
- data/lib/pact/mock_service/interactions/actual_interactions.rb +36 -0
- data/lib/pact/mock_service/interactions/candidate_interactions.rb +15 -0
- data/lib/pact/mock_service/interactions/expected_interactions.rb +18 -0
- data/lib/pact/mock_service/interactions/interaction_diff_message.rb +45 -0
- data/lib/pact/mock_service/interactions/interaction_mismatch.rb +74 -0
- data/lib/pact/mock_service/interactions/interactions_filter.rb +34 -0
- data/lib/pact/mock_service/interactions/verification.rb +48 -0
- data/lib/pact/mock_service/interactions/verified_interactions.rb +20 -0
- data/lib/pact/mock_service/logger.rb +27 -0
- data/lib/pact/mock_service/request_handlers/base_administration_request_handler.rb +42 -0
- data/lib/pact/mock_service/request_handlers/base_request_handler.rb +22 -0
- data/lib/pact/mock_service/request_handlers/index_get.rb +23 -0
- data/lib/pact/mock_service/request_handlers/interaction_delete.rb +36 -0
- data/lib/pact/mock_service/request_handlers/interaction_post.rb +41 -0
- data/lib/pact/mock_service/request_handlers/interaction_replay.rb +163 -0
- data/lib/pact/mock_service/request_handlers/interactions_put.rb +42 -0
- data/lib/pact/mock_service/request_handlers/log_get.rb +27 -0
- data/lib/pact/mock_service/request_handlers/missing_interactions_get.rb +33 -0
- data/lib/pact/mock_service/request_handlers/options.rb +42 -0
- data/lib/pact/mock_service/request_handlers/pact_post.rb +38 -0
- data/lib/pact/mock_service/request_handlers/verification_get.rb +72 -0
- data/lib/pact/mock_service/request_handlers.rb +40 -0
- data/lib/pact/mock_service/run.rb +14 -4
- data/lib/pact/mock_service/session.rb +70 -0
- data/lib/pact/mock_service/spawn.rb +26 -12
- data/lib/pact/mock_service/version.rb +1 -1
- data/lib/pact/mock_service.rb +2 -1
- metadata +29 -24
- data/lib/pact/consumer/interactions_filter.rb +0 -32
- data/lib/pact/consumer/mock_service/actual_interactions.rb +0 -34
- data/lib/pact/consumer/mock_service/app.rb +0 -58
- data/lib/pact/consumer/mock_service/candidate_interactions.rb +0 -13
- data/lib/pact/consumer/mock_service/expected_interactions.rb +0 -17
- data/lib/pact/consumer/mock_service/index_get.rb +0 -22
- data/lib/pact/consumer/mock_service/interaction_delete.rb +0 -39
- data/lib/pact/consumer/mock_service/interaction_mismatch.rb +0 -73
- data/lib/pact/consumer/mock_service/interaction_post.rb +0 -95
- data/lib/pact/consumer/mock_service/interaction_replay.rb +0 -162
- data/lib/pact/consumer/mock_service/log_get.rb +0 -28
- data/lib/pact/consumer/mock_service/missing_interactions_get.rb +0 -32
- data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +0 -40
- data/lib/pact/consumer/mock_service/options.rb +0 -43
- data/lib/pact/consumer/mock_service/pact_post.rb +0 -38
- data/lib/pact/consumer/mock_service/request_handlers.rb +0 -41
- data/lib/pact/consumer/mock_service/verification.rb +0 -46
- data/lib/pact/consumer/mock_service/verification_get.rb +0 -73
- data/lib/pact/consumer/mock_service/verified_interactions.rb +0 -18
- data/lib/pact/consumer/mock_service.rb +0 -43
@@ -1,5 +1,8 @@
|
|
1
|
-
require 'pact/
|
1
|
+
require 'pact/mock_service/app'
|
2
2
|
require 'pact/consumer/server'
|
3
|
+
require 'pact/consumer/mock_service/set_location'
|
4
|
+
|
5
|
+
# Starts a new MockService on a new Thread. Called by the Control Server.
|
3
6
|
|
4
7
|
module Pact
|
5
8
|
module MockService
|
@@ -19,7 +22,7 @@ module Pact
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def call
|
22
|
-
mock_service =
|
25
|
+
mock_service = build_app
|
23
26
|
start_mock_service mock_service, port
|
24
27
|
puts "Started mock service for #{provider} on #{port}"
|
25
28
|
mock_service
|
@@ -27,10 +30,13 @@ module Pact
|
|
27
30
|
|
28
31
|
private
|
29
32
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
def build_app
|
34
|
+
Pact::Consumer::SetLocation.new(mock_service, base_url)
|
35
|
+
end
|
36
|
+
|
37
|
+
def mock_service
|
38
|
+
Pact::MockService.new(
|
39
|
+
log_file: create_log_file,
|
34
40
|
name: name,
|
35
41
|
consumer: consumer,
|
36
42
|
provider: provider,
|
@@ -43,15 +49,15 @@ module Pact
|
|
43
49
|
Pact::Server.new(app, port, ssl: options[:ssl]).boot
|
44
50
|
end
|
45
51
|
|
46
|
-
def create_log_file
|
52
|
+
def create_log_file
|
47
53
|
FileUtils::mkdir_p options[:log_dir]
|
48
|
-
log = File.open(log_file_path
|
54
|
+
log = File.open(log_file_path, 'w')
|
49
55
|
log.sync = true
|
50
56
|
log
|
51
57
|
end
|
52
58
|
|
53
|
-
def log_file_name
|
54
|
-
lower_case_name =
|
59
|
+
def log_file_name
|
60
|
+
lower_case_name = name.downcase.gsub(/\s+/, '_')
|
55
61
|
if lower_case_name.include?('_service')
|
56
62
|
lower_case_name.gsub('_service', '_mock_service')
|
57
63
|
else
|
@@ -59,8 +65,16 @@ module Pact
|
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
62
|
-
def log_file_path
|
63
|
-
File.join(options[:log_dir], "#{log_file_name
|
68
|
+
def log_file_path
|
69
|
+
File.join(options[:log_dir], "#{log_file_name}.log")
|
70
|
+
end
|
71
|
+
|
72
|
+
def base_url
|
73
|
+
options[:ssl] ? "https://localhost:#{port}" : "http://localhost:#{port}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def name
|
77
|
+
"#{provider} mock service"
|
64
78
|
end
|
65
79
|
end
|
66
80
|
|
data/lib/pact/mock_service.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require 'pact/consumer/
|
1
|
+
require 'pact/consumer/app_manager'
|
2
|
+
require 'pact/mock_service/app'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact-mock_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Fraser
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2015-
|
15
|
+
date: 2015-02-04 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rack
|
@@ -251,39 +251,21 @@ extensions: []
|
|
251
251
|
extra_rdoc_files: []
|
252
252
|
files:
|
253
253
|
- bin/pact-mock-service
|
254
|
-
- lib/pact/consumer/app_manager.rb
|
255
|
-
- lib/pact/consumer/interactions_filter.rb
|
256
|
-
- lib/pact/consumer/mock_service/actual_interactions.rb
|
257
|
-
- lib/pact/consumer/mock_service/app.rb
|
258
|
-
- lib/pact/consumer/mock_service/candidate_interactions.rb
|
259
254
|
- lib/pact/consumer/mock_service/cors_origin_header_middleware.rb
|
260
255
|
- lib/pact/consumer/mock_service/error_handler.rb
|
261
|
-
- lib/pact/consumer/mock_service/expected_interactions.rb
|
262
|
-
- lib/pact/consumer/mock_service/index_get.rb
|
263
|
-
- lib/pact/consumer/mock_service/interaction_delete.rb
|
264
|
-
- lib/pact/consumer/mock_service/interaction_mismatch.rb
|
265
|
-
- lib/pact/consumer/mock_service/interaction_post.rb
|
266
|
-
- lib/pact/consumer/mock_service/interaction_replay.rb
|
267
|
-
- lib/pact/consumer/mock_service/log_get.rb
|
268
|
-
- lib/pact/consumer/mock_service/missing_interactions_get.rb
|
269
|
-
- lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb
|
270
|
-
- lib/pact/consumer/mock_service/options.rb
|
271
|
-
- lib/pact/consumer/mock_service/pact_post.rb
|
272
256
|
- lib/pact/consumer/mock_service/rack_request_helper.rb
|
273
|
-
- lib/pact/consumer/mock_service/
|
274
|
-
- lib/pact/consumer/mock_service/verification.rb
|
275
|
-
- lib/pact/consumer/mock_service/verification_get.rb
|
276
|
-
- lib/pact/consumer/mock_service/verified_interactions.rb
|
277
|
-
- lib/pact/consumer/mock_service.rb
|
278
|
-
- lib/pact/consumer/mock_service_client.rb
|
257
|
+
- lib/pact/consumer/mock_service/set_location.rb
|
279
258
|
- lib/pact/consumer/server.rb
|
280
259
|
- lib/pact/consumer_contract/consumer_contract_decorator.rb
|
281
260
|
- lib/pact/consumer_contract/consumer_contract_writer.rb
|
282
261
|
- lib/pact/consumer_contract/interaction_decorator.rb
|
283
262
|
- lib/pact/consumer_contract/request_decorator.rb
|
284
263
|
- lib/pact/consumer_contract/response_decorator.rb
|
264
|
+
- lib/pact/mock_service/app.rb
|
265
|
+
- lib/pact/mock_service/app_manager.rb
|
285
266
|
- lib/pact/mock_service/cli/pidfile.rb
|
286
267
|
- lib/pact/mock_service/cli.rb
|
268
|
+
- lib/pact/mock_service/client.rb
|
287
269
|
- lib/pact/mock_service/control_server/app.rb
|
288
270
|
- lib/pact/mock_service/control_server/delegator.rb
|
289
271
|
- lib/pact/mock_service/control_server/index.rb
|
@@ -292,12 +274,35 @@ files:
|
|
292
274
|
- lib/pact/mock_service/control_server/require_pacticipant_headers.rb
|
293
275
|
- lib/pact/mock_service/control_server/run.rb
|
294
276
|
- lib/pact/mock_service/interaction_decorator.rb
|
277
|
+
- lib/pact/mock_service/interactions/actual_interactions.rb
|
278
|
+
- lib/pact/mock_service/interactions/candidate_interactions.rb
|
279
|
+
- lib/pact/mock_service/interactions/expected_interactions.rb
|
280
|
+
- lib/pact/mock_service/interactions/interaction_diff_message.rb
|
281
|
+
- lib/pact/mock_service/interactions/interaction_mismatch.rb
|
282
|
+
- lib/pact/mock_service/interactions/interactions_filter.rb
|
283
|
+
- lib/pact/mock_service/interactions/verification.rb
|
284
|
+
- lib/pact/mock_service/interactions/verified_interactions.rb
|
285
|
+
- lib/pact/mock_service/logger.rb
|
295
286
|
- lib/pact/mock_service/request_decorator.rb
|
287
|
+
- lib/pact/mock_service/request_handlers/base_administration_request_handler.rb
|
288
|
+
- lib/pact/mock_service/request_handlers/base_request_handler.rb
|
289
|
+
- lib/pact/mock_service/request_handlers/index_get.rb
|
290
|
+
- lib/pact/mock_service/request_handlers/interaction_delete.rb
|
291
|
+
- lib/pact/mock_service/request_handlers/interaction_post.rb
|
292
|
+
- lib/pact/mock_service/request_handlers/interaction_replay.rb
|
293
|
+
- lib/pact/mock_service/request_handlers/interactions_put.rb
|
294
|
+
- lib/pact/mock_service/request_handlers/log_get.rb
|
295
|
+
- lib/pact/mock_service/request_handlers/missing_interactions_get.rb
|
296
|
+
- lib/pact/mock_service/request_handlers/options.rb
|
297
|
+
- lib/pact/mock_service/request_handlers/pact_post.rb
|
298
|
+
- lib/pact/mock_service/request_handlers/verification_get.rb
|
299
|
+
- lib/pact/mock_service/request_handlers.rb
|
296
300
|
- lib/pact/mock_service/response_decorator.rb
|
297
301
|
- lib/pact/mock_service/run.rb
|
298
302
|
- lib/pact/mock_service/server/restart.rb
|
299
303
|
- lib/pact/mock_service/server/spawn.rb
|
300
304
|
- lib/pact/mock_service/server/wait_for_server_up.rb
|
305
|
+
- lib/pact/mock_service/session.rb
|
301
306
|
- lib/pact/mock_service/spawn.rb
|
302
307
|
- lib/pact/mock_service/version.rb
|
303
308
|
- lib/pact/mock_service.rb
|
@@ -1,32 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# When running in pactfile_write_mode :overwrite, all interactions are cleared from the
|
3
|
-
# pact file, and all new interactions should be distinct (unique description and provider state).
|
4
|
-
# When running in pactfile_write_mode :update, an interaction with the same description
|
5
|
-
# and provider state as an existing one will just overwrite that one interaction.
|
6
|
-
#
|
7
|
-
|
8
|
-
module Pact
|
9
|
-
module Consumer
|
10
|
-
|
11
|
-
#TODO: think of a better word than filter
|
12
|
-
class InteractionsFilter
|
13
|
-
def initialize interactions = []
|
14
|
-
@interactions = interactions
|
15
|
-
end
|
16
|
-
|
17
|
-
def index_of interaction
|
18
|
-
@interactions.find_index{ |i| i.matches_criteria?(description: interaction.description, provider_state: interaction.provider_state)}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class UpdatableInteractionsFilter < InteractionsFilter
|
23
|
-
def << interaction
|
24
|
-
if (ndx = index_of(interaction))
|
25
|
-
@interactions[ndx] = interaction
|
26
|
-
else
|
27
|
-
@interactions << interaction
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/candidate_interactions'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
module Consumer
|
5
|
-
class ActualInteractions
|
6
|
-
|
7
|
-
attr_reader :matched_interactions, :interaction_mismatches, :unexpected_requests
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
clear
|
11
|
-
end
|
12
|
-
|
13
|
-
# For testing, sigh
|
14
|
-
def clear
|
15
|
-
@matched_interactions = []
|
16
|
-
@interaction_mismatches = []
|
17
|
-
@unexpected_requests = []
|
18
|
-
end
|
19
|
-
|
20
|
-
def register_matched interaction
|
21
|
-
@matched_interactions << interaction
|
22
|
-
end
|
23
|
-
|
24
|
-
def register_unexpected_request request
|
25
|
-
@unexpected_requests << request
|
26
|
-
end
|
27
|
-
|
28
|
-
def register_interaction_mismatch interaction_mismatch
|
29
|
-
@interaction_mismatches << interaction_mismatch
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'rack'
|
2
|
-
require 'uri'
|
3
|
-
require 'json'
|
4
|
-
require 'logger'
|
5
|
-
require 'pact/consumer/mock_service/cors_origin_header_middleware'
|
6
|
-
require 'pact/consumer/mock_service/request_handlers'
|
7
|
-
|
8
|
-
module Pact
|
9
|
-
module Consumer
|
10
|
-
class MockService
|
11
|
-
class App
|
12
|
-
|
13
|
-
def initialize options = {}
|
14
|
-
@name = options.fetch(:name, "MockService")
|
15
|
-
@logger = options.fetch(:logger)
|
16
|
-
expected_interactions = ExpectedInteractions.new
|
17
|
-
actual_interactions = ActualInteractions.new
|
18
|
-
verified_interactions = VerifiedInteractions.new
|
19
|
-
@consumer_contact_details = {
|
20
|
-
pact_dir: options[:pact_dir],
|
21
|
-
consumer: {name: options[:consumer]},
|
22
|
-
provider: {name: options[:provider]},
|
23
|
-
interactions: verified_interactions
|
24
|
-
}
|
25
|
-
|
26
|
-
@request_handlers = Pact::Consumer::MockService::RequestHandlers.new(@name, @logger, expected_interactions, actual_interactions, verified_interactions, options)
|
27
|
-
end
|
28
|
-
|
29
|
-
def call env
|
30
|
-
@request_handlers.call(env)
|
31
|
-
end
|
32
|
-
|
33
|
-
def shutdown
|
34
|
-
write_pact_if_configured
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def write_pact_if_configured
|
40
|
-
consumer_contract_writer = ConsumerContractWriter.new(@consumer_contact_details, StdoutLogger.new)
|
41
|
-
consumer_contract_writer.write if consumer_contract_writer.can_write?
|
42
|
-
end
|
43
|
-
|
44
|
-
def to_s
|
45
|
-
"#{@name} #{super.to_s}"
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
# Can't write to a file in a TRAP, might deadlock
|
51
|
-
class StdoutLogger
|
52
|
-
def info message
|
53
|
-
$stdout.puts "\n#{message}"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/candidate_interactions'
|
2
|
-
|
3
|
-
module Pact
|
4
|
-
module Consumer
|
5
|
-
class ExpectedInteractions < Array
|
6
|
-
|
7
|
-
def find_candidate_interactions actual_request
|
8
|
-
CandidateInteractions.new(
|
9
|
-
select do | interaction |
|
10
|
-
interaction.request.matches_route? actual_request
|
11
|
-
end
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/rack_request_helper'
|
2
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Consumer
|
6
|
-
|
7
|
-
class IndexGet < MockServiceAdministrationEndpoint
|
8
|
-
|
9
|
-
def request_path
|
10
|
-
''
|
11
|
-
end
|
12
|
-
|
13
|
-
def request_method
|
14
|
-
'GET'
|
15
|
-
end
|
16
|
-
|
17
|
-
def respond env
|
18
|
-
[200, {'Content-Type' => 'text/plain'}, ['Mock service running']]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/rack_request_helper'
|
2
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
3
|
-
|
4
|
-
module Pact
|
5
|
-
module Consumer
|
6
|
-
|
7
|
-
class InteractionDelete < MockServiceAdministrationEndpoint
|
8
|
-
|
9
|
-
include RackRequestHelper
|
10
|
-
|
11
|
-
attr_accessor :expected_interactions, :actual_interactions
|
12
|
-
|
13
|
-
def initialize name, logger, expected_interactions, actual_interactions
|
14
|
-
super name, logger
|
15
|
-
@expected_interactions = expected_interactions
|
16
|
-
@actual_interactions = actual_interactions
|
17
|
-
end
|
18
|
-
|
19
|
-
def request_path
|
20
|
-
'/interactions'
|
21
|
-
end
|
22
|
-
|
23
|
-
def request_method
|
24
|
-
'DELETE'
|
25
|
-
end
|
26
|
-
|
27
|
-
def respond env
|
28
|
-
expected_interactions.clear
|
29
|
-
actual_interactions.clear
|
30
|
-
logger.info "Cleared interactions before example \"#{example_description(env)}\""
|
31
|
-
[200, {}, ['Deleted interactions']]
|
32
|
-
end
|
33
|
-
|
34
|
-
def example_description env
|
35
|
-
params_hash(env).fetch('example_description', [])[0]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
module Pact
|
2
|
-
module Consumer
|
3
|
-
|
4
|
-
# Presents the differences between an actual request, and a list of
|
5
|
-
# expected interactions where the methods and paths match the actual request.
|
6
|
-
# This is used to display a helpful message to the user when a request
|
7
|
-
# comes in that doesn't match any of the expected interactions.
|
8
|
-
class InteractionMismatch
|
9
|
-
|
10
|
-
attr_accessor :candidate_interactions, :actual_request
|
11
|
-
|
12
|
-
# Assumes the method and path matches...
|
13
|
-
|
14
|
-
def initialize candidate_interactions, actual_request
|
15
|
-
@candidate_interactions = candidate_interactions
|
16
|
-
@actual_request = actual_request
|
17
|
-
@candiate_diffs = candidate_interactions.collect{ | candidate_interaction| CandidateDiff.new(candidate_interaction, actual_request)}
|
18
|
-
end
|
19
|
-
|
20
|
-
def to_hash
|
21
|
-
candiate_diffs.collect(&:to_hash)
|
22
|
-
end
|
23
|
-
|
24
|
-
def to_s
|
25
|
-
candiate_diffs.collect(&:to_s).join("\n")
|
26
|
-
end
|
27
|
-
|
28
|
-
def short_summary
|
29
|
-
mismatched_attributes = candiate_diffs.collect(&:mismatched_attributes).flatten.uniq.join(", ").reverse.sub(",", "dna ").reverse #OMG what a hack!
|
30
|
-
actual_request.method_and_path + " (request #{mismatched_attributes} did not match)"
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
attr_accessor :candiate_diffs
|
36
|
-
|
37
|
-
class CandidateDiff
|
38
|
-
|
39
|
-
attr_accessor :candidate_interaction, :actual_request
|
40
|
-
|
41
|
-
def initialize candidate_interaction, actual_request
|
42
|
-
@candidate_interaction = candidate_interaction
|
43
|
-
@actual_request = actual_request
|
44
|
-
end
|
45
|
-
|
46
|
-
def mismatched_attributes
|
47
|
-
diff.keys
|
48
|
-
end
|
49
|
-
|
50
|
-
def to_hash
|
51
|
-
summary = {:description => candidate_interaction.description}
|
52
|
-
summary[:provider_state] = candidate_interaction.provider_state if candidate_interaction.provider_state
|
53
|
-
summary.merge(diff)
|
54
|
-
end
|
55
|
-
|
56
|
-
def to_s
|
57
|
-
[
|
58
|
-
"Diff with interaction: #{candidate_interaction.description_with_provider_state_quoted}",
|
59
|
-
diff_formatter.call(diff, {colour: false})
|
60
|
-
].join("\n")
|
61
|
-
end
|
62
|
-
|
63
|
-
def diff_formatter
|
64
|
-
Pact.configuration.diff_formatter_for_content_type(candidate_interaction.request.content_type)
|
65
|
-
end
|
66
|
-
|
67
|
-
def diff
|
68
|
-
@diff ||= candidate_interaction.request.difference(actual_request)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'pact/consumer/mock_service/mock_service_administration_endpoint'
|
2
|
-
require 'pact/mock_service/interaction_decorator'
|
3
|
-
require 'pact/shared/json_differ'
|
4
|
-
|
5
|
-
module Pact
|
6
|
-
module Consumer
|
7
|
-
class InteractionPost < MockServiceAdministrationEndpoint
|
8
|
-
|
9
|
-
def initialize name, logger, expected_interactions, verified_interactions
|
10
|
-
super name, logger
|
11
|
-
@expected_interactions = expected_interactions
|
12
|
-
@verified_interactions = verified_interactions
|
13
|
-
end
|
14
|
-
|
15
|
-
def request_path
|
16
|
-
'/interactions'
|
17
|
-
end
|
18
|
-
|
19
|
-
def request_method
|
20
|
-
'POST'
|
21
|
-
end
|
22
|
-
|
23
|
-
def respond env
|
24
|
-
request_body = env['rack.input'].string
|
25
|
-
interaction = Interaction.from_hash(JSON.load(request_body)) # Load creates the Pact::XXX classes
|
26
|
-
|
27
|
-
if (previous_interaction = interaction_already_verified_with_same_description_and_provider_state_but_not_equal(interaction))
|
28
|
-
handle_almost_duplicate_interaction previous_interaction, interaction
|
29
|
-
else
|
30
|
-
add_expected_interaction request_body, interaction
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
attr_accessor :expected_interactions, :verified_interactions
|
37
|
-
|
38
|
-
def add_expected_interaction request_body, interaction
|
39
|
-
expected_interactions << interaction
|
40
|
-
logger.info "Registered expected interaction #{interaction.request.method_and_path}"
|
41
|
-
logger.debug JSON.pretty_generate JSON.parse(request_body)
|
42
|
-
[200, {}, ['Added interaction']]
|
43
|
-
end
|
44
|
-
|
45
|
-
def handle_almost_duplicate_interaction previous_interaction, interaction
|
46
|
-
message = InteractionDiffMessage.new(previous_interaction, interaction).to_s
|
47
|
-
logger.error message
|
48
|
-
[500, {}, [message]]
|
49
|
-
end
|
50
|
-
|
51
|
-
def interaction_already_verified_with_same_description_and_provider_state_but_not_equal interaction
|
52
|
-
other = verified_interactions.find_matching_description_and_provider_state interaction
|
53
|
-
other && other != interaction ? other : nil
|
54
|
-
end
|
55
|
-
|
56
|
-
class InteractionDiffMessage
|
57
|
-
|
58
|
-
def initialize previous_interaction, new_interaction
|
59
|
-
@previous_interaction = previous_interaction
|
60
|
-
@new_interaction = new_interaction
|
61
|
-
end
|
62
|
-
|
63
|
-
def to_s
|
64
|
-
"An interaction with same description (#{new_interaction.description.inspect}) and provider state (#{new_interaction.provider_state.inspect}) but a different #{differences} has already been used. Please use a different description or provider state."
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
attr_reader :previous_interaction, :new_interaction
|
70
|
-
|
71
|
-
def differences
|
72
|
-
diff = Pact::JsonDiffer.call(previous_interaction_hash, new_interaction_hash, allow_unexpected_keys: false)
|
73
|
-
diff.keys.collect do | parent_key |
|
74
|
-
diff[parent_key].keys.collect do | child_key |
|
75
|
-
"#{parent_key} #{child_key}"
|
76
|
-
end
|
77
|
-
end.flatten.join(", ").reverse.sub(",", "dna ").reverse
|
78
|
-
end
|
79
|
-
|
80
|
-
def previous_interaction_hash
|
81
|
-
raw_hash previous_interaction
|
82
|
-
end
|
83
|
-
|
84
|
-
def new_interaction_hash
|
85
|
-
raw_hash new_interaction
|
86
|
-
end
|
87
|
-
|
88
|
-
def raw_hash interaction
|
89
|
-
JSON.parse(Pact::MockService::InteractionDecorator.new(interaction).to_json)
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|