pact-mock_service 0.2.4 → 0.3.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/lib/pact/consumer/mock_service/set_location.rb +28 -0
  4. data/lib/pact/consumer_contract/consumer_contract_writer.rb +2 -2
  5. data/lib/pact/mock_service/app.rb +56 -0
  6. data/lib/pact/{consumer → mock_service}/app_manager.rb +4 -4
  7. data/lib/pact/{consumer/mock_service_client.rb → mock_service/client.rb} +2 -2
  8. data/lib/pact/mock_service/control_server/delegator.rb +1 -12
  9. data/lib/pact/mock_service/control_server/mock_service_creator.rb +1 -1
  10. data/lib/pact/mock_service/interactions/actual_interactions.rb +36 -0
  11. data/lib/pact/mock_service/interactions/candidate_interactions.rb +15 -0
  12. data/lib/pact/mock_service/interactions/expected_interactions.rb +18 -0
  13. data/lib/pact/mock_service/interactions/interaction_diff_message.rb +45 -0
  14. data/lib/pact/mock_service/interactions/interaction_mismatch.rb +74 -0
  15. data/lib/pact/mock_service/interactions/interactions_filter.rb +34 -0
  16. data/lib/pact/mock_service/interactions/verification.rb +48 -0
  17. data/lib/pact/mock_service/interactions/verified_interactions.rb +20 -0
  18. data/lib/pact/mock_service/logger.rb +27 -0
  19. data/lib/pact/mock_service/request_handlers/base_administration_request_handler.rb +42 -0
  20. data/lib/pact/mock_service/request_handlers/base_request_handler.rb +22 -0
  21. data/lib/pact/mock_service/request_handlers/index_get.rb +23 -0
  22. data/lib/pact/mock_service/request_handlers/interaction_delete.rb +36 -0
  23. data/lib/pact/mock_service/request_handlers/interaction_post.rb +41 -0
  24. data/lib/pact/mock_service/request_handlers/interaction_replay.rb +163 -0
  25. data/lib/pact/mock_service/request_handlers/interactions_put.rb +42 -0
  26. data/lib/pact/mock_service/request_handlers/log_get.rb +27 -0
  27. data/lib/pact/mock_service/request_handlers/missing_interactions_get.rb +33 -0
  28. data/lib/pact/mock_service/request_handlers/options.rb +42 -0
  29. data/lib/pact/mock_service/request_handlers/pact_post.rb +38 -0
  30. data/lib/pact/mock_service/request_handlers/verification_get.rb +72 -0
  31. data/lib/pact/mock_service/request_handlers.rb +40 -0
  32. data/lib/pact/mock_service/run.rb +14 -4
  33. data/lib/pact/mock_service/session.rb +70 -0
  34. data/lib/pact/mock_service/spawn.rb +26 -12
  35. data/lib/pact/mock_service/version.rb +1 -1
  36. data/lib/pact/mock_service.rb +2 -1
  37. metadata +29 -24
  38. data/lib/pact/consumer/interactions_filter.rb +0 -32
  39. data/lib/pact/consumer/mock_service/actual_interactions.rb +0 -34
  40. data/lib/pact/consumer/mock_service/app.rb +0 -58
  41. data/lib/pact/consumer/mock_service/candidate_interactions.rb +0 -13
  42. data/lib/pact/consumer/mock_service/expected_interactions.rb +0 -17
  43. data/lib/pact/consumer/mock_service/index_get.rb +0 -22
  44. data/lib/pact/consumer/mock_service/interaction_delete.rb +0 -39
  45. data/lib/pact/consumer/mock_service/interaction_mismatch.rb +0 -73
  46. data/lib/pact/consumer/mock_service/interaction_post.rb +0 -95
  47. data/lib/pact/consumer/mock_service/interaction_replay.rb +0 -162
  48. data/lib/pact/consumer/mock_service/log_get.rb +0 -28
  49. data/lib/pact/consumer/mock_service/missing_interactions_get.rb +0 -32
  50. data/lib/pact/consumer/mock_service/mock_service_administration_endpoint.rb +0 -40
  51. data/lib/pact/consumer/mock_service/options.rb +0 -43
  52. data/lib/pact/consumer/mock_service/pact_post.rb +0 -38
  53. data/lib/pact/consumer/mock_service/request_handlers.rb +0 -41
  54. data/lib/pact/consumer/mock_service/verification.rb +0 -46
  55. data/lib/pact/consumer/mock_service/verification_get.rb +0 -73
  56. data/lib/pact/consumer/mock_service/verified_interactions.rb +0 -18
  57. data/lib/pact/consumer/mock_service.rb +0 -43
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ebcb0082a273a588dcca76818918e469ad66fad1
4
- data.tar.gz: 0555f3c7bc6f652577e3efb3f96967fd203437f5
3
+ metadata.gz: fd03f421bbf55e3e676c14e1381c0b8276b65929
4
+ data.tar.gz: b083148cc1cc3d7ca79a2a42dc4b55b3b3129bf8
5
5
  SHA512:
6
- metadata.gz: ca2923d11a5d07fec5906ef98eb2300048d23247fff17efcbc99ea4c1706aec9f9116c346debaf8fdcbb19725ce36f5ce7719a4181764b71402d4d7298cb1155
7
- data.tar.gz: 368e8f6e568cbf212f5c6e64009b9cd0caa7832979025091ccd7676853aa4e413b1631a8ec92805b58cf59d0881a9c0a9f844ac368771d0449ebbd76073880e7
6
+ metadata.gz: 5d19c285a1b6c2d97ff25407ede34967c06471ae80f965ddc3cc1ca24e08b313bfaafca9ac7c49f711879e549fee6109aa653430bd063944e4d65c026d163237
7
+ data.tar.gz: ed483795cb21f664e482499f53b0fade46e774d978c051edbe906c9b4d5f464433523e6c22d17adcce9690c9a73a4fffde2cb5bba10d2cf4c84094e5050cab5e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@ Do this to generate your change history
2
2
 
3
3
  git log --pretty=format:' * %h - %s (%an, %ad)'
4
4
 
5
+ ### 0.3.0 (4 Feb 2015)
6
+
7
+ * 60869be - Refactor - moving classes from Pact::Consumer module into Pact::MockService module. (Beth Skurrie, Wed Feb 4 19:28:54 2015 +1100)
8
+ * 4ada4f0 - Added endpoint for PUT /interactions. Allow javascript client to set up all interactions at once and avoid callback hell. (Beth Skurrie, Thu Jan 29 21:48:00 2015 +1100)
9
+ * a329f49 - Add X-Pact-Mock-Service-Location header to all responses from the MockService (Beth Skurrie, Sun Jan 25 09:00:20 2015 +1100)
10
+
5
11
  ### 0.2.4 (24 Jan 2015)
6
12
 
7
13
  * b14050e - Add --ssl option for control server (Beth, Sat Jan 24 22:14:14 2015 +1100)
@@ -0,0 +1,28 @@
1
+ module Pact
2
+ module Consumer
3
+ class SetLocation
4
+
5
+ LOCATION = 'X-Pact-Mock-Service-Location'.freeze
6
+ HTTP_X_PACT_MOCK_SERVICE = 'HTTP_X_PACT_MOCK_SERVICE'
7
+
8
+ def initialize app, base_url
9
+ @app = app
10
+ @location_header = {LOCATION => base_url}.freeze
11
+ end
12
+
13
+ def call env
14
+ response = @app.call(env)
15
+ env[HTTP_X_PACT_MOCK_SERVICE] ? add_location_header_to_response(response) : response
16
+ end
17
+
18
+ def add_location_header_to_response response
19
+ [response.first, response[1].merge(@location_header), response.last]
20
+ end
21
+
22
+ def shutdown
23
+ @app.shutdown
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  require 'pact/consumer_contract'
2
- require 'pact/consumer/interactions_filter'
2
+ require 'pact/mock_service/interactions/interactions_filter'
3
3
  require 'pact/consumer_contract/file_name'
4
4
  require 'pact/consumer_contract/pact_file'
5
5
  require 'pact/consumer_contract/consumer_contract_decorator'
@@ -63,7 +63,7 @@ module Pact
63
63
  def interactions_for_new_consumer_contract
64
64
  if updating?
65
65
  merged_interactions = existing_interactions.dup
66
- filter = Consumer::UpdatableInteractionsFilter.new(merged_interactions)
66
+ filter = Pact::MockService::Interactions::UpdatableInteractionsFilter.new(merged_interactions)
67
67
  interactions.each {|i| filter << i }
68
68
  merged_interactions
69
69
  else
@@ -0,0 +1,56 @@
1
+ require 'rack'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'pact/mock_service/logger'
5
+ require 'pact/consumer/mock_service/cors_origin_header_middleware'
6
+ require 'pact/mock_service/request_handlers'
7
+ require 'pact/consumer/mock_service/error_handler'
8
+ require 'pact/mock_service/session'
9
+
10
+ module Pact
11
+ module MockService
12
+
13
+ def self.new *args
14
+ App.new(*args)
15
+ end
16
+
17
+ class App
18
+
19
+ def initialize options = {}
20
+ @name = options.fetch(:name, "MockService")
21
+ logger = Logger.from_options(options)
22
+ @session = Session.new(options.merge(logger: logger))
23
+ request_handlers = RequestHandlers.new(@name, logger, @session, options)
24
+ @app = Rack::Builder.app do
25
+ use Pact::Consumer::MockService::ErrorHandler, logger
26
+ use Pact::Consumer::CorsOriginHeaderMiddleware, options[:cors_enabled]
27
+ run request_handlers
28
+ end
29
+ end
30
+
31
+ def call env
32
+ @app.call env
33
+ end
34
+
35
+ def shutdown
36
+ write_pact_if_configured
37
+ end
38
+
39
+ def write_pact_if_configured
40
+ consumer_contract_writer = ConsumerContractWriter.new(@session.consumer_contract_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
+ end
48
+
49
+ # Can't write to a file in a TRAP, might deadlock
50
+ class StdoutLogger
51
+ def info message
52
+ $stdout.puts "\n#{message}"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -6,11 +6,11 @@ require 'find_a_port'
6
6
  require 'pact/logging'
7
7
  require 'pact/consumer/server'
8
8
  require 'singleton'
9
- require 'pact/consumer/mock_service'
9
+ require 'pact/mock_service/app'
10
10
  require 'find_a_port'
11
11
 
12
12
  module Pact
13
- module Consumer
13
+ module MockService
14
14
  class AppManager
15
15
 
16
16
  include Pact::Logging
@@ -27,7 +27,7 @@ module Pact
27
27
  raise "Currently only http is supported" unless uri.scheme == 'http'
28
28
  raise "Currently only services on localhost are supported" unless uri.host == 'localhost'
29
29
 
30
- register(MockService.new(log_file: create_log_file(name), name: name, pact_dir: pact_dir), uri.port)
30
+ register(Pact::MockService.new(log_file: create_log_file(name), name: name, pact_dir: pact_dir), uri.port)
31
31
  end
32
32
 
33
33
  def register(app, port = FindAPort.available_port)
@@ -133,7 +133,7 @@ module Pact
133
133
  end
134
134
 
135
135
  def is_a_mock_service?
136
- app.is_a? MockService
136
+ app.is_a? Pact::MockService::App
137
137
  end
138
138
 
139
139
  def to_s
@@ -2,8 +2,8 @@ require 'net/http'
2
2
  require 'pact/mock_service/interaction_decorator'
3
3
 
4
4
  module Pact
5
- module Consumer
6
- class MockServiceClient
5
+ module MockService
6
+ class Client
7
7
 
8
8
  MOCK_SERVICE_ADMINISTRATON_HEADERS = {'X-Pact-Mock-Service' => 'true'}
9
9
 
@@ -11,16 +11,13 @@ module Pact
11
11
 
12
12
  HTTP_X_PACT_CONSUMER = 'HTTP_X_PACT_CONSUMER'.freeze
13
13
  HTTP_X_PACT_PROVIDER = 'HTTP_X_PACT_PROVIDER'.freeze
14
- LOCATION = 'X-Pact-Mock-Service-Location'.freeze
15
14
  PACT_MOCK_SERVICE_HEADER = {'HTTP_X_PACT_MOCK_SERVICE' => 'true'}.freeze
16
15
  NOT_FOUND_RESPONSE = [404, {}, []].freeze
17
16
 
18
- def initialize app, base_url, consumer_name, provider_name
17
+ def initialize app, consumer_name, provider_name
19
18
  @app = app
20
- @base_url = base_url
21
19
  @consumer_name = consumer_name
22
20
  @provider_name = provider_name
23
- @location_header = {LOCATION => @base_url}.freeze
24
21
  end
25
22
 
26
23
  def call env
@@ -39,16 +36,8 @@ module Pact
39
36
  end
40
37
 
41
38
  def delegate env
42
- add_location_header_to_response(call_app(env))
43
- end
44
-
45
- def call_app env
46
39
  @app.call(env.merge(PACT_MOCK_SERVICE_HEADER))
47
40
  end
48
-
49
- def add_location_header_to_response response
50
- [response.first, response[1].merge(@location_header), response.last]
51
- end
52
41
  end
53
42
  end
54
43
  end
@@ -23,7 +23,7 @@ module Pact
23
23
  provider_name = env['HTTP_X_PACT_PROVIDER']
24
24
  port = FindAPort.available_port
25
25
  mock_service = Pact::MockService::Spawn.(consumer_name, provider_name, port, options)
26
- delegator = Delegator.new(mock_service, "http://localhost:#{port}", consumer_name, provider_name)
26
+ delegator = Delegator.new(mock_service, consumer_name, provider_name)
27
27
  @mock_services.add(delegator)
28
28
  response = delegator.call(env)
29
29
  response
@@ -0,0 +1,36 @@
1
+ require 'pact/mock_service/interactions/candidate_interactions'
2
+
3
+ module Pact
4
+ module MockService
5
+ module Interactions
6
+ class ActualInteractions
7
+
8
+ attr_reader :matched_interactions, :interaction_mismatches, :unexpected_requests
9
+
10
+ def initialize
11
+ clear
12
+ end
13
+
14
+ # For testing, sigh
15
+ def clear
16
+ @matched_interactions = []
17
+ @interaction_mismatches = []
18
+ @unexpected_requests = []
19
+ end
20
+
21
+ def register_matched interaction
22
+ @matched_interactions << interaction
23
+ end
24
+
25
+ def register_unexpected_request request
26
+ @unexpected_requests << request
27
+ end
28
+
29
+ def register_interaction_mismatch interaction_mismatch
30
+ @interaction_mismatches << interaction_mismatch
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ module Pact
2
+ module MockService
3
+ module Interactions
4
+ class CandidateInteractions < Array
5
+
6
+ def matching_interactions actual_request
7
+ select do | candidate_interaction |
8
+ candidate_interaction.request.matches? actual_request
9
+ end
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'pact/mock_service/interactions/candidate_interactions'
2
+
3
+ module Pact
4
+ module MockService
5
+ module Interactions
6
+ class ExpectedInteractions < Array
7
+
8
+ def find_candidate_interactions actual_request
9
+ Pact::MockService::Interactions::CandidateInteractions.new(
10
+ select do | interaction |
11
+ interaction.request.matches_route? actual_request
12
+ end
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ require 'pact/shared/json_differ'
2
+ require 'pact/mock_service/interaction_decorator'
3
+
4
+ module Pact
5
+ module MockService
6
+ module Interactions
7
+ class InteractionDiffMessage
8
+
9
+ def initialize previous_interaction, new_interaction
10
+ @previous_interaction = previous_interaction
11
+ @new_interaction = new_interaction
12
+ end
13
+
14
+ def to_s
15
+ "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."
16
+ end
17
+
18
+ private
19
+
20
+ attr_reader :previous_interaction, :new_interaction
21
+
22
+ def differences
23
+ diff = Pact::JsonDiffer.call(previous_interaction_hash, new_interaction_hash, allow_unexpected_keys: false)
24
+ diff.keys.collect do | parent_key |
25
+ diff[parent_key].keys.collect do | child_key |
26
+ "#{parent_key} #{child_key}"
27
+ end
28
+ end.flatten.join(", ").reverse.sub(",", "dna ").reverse
29
+ end
30
+
31
+ def previous_interaction_hash
32
+ raw_hash previous_interaction
33
+ end
34
+
35
+ def new_interaction_hash
36
+ raw_hash new_interaction
37
+ end
38
+
39
+ def raw_hash interaction
40
+ JSON.parse(Pact::MockService::InteractionDecorator.new(interaction).to_json)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,74 @@
1
+ module Pact
2
+ module MockService
3
+ module Interactions
4
+
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
74
+ end
@@ -0,0 +1,34 @@
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 MockService
10
+ module Interactions
11
+
12
+ #TODO: think of a better word than filter
13
+ class InteractionsFilter
14
+ def initialize interactions = []
15
+ @interactions = interactions
16
+ end
17
+
18
+ def index_of interaction
19
+ @interactions.find_index{ |i| i.matches_criteria?(description: interaction.description, provider_state: interaction.provider_state)}
20
+ end
21
+ end
22
+
23
+ class UpdatableInteractionsFilter < InteractionsFilter
24
+ def << interaction
25
+ if (ndx = index_of(interaction))
26
+ @interactions[ndx] = interaction
27
+ else
28
+ @interactions << interaction
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,48 @@
1
+ module Pact
2
+ module MockService
3
+ module Interactions
4
+ class Verification
5
+
6
+ def initialize expected_interactions, actual_interactions
7
+ @expected_interactions = expected_interactions
8
+ @actual_interactions = actual_interactions
9
+ end
10
+
11
+ def all_matched?
12
+ interaction_diffs.empty?
13
+ end
14
+
15
+ def interaction_diffs
16
+ {
17
+ :missing_interactions => missing_interactions_summaries,
18
+ :interaction_mismatches => interaction_mismatches_summaries,
19
+ :unexpected_requests => unexpected_requests_summaries
20
+ }.each_with_object({}) do | (key, value), hash |
21
+ hash[key] = value if value.any?
22
+ end
23
+ end
24
+
25
+ def missing_interactions_summaries
26
+ missing_interactions.collect(&:request).collect(&:method_and_path)
27
+ end
28
+
29
+ def interaction_mismatches_summaries
30
+ actual_interactions.interaction_mismatches.collect(&:short_summary)
31
+ end
32
+
33
+ def unexpected_requests_summaries
34
+ actual_interactions.unexpected_requests.collect(&:method_and_path)
35
+ end
36
+
37
+ def missing_interactions
38
+ expected_interactions - actual_interactions.matched_interactions - @actual_interactions.interaction_mismatches.collect(&:candidate_interactions).flatten
39
+ end
40
+
41
+ private
42
+
43
+ attr_reader :expected_interactions, :actual_interactions
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,20 @@
1
+ module Pact
2
+ module MockService
3
+ module Interactions
4
+ class VerifiedInteractions < Array
5
+
6
+ def << interaction
7
+ unless find_matching_description_and_provider_state interaction
8
+ super
9
+ end
10
+ end
11
+
12
+ def find_matching_description_and_provider_state interaction
13
+ find do |candidate_interaction|
14
+ candidate_interaction.matches_criteria?(description: interaction.description, provider_state: interaction.provider_state)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ require 'logger'
2
+
3
+ module Pact
4
+ module MockService
5
+ class Logger < ::Logger
6
+
7
+ attr_reader :description
8
+
9
+ def initialize stream
10
+ super stream
11
+ @description = if stream.is_a? File
12
+ File.absolute_path(stream).gsub(Dir.pwd + "/", '')
13
+ else
14
+ "standard out/err"
15
+ end
16
+ end
17
+
18
+ def self.from_options options
19
+ log_stream = options[:log_file] || $stdout
20
+ logger = new log_stream
21
+ logger.formatter = options[:log_formatter] if options[:log_formatter]
22
+ logger.level = Pact.configuration.logger.level
23
+ logger
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,42 @@
1
+ require 'pact/consumer/mock_service/rack_request_helper'
2
+ require 'pact/mock_service/request_handlers/base_request_handler'
3
+
4
+ module Pact
5
+ module MockService
6
+ module RequestHandlers
7
+ class BaseAdministrationRequestHandler < BaseRequestHandler
8
+
9
+ attr_accessor :logger, :name
10
+
11
+ def initialize name, logger
12
+ @name = name
13
+ @logger = logger
14
+ end
15
+
16
+ def match? env
17
+ has_mock_service_header?(env) && path_matches?(env) && method_matches?(env)
18
+ end
19
+
20
+ def has_mock_service_header? env
21
+ env['HTTP_X_PACT_MOCK_SERVICE']
22
+ end
23
+
24
+ def path_matches? env
25
+ env['PATH_INFO'].chomp("/") == request_path
26
+ end
27
+
28
+ def method_matches? env
29
+ env['REQUEST_METHOD'] == request_method
30
+ end
31
+
32
+ def request_path
33
+ raise NotImplementedError
34
+ end
35
+
36
+ def request_method
37
+ raise NotImplementedError
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ require 'pact/consumer/mock_service/rack_request_helper'
2
+
3
+ module Pact
4
+ module MockService
5
+ module RequestHandlers
6
+ class BaseRequestHandler
7
+
8
+ NOT_FOUND_RESPONSE = [404, {}, []].freeze
9
+
10
+ include Pact::Consumer::RackRequestHelper
11
+
12
+ def match? env
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def call env
17
+ match?(env) ? respond(env) : NOT_FOUND_RESPONSE
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ require 'pact/mock_service/request_handlers/base_administration_request_handler'
2
+
3
+ module Pact
4
+ module MockService
5
+ module RequestHandlers
6
+
7
+ class IndexGet < BaseAdministrationRequestHandler
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
23
+ end
@@ -0,0 +1,36 @@
1
+ require 'pact/mock_service/request_handlers/base_administration_request_handler'
2
+
3
+ module Pact
4
+ module MockService
5
+ module RequestHandlers
6
+
7
+ class InteractionDelete < BaseAdministrationRequestHandler
8
+
9
+ attr_accessor :session
10
+
11
+ def initialize name, logger, session
12
+ super name, logger
13
+ @session = session
14
+ end
15
+
16
+ def request_path
17
+ '/interactions'
18
+ end
19
+
20
+ def request_method
21
+ 'DELETE'
22
+ end
23
+
24
+ def respond env
25
+ session.clear_expected_and_actual_interactions
26
+ logger.info "Cleared interactions before example \"#{example_description(env)}\""
27
+ [200, {}, ['Deleted interactions']]
28
+ end
29
+
30
+ def example_description env
31
+ params_hash(env).fetch('example_description', [])[0]
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end