pact_broker 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +0 -1
  3. data/.rspec +1 -0
  4. data/CHANGELOG.md +47 -0
  5. data/README.md +4 -2
  6. data/config.ru +3 -5
  7. data/db/migrations/09_add_timestamps.rb +12 -0
  8. data/db/migrations/10_populate_timestamps.rb +15 -0
  9. data/db/migrations/11_made_timestamps_mandatory.rb +20 -0
  10. data/db/migrations/12_create_webhooks_table.rb +21 -0
  11. data/db/migrations/13_add_columns_to_webhooks.rb +8 -0
  12. data/lib/pact_broker/api.rb +14 -0
  13. data/lib/pact_broker/api/decorators.rb +2 -2
  14. data/lib/pact_broker/api/decorators/base_decorator.rb +2 -1
  15. data/lib/pact_broker/api/decorators/basic_pacticipant_decorator.rb +21 -0
  16. data/lib/pact_broker/api/decorators/decorator_context.rb +20 -0
  17. data/lib/pact_broker/api/decorators/latest_pact_decorator.rb +2 -2
  18. data/lib/pact_broker/api/decorators/pact_decorator.rb +12 -5
  19. data/lib/pact_broker/api/decorators/pact_details_decorator.rb +22 -0
  20. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +6 -4
  21. data/lib/pact_broker/api/decorators/relationships_csv_decorator.rb +25 -3
  22. data/lib/pact_broker/api/decorators/representable_pact.rb +3 -1
  23. data/lib/pact_broker/api/decorators/tag_decorator.rb +3 -0
  24. data/lib/pact_broker/api/decorators/webhook_decorator.rb +52 -0
  25. data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +58 -0
  26. data/lib/pact_broker/api/decorators/webhook_request_decorator.rb +18 -0
  27. data/lib/pact_broker/api/decorators/webhooks_decorator.rb +37 -0
  28. data/lib/pact_broker/api/pact_broker_urls.rb +16 -0
  29. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +2 -1
  30. data/lib/pact_broker/api/resources/base_resource.rb +12 -1
  31. data/lib/pact_broker/api/resources/group.rb +38 -0
  32. data/lib/pact_broker/api/resources/index.rb +30 -21
  33. data/lib/pact_broker/api/resources/latest_pact.rb +1 -1
  34. data/lib/pact_broker/api/resources/latest_pacts.rb +1 -1
  35. data/lib/pact_broker/api/resources/pact.rb +18 -2
  36. data/lib/pact_broker/api/resources/pact_webhooks.rb +87 -0
  37. data/lib/pact_broker/api/resources/pacticipant.rb +15 -6
  38. data/lib/pact_broker/api/resources/pacticipants.rb +1 -1
  39. data/lib/pact_broker/api/resources/tag.rb +2 -2
  40. data/lib/pact_broker/api/resources/webhook.rb +44 -0
  41. data/lib/pact_broker/api/resources/webhook_execution.rb +43 -0
  42. data/lib/pact_broker/api/resources/webhooks.rb +29 -0
  43. data/lib/pact_broker/app.rb +46 -8
  44. data/lib/pact_broker/db.rb +10 -0
  45. data/lib/pact_broker/doc/controllers/app.rb +32 -0
  46. data/lib/pact_broker/doc/views/latest-pacts.markdown +3 -0
  47. data/lib/pact_broker/doc/views/layouts/main.haml +5 -0
  48. data/lib/pact_broker/doc/views/pacticipants.markdown +10 -0
  49. data/lib/pact_broker/doc/views/self.markdown +8 -0
  50. data/lib/pact_broker/doc/views/webhooks.markdown +48 -0
  51. data/lib/pact_broker/functions/groupify.rb +39 -0
  52. data/lib/pact_broker/jobs/after_pact_save.rb +13 -0
  53. data/lib/pact_broker/json.rb +4 -0
  54. data/lib/pact_broker/locale/en.yml +23 -0
  55. data/lib/pact_broker/messages.rb +18 -0
  56. data/lib/pact_broker/models/group.rb +21 -0
  57. data/lib/pact_broker/models/pact.rb +4 -2
  58. data/lib/pact_broker/models/pacticipant.rb +3 -1
  59. data/lib/pact_broker/models/relationship.rb +34 -0
  60. data/lib/pact_broker/models/tag.rb +3 -1
  61. data/lib/pact_broker/models/version.rb +3 -1
  62. data/lib/pact_broker/models/webhook.rb +53 -0
  63. data/lib/pact_broker/models/webhook_execution_result.rb +26 -0
  64. data/lib/pact_broker/models/webhook_request.rb +107 -0
  65. data/lib/pact_broker/models/webhook_request_header.rb +13 -0
  66. data/lib/pact_broker/repositories.rb +6 -0
  67. data/lib/pact_broker/repositories/pact_repository.rb +25 -7
  68. data/lib/pact_broker/repositories/pacticipant_repository.rb +4 -0
  69. data/lib/pact_broker/repositories/webhook_repository.rb +134 -0
  70. data/lib/pact_broker/services.rb +10 -0
  71. data/lib/pact_broker/services/group_service.rb +24 -0
  72. data/lib/pact_broker/services/pact_service.rb +37 -7
  73. data/lib/pact_broker/services/pacticipant_service.rb +12 -1
  74. data/lib/pact_broker/services/webhook_service.rb +63 -0
  75. data/lib/pact_broker/tasks.rb +0 -1
  76. data/lib/pact_broker/ui/controllers/base_controller.rb +1 -0
  77. data/lib/pact_broker/ui/controllers/groups.rb +25 -0
  78. data/lib/pact_broker/ui/controllers/relationships.rb +0 -2
  79. data/lib/pact_broker/ui/helpers/url_helper.rb +17 -0
  80. data/lib/pact_broker/ui/view_models/relationship.rb +13 -4
  81. data/lib/pact_broker/ui/view_models/relationships.rb +1 -1
  82. data/lib/pact_broker/ui/views/groups/show.html.erb +409 -0
  83. data/lib/pact_broker/ui/views/relationships/show.haml +4 -2
  84. data/lib/pact_broker/version.rb +1 -1
  85. data/pact_broker.gemspec +7 -6
  86. data/public/{d3.v3.js.pagespeed.ce.dFNRrGTALe.js → javascripts/d3.v3.js.pagespeed.ce.dFNRrGTALe.js} +0 -0
  87. data/public/stylesheets/relationships.css +4 -0
  88. data/spec/integration/endpoints/group.rb +22 -0
  89. data/spec/lib/pact_broker/api/decorators/pact_decorator_spec.rb +49 -0
  90. data/spec/lib/pact_broker/api/decorators/pacticipant_decorator_spec.rb +25 -0
  91. data/spec/lib/pact_broker/api/decorators/relationships_csv_decorator_spec.rb +7 -4
  92. data/spec/lib/pact_broker/api/decorators/webhook_decorator_spec.rb +121 -0
  93. data/spec/lib/pact_broker/api/decorators/webhook_execution_result_decorator_spec.rb +69 -0
  94. data/spec/lib/pact_broker/api/decorators/webhook_request_decorator_spec.rb +78 -0
  95. data/spec/lib/pact_broker/api/decorators/webhooks_decorator_spec.rb +46 -0
  96. data/spec/lib/pact_broker/api/resources/group_spec.rb +80 -0
  97. data/spec/lib/pact_broker/api/resources/pact_spec.rb +41 -0
  98. data/spec/lib/pact_broker/api/resources/pact_webhooks_spec.rb +184 -0
  99. data/spec/lib/pact_broker/api/resources/pacticipant_spec.rb +71 -0
  100. data/spec/lib/pact_broker/api/resources/webhook_execution_spec.rb +77 -0
  101. data/spec/lib/pact_broker/api/resources/webhook_spec.rb +60 -0
  102. data/spec/lib/pact_broker/api/resources/webhooks_spec.rb +44 -0
  103. data/spec/lib/pact_broker/doc/controllers/app_spec.rb +51 -0
  104. data/spec/lib/pact_broker/functions/groupify_spec.rb +50 -0
  105. data/spec/lib/pact_broker/models/group_spec.rb +26 -0
  106. data/spec/lib/pact_broker/models/webhook_request_spec.rb +175 -0
  107. data/spec/lib/pact_broker/models/webhook_spec.rb +59 -0
  108. data/spec/lib/pact_broker/repositories/pact_repository_spec.rb +40 -0
  109. data/spec/lib/pact_broker/repositories/webhook_repository_spec.rb +257 -0
  110. data/spec/lib/pact_broker/services/group_service_spec.rb +52 -0
  111. data/spec/lib/pact_broker/services/pact_service_spec.rb +49 -0
  112. data/spec/lib/pact_broker/services/pacticipant_service_spec.rb +50 -0
  113. data/spec/lib/pact_broker/services/webhook_service_spec.rb +51 -0
  114. data/spec/lib/pact_broker/ui/view_models/relationship_spec.rb +20 -6
  115. data/spec/lib/pact_broker/ui/view_models/relationships_spec.rb +33 -0
  116. data/spec/service_consumers/provider_states_for_pact_broker_client.rb +1 -1
  117. data/spec/spec_helper.rb +11 -4
  118. data/spec/support/provider_state_builder.rb +11 -0
  119. data/spec/support/shared_examples_for_responses.rb +25 -0
  120. data/vendor/hal-browser/js/hal/views/embedded_resource.js +3 -3
  121. data/vendor/hal-browser/js/hal/views/resource.js +3 -3
  122. metadata +174 -80
  123. data/assets/d3.v3.js +0 -9263
  124. data/assets/force.csv +0 -29
  125. data/assets/index.html +0 -186
  126. data/assets/index2.html +0 -224
  127. data/assets/relationships +0 -4
  128. data/assets/stylesheets/github.css +0 -387
  129. data/lib/pact_broker/tasks/delete.rake +0 -20
  130. data/public/Network Graph REA.html +0 -48
  131. data/public/rea.csv +0 -10
@@ -0,0 +1,13 @@
1
+ module PactBroker
2
+ module Jobs
3
+ class AfterPactSave
4
+
5
+
6
+
7
+ def perform
8
+
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module PactBroker
3
+ PACT_PARSING_OPTIONS = { max_nesting: 50 }
4
+ end
@@ -0,0 +1,23 @@
1
+ en:
2
+ pact_broker:
3
+ errors:
4
+ validation:
5
+ attribute_missing: "Missing required attribute '%{attribute}'"
6
+ invalid_http_method: "Invalid HTTP method '%{method}'"
7
+ invalid_url: "Invalid URL '%{url}'. Expected format: http://example.org"
8
+ "400":
9
+ title: 400 Malformed Request
10
+ message: The request was malformed and could not be processed.
11
+ "404":
12
+ title: 404 Not Found
13
+ message: The requested document was not found on this server.
14
+ "500":
15
+ title: 500 Internal Server Error
16
+ message: "The server encountered an error while processing this request: <pre>%{error}</pre>"
17
+ "501":
18
+ title: 501 Not Implemented
19
+ message: "The server does not support the %{method} method."
20
+ "503":
21
+ title: 503 Service Unavailable
22
+ message: The server is currently unable to handle the request due to a temporary overloading or maintenance of the server.
23
+
@@ -0,0 +1,18 @@
1
+ require 'i18n'
2
+
3
+ I18n.config.load_path << File.expand_path("../locale/en.yml", __FILE__)
4
+
5
+ module PactBroker
6
+ # Provides an interface to the I18n library specifically for
7
+ # {Webmachine}'s messages.
8
+ module Messages
9
+ # Interpolates an internationalized string.
10
+ # @param [String] key the name of the string to interpolate
11
+ # @param [Hash] options options to pass to I18n, including
12
+ # variables to interpolate.
13
+ # @return [String] the interpolated string
14
+ def message(key, options={})
15
+ ::I18n.t(key, options.merge(:scope => :pact_broker))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require 'versionomy'
2
+
3
+ module PactBroker
4
+ module Models
5
+ class Group < Array
6
+
7
+ def initialize *relationships
8
+ self.concat relationships.flatten
9
+ end
10
+
11
+ def == other
12
+ Group === other && super
13
+ end
14
+
15
+ def include_pacticipant? pacticipant
16
+ any? { | relationship | relationship.include? pacticipant }
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -1,4 +1,4 @@
1
- require 'sequel'
1
+ require 'pact_broker/db'
2
2
 
3
3
  module PactBroker
4
4
 
@@ -19,12 +19,14 @@ module PactBroker
19
19
  end
20
20
 
21
21
  def to_s
22
- "Pact: provider_id=#{provider_id}"
22
+ "Pact: provider_id=#{provider_id} created_at=#{created_at} updated_at=#{updated_at}"
23
23
  end
24
24
 
25
25
  def to_json options = {}
26
26
  json_content
27
27
  end
28
28
  end
29
+
30
+ Pact.plugin :timestamps, :update_on_create=>true
29
31
  end
30
32
  end
@@ -1,4 +1,4 @@
1
- require 'sequel'
1
+ require 'pact_broker/db'
2
2
 
3
3
  module PactBroker
4
4
 
@@ -19,5 +19,7 @@ module PactBroker
19
19
  "Pacticipant: id=#{id}, name=#{name}"
20
20
  end
21
21
  end
22
+
23
+ Pacticipant.plugin :timestamps, :update_on_create=>true
22
24
  end
23
25
  end
@@ -22,6 +22,40 @@ module PactBroker
22
22
  eq?(other)
23
23
  end
24
24
 
25
+ def consumer_name
26
+ consumer.name
27
+ end
28
+
29
+ def provider_name
30
+ provider.name
31
+ end
32
+
33
+ def pacticipants
34
+ [consumer, provider]
35
+ end
36
+
37
+ def connected? other
38
+ (self.to_a & other.to_a).any?
39
+ end
40
+
41
+ def include? pacticipant
42
+ pacticipant.id == consumer.id || pacticipant.id == provider.id
43
+ end
44
+
45
+ def <=> other
46
+ comp = consumer_name <=> other.consumer_name
47
+ return comp unless comp == 0
48
+ provider_name <=> other.provider_name
49
+ end
50
+
51
+ def to_s
52
+ "Relationship between #{consumer_name} and #{provider_name}"
53
+ end
54
+
55
+ def to_a
56
+ [consumer, provider]
57
+ end
58
+
25
59
  end
26
60
  end
27
61
  end
@@ -1,4 +1,4 @@
1
- require 'sequel'
1
+ require 'pact_broker/db'
2
2
 
3
3
  module PactBroker
4
4
 
@@ -11,5 +11,7 @@ module PactBroker
11
11
 
12
12
 
13
13
  end
14
+
15
+ Tag.plugin :timestamps, :update_on_create=>true
14
16
  end
15
17
  end
@@ -1,4 +1,4 @@
1
- require 'sequel'
1
+ require 'pact_broker/db'
2
2
  require 'pact_broker/models/order_versions'
3
3
 
4
4
  module PactBroker
@@ -19,5 +19,7 @@ module PactBroker
19
19
  "Version: number=#{number}, pacticipant=#{pacticipant_id}"
20
20
  end
21
21
  end
22
+
23
+ Version.plugin :timestamps, :update_on_create=>true
22
24
  end
23
25
  end
@@ -0,0 +1,53 @@
1
+ require 'pact_broker/models/webhook_request'
2
+ require 'pact_broker/messages'
3
+ require 'pact_broker/logging'
4
+
5
+ module PactBroker
6
+
7
+ module Models
8
+
9
+ class Webhook
10
+
11
+ include Messages
12
+ include Logging
13
+
14
+ attr_accessor :uuid, :consumer, :provider, :request, :created_at, :updated_at
15
+
16
+ def initialize attributes = {}
17
+ @uuid = attributes[:uuid]
18
+ @request = attributes[:request]
19
+ @consumer = attributes[:consumer]
20
+ @provider = attributes[:provider]
21
+ @created_at = attributes[:created_at]
22
+ @updated_at = attributes[:updated_at]
23
+ end
24
+
25
+ def validate
26
+ messages = []
27
+ messages << message('errors.validation.attribute_missing', attribute: 'request') unless request
28
+ messages.concat request.validate if request
29
+ messages
30
+ end
31
+
32
+ def description
33
+ "A webhook for the pact between #{consumer.name} and #{provider.name}"
34
+ end
35
+
36
+ def request_description
37
+ request && request.description
38
+ end
39
+
40
+ #TODO retries
41
+ def execute
42
+ logger.info "Executing #{self}"
43
+ request.execute
44
+ end
45
+
46
+ def to_s
47
+ "webhook for consumer=#{consumer.name} provider=#{provider.name} uuid=#{uuid} request=#{request}"
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,26 @@
1
+ module PactBroker
2
+
3
+ module Models
4
+
5
+ class WebhookExecutionResult
6
+
7
+ def initialize response, error = nil
8
+ @response = response
9
+ @error = error
10
+ end
11
+
12
+ def success?
13
+ !@response.nil? && @response.code.to_i < 400
14
+ end
15
+
16
+ def response
17
+ @response
18
+ end
19
+
20
+ def error
21
+ @error
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,107 @@
1
+ require 'pact_broker/models/webhook_request_header'
2
+ require 'pact_broker/models/webhook_execution_result'
3
+ require 'pact_broker/logging'
4
+ require 'pact_broker/messages'
5
+
6
+ module PactBroker
7
+
8
+ module Models
9
+
10
+ class WebhookRequestError < StandardError
11
+
12
+ def initialize message, response
13
+ super message
14
+ @response = response
15
+ end
16
+
17
+ end
18
+
19
+ class WebhookRequest
20
+
21
+ include PactBroker::Logging
22
+ include PactBroker::Messages
23
+
24
+ attr_accessor :method, :url, :headers, :body, :username, :password
25
+
26
+ def initialize attributes = {}
27
+ @method = attributes[:method]
28
+ @url = attributes[:url]
29
+ @username = attributes[:username]
30
+ @password = attributes[:password]
31
+ @headers = attributes[:headers] || {}
32
+ @body = attributes[:body]
33
+ end
34
+
35
+ def description
36
+ "#{method.upcase} #{URI(url).host}"
37
+ end
38
+
39
+ def display_password
40
+ password.nil? ? nil : "**********"
41
+ end
42
+
43
+ def execute
44
+
45
+ begin
46
+ #TODO make it work with https
47
+ req = http_request
48
+
49
+ headers.each_pair do | name, value |
50
+ req[name] = value
51
+ end
52
+
53
+ req.basic_auth(username, password) if username
54
+
55
+ req.body = body
56
+
57
+ logger.info "Making webhook request #{to_s}"
58
+ response = Net::HTTP.start(uri.hostname, uri.port) do |http|
59
+ http.request req
60
+ end
61
+
62
+ logger.info "Received response status=#{response.code} body=#{response.body}"
63
+ WebhookExecutionResult.new(response)
64
+
65
+ rescue StandardError => e
66
+ logger.error "Error executing webhook #{e.class.name} - #{e.message}"
67
+ logger.error e.backtrace.join("\n")
68
+ WebhookExecutionResult.new(nil, e)
69
+ end
70
+
71
+ end
72
+
73
+ def validate
74
+ messages = []
75
+ messages << message('errors.validation.attribute_missing', attribute: 'method') unless method
76
+ messages << message('errors.validation.attribute_missing', attribute: 'url') unless url
77
+ messages << message('errors.validation.invalid_http_method', method: method) unless method && method_valid?
78
+ messages << message('errors.validation.invalid_url', url: url) unless url && url_valid?
79
+ messages
80
+ end
81
+
82
+ private
83
+
84
+ def to_s
85
+ "#{method.upcase} #{url}, username=#{username}, password=#{display_password}, headers=#{headers}, body=#{body}"
86
+ end
87
+
88
+ def http_request
89
+ Net::HTTP.const_get(method.capitalize).new(url)
90
+ end
91
+
92
+ def method_valid?
93
+ Net::HTTP.const_defined?(method.capitalize)
94
+ end
95
+
96
+ def url_valid?
97
+ uri.scheme && uri.host
98
+ end
99
+
100
+ def uri
101
+ URI(url)
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,13 @@
1
+ module PactBroker
2
+ module Models
3
+ class WebhookRequestHeader
4
+
5
+ attr_accessor :name, :value
6
+
7
+ def initialize name, value
8
+ @name = name
9
+ @value = value
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,6 +3,8 @@ require 'pact_broker/repositories/pacticipant_repository'
3
3
  require 'pact_broker/repositories/version_repository'
4
4
  require 'pact_broker/repositories/pact_repository'
5
5
  require 'pact_broker/repositories/tag_repository'
6
+ require 'pact_broker/repositories/webhook_repository'
7
+
6
8
 
7
9
  module PactBroker
8
10
  module Repositories
@@ -22,6 +24,10 @@ module PactBroker
22
24
  TagRepository.new
23
25
  end
24
26
 
27
+ def webhook_repository
28
+ WebhookRepository.new
29
+ end
30
+
25
31
  extend self
26
32
  end
27
33
  end
@@ -13,12 +13,12 @@ module PactBroker
13
13
  end
14
14
 
15
15
  def find_latest_pacts
16
-
17
- db[:latest_pacts].select(:id, :consumer_name, :provider_name, :consumer_version_number).all.collect do | row |
18
- consumer = OpenStruct.new(name: row[:"`consumer_name`"])
19
- provider = OpenStruct.new(name: row[:"`provider_name`"])
20
- consumer_version = OpenStruct.new(number: row[:"`consumer_version_number`"], pacticipant: consumer)
21
- pact = OpenStruct.new(id: row[:id], consumer: consumer, consumer_version: consumer_version, provider: provider)
16
+ # Need to use aliases because sqlite returns row with `` in the column name, mysql does not
17
+ db[:latest_pacts].select(:id,
18
+ :consumer_id___consumer_id, :consumer_name___consumer_name,
19
+ :provider_id___provider_id, :provider_name___provider_name,
20
+ :consumer_version_number___consumer_version_number).all.collect do | row |
21
+ row_to_pact row
22
22
  end
23
23
 
24
24
  end
@@ -45,6 +45,11 @@ module PactBroker
45
45
  end
46
46
  end
47
47
 
48
+ def find_previous_pact pact
49
+ previous_pact = db[:all_pacts].where(:consumer_id => pact.consumer.id, :provider_id => pact.provider.id).where('consumer_version_order < ?', pact.consumer_version.order).order(:consumer_version_order).last
50
+ previous_pact ? row_to_pact(previous_pact) : nil
51
+ end
52
+
48
53
  private
49
54
 
50
55
  def db
@@ -52,7 +57,9 @@ module PactBroker
52
57
  end
53
58
 
54
59
  def pact_finder consumer_name, provider_name
55
- PactBroker::Models::Pact.select(:pacts__id, :pacts__json_content, :pacts__version_id, :pacts__provider_id, :versions__number___consumer_version_number).
60
+ PactBroker::Models::Pact.select(
61
+ :pacts__id, :pacts__json_content, :pacts__version_id, :pacts__provider_id, :pacts__created_at, :pacts__updated_at,
62
+ :versions__number___consumer_version_number).
56
63
  join(:versions, {:id => :version_id}, {implicit_qualifier: :pacts}).
57
64
  join(:pacticipants, {:id => :pacticipant_id}, {:table_alias => :consumers, implicit_qualifier: :versions}).
58
65
  join(:pacticipants, {:id => :provider_id}, {:table_alias => :providers, implicit_qualifier: :pacts}).
@@ -66,6 +73,17 @@ module PactBroker
66
73
  where('tags.name = ?', tag)
67
74
  end
68
75
 
76
+ def row_to_pact row
77
+ # Equality fails inside Relationship.connected if using OpenStruct, can't seem to duplicate it
78
+ # in a test though.
79
+ consumer = Models::Pacticipant.new(name: row[:consumer_name])
80
+ consumer.id = row[:consumer_id]
81
+ provider = Models::Pacticipant.new(name: row[:provider_name])
82
+ provider.id = row[:provider_id]
83
+ consumer_version = OpenStruct.new(number: row[:consumer_version_number], pacticipant: consumer)
84
+ pact = OpenStruct.new(id: row[:id], consumer: consumer, consumer_version: consumer_version, provider: provider, consumer_version_number: row[:consumer_version_number])
85
+ end
86
+
69
87
  end
70
88
  end
71
89
  end