pact_broker 2.59.1 → 2.62.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +53 -0
  3. data/README.md +1 -1
  4. data/db/migrations/20200922_add_event_to_triggered_webhook.rb +5 -0
  5. data/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema.rb +10 -3
  6. data/lib/pact_broker/api/contracts/verifiable_pacts_query_schema.rb +1 -0
  7. data/lib/pact_broker/api/decorators/triggered_webhook_decorator.rb +1 -0
  8. data/lib/pact_broker/api/decorators/verifiable_pact_decorator.rb +5 -5
  9. data/lib/pact_broker/api/pact_broker_urls.rb +9 -2
  10. data/lib/pact_broker/api/resources/all_webhooks.rb +1 -6
  11. data/lib/pact_broker/api/resources/can_i_deploy.rb +0 -4
  12. data/lib/pact_broker/api/resources/default_base_resource.rb +9 -0
  13. data/lib/pact_broker/api/resources/error_handler.rb +2 -4
  14. data/lib/pact_broker/api/resources/error_test.rb +4 -2
  15. data/lib/pact_broker/api/resources/group.rb +0 -4
  16. data/lib/pact_broker/api/resources/index.rb +11 -8
  17. data/lib/pact_broker/api/resources/integration.rb +0 -4
  18. data/lib/pact_broker/api/resources/integrations.rb +0 -4
  19. data/lib/pact_broker/api/resources/label.rb +0 -8
  20. data/lib/pact_broker/api/resources/latest_pact.rb +1 -5
  21. data/lib/pact_broker/api/resources/latest_pacts.rb +1 -5
  22. data/lib/pact_broker/api/resources/latest_verifications_for_consumer_version.rb +0 -4
  23. data/lib/pact_broker/api/resources/matrix.rb +4 -0
  24. data/lib/pact_broker/api/resources/matrix_for_consumer_and_provider.rb +4 -0
  25. data/lib/pact_broker/api/resources/metrics.rb +4 -0
  26. data/lib/pact_broker/api/resources/pact.rb +4 -8
  27. data/lib/pact_broker/api/resources/pact_content_diff.rb +4 -0
  28. data/lib/pact_broker/api/resources/pact_triggered_webhooks.rb +5 -1
  29. data/lib/pact_broker/api/resources/pact_versions.rb +5 -1
  30. data/lib/pact_broker/api/resources/pact_webhooks.rb +5 -1
  31. data/lib/pact_broker/api/resources/pact_webhooks_status.rb +5 -1
  32. data/lib/pact_broker/api/resources/pacticipant.rb +5 -9
  33. data/lib/pact_broker/api/resources/pacticipants.rb +0 -4
  34. data/lib/pact_broker/api/resources/pacticipants_for_label.rb +4 -0
  35. data/lib/pact_broker/api/resources/previous_distinct_pact_version.rb +4 -9
  36. data/lib/pact_broker/api/resources/provider_pacts.rb +1 -5
  37. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +8 -6
  38. data/lib/pact_broker/api/resources/relationships.rb +4 -2
  39. data/lib/pact_broker/api/resources/tag.rb +5 -5
  40. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +5 -2
  41. data/lib/pact_broker/api/resources/triggered_webhook_logs.rb +7 -5
  42. data/lib/pact_broker/api/resources/verification.rb +5 -5
  43. data/lib/pact_broker/api/resources/verification_triggered_webhooks.rb +6 -12
  44. data/lib/pact_broker/api/resources/verifications.rb +5 -5
  45. data/lib/pact_broker/api/resources/version.rb +5 -5
  46. data/lib/pact_broker/api/resources/versions.rb +5 -2
  47. data/lib/pact_broker/api/resources/webhook.rb +4 -0
  48. data/lib/pact_broker/api/resources/webhook_execution.rb +4 -0
  49. data/lib/pact_broker/api/resources/webhooks.rb +5 -1
  50. data/lib/pact_broker/app.rb +1 -1
  51. data/lib/pact_broker/badges/service.rb +1 -1
  52. data/lib/pact_broker/certificates/service.rb +2 -2
  53. data/lib/pact_broker/configuration.rb +21 -1
  54. data/lib/pact_broker/db.rb +14 -0
  55. data/lib/pact_broker/db/table_dependency_calculator.rb +45 -0
  56. data/lib/pact_broker/doc/views/provider-pacts-for-verification.markdown +78 -0
  57. data/lib/pact_broker/domain/pact.rb +9 -0
  58. data/lib/pact_broker/domain/webhook_request.rb +3 -1
  59. data/lib/pact_broker/matrix/deployment_status_summary.rb +1 -1
  60. data/lib/pact_broker/pacts/build_verifiable_pact_notices.rb +7 -4
  61. data/lib/pact_broker/pacts/content.rb +30 -5
  62. data/lib/pact_broker/pacts/repository.rb +25 -31
  63. data/lib/pact_broker/pacts/selector.rb +8 -0
  64. data/lib/pact_broker/test/test_data_builder.rb +1 -1
  65. data/lib/pact_broker/version.rb +1 -1
  66. data/lib/pact_broker/webhooks/job.rb +8 -2
  67. data/lib/pact_broker/webhooks/repository.rb +3 -2
  68. data/lib/pact_broker/webhooks/service.rb +2 -2
  69. data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -3
  70. data/lib/pact_broker/webhooks/webhook_event.rb +1 -2
  71. data/script/seed.rb +39 -17
  72. data/spec/features/get_provider_pacts_for_verification_spec.rb +8 -0
  73. data/spec/lib/pact_broker/api/contracts/verifiable_pacts_json_query_schema_spec.rb +23 -4
  74. data/spec/lib/pact_broker/api/decorators/pact_webhooks_status_decorator_spec.rb +2 -1
  75. data/spec/lib/pact_broker/api/decorators/triggered_webhook_decorator_spec.rb +3 -1
  76. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +15 -0
  77. data/spec/lib/pact_broker/api/resources/default_base_resource_spec.rb +10 -5
  78. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +18 -1
  79. data/spec/lib/pact_broker/api/resources/provider_pacts_for_verification_spec.rb +1 -1
  80. data/spec/lib/pact_broker/api/resources/verification_triggered_webhooks_spec.rb +0 -1
  81. data/spec/lib/pact_broker/badges/service_spec.rb +1 -1
  82. data/spec/lib/pact_broker/certificates/service_spec.rb +3 -3
  83. data/spec/lib/pact_broker/pacts/content_spec.rb +90 -0
  84. data/spec/lib/pact_broker/pacts/repository_find_for_verification_fallback_spec.rb +14 -0
  85. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +62 -0
  86. data/spec/lib/pact_broker/webhooks/job_spec.rb +19 -1
  87. data/spec/lib/pact_broker/webhooks/repository_spec.rb +3 -2
  88. data/spec/lib/pact_broker/webhooks/service_spec.rb +2 -2
  89. data/spec/support/database_cleaner.rb +1 -5
  90. data/tasks/database.rb +1 -0
  91. data/tasks/database/table_dependency_calculator.rb +4 -41
  92. metadata +5 -2
@@ -53,6 +53,14 @@ module PactBroker
53
53
  Selector.new(tag: tag, consumer: consumer)
54
54
  end
55
55
 
56
+ def self.latest_for_tag_and_consumer(tag, consumer)
57
+ Selector.new(latest: true, tag: tag, consumer: consumer)
58
+ end
59
+
60
+ def self.latest_for_consumer(consumer)
61
+ Selector.new(latest: true, consumer: consumer)
62
+ end
63
+
56
64
  def self.from_hash hash
57
65
  Selector.new(hash)
58
66
  end
@@ -294,7 +294,7 @@ module PactBroker
294
294
  params.delete(:comment)
295
295
  trigger_uuid = params[:trigger_uuid] || webhook_service.next_uuid
296
296
  verification = @webhook.trigger_on_provider_verification_published? ? @verification : nil
297
- @triggered_webhook = webhook_repository.create_triggered_webhook trigger_uuid, @webhook, @pact, verification, PactBroker::Webhooks::Service::RESOURCE_CREATION
297
+ @triggered_webhook = webhook_repository.create_triggered_webhook trigger_uuid, @webhook, @pact, verification, PactBroker::Webhooks::Service::RESOURCE_CREATION, @webhook.events.first.name
298
298
  @triggered_webhook.update(status: params[:status]) if params[:status]
299
299
  set_created_at_if_set params[:created_at], :triggered_webhooks, {id: @triggered_webhook.id}
300
300
  self
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '2.59.1'
2
+ VERSION = '2.62.0'
3
3
  end
@@ -7,9 +7,10 @@ module PactBroker
7
7
  module Webhooks
8
8
  class Job
9
9
 
10
+ INFO_ERROR_PREFIXES = %w{Errno:: Timeout:: Net:: OpenSSL:: EOFError SocketError}
11
+
10
12
  include SuckerPunch::Job
11
13
  include PactBroker::Logging
12
- include PactBroker::Logging
13
14
 
14
15
  def perform data
15
16
  data.fetch(:database_connector).call do
@@ -62,7 +63,12 @@ module PactBroker
62
63
  end
63
64
 
64
65
  def handle_error e
65
- log_error e, "Error executing triggered webhook with ID #{triggered_webhook ? triggered_webhook.id : nil}"
66
+ message = "Error executing triggered webhook with ID #{triggered_webhook ? triggered_webhook.id : nil}"
67
+ if e.class.name.start_with?(*INFO_ERROR_PREFIXES)
68
+ logger.info(message, e)
69
+ else
70
+ logger.warn(message, e)
71
+ end
66
72
  handle_failure
67
73
  end
68
74
 
@@ -101,7 +101,7 @@ module PactBroker
101
101
  .collect(&:to_domain)
102
102
  end
103
103
 
104
- def create_triggered_webhook trigger_uuid, webhook, pact, verification, trigger_type
104
+ def create_triggered_webhook trigger_uuid, webhook, pact, verification, trigger_type, event_name
105
105
  db_webhook = Webhook.where(uuid: webhook.uuid).single_record
106
106
  TriggeredWebhook.create(
107
107
  status: TriggeredWebhook::STATUS_NOT_RUN,
@@ -112,7 +112,8 @@ module PactBroker
112
112
  trigger_uuid: trigger_uuid,
113
113
  trigger_type: trigger_type,
114
114
  consumer: pact.consumer,
115
- provider: pact.provider
115
+ provider: pact.provider,
116
+ event_name: event_name
116
117
  )
117
118
  end
118
119
 
@@ -136,14 +136,14 @@ module PactBroker
136
136
  trigger_uuid = next_uuid
137
137
  webhooks.each do | webhook |
138
138
  begin
139
- triggered_webhook = webhook_repository.create_triggered_webhook(trigger_uuid, webhook, pact, verification, RESOURCE_CREATION)
139
+ triggered_webhook = webhook_repository.create_triggered_webhook(trigger_uuid, webhook, pact, verification, RESOURCE_CREATION, event_name)
140
140
  logger.info "Scheduling job for webhook with uuid #{webhook.uuid}"
141
141
  logger.debug "Schedule webhook with options #{options}"
142
142
  job_data = { triggered_webhook: triggered_webhook }.deep_merge(options)
143
143
  # Delay slightly to make sure the request transaction has finished before we execute the webhook
144
144
  Job.perform_in(5, job_data)
145
145
  rescue StandardError => e
146
- log_error e
146
+ logger.warn("Error scheduling webhook execution for webhook with uuid #{webhook.uuid}", e)
147
147
  end
148
148
  end
149
149
  end
@@ -8,6 +8,7 @@ require 'pact_broker/webhooks/execution'
8
8
  module PactBroker
9
9
  module Webhooks
10
10
  class TriggeredWebhook < Sequel::Model(:triggered_webhooks)
11
+ plugin :timestamps, update_on_create: true
11
12
 
12
13
  TRIGGER_TYPE_RESOURCE_CREATION = 'resource_creation'
13
14
  TRIGGER_TYPE_USER = 'user'
@@ -95,9 +96,6 @@ module PactBroker
95
96
  end
96
97
  end
97
98
  end
98
-
99
- TriggeredWebhook.plugin :timestamps, update_on_create: true
100
-
101
99
  end
102
100
  end
103
101
 
@@ -4,6 +4,7 @@ require 'pact_broker/repositories/helpers'
4
4
  module PactBroker
5
5
  module Webhooks
6
6
  class WebhookEvent < Sequel::Model
7
+ plugin :timestamps, update_on_create: true
7
8
 
8
9
  CONTRACT_PUBLISHED = 'contract_published'
9
10
  CONTRACT_CONTENT_CHANGED = 'contract_content_changed'
@@ -38,8 +39,6 @@ module PactBroker
38
39
  name == VERIFICATION_FAILED
39
40
  end
40
41
  end
41
-
42
- WebhookEvent.plugin :timestamps, update_on_create: true
43
42
  end
44
43
  end
45
44
 
@@ -46,24 +46,46 @@ webhook_body = {
46
46
 
47
47
  PactBroker.configuration.base_equality_only_on_content_that_affects_verification_results = false
48
48
 
49
- # .create_global_webhook(
50
- # method: 'POST',
51
- # url: "http://localhost:9292/pact-changed-webhook",
52
- # body: webhook_body.to_json,
53
- # username: "foo",
54
- # password: "bar")
55
- TestDataBuilder.new
56
- .create_global_verification_succeeded_webhook(
57
- method: 'POST',
58
- url: "http://localhost:9292/verification-published-webhook",
59
- body: webhook_body.to_json)
60
- .set_now(Date.today - 101)
61
- .create_pact_with_hierarchy("Foo/Foo", "100", "Bar/Bar")
62
- .create_pact_with_hierarchy("Foo", "1", "Bar")
63
- .create_pact_with_hierarchy("<script>alert('hello')</script>", "<script>alert(\"version\")</script>", "Bar/Bar")
64
- .create_consumer_version_tag("prod")
65
- .create_verification(provider_version: "1", tag_names: "prod")
49
+ json_content = <<-HEREDOC
50
+ {
51
+ "consumer": {
52
+ "name": "Foo"
53
+ },
54
+ "provider": {
55
+ "name": "Bar"
56
+ },
57
+ "interactions": [
58
+ {
59
+ "description": "a retrieve thing request",
60
+ "request": {
61
+ "method": "get",
62
+ "path": "/thing"
63
+ },
64
+ "response": {
65
+ "status": 200,
66
+ "headers": {
67
+ "Content-Type": "application/json"
68
+ },
69
+ "body": {
70
+ "name": "Thing 1"
71
+ }
72
+ }
73
+ }
74
+ ],
75
+ "metadata": {
76
+ "pactSpecification": {
77
+ "version": "2.0.0"
78
+ }
79
+ }
80
+ }
81
+ HEREDOC
66
82
 
83
+ TestDataBuilder.new
84
+ .create_pact_with_hierarchy("Foo", "1", "Bar", json_content)
85
+ .create_consumer_version_tag("master")
86
+ .create_verification(provider_version: "1", tag_name: "master")
87
+ .create_pact_with_hierarchy("Foo", "2", "Bar", json_content.gsub("200", "201"))
88
+ .create_consumer_version_tag("feat/x")
67
89
 
68
90
  # .create_certificate(path: 'spec/fixtures/certificates/self-signed.badssl.com.pem')
69
91
  # .create_consumer("Bethtest")
@@ -33,6 +33,10 @@ describe "Get provider pacts for verification" do
33
33
  expect(pacts.size).to eq 1
34
34
  end
35
35
 
36
+ it "returns a deprecation notice" do
37
+ expect(last_response_body[:_embedded][:pacts].first[:verificationProperties][:notices].first[:text]).to start_with("WARNING")
38
+ end
39
+
36
40
  context "when the provider does not exist" do
37
41
  let(:path) { "/pacts/provider/ProviderThatDoesNotExist/for-verification" }
38
42
 
@@ -62,6 +66,10 @@ describe "Get provider pacts for verification" do
62
66
  expect(pacts.size).to eq 1
63
67
  end
64
68
 
69
+ it "does not include a deprecation notice" do
70
+ expect(last_response_body[:_embedded][:pacts].first[:verificationProperties][:notices].first[:text]).to_not start_with("WARNING")
71
+ end
72
+
65
73
  context "when the provider does not exist" do
66
74
  let(:path) { "/pacts/provider/ProviderThatDoesNotExist/for-verification" }
67
75
 
@@ -71,6 +71,27 @@ module PactBroker
71
71
  end
72
72
  end
73
73
 
74
+ context "when the latest version for a particular consumer is requested" do
75
+ let(:consumer_version_selectors) do
76
+ [{
77
+ consumer: "Foo",
78
+ latest: true
79
+ }]
80
+ end
81
+
82
+ it { is_expected.to be_empty }
83
+ end
84
+
85
+ context "when the latest version for all is requested" do
86
+ let(:consumer_version_selectors) do
87
+ [{
88
+ latest: true
89
+ }]
90
+ end
91
+
92
+ it { is_expected.to be_empty }
93
+ end
94
+
74
95
  context "when providerVersionTags is not an array" do
75
96
  let(:provider_version_tags) { true }
76
97
 
@@ -89,7 +110,7 @@ module PactBroker
89
110
  end
90
111
 
91
112
  it "flattens the messages" do
92
- expect(subject[:consumerVersionSelectors].first).to eq "tag is missing at index 0"
113
+ expect(subject[:consumerVersionSelectors].first).to eq "latest must be true, or a tag must be provided (at index 0)"
93
114
  end
94
115
  end
95
116
 
@@ -150,9 +171,7 @@ module PactBroker
150
171
  }]
151
172
  end
152
173
 
153
- it "has an error" do
154
- expect(subject[:consumerVersionSelectors].first).to include "not yet supported"
155
- end
174
+ it { is_expected.to be_empty }
156
175
  end
157
176
  end
158
177
  end
@@ -22,7 +22,8 @@ module PactBroker
22
22
  number_of_attempts_made: 1,
23
23
  number_of_attempts_remaining: 2,
24
24
  created_at: DateTime.new(2017),
25
- updated_at: DateTime.new(2017)
25
+ updated_at: DateTime.new(2017),
26
+ event_name: 'some_event'
26
27
  )
27
28
  end
28
29
 
@@ -7,6 +7,7 @@ module PactBroker
7
7
  let(:triggered_webhook) do
8
8
  double('PactBroker::Webhooks::TriggeredWebhook',
9
9
  trigger_type: PactBroker::Webhooks::TriggeredWebhook::TRIGGER_TYPE_RESOURCE_CREATION,
10
+ event_name: 'some_event',
10
11
  status: status,
11
12
  failure?: failure,
12
13
  retrying?: retrying,
@@ -55,7 +56,8 @@ module PactBroker
55
56
  status: 'success',
56
57
  triggerType: 'resource_creation',
57
58
  attemptsMade: 1,
58
- attemptsRemaining: 2
59
+ attemptsRemaining: 2,
60
+ eventName: 'some_event'
59
61
  )
60
62
  end
61
63
  end
@@ -3,6 +3,10 @@ require 'pact_broker/api/pact_broker_urls'
3
3
  module PactBroker
4
4
  module Api
5
5
  describe PactBrokerUrls do
6
+ before do
7
+ allow(PactBrokerUrls).to receive(:logger).and_return(logger)
8
+ end
9
+ let(:logger) { double('logger').as_null_object }
6
10
 
7
11
  # Regex find all the URL parameter names
8
12
  # \/\{[^\}\s\[\(\.]+\}
@@ -117,6 +121,17 @@ module PactBroker
117
121
  expect(PactBrokerUrls.decode_webhook_metadata(nil)).to eq({})
118
122
  end
119
123
  end
124
+
125
+ context "when the metadata is not valid base64" do
126
+ it "returns an empty hash" do
127
+ expect(PactBrokerUrls.decode_webhook_metadata("foo==,")).to eq({})
128
+ end
129
+
130
+ it "logs a warning" do
131
+ expect(logger).to receive(:warn).with("Exception parsing webhook metadata: foo==,", ArgumentError)
132
+ PactBrokerUrls.decode_webhook_metadata("foo==,")
133
+ end
134
+ end
120
135
  end
121
136
 
122
137
  describe "latest_verification_for_pact_url" do
@@ -133,23 +133,28 @@ module PactBroker
133
133
  .select { |klass| klass < DefaultBaseResource }
134
134
  .select { |klass| !klass.name.end_with?("BaseResource") }
135
135
 
136
- ALL_RESOURCES.each do | resource |
137
- describe resource do
136
+ ALL_RESOURCES.each do | resource_class |
137
+ describe resource_class do
138
138
  let(:request) { double('request', uri: URI("http://example.org")).as_null_object }
139
139
  let(:response) { double('response') }
140
+ let(:resource) { resource_class.new(request, response) }
140
141
 
141
142
  it "includes OPTIONS in the list of allowed_methods" do
142
- expect(resource.new(request, response).allowed_methods).to include "OPTIONS"
143
+ expect(resource.allowed_methods).to include "OPTIONS"
143
144
  end
144
145
 
145
146
  it "calls super in its constructor" do
146
147
  expect(PactBroker.configuration.before_resource).to receive(:call)
147
- resource.new(request, response)
148
+ resource
148
149
  end
149
150
 
150
151
  it "calls super in finish_request" do
151
152
  expect(PactBroker.configuration.after_resource).to receive(:call)
152
- resource.new(request, response).finish_request
153
+ resource.finish_request
154
+ end
155
+
156
+ it "has a policy_name method" do
157
+ expect(resource).to respond_to(:policy_name)
153
158
  end
154
159
  end
155
160
  end
@@ -5,7 +5,6 @@ module PactBroker
5
5
  module Resources
6
6
  describe ErrorHandler do
7
7
  describe "call" do
8
-
9
8
  before do
10
9
  allow(ErrorHandler).to receive(:logger).and_return(logger)
11
10
  allow(SecureRandom).to receive(:urlsafe_base64).and_return("bYWfn-+yWPlf")
@@ -45,6 +44,24 @@ module PactBroker
45
44
  subject
46
45
  end
47
46
 
47
+ context "when the error class is in the warning_error_classes list" do
48
+ let(:error) { Sequel::ForeignKeyConstraintViolation.new }
49
+
50
+ it "logs at warn so as not to wake everyone up in the middle of the night" do
51
+ expect(logger).to receive(:warn).with(/bYWfnyWPlf/, error)
52
+ subject
53
+ end
54
+ end
55
+
56
+ context "when the error is not reportable and not a warning level" do
57
+ let(:error) { PactBroker::Error.new('foo') }
58
+
59
+ it "logs at info" do
60
+ expect(logger).to receive(:info).with(/bYWfnyWPlf/, error)
61
+ subject
62
+ end
63
+ end
64
+
48
65
  context "when show_backtrace_in_error_response? is true" do
49
66
  before do
50
67
  allow(PactBroker.configuration).to receive(:show_backtrace_in_error_response?).and_return(true)
@@ -11,7 +11,7 @@ module PactBroker
11
11
  end
12
12
 
13
13
  let(:provider) { double('provider') }
14
- let(:pacts) { double('pacts') }
14
+ let(:pacts) { [] }
15
15
  let(:path) { '/pacts/provider/Bar/for-verification' }
16
16
  let(:decorator) { instance_double('PactBroker::Api::Decorators::VerifiablePactsDecorator') }
17
17
  let(:query) do
@@ -34,7 +34,6 @@ module PactBroker
34
34
  end
35
35
 
36
36
  context "when the verification exists" do
37
-
38
37
  it "finds the triggered webhooks for the verification" do
39
38
  expect(webhook_service).to receive(:find_triggered_webhooks_for_verification)
40
39
  subject
@@ -286,7 +286,7 @@ module PactBroker
286
286
  end
287
287
 
288
288
  it "logs the error" do
289
- expect(logger).to receive(:error).with(/Error retrieving badge from.*shield.*an error/)
289
+ expect(logger).to receive(:warn).with(/Error retrieving badge from.*shield.*/, RuntimeError)
290
290
  subject
291
291
  end
292
292
 
@@ -30,8 +30,8 @@ module PactBroker
30
30
  it "logs the error" do
31
31
  subject
32
32
 
33
- expect(logger).to have_received(:error)
34
- .with(/Error adding certificate/).at_least(1).times
33
+ expect(logger).to have_received(:warn)
34
+ .with(/Error adding certificate/, StandardError).at_least(1).times
35
35
  end
36
36
 
37
37
  it "returns an OpenSSL::X509::Store" do
@@ -66,7 +66,7 @@ module PactBroker
66
66
  let(:certificate_content) { File.read('spec/fixtures/certificate-invalid.pem') }
67
67
 
68
68
  it "logs an error" do
69
- expect(logger).to receive(:error).with(/Error.*1234/)
69
+ expect(logger).to receive(:warn).with(/Error.*1234/, StandardError)
70
70
  subject
71
71
  end
72
72
 
@@ -308,6 +308,14 @@ module PactBroker
308
308
  expect(subject.interactions_missing_test_results.count).to eq 1
309
309
  end
310
310
 
311
+ context "with no interactions" do
312
+ let(:pact_content) { {} }
313
+
314
+ it "does not blow up" do
315
+ expect(subject.interactions_missing_test_results.count).to eq 0
316
+ end
317
+ end
318
+
311
319
  context "with nil test results" do
312
320
  let(:test_results) { nil }
313
321
 
@@ -351,6 +359,88 @@ module PactBroker
351
359
  expect(subject.to_hash).to eq merged_with_empty_tests
352
360
  end
353
361
  end
362
+
363
+ context "with the new format" do
364
+ let(:test_results) do
365
+ [
366
+ {
367
+ "interactionId" => "1",
368
+ "success "=> false
369
+ },{
370
+ "foo" => "bar"
371
+ }
372
+ ]
373
+ end
374
+
375
+ let(:pact_content) do
376
+ {
377
+ "interactions" => [
378
+ {
379
+ "_id" => "1"
380
+ },
381
+ {
382
+ "_id" => "2"
383
+ }
384
+ ]
385
+ }
386
+ end
387
+
388
+ let(:merged) do
389
+ {
390
+ "interactions" => [
391
+ {
392
+ "_id" => "1",
393
+ "tests" => [{
394
+ "interactionId" => "1",
395
+ "success "=> false
396
+ }]
397
+ },{
398
+ "_id" => "2",
399
+ "tests" => []
400
+ }
401
+ ]
402
+ }
403
+ end
404
+
405
+ it "merges the tests into the pact content" do
406
+ expect(subject.to_hash).to eq merged
407
+ end
408
+ end
409
+ end
410
+
411
+ describe "interaction_ids" do
412
+ let(:interaction_1) do
413
+ {
414
+ _id: '1'
415
+ }
416
+ end
417
+
418
+ let(:interaction_2) do
419
+ {
420
+ _id: '2'
421
+ }
422
+ end
423
+
424
+ let(:interaction_3) do
425
+ {
426
+ }
427
+ end
428
+
429
+ let(:content_hash) do
430
+ {
431
+ interactions: [interaction_1, interaction_2, interaction_3]
432
+ }
433
+ end
434
+
435
+ subject { Content.from_json(content_hash.to_json) }
436
+
437
+ its(:interaction_ids) { is_expected.to eq ['1', '2'] }
438
+
439
+ context "when there are no interactions" do
440
+ let(:content_hash) { {} }
441
+
442
+ its(:interaction_ids) { is_expected.to eq [] }
443
+ end
354
444
  end
355
445
  end
356
446
  end