pact_broker 2.81.0 → 2.82.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/CHANGELOG.md +30 -0
  4. data/DEVELOPER_SETUP.md +1 -1
  5. data/README.md +7 -5
  6. data/config.ru +3 -28
  7. data/db/migrations/20210722_add_index_to_triggered_webhooks_webhook_uuid.rb +7 -0
  8. data/db/migrations/20210810_set_allow_contract_modification.rb +17 -0
  9. data/docs/CONFIGURATION.md +398 -0
  10. data/docs/configuration.yml +320 -0
  11. data/example/Gemfile +4 -4
  12. data/example/README.md +15 -22
  13. data/example/config.ru +1 -24
  14. data/example/config/pact_broker.yml +9 -0
  15. data/example/config/puma.rb +3 -0
  16. data/lib/db.rb +1 -1
  17. data/lib/pact_broker/api/authorization/resource_access_policy.rb +68 -0
  18. data/lib/pact_broker/api/authorization/resource_access_rules.rb +40 -0
  19. data/lib/pact_broker/api/decorators/deployed_version_decorator.rb +2 -0
  20. data/lib/pact_broker/api/decorators/released_version_decorator.rb +2 -0
  21. data/lib/pact_broker/api/middleware/basic_auth.rb +63 -0
  22. data/lib/pact_broker/api/resources/pact.rb +15 -6
  23. data/lib/pact_broker/api/resources/tag.rb +1 -14
  24. data/lib/pact_broker/app.rb +52 -30
  25. data/lib/pact_broker/config/basic_auth_configuration.rb +38 -0
  26. data/lib/pact_broker/config/load.rb +21 -10
  27. data/lib/pact_broker/config/runtime_configuration.rb +188 -0
  28. data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +41 -0
  29. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +119 -0
  30. data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +61 -0
  31. data/lib/pact_broker/configuration.rb +67 -131
  32. data/lib/pact_broker/contracts/notice.rb +4 -0
  33. data/lib/pact_broker/contracts/service.rb +4 -4
  34. data/lib/pact_broker/db/models.rb +3 -0
  35. data/lib/pact_broker/db/validate_encoding.rb +0 -4
  36. data/lib/pact_broker/deployments/deployed_version.rb +8 -2
  37. data/lib/pact_broker/deployments/deployed_version_service.rb +13 -6
  38. data/lib/pact_broker/deployments/environment.rb +1 -1
  39. data/lib/pact_broker/deployments/released_version.rb +8 -0
  40. data/lib/pact_broker/deployments/released_version_service.rb +12 -0
  41. data/lib/pact_broker/doc/views/provider-pacts-for-verification.markdown +4 -0
  42. data/lib/pact_broker/domain/pacticipant.rb +17 -13
  43. data/lib/pact_broker/domain/verification.rb +4 -22
  44. data/lib/pact_broker/domain/version.rb +9 -5
  45. data/lib/pact_broker/domain/webhook.rb +4 -0
  46. data/lib/pact_broker/error.rb +1 -0
  47. data/lib/pact_broker/errors.rb +1 -1
  48. data/lib/pact_broker/feature_toggle.rb +3 -5
  49. data/lib/pact_broker/hash_refinements.rb +0 -1
  50. data/lib/pact_broker/index/service.rb +4 -6
  51. data/lib/pact_broker/initializers/database_connection.rb +80 -0
  52. data/lib/pact_broker/integrations/integration.rb +5 -0
  53. data/lib/pact_broker/integrations/service.rb +4 -2
  54. data/lib/pact_broker/locale/en.yml +1 -0
  55. data/lib/pact_broker/logging.rb +2 -1
  56. data/lib/pact_broker/matrix/integration.rb +1 -1
  57. data/lib/pact_broker/matrix/parse_can_i_deploy_query.rb +2 -2
  58. data/lib/pact_broker/matrix/quick_row.rb +10 -0
  59. data/lib/pact_broker/matrix/repository.rb +64 -3
  60. data/lib/pact_broker/metrics/service.rb +16 -13
  61. data/lib/pact_broker/pacticipants/repository.rb +4 -0
  62. data/lib/pact_broker/pacticipants/service.rb +9 -1
  63. data/lib/pact_broker/pacts/pact_publication.rb +10 -13
  64. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +6 -1
  65. data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +1 -2
  66. data/lib/pact_broker/pacts/pact_version.rb +25 -11
  67. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +54 -77
  68. data/lib/pact_broker/pacts/selected_pact.rb +1 -1
  69. data/lib/pact_broker/pacts/selector.rb +15 -2
  70. data/lib/pact_broker/pacts/selectors.rb +4 -0
  71. data/lib/pact_broker/pacts/service.rb +4 -0
  72. data/lib/pact_broker/repositories/scopes.rb +12 -1
  73. data/lib/pact_broker/string_refinements.rb +6 -0
  74. data/lib/pact_broker/tags/service.rb +8 -1
  75. data/lib/pact_broker/test/http_test_data_builder.rb +11 -5
  76. data/lib/pact_broker/ui/views/index/_css_and_js.haml +11 -9
  77. data/lib/pact_broker/ui/views/index/_pagination.haml +3 -1
  78. data/lib/pact_broker/ui/views/layouts/main.haml +5 -3
  79. data/lib/pact_broker/ui/views/matrix/show.haml +10 -8
  80. data/lib/pact_broker/verifications/required_verification.rb +28 -0
  81. data/lib/pact_broker/verifications/service.rb +49 -1
  82. data/lib/pact_broker/version.rb +1 -1
  83. data/lib/pact_broker/versions/repository.rb +15 -0
  84. data/lib/pact_broker/versions/service.rb +32 -2
  85. data/lib/pact_broker/webhooks/event_listener.rb +3 -0
  86. data/lib/pact_broker/webhooks/trigger_service.rb +30 -14
  87. data/lib/pact_broker/webhooks/triggered_webhook.rb +1 -0
  88. data/lib/pact_broker/webhooks/webhook.rb +2 -2
  89. data/lib/pact_broker/webhooks/webhook_event.rb +6 -1
  90. data/lib/semantic_logger/formatters/short.rb +29 -0
  91. data/pact_broker.gemspec +1 -0
  92. data/script/data/auto-create-things-for-tags.rb +19 -0
  93. data/script/data/contract-published-requiring-verification.rb +27 -0
  94. data/script/{reproduce-issue-expand-currently-deployed.rb → data/expand-currently-deployed.rb} +0 -0
  95. data/script/docs/generate-configuration-docs.rb +86 -0
  96. data/spec/features/get_latest_pact_badge_spec.rb +1 -0
  97. data/spec/features/get_matrix_badge_spec.rb +1 -0
  98. data/spec/features/publish_pact_spec.rb +21 -7
  99. data/spec/features/wip_pacts_spec.rb +1 -1
  100. data/spec/fixtures/approvals/matrix_integration_environment_spec.approved.json +62 -0
  101. data/spec/fixtures/approvals/matrix_integration_ignore_spec.approved.json +124 -0
  102. data/spec/fixtures/approvals/matrix_integration_spec.approved.json +173 -0
  103. data/spec/fixtures/approvals/publish_contract_no_branch.approved.json +9 -9
  104. data/spec/fixtures/approvals/publish_contract_nothing_exists.approved.json +7 -7
  105. data/spec/fixtures/approvals/publish_contract_nothing_exists_with_webhook.approved.json +5 -5
  106. data/spec/fixtures/approvals/publish_contract_verification_already_exists.approved.json +5 -5
  107. data/spec/lib/pact_broker/api/middleware/basic_auth_spec.rb +312 -0
  108. data/spec/lib/pact_broker/api/resources/tag_spec.rb +14 -39
  109. data/spec/lib/pact_broker/app_basic_auth_spec.rb +122 -0
  110. data/spec/lib/pact_broker/config/load_spec.rb +33 -6
  111. data/spec/lib/pact_broker/config/runtime_configuration_logging_methods_spec.rb +22 -0
  112. data/spec/lib/pact_broker/config/runtime_configuration_spec.rb +71 -0
  113. data/spec/lib/pact_broker/configuration_spec.rb +51 -25
  114. data/spec/lib/pact_broker/errors/error_logger_spec.rb +3 -0
  115. data/spec/lib/pact_broker/feature_toggle_spec.rb +18 -19
  116. data/spec/lib/pact_broker/matrix/integration_environment_spec.rb +12 -0
  117. data/spec/lib/pact_broker/matrix/integration_ignore_spec.rb +15 -3
  118. data/spec/lib/pact_broker/matrix/integration_spec.rb +47 -6
  119. data/spec/lib/pact_broker/matrix/parse_can_i_deploy_query_spec.rb +16 -1
  120. data/spec/lib/pact_broker/matrix/repository_dependency_spec.rb +0 -2
  121. data/spec/lib/pact_broker/matrix/repository_spec.rb +0 -2
  122. data/spec/lib/pact_broker/metrics/service_spec.rb +44 -0
  123. data/spec/lib/pact_broker/pacticipants/service_spec.rb +28 -5
  124. data/spec/lib/pact_broker/pacts/pact_publication_selector_dataset_module_spec.rb +25 -0
  125. data/spec/lib/pact_broker/pacts/pact_version_spec.rb +30 -1
  126. data/spec/lib/pact_broker/pacts/repository_find_for_verification_spec.rb +107 -20
  127. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +1 -1
  128. data/spec/lib/pact_broker/tags/service_spec.rb +24 -8
  129. data/spec/lib/pact_broker/verifications/service_spec.rb +146 -0
  130. data/spec/lib/pact_broker/versions/repository_spec.rb +38 -2
  131. data/spec/lib/pact_broker/versions/service_spec.rb +93 -2
  132. data/spec/lib/pact_broker/webhooks/trigger_service_spec.rb +54 -2
  133. data/spec/lib/rack/pact_broker/invalid_uri_protection_spec.rb +3 -3
  134. data/spec/spec_helper.rb +2 -1
  135. data/spec/support/approvals.rb +29 -0
  136. metadata +52 -13
  137. data/example/basic_auth/Gemfile +0 -5
  138. data/example/basic_auth/Procfile +0 -1
  139. data/example/basic_auth/README.md +0 -43
  140. data/example/basic_auth/config.ru +0 -19
  141. data/example/example_data.sql +0 -19
  142. data/spec/lib/pact_broker/config/save_and_load_spec.rb +0 -25
  143. data/spec/lib/pact_broker/pacts/service_find_for_verification_spec.rb +0 -50
@@ -3,11 +3,23 @@ require "pact_broker/config/load"
3
3
  module PactBroker
4
4
  module Config
5
5
  describe Load do
6
-
7
6
  describe ".call" do
8
7
 
9
- class MockConfig
10
- attr_accessor :foo, :bar, :nana, :meep, :lalala, :meow, :peebo, :whitelist, :blah
8
+ class MockConfig < Anyway::Config
9
+ attr_config(
10
+ foo: "default",
11
+ bar: "default",
12
+ nana: "default",
13
+ meep: "default",
14
+ lalala: "default",
15
+ meow: "default",
16
+ peebo: "default",
17
+ whitelist: "default",
18
+ blah: "default",
19
+ setting_with_override: "default"
20
+ )
21
+ attr_config(:setting_with_no_default)
22
+ config_name :foo
11
23
  end
12
24
 
13
25
  before do
@@ -21,9 +33,14 @@ module PactBroker
21
33
  Setting.create(name: "unknown", type: "string", value: nil)
22
34
  Setting.create(name: "whitelist", type: "space_delimited_string_list", value: "foo bar")
23
35
  Setting.create(name: "blah", type: "symbol", value: "boop")
36
+ Setting.create(name: "setting_with_no_default", type: "string", value: "boop")
37
+ Setting.create(name: "setting_with_override", type: "string", value: "meep")
38
+
39
+ allow(Load.logger).to receive(:warn)
40
+ allow(Load.logger).to receive(:debug)
24
41
  end
25
42
 
26
- let(:configuration) { MockConfig.new }
43
+ let(:configuration) { MockConfig.new(setting_with_override: "overridden") }
27
44
 
28
45
  subject { Load.call(configuration) }
29
46
 
@@ -72,9 +89,19 @@ module PactBroker
72
89
  expect(configuration.whitelist).to eq ["foo", "bar"]
73
90
  end
74
91
 
92
+ it "loads settings where there is no default" do
93
+ subject
94
+ expect(configuration.setting_with_no_default).to eq "boop"
95
+ end
96
+
97
+ it "does not overwrite settings that did not come from the default class" do
98
+ expect(Load.logger).to receive(:debug).with(/Ignoring.*setting_with_override/)
99
+ subject
100
+ expect(configuration.setting_with_override).to eq "overridden"
101
+ end
102
+
75
103
  it "does not load a setting where the Configuration object does not have a matching property" do
76
- allow(Load.logger).to receive(:warn)
77
- expect(Load.logger).to receive(:warn).with("Could not load configuration setting \"unknown\" as there is no matching attribute on the Configuration class")
104
+ expect(Load.logger).to receive(:warn).with("Could not load configuration setting \"unknown\" as there is no matching attribute on the PactBroker::Config::MockConfig class")
78
105
  subject
79
106
  end
80
107
  end
@@ -0,0 +1,22 @@
1
+ require "pact_broker/config/runtime_configuration_logging_methods"
2
+
3
+ module PactBroker
4
+ module Config
5
+ describe RuntimeConfigurationLoggingMethods do
6
+ let(:string_io) { StringIO.new }
7
+ let(:logger) { Logger.new(string_io) }
8
+ let(:initial_values) { { database_password: "foo", database_url: "protocol://username:password@host/database"} }
9
+ let(:runtime_configuration) { RuntimeConfiguration.new(initial_values) }
10
+
11
+ subject do
12
+ runtime_configuration.log_configuration(logger)
13
+ string_io.string
14
+ end
15
+
16
+ it "redacts the sensitive values" do
17
+ expect(subject).to include "database_password=*****"
18
+ expect(subject).to include "database_url=protocol://username:*****@host/database"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,71 @@
1
+ require "pact_broker/config/runtime_configuration"
2
+
3
+ module PactBroker
4
+ module Config
5
+ describe RuntimeConfiguration do
6
+ describe "base_url" do
7
+ it "does not expose base_url for delegation" do
8
+ expect(RuntimeConfiguration.getter_and_setter_method_names).to_not include :base_url
9
+ end
10
+
11
+ it "does not support the method base_url as base_urls should be used instead" do
12
+ expect { RuntimeConfiguration.new.base_url }.to raise_error NotImplementedError
13
+ end
14
+ end
15
+
16
+ context "with a base_url and base_urls as strings" do
17
+ subject do
18
+ runtime_configuration = RuntimeConfiguration.new
19
+ runtime_configuration.base_url = "foo blah"
20
+ runtime_configuration.base_urls = "bar wiffle"
21
+ runtime_configuration
22
+ end
23
+
24
+ its(:base_urls) { is_expected.to eq %w[bar wiffle foo blah] }
25
+ end
26
+
27
+ context "with a base_url and base_urls as the same strings" do
28
+ subject do
29
+ runtime_configuration = RuntimeConfiguration.new
30
+ runtime_configuration.base_url = "foo blah"
31
+ runtime_configuration.base_urls = "foo meep"
32
+ runtime_configuration
33
+ end
34
+
35
+ its(:base_urls) { is_expected.to eq %w[foo meep blah] }
36
+ end
37
+
38
+ context "with just base_url as a string" do
39
+ subject do
40
+ runtime_configuration = RuntimeConfiguration.new
41
+ runtime_configuration.base_url = "foo blah"
42
+ runtime_configuration
43
+ end
44
+
45
+ its(:base_urls) { is_expected.to eq %w[foo blah] }
46
+ end
47
+
48
+ context "with just base_urls as a string" do
49
+ subject do
50
+ runtime_configuration = RuntimeConfiguration.new
51
+ runtime_configuration.base_url = nil
52
+ runtime_configuration.base_urls = "bar wiffle"
53
+ runtime_configuration
54
+ end
55
+
56
+ its(:base_urls) { is_expected.to eq %w[bar wiffle] }
57
+ end
58
+
59
+ context "with base_url and base_urls as arrays" do
60
+ subject do
61
+ runtime_configuration = RuntimeConfiguration.new
62
+ runtime_configuration.base_url = %w[foo blah]
63
+ runtime_configuration.base_urls = %w[bar wiffle]
64
+ runtime_configuration
65
+ end
66
+
67
+ its(:base_urls) { is_expected.to eq %w[bar wiffle foo blah] }
68
+ end
69
+ end
70
+ end
71
+ end
@@ -5,7 +5,6 @@ require "pact_broker/config/setting"
5
5
 
6
6
  module PactBroker
7
7
  describe Configuration do
8
-
9
8
  describe "show_backtrace_in_error_response?" do
10
9
  before do
11
10
  allow(ENV).to receive(:[]).and_call_original
@@ -36,7 +35,54 @@ module PactBroker
36
35
  end
37
36
  end
38
37
 
39
- context "default configuration" do
38
+ describe "with_runtime_configuration_overrides" do
39
+ before do
40
+ allow(PactBroker.configuration).to receive(:logger).and_return(logger)
41
+ end
42
+ let(:logger) { double("logger", debug?: true, debug: nil, warn: nil) }
43
+
44
+ it "overrides the specified runtime configuration attributes within the block" do
45
+ attribute_in_block = nil
46
+ PactBroker.with_runtime_configuration_overrides(disable_ssl_verification: "true") do
47
+ attribute_in_block = PactBroker.configuration.disable_ssl_verification
48
+ end
49
+ expect(attribute_in_block).to eq true
50
+ expect(PactBroker.configuration.disable_ssl_verification).to eq false
51
+ end
52
+
53
+ it "logs the overrides at debug level" do
54
+ expect(logger).to receive(:debug).with("Overridding runtime configuration", payload: hash_including(overrides: { disable_ssl_verification: true }))
55
+ PactBroker.with_runtime_configuration_overrides(disable_ssl_verification: "true") do
56
+ "foo"
57
+ end
58
+ end
59
+
60
+ it "does not override the other runtime configuration attributes within the block" do
61
+ attribute_in_block = nil
62
+ PactBroker.with_runtime_configuration_overrides(disable_ssl_verification: "true") do
63
+ attribute_in_block = PactBroker.configuration.webhook_scheme_whitelist
64
+ end
65
+ expect(PactBroker.configuration.webhook_scheme_whitelist).to eq attribute_in_block
66
+ end
67
+
68
+ it "returns the results of the block" do
69
+ return_value = PactBroker.with_runtime_configuration_overrides(disable_ssl_verification: "true") do
70
+ "foo"
71
+ end
72
+ expect(return_value).to eq "foo"
73
+ end
74
+
75
+ context "when the specified runtime attribute does not exist" do
76
+ it "logs that it has ignored those attributes" do
77
+ expect(logger).to receive(:debug).with("Overridding runtime configuration", payload: hash_including(ignoring: { no_existy: true }))
78
+ PactBroker.with_runtime_configuration_overrides(no_existy: "true") do
79
+ "foo"
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "default configuration" do
40
86
  describe ".html_pact_renderer" do
41
87
 
42
88
  let(:pact) { double("pact") }
@@ -55,8 +101,8 @@ module PactBroker
55
101
  end
56
102
 
57
103
  it "allows setting the whitelist by an array" do
58
- PactBroker.configuration.webhook_http_method_whitelist = ["foo"]
59
- expect(PactBroker.configuration.webhook_http_method_whitelist).to be_a Config::SpaceDelimitedStringList
104
+ PactBroker.configuration.webhook_http_method_whitelist = ["foo", "/.*/"]
105
+ expect(PactBroker.configuration.webhook_http_method_whitelist).to eq ["foo", /.*/]
60
106
  end
61
107
  end
62
108
 
@@ -68,7 +114,7 @@ module PactBroker
68
114
 
69
115
  it "allows setting the 'webhook_http_code_success' by an array" do
70
116
  PactBroker.configuration.webhook_http_code_success = [200, 201, 202]
71
- expect(PactBroker.configuration.webhook_http_code_success).to be_a Config::SpaceDelimitedIntegerList
117
+ expect(PactBroker.configuration.webhook_http_code_success).to eq [200, 201, 202]
72
118
  end
73
119
  end
74
120
 
@@ -86,26 +132,6 @@ module PactBroker
86
132
  end
87
133
  end
88
134
 
89
- describe "SETTING_NAMES" do
90
- let(:configuration) { PactBroker::Configuration.new}
91
-
92
- Configuration::SAVABLE_SETTING_NAMES.each do | setting_name |
93
- describe setting_name do
94
- it "exists as a method on a PactBroker::Configuration instance" do
95
- expect(configuration).to respond_to(setting_name)
96
- end
97
- end
98
- end
99
- end
100
-
101
- describe "save_to_database" do
102
- let(:configuration) { PactBroker::Configuration.default_configuration }
103
-
104
- it "saves the configuration to the database" do
105
- expect { configuration.save_to_database }.to change { PactBroker::Config::Setting.count }.by(Configuration::SAVABLE_SETTING_NAMES.size)
106
- end
107
- end
108
-
109
135
  describe "load_from_database!" do
110
136
  let(:configuration) { PactBroker::Configuration.new }
111
137
 
@@ -18,6 +18,9 @@ module PactBroker
18
18
  subject { ErrorLogger.call(error, error_reference, env) }
19
19
 
20
20
  context "when the error class is in the warning_error_classes list" do
21
+ before do
22
+ allow(PactBroker.configuration).to receive(:warning_error_classes).and_return([Sequel::ForeignKeyConstraintViolation])
23
+ end
21
24
  let(:error) { Sequel::ForeignKeyConstraintViolation.new }
22
25
 
23
26
  it "logs at warn so as not to wake everyone up in the middle of the night" do
@@ -1,32 +1,31 @@
1
1
  require "pact_broker/feature_toggle"
2
+ require "anyway/testing/helpers"
2
3
 
3
4
  module PactBroker
4
5
  describe FeatureToggle do
5
6
  describe "enabled?" do
6
- before do
7
- allow(ENV).to receive(:[]).and_call_original
8
- end
7
+ include Anyway::Testing::Helpers
9
8
 
10
9
  let(:ignore_env) { false }
11
10
 
12
11
  subject { FeatureToggle.enabled?(:foo, ignore_env) }
13
12
 
14
13
  context "when RACK_ENV is not production" do
15
- before do
16
- allow(ENV).to receive(:[]).with("RACK_ENV").and_return("development")
14
+ around do | example |
15
+ with_env("RACK_ENV" => "development", &example)
17
16
  end
18
17
 
19
18
  context "when PACT_BROKER_FEATURES includes the given string" do
20
- before do
21
- allow(ENV).to receive(:[]).with("PACT_BROKER_FEATURES").and_return("foo bar")
19
+ around do | example |
20
+ with_env("PACT_BROKER_FEATURES" => "foo bar", &example)
22
21
  end
23
22
 
24
23
  it { is_expected.to be true }
25
24
  end
26
25
 
27
26
  context "when PACT_BROKER_FEATURES does not include the given string" do
28
- before do
29
- allow(ENV).to receive(:[]).with("PACT_BROKER_FEATURES").and_return(nil)
27
+ around do | example |
28
+ with_env("PACT_BROKER_FEATURES" => "", &example)
30
29
  end
31
30
 
32
31
  it { is_expected.to be true }
@@ -40,37 +39,37 @@ module PactBroker
40
39
  end
41
40
 
42
41
  context "when RACK_ENV is production" do
43
- before do
44
- allow(ENV).to receive(:[]).with("RACK_ENV").and_return("production")
42
+ around do | example |
43
+ with_env("RACK_ENV" => "production", &example)
45
44
  end
46
45
 
47
46
  context "when PACT_BROKER_FEATURES includes the given string" do
48
- before do
49
- allow(ENV).to receive(:[]).with("PACT_BROKER_FEATURES").and_return("foo bar")
47
+ around do | example |
48
+ with_env("PACT_BROKER_FEATURES" => "foo bar", &example)
50
49
  end
51
50
 
52
51
  it { is_expected.to be true }
53
52
  end
54
53
 
55
54
  context "when PACT_BROKER_FEATURES includes the given string inside another word" do
56
- before do
57
- allow(ENV).to receive(:[]).with("PACT_BROKER_FEATURES").and_return("foowiffle bar")
55
+ around do | example |
56
+ with_env("PACT_BROKER_FEATURES" => "foowiffle bar", &example)
58
57
  end
59
58
 
60
59
  it { is_expected.to be false }
61
60
  end
62
61
 
63
62
  context "when PACT_BROKER_FEATURES includes the given string but the case doesn't match" do
64
- before do
65
- allow(ENV).to receive(:[]).with("PACT_BROKER_FEATURES").and_return("FOO bar")
63
+ around do | example |
64
+ with_env("PACT_BROKER_FEATURES" => "FOO bar", &example)
66
65
  end
67
66
 
68
67
  it { is_expected.to be true }
69
68
  end
70
69
 
71
70
  context "when PACT_BROKER_FEATURES does not include the given string" do
72
- before do
73
- allow(ENV).to receive(:[]).with("PACT_BROKER_FEATURES").and_return(nil)
71
+ around do | example |
72
+ with_env("PACT_BROKER_FEATURES" => nil, &example)
74
73
  end
75
74
 
76
75
  it { is_expected.to be false }
@@ -4,6 +4,10 @@ module PactBroker
4
4
  module Matrix
5
5
  describe Service do
6
6
  describe "find with environments" do
7
+ include MatrixQueryContentForApproval
8
+
9
+ ENVIRONMENT_APPROVALS = {}
10
+
7
11
  subject { Service.can_i_deploy(selectors, options) }
8
12
 
9
13
  # Useful for eyeballing the messages to make sure they read nicely
@@ -15,6 +19,14 @@ module PactBroker
15
19
  # end
16
20
  # end
17
21
 
22
+ after do | example |
23
+ ENVIRONMENT_APPROVALS[example.full_description] = matrix_query_content_for_approval(subject)
24
+ end
25
+
26
+ after(:all) do
27
+ Approvals.verify(ENVIRONMENT_APPROVALS, :name => file_name_to_approval_name(__FILE__) , format: :json)
28
+ end
29
+
18
30
  context "when there is a successful verification between the provider in test environment and the consumer to be deployed" do
19
31
  before do
20
32
  td.create_environment("test")
@@ -4,6 +4,10 @@ module PactBroker
4
4
  module Matrix
5
5
  describe Service do
6
6
  describe "find" do
7
+ include MatrixQueryContentForApproval
8
+
9
+ INTEGRATION_IGNORE_APPROVALS = {}
10
+
7
11
  subject { Service.can_i_deploy(selectors, options) }
8
12
 
9
13
  # Useful for eyeballing the messages to make sure they read nicely
@@ -15,6 +19,14 @@ module PactBroker
15
19
  # end
16
20
  end
17
21
 
22
+ after do | example |
23
+ INTEGRATION_IGNORE_APPROVALS[example.full_description] = matrix_query_content_for_approval(subject)
24
+ end
25
+
26
+ after(:all) do
27
+ Approvals.verify(INTEGRATION_IGNORE_APPROVALS, :name => file_name_to_approval_name(__FILE__) , format: :json)
28
+ end
29
+
18
30
  let(:options) { {} }
19
31
 
20
32
  shared_examples_for "without any ignore selectors" do
@@ -187,9 +199,9 @@ module PactBroker
187
199
 
188
200
  let(:ignore_selectors) { [] }
189
201
 
190
- it "does allows the provider to be deployed even without ignoring anything because there is no connection between that version of the provider and the consumer" do
191
- expect(subject.deployment_status_summary).to be_deployable
192
- expect(subject.deployment_status_summary.reasons.collect(&:class)).to include(PactBroker::Matrix::NoDependenciesMissing)
202
+ it "does not allows the provider to be deployed" do
203
+ expect(subject.deployment_status_summary).to_not be_deployable
204
+ expect(subject.deployment_status_summary.reasons.collect(&:class)).to include(PactBroker::Matrix::PactNotEverVerifiedByProvider)
193
205
  end
194
206
  end
195
207
 
@@ -4,6 +4,10 @@ module PactBroker
4
4
  module Matrix
5
5
  describe Service do
6
6
  describe "find" do
7
+ include MatrixQueryContentForApproval
8
+
9
+ INTEGRATION_APPROVALS = {}
10
+
7
11
  subject { Service.can_i_deploy(selectors, options) }
8
12
 
9
13
  # Useful for eyeballing the messages to make sure they read nicely
@@ -15,6 +19,14 @@ module PactBroker
15
19
  # end
16
20
  # end
17
21
 
22
+ after do | example |
23
+ INTEGRATION_APPROVALS[example.full_description] = matrix_query_content_for_approval(subject)
24
+ end
25
+
26
+ after(:all) do
27
+ Approvals.verify(INTEGRATION_APPROVALS, :name => file_name_to_approval_name(__FILE__) , format: :json)
28
+ end
29
+
18
30
  let(:options) { {} }
19
31
 
20
32
  describe "find" do
@@ -69,12 +81,16 @@ module PactBroker
69
81
  [ UnresolvedSelector.new(pacticipant_name: "Foo", pacticipant_version_number: "1") ]
70
82
  end
71
83
 
84
+ let(:options) do
85
+ { latest: true, tag: "prod", latestby: "cvp" }
86
+ end
87
+
72
88
  it "returns 2 integrations" do
73
89
  expect(subject.integrations.size).to eq 2
74
90
  end
75
91
 
76
- it "but cannot resolve selectors for the providers" do
77
- expect(subject.resolved_selectors.size).to eq 1
92
+ it "it creates selectors for the providers" do
93
+ expect(subject.resolved_selectors.size).to eq 3
78
94
  end
79
95
 
80
96
  it "does not allow the consumer to be deployed" do
@@ -99,7 +115,7 @@ module PactBroker
99
115
  [ UnresolvedSelector.new(pacticipant_name: "Foo", pacticipant_version_number: "3.0.0") ]
100
116
  end
101
117
 
102
- let(:options) { {latest: true, tag: "prod", latestby: "cvp"} }
118
+ let(:options) { { latest: true, tag: "prod", latestby: "cvp" } }
103
119
 
104
120
  it "returns 2 integrations" do
105
121
  expect(subject.integrations.size).to eq 2
@@ -121,7 +137,7 @@ module PactBroker
121
137
  describe "when deploying an old version of a consumer that has added a new provider since that version" do
122
138
  before do
123
139
  td.create_pact_with_hierarchy("Foo", "1", "Bar")
124
- .create_verification(provider_version: "2")
140
+ .create_verification(provider_version: "2", tag_names: ["prod"])
125
141
  .create_consumer_version("2")
126
142
  .create_pact
127
143
  .create_verification(provider_version: "3")
@@ -134,6 +150,8 @@ module PactBroker
134
150
  [ UnresolvedSelector.new(pacticipant_name: "Foo", pacticipant_version_number: "1") ]
135
151
  end
136
152
 
153
+ let(:options) { { latest: true, tag: "prod", latestby: "cvp" } }
154
+
137
155
  it "allows the old version of the consumer to be deployed" do
138
156
  expect(subject.deployment_status_summary).to be_deployable
139
157
  end
@@ -408,13 +426,36 @@ module PactBroker
408
426
  ]
409
427
  end
410
428
 
411
- let(:options) { { latestby: "cvpv"} }
429
+ let(:options) { { latestby: "cvpv" } }
412
430
 
413
- it "should allow the consumer to be deployed" do
431
+ it "allows the consumer to be deployed" do
414
432
  expect(subject.deployment_status_summary).to be_deployable
415
433
  end
416
434
  end
417
435
 
436
+ # https://github.com/pact-foundation/pact_broker/issues/485
437
+ describe "when a provider version has no verification results with the consumer version already in the environment" do
438
+ before do
439
+ td.create_pact_with_verification("Foo", "1", "Bar", "1")
440
+ .create_pact_with_verification("NotInTest", "1", "Bar", "1")
441
+ .create_consumer_version_tag("test")
442
+ .create_provider_version("2")
443
+ end
444
+
445
+ let(:selectors) do
446
+ [
447
+ UnresolvedSelector.new(pacticipant_name: "Bar", pacticipant_version_number: "2"),
448
+ ]
449
+ end
450
+
451
+ let(:options) { { latestby: "cvp", tag: "test", latest: true } }
452
+
453
+ it "does not allow the provider to be deployed" do
454
+ expect(subject.deployment_status_summary).to_not be_deployable
455
+ expect(subject.deployment_status_summary.reasons.collect(&:class)).to eq [PactBroker::Matrix::PactNotEverVerifiedByProvider]
456
+ end
457
+ end
458
+
418
459
  describe "when verification results are published missing tests for some interactions" do
419
460
  let(:pact_content) do
420
461
  {