pact_broker 2.83.0 → 2.84.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/Dockerfile +1 -1
  4. data/db/migrations/20210816_create_branches_tables.rb +40 -0
  5. data/db/migrations/20210831_add_index_to_pact_publications.rb +7 -0
  6. data/db/migrations/20210908_add_auto_created.rb +24 -0
  7. data/issue-reproduction/Dockerfile-pact-broker +1 -1
  8. data/lib/pact_broker/api/contracts/{verifiable_pacts_json_query_schema.rb → pacts_for_verification_json_query_schema.rb} +1 -1
  9. data/lib/pact_broker/api/contracts/{verifiable_pacts_query_schema.rb → pacts_for_verification_query_string_schema.rb} +1 -1
  10. data/lib/pact_broker/api/decorators/branch_version_decorator.rb +20 -0
  11. data/lib/pact_broker/api/decorators/dashboard_decorator.rb +4 -2
  12. data/lib/pact_broker/api/decorators/embedded_branch_version_decorator.rb +21 -0
  13. data/lib/pact_broker/api/decorators/embedded_tag_decorator.rb +0 -5
  14. data/lib/pact_broker/api/decorators/matrix_decorator.rb +11 -2
  15. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +8 -0
  16. data/lib/pact_broker/api/decorators/{verifiable_pacts_query_decorator.rb → pacts_for_verification_query_decorator.rb} +2 -2
  17. data/lib/pact_broker/api/decorators/version_decorator.rb +1 -1
  18. data/lib/pact_broker/api/pact_broker_urls.rb +8 -0
  19. data/lib/pact_broker/api/resources/branch_version.rb +48 -0
  20. data/lib/pact_broker/api/resources/index.rb +6 -0
  21. data/lib/pact_broker/api/resources/provider_pacts_for_verification.rb +6 -6
  22. data/lib/pact_broker/api/resources/version.rb +0 -8
  23. data/lib/pact_broker/api.rb +1 -0
  24. data/lib/pact_broker/config/runtime_configuration.rb +12 -0
  25. data/lib/pact_broker/contracts/service.rb +1 -1
  26. data/lib/pact_broker/db/data_migrations/create_branches.rb +97 -0
  27. data/lib/pact_broker/db/data_migrations/set_pacticipant_main_branch.rb +2 -0
  28. data/lib/pact_broker/db/migrate_data.rb +1 -1
  29. data/lib/pact_broker/db/models.rb +6 -0
  30. data/lib/pact_broker/deployments/deployed_version.rb +4 -0
  31. data/lib/pact_broker/deployments/deployed_version_service.rb +4 -3
  32. data/lib/pact_broker/deployments/environment.rb +4 -0
  33. data/lib/pact_broker/deployments/environment_service.rb +13 -8
  34. data/lib/pact_broker/doc/views/index/pacticipant-branch-version.markdown +14 -0
  35. data/lib/pact_broker/doc/views/webhooks.markdown +1 -0
  36. data/lib/pact_broker/domain/index_item.rb +15 -17
  37. data/lib/pact_broker/domain/pacticipant.rb +11 -0
  38. data/lib/pact_broker/domain/tag.rb +1 -2
  39. data/lib/pact_broker/domain/verification.rb +16 -13
  40. data/lib/pact_broker/domain/version.rb +87 -33
  41. data/lib/pact_broker/index/service.rb +8 -4
  42. data/lib/pact_broker/locale/en.yml +1 -0
  43. data/lib/pact_broker/matrix/quick_row.rb +6 -6
  44. data/lib/pact_broker/metrics/service.rb +7 -1
  45. data/lib/pact_broker/pacts/pact_publication.rb +22 -25
  46. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +74 -33
  47. data/lib/pact_broker/pacts/pact_publication_selector_dataset_module.rb +18 -13
  48. data/lib/pact_broker/pacts/pact_publication_wip_dataset_module.rb +16 -4
  49. data/lib/pact_broker/pacts/pact_version.rb +11 -0
  50. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +3 -3
  51. data/lib/pact_broker/pacts/selected_pact.rb +2 -2
  52. data/lib/pact_broker/pacts/selector.rb +98 -33
  53. data/lib/pact_broker/repositories.rb +5 -0
  54. data/lib/pact_broker/services.rb +9 -0
  55. data/lib/pact_broker/test/http_test_data_builder.rb +32 -7
  56. data/lib/pact_broker/test/test_data_builder.rb +25 -24
  57. data/lib/pact_broker/ui/view_models/index_item.rb +11 -0
  58. data/lib/pact_broker/ui/view_models/matrix_branch.rb +39 -0
  59. data/lib/pact_broker/ui/view_models/matrix_line.rb +11 -16
  60. data/lib/pact_broker/ui/views/index/show-with-tags.haml +12 -11
  61. data/lib/pact_broker/ui/views/matrix/show.haml +8 -8
  62. data/lib/pact_broker/version.rb +1 -1
  63. data/lib/pact_broker/versions/branch.rb +29 -0
  64. data/lib/pact_broker/versions/branch_head.rb +45 -0
  65. data/lib/pact_broker/versions/branch_service.rb +24 -0
  66. data/lib/pact_broker/versions/branch_version.rb +64 -0
  67. data/lib/pact_broker/versions/branch_version_repository.rb +34 -0
  68. data/lib/pact_broker/versions/eager_loaders.rb +0 -42
  69. data/lib/pact_broker/versions/repository.rb +25 -12
  70. data/lib/pact_broker/versions/service.rb +3 -22
  71. data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +11 -2
  72. data/lib/sequel/plugins/insert_ignore.rb +4 -0
  73. data/lib/sequel/plugins/upsert.rb +4 -0
  74. data/public/javascripts/index.js +129 -34
  75. data/scaffolding/templates/decorator.rb.erb +3 -1
  76. data/scaffolding/templates/migration.erb +1 -1
  77. data/scaffolding/templates/model.erb +2 -2
  78. data/scaffolding/templates/repository.rb.erb +2 -2
  79. data/scaffolding/templates/repository_spec.rb.erb +1 -1
  80. data/scaffolding/templates/resource.erb +2 -2
  81. data/scaffolding/templates/resource_spec.rb.erb +1 -1
  82. data/scaffolding/templates/service.rb.erb +3 -3
  83. data/scaffolding/templates/service_spec.rb.erb +1 -1
  84. data/script/data/branches.rb +35 -0
  85. data/script/data/issue-494.rb +25 -0
  86. data/spec/features/create_branch_version_spec.rb +29 -0
  87. data/spec/features/create_tag_spec.rb +1 -1
  88. data/spec/features/create_version_spec.rb +2 -4
  89. data/spec/features/get_branch_version_spec.rb +12 -0
  90. data/spec/features/publish_pact_all_in_one_spec.rb +0 -1
  91. data/spec/features/update_version_spec.rb +0 -55
  92. data/spec/fixtures/approvals/modifiable_resources.approved.json +3 -0
  93. data/spec/fixtures/approvals/publish_contract_nothing_exists.approved.json +1 -2
  94. data/spec/fixtures/approvals/publish_contract_nothing_exists_with_webhook.approved.json +1 -2
  95. data/spec/fixtures/approvals/publish_contract_verification_already_exists.approved.json +1 -2
  96. data/spec/fixtures/dashboard.json +4 -2
  97. data/spec/integration/ui/index_spec.rb +0 -2
  98. data/spec/integration/ui/matrix_spec.rb +0 -1
  99. data/spec/lib/pact_broker/api/contracts/{verifiable_pacts_json_query_schema_combinations_spec.rb → pacts_for_verification_json_query_schema_combinations_spec.rb} +6 -6
  100. data/spec/lib/pact_broker/api/contracts/{verifiable_pacts_json_query_schema_spec.rb → pacts_for_verification_json_query_schema_spec.rb} +3 -3
  101. data/spec/lib/pact_broker/api/contracts/{verifiable_pacts_query_schema_spec.rb → pacts_for_verification_query_string_schema_spec.rb} +3 -3
  102. data/spec/lib/pact_broker/api/decorators/dashboard_decorator_spec.rb +7 -7
  103. data/spec/lib/pact_broker/api/decorators/matrix_decorator_spec.rb +19 -4
  104. data/spec/lib/pact_broker/api/decorators/{verifiable_pacts_query_decorator_spec.rb → pacts_for_verification_query_decorator_spec.rb} +3 -3
  105. data/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +7 -3
  106. data/spec/lib/pact_broker/contracts/service_spec.rb +24 -3
  107. data/spec/lib/pact_broker/db/data_migrations/create_branches_spec.rb +57 -0
  108. data/spec/lib/pact_broker/domain/index_item_spec.rb +1 -1
  109. data/spec/lib/pact_broker/domain/version_spec.rb +1 -35
  110. data/spec/lib/pact_broker/metrics/service_spec.rb +4 -1
  111. data/spec/lib/pact_broker/pacts/pact_publication_dataset_module_spec.rb +109 -10
  112. data/spec/lib/pact_broker/pacts/pact_publication_selector_dataset_module_spec.rb +3 -2
  113. data/spec/lib/pact_broker/pacts/pact_publication_spec.rb +5 -5
  114. data/spec/lib/pact_broker/pacts/repository_find_for_currently_deployed_spec.rb +2 -2
  115. data/spec/lib/pact_broker/pacts/repository_find_for_currently_supported_releases_spec.rb +2 -2
  116. data/spec/lib/pact_broker/pacts/selector_spec.rb +45 -3
  117. data/spec/lib/pact_broker/pacts/verifiable_pact_messages_spec.rb +5 -5
  118. data/spec/lib/pact_broker/relationships/groupify_spec.rb +0 -5
  119. data/spec/lib/pact_broker/ui/view_models/index_item_spec.rb +15 -3
  120. data/spec/lib/pact_broker/verifications/repository_spec.rb +1 -1
  121. data/spec/lib/pact_broker/versions/branch_service_spec.rb +71 -0
  122. data/spec/lib/pact_broker/versions/branch_version_repository_spec.rb +81 -0
  123. data/spec/lib/pact_broker/versions/branch_version_spec.rb +27 -0
  124. data/spec/lib/pact_broker/versions/repository_spec.rb +91 -6
  125. data/spec/lib/pact_broker/versions/service_spec.rb +4 -3
  126. data/spec/lib/pact_broker/webhooks/render_spec.rb +6 -0
  127. data/spec/lib/sequel/plugins/upsert_spec.rb +11 -5
  128. data/spec/migrations/44_add_provider_version_to_verification_spec.rb +6 -9
  129. metadata +42 -15
  130. data/lib/pact_broker/versions/lazy_loaders.rb +0 -13
@@ -43,6 +43,7 @@ module PactBroker
43
43
  .create_pact
44
44
  .create_consumer_version("2", branch: "main")
45
45
  .create_pact
46
+ .revise_pact
46
47
  .create_consumer_version("3", branch: "not-main")
47
48
  .create_pact
48
49
  .create_consumer("Bob", main_branch: "develop")
@@ -62,12 +63,12 @@ module PactBroker
62
63
  it "returns the latest pact for the main branch of every consumer" do
63
64
  expect(subject.size).to eq 2
64
65
  expect(subject.sort_by(&:id).first.consumer.name).to eq "Foo"
65
- expect(subject.sort_by(&:id).first.consumer_version.branch).to eq "main"
66
66
  expect(subject.sort_by(&:id).first.consumer_version.number).to eq "2"
67
+ expect(subject.sort_by(&:id).first.values[:branch_name]).to eq "main"
67
68
 
68
69
  expect(subject.sort_by(&:id).last.consumer.name).to eq "Bob"
69
- expect(subject.sort_by(&:id).last.consumer_version.branch).to eq "develop"
70
70
  expect(subject.sort_by(&:id).last.consumer_version.number).to eq "5"
71
+ expect(subject.sort_by(&:id).last.values[:branch_name]).to eq "develop"
71
72
  end
72
73
  end
73
74
 
@@ -256,9 +256,9 @@ module PactBroker
256
256
  expect(subject.size).to eq 3
257
257
  subject.collect(&:values)
258
258
 
259
- expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch] == "main" }.consumer_version.number).to eq "3"
260
- expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch] == "feat/x" }.consumer_version.number).to eq "4"
261
- expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp[:branch] == "main" }.consumer_version.number).to eq "6"
259
+ expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "3"
260
+ expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch_name] == "feat/x" }.consumer_version.number).to eq "4"
261
+ expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "6"
262
262
  end
263
263
 
264
264
  context "chained with created after" do
@@ -267,8 +267,8 @@ module PactBroker
267
267
  its(:size) { is_expected.to eq 2 }
268
268
 
269
269
  it "returns the right versions" do
270
- expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch] == "feat/x" }.consumer_version.number).to eq "4"
271
- expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp[:branch] == "main" }.consumer_version.number).to eq "6"
270
+ expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch_name] == "feat/x" }.consumer_version.number).to eq "4"
271
+ expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "6"
272
272
  end
273
273
  end
274
274
  end
@@ -114,8 +114,8 @@ module PactBroker
114
114
  it "returns one pact_publication with multiple selectors" do
115
115
  expect(subject.size).to eq 1
116
116
  expect(subject.first.selectors.size).to eq 2
117
- expect(subject.first.selectors.first.environment.name).to eq "test"
118
- expect(subject.first.selectors.last.environment.name).to eq "prod"
117
+ expect(subject.first.selectors.first.environment.name).to eq "prod"
118
+ expect(subject.first.selectors.last.environment.name).to eq "test"
119
119
  end
120
120
  end
121
121
  end
@@ -149,8 +149,8 @@ module PactBroker
149
149
  it "returns one pact_publication with multiple selectors" do
150
150
  expect(subject.size).to eq 1
151
151
  expect(subject.first.selectors.size).to eq 2
152
- expect(subject.first.selectors.first.environment.name).to eq "test"
153
- expect(subject.first.selectors.last.environment.name).to eq "prod"
152
+ expect(subject.first.selectors.first.environment.name).to eq "prod"
153
+ expect(subject.first.selectors.last.environment.name).to eq "test"
154
154
  end
155
155
  end
156
156
  end
@@ -12,23 +12,65 @@ module PactBroker
12
12
  let(:all_prod_for_consumer_1) { Selector.all_for_tag_and_consumer("prod", "Foo") }
13
13
  let(:all_prod_for_consumer_2) { Selector.all_for_tag_and_consumer("prod", "Bar") }
14
14
  let(:all_dev_for_consumer_1) { Selector.all_for_tag_and_consumer("dev", "Bar") }
15
- let(:all_prod) { Selector.all_for_tag("prod") }
15
+ let(:all_tagged_prod) { Selector.all_for_tag("prod") }
16
16
  let(:all_dev) { Selector.all_for_tag("dev") }
17
17
  let(:currently_deployed_to_prod) { Selector.for_currently_deployed("prod") }
18
18
  let(:currently_deployed_to_test) { Selector.for_currently_deployed("test") }
19
19
  let(:currently_supported_in_prod) { Selector.for_currently_supported("prod") }
20
20
 
21
21
  let(:unsorted_selectors) do
22
- [currently_supported_in_prod, all_prod, all_dev, currently_deployed_to_prod, all_dev_for_consumer_1, latest_for_branch_main, latest_for_tag_prod, currently_deployed_to_test, overall_latest_1, overall_latest_1, latest_for_tag_dev, all_prod_for_consumer_2, all_prod_for_consumer_1]
22
+ [currently_supported_in_prod, all_tagged_prod, all_dev, currently_deployed_to_prod, all_dev_for_consumer_1, latest_for_branch_main, latest_for_tag_prod, currently_deployed_to_test, overall_latest_1, overall_latest_1, latest_for_tag_dev, all_prod_for_consumer_2, all_prod_for_consumer_1]
23
23
  end
24
24
 
25
25
  let(:expected_sorted_selectors) do
26
- [overall_latest_1, overall_latest_1, latest_for_branch_main, currently_deployed_to_prod, currently_deployed_to_test, currently_supported_in_prod, latest_for_tag_dev, latest_for_tag_prod, all_dev_for_consumer_1, all_prod_for_consumer_2, all_prod_for_consumer_1, all_dev, all_prod]
26
+ [
27
+ overall_latest_1,
28
+ overall_latest_1,
29
+ latest_for_branch_main,
30
+ latest_for_tag_dev,
31
+ latest_for_tag_prod,
32
+ all_dev_for_consumer_1,
33
+ all_dev,
34
+ all_prod_for_consumer_2,
35
+ all_prod_for_consumer_1,
36
+ all_tagged_prod,
37
+ currently_deployed_to_prod,
38
+ currently_deployed_to_test,
39
+ currently_supported_in_prod,
40
+ ]
27
41
  end
28
42
 
29
43
  it "sorts the selectors" do
30
44
  expect(unsorted_selectors.sort).to eq(expected_sorted_selectors)
31
45
  end
46
+
47
+ context "with resolved selectors" do
48
+ let(:currently_deployed_to_prod) { Selector.for_currently_deployed("prod").resolve_for_environment(double("version", order: 1), double("environment", name: "prod", production?: true)) }
49
+ let(:currently_deployed_to_test) { Selector.for_currently_deployed("test").resolve_for_environment(double("version", order: 1), double("environment", name: "test", production?: false)) }
50
+ let(:currently_supported_in_prod) { Selector.for_currently_supported("prod").resolve_for_environment(double("version", order: 1), double("environment", name: "prod", production?: true)) }
51
+
52
+ let(:expected_sorted_selectors) do
53
+ [
54
+ overall_latest_1,
55
+ overall_latest_1,
56
+ latest_for_branch_main,
57
+ latest_for_tag_dev,
58
+ latest_for_tag_prod,
59
+ all_dev_for_consumer_1,
60
+ all_dev,
61
+ all_prod_for_consumer_2,
62
+ all_prod_for_consumer_1,
63
+ all_tagged_prod,
64
+ currently_deployed_to_test,
65
+ currently_deployed_to_prod,
66
+ currently_supported_in_prod,
67
+ ]
68
+ end
69
+
70
+ it "sorts the selectors" do
71
+ expect(unsorted_selectors.sort).to eq(expected_sorted_selectors)
72
+ end
73
+ end
32
74
  end
33
75
  end
34
76
  end
@@ -27,9 +27,9 @@ module PactBroker
27
27
  )
28
28
  end
29
29
  let(:consumer_version) { double("version", number: "1234", order: 1) }
30
- let(:environment) { instance_double("PactBroker::Deployments::Environment", name: "test") }
30
+ let(:environment) { instance_double("PactBroker::Deployments::Environment", name: "test", production?: false) }
31
31
  let(:test_environment) { environment }
32
- let(:prod_environment) { instance_double("PactBroker::Deployments::Environment", name: "prod") }
32
+ let(:prod_environment) { instance_double("PactBroker::Deployments::Environment", name: "prod", production?: true) }
33
33
 
34
34
  subject { VerifiablePactMessages.new(verifiable_pact, pact_version_url) }
35
35
 
@@ -171,13 +171,13 @@ module PactBroker
171
171
  context "when the consumer version is currently deployed to a multiple environments" do
172
172
  let(:selectors) do
173
173
  Selectors.new(
174
- Selector.for_currently_deployed("dev").resolve_for_environment(consumer_version, double("environment", name: "dev")),
174
+ Selector.for_currently_deployed("dev").resolve_for_environment(consumer_version, double("environment", name: "dev", production?: false)),
175
175
  Selector.for_currently_deployed("test").resolve_for_environment(consumer_version, test_environment),
176
176
  Selector.for_currently_deployed("prod").resolve_for_environment(consumer_version, prod_environment)
177
177
  )
178
178
  end
179
179
 
180
- its(:inclusion_reason) { is_expected.to include "consumer version(s) currently deployed to dev (1234), prod (1234) and test (1234)"}
180
+ its(:inclusion_reason) { is_expected.to include "consumer version(s) currently deployed to dev (1234), test (1234) and prod (1234)"}
181
181
  end
182
182
 
183
183
  context "when the currently deployed consumer version is for a consumer" do
@@ -190,7 +190,7 @@ module PactBroker
190
190
  )
191
191
  end
192
192
 
193
- its(:inclusion_reason) { is_expected.to include "version(s) of Foo currently deployed to prod (1234) and test (1234)"}
193
+ its(:inclusion_reason) { is_expected.to include "version(s) of Foo currently deployed to test (1234) and prod (1234)"}
194
194
  its(:inclusion_reason) { is_expected.to include "version(s) of Bar currently deployed to test (1234)"}
195
195
  its(:inclusion_reason) { is_expected.to include "consumer version(s) currently deployed to test (1234)"}
196
196
  end
@@ -3,11 +3,8 @@ require "pact_broker/relationships/groupify"
3
3
  require "pact_broker/domain/index_item"
4
4
 
5
5
  module PactBroker
6
-
7
6
  module Relationships
8
-
9
7
  describe Groupify do
10
-
11
8
  describe ".call" do
12
9
 
13
10
  let(:consumer_a) { double("consumer a", id: 1, name: "consumer a") }
@@ -40,9 +37,7 @@ module PactBroker
40
37
  expect(groups[1]).to eq(Domain::Group.new(relationship_3))
41
38
  expect(groups[2]).to eq(Domain::Group.new(relationship_5, relationship_6))
42
39
  end
43
-
44
40
  end
45
41
  end
46
-
47
42
  end
48
43
  end
@@ -7,11 +7,13 @@ module PactBroker
7
7
  module ViewDomain
8
8
  describe IndexItem do
9
9
 
10
- let(:consumer) { instance_double("PactBroker::Domain::Pacticipant", name: "Consumer Name")}
11
- let(:provider) { instance_double("PactBroker::Domain::Pacticipant", name: "Provider Name")}
10
+ let(:consumer) { instance_double("PactBroker::Domain::Pacticipant", name: "Consumer Name") }
11
+ let(:provider) { instance_double("PactBroker::Domain::Pacticipant", name: "Provider Name") }
12
+ let(:consumer_version) { instance_double("PactBroker::Domain::Version") }
13
+
12
14
  let(:latest_pact) { instance_double("PactBroker::Domain::Pact", consumer_version_number: "1.2.3") }
13
15
  let(:latest_verification) { instance_double("PactBroker::Domain::Verification") }
14
- let(:domain_relationship) { PactBroker::Domain::IndexItem.new(consumer, provider, latest_pact, latest, latest_verification, [], [], tags, latest_verification_latest_tags)}
16
+ let(:domain_relationship) { PactBroker::Domain::IndexItem.new(consumer, provider, consumer_version, latest_pact, latest, latest_verification, [], [], tags, latest_verification_latest_tags)}
15
17
  let(:tags) { [] }
16
18
  let(:verification_tag_1) { instance_double("PactBroker::Tags::TagWithLatestFlag", name: "dev") }
17
19
  let(:verification_tag_2) { instance_double("PactBroker::Tags::TagWithLatestFlag", name: "prod") }
@@ -135,6 +137,16 @@ module PactBroker
135
137
  its(:provider_version_latest_tag_names) { is_expected.to eq ["dev", "prod"] }
136
138
  end
137
139
 
140
+ describe "tagged_pacts" do
141
+ let(:tags) { ["master", "prod"] }
142
+ its(:tagged_pacts) do
143
+ is_expected.to eq([
144
+ { tag: "master", deletionUrl: "/pacts/provider/Provider%20Name/consumer/Consumer%20Name/tag/master" }.to_json,
145
+ { tag: "prod", deletionUrl: "/pacts/provider/Provider%20Name/consumer/Consumer%20Name/tag/prod" }.to_json
146
+ ])
147
+ end
148
+ end
149
+
138
150
  describe "<=>" do
139
151
 
140
152
  let(:relationship_model_4) { double("PactBroker::Domain::IndexItem", consumer_name: "A", provider_name: "X") }
@@ -36,7 +36,7 @@ module PactBroker
36
36
  end
37
37
 
38
38
  it "sets the tag names" do
39
- expect(subject.reload.tag_names).to eq ["foo", "bar"]
39
+ expect(subject.reload.tag_names.sort).to eq ["bar", "foo"]
40
40
  end
41
41
 
42
42
  it "saves the consumer_version_selector_hashes" do
@@ -0,0 +1,71 @@
1
+ require "pact_broker/versions/branch_service"
2
+
3
+ module PactBroker
4
+ module Versions
5
+ describe BranchService do
6
+ describe ".find_branch_version" do
7
+ before do
8
+ td.create_consumer("Foo")
9
+ .create_consumer_version("1", branch: "main")
10
+ .create_consumer_version("1", branch: "feat/x")
11
+ .create_consumer_version("2", branch: "main")
12
+ end
13
+
14
+ subject { BranchService.find_branch_version(pacticipant_name: "Foo", version_number: "1", branch_name: "main") }
15
+
16
+ its(:version_number) { is_expected.to eq "1" }
17
+ end
18
+
19
+ describe "#create_branch_version" do
20
+ subject { BranchService.find_or_create_branch_version(pacticipant_name: "Foo", version_number: "1", branch_name: "main") }
21
+
22
+ context "when nothing exists" do
23
+ it "creates and returns the branch version" do
24
+ expect(subject.pacticipant.name).to eq "Foo"
25
+ expect(subject.version_number).to eq "1"
26
+ expect(subject.branch_name).to eq "main"
27
+ end
28
+ end
29
+
30
+ context "when everything exists except the branch version" do
31
+ before do
32
+ td.create_consumer("Foo")
33
+ .create_consumer_version("0", branch: "main")
34
+ end
35
+
36
+ it "does not create the branch" do
37
+ expect{ subject }.to_not change { PactBroker::Versions::Branch.where(name: "main").count }
38
+ end
39
+
40
+ it "creates and returns the branch version" do
41
+ expect(subject.pacticipant.name).to eq "Foo"
42
+ expect(subject.version_number).to eq "1"
43
+ expect(subject.branch_name).to eq "main"
44
+ expect(subject.branch_head).to_not be nil
45
+ end
46
+ end
47
+
48
+ context "when everything exists" do
49
+ before do
50
+ td.create_consumer("Foo")
51
+ .create_consumer_version("1", branch: "main")
52
+
53
+ BranchVersion.dataset.update(updated_at: Sequel.datetime_class.now - 10, created_at: Sequel.datetime_class.now - 10)
54
+ end
55
+
56
+ it "does not create a new branch version" do
57
+ expect{ subject }.to_not change { PactBroker::Versions::BranchVersion.count }
58
+ end
59
+
60
+ it "updates the updated_at" do
61
+ expect{ subject }.to change { PactBroker::Versions::BranchVersion.first.updated_at }
62
+ end
63
+
64
+ it "does not change the created_at" do
65
+ expect{ subject }.to_not change { PactBroker::Versions::BranchVersion.first.created_at }
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,81 @@
1
+ require "pact_broker/versions/branch_version_repository"
2
+
3
+ module PactBroker
4
+ module Versions
5
+ describe BranchVersionRepository do
6
+ describe "add_branch" do
7
+ before do
8
+ allow(repository).to receive(:pacticipant_service).and_return(pacticipant_service)
9
+ allow(pacticipant_service).to receive(:maybe_set_main_branch)
10
+ end
11
+ let!(:version) { td.create_consumer("Foo").create_consumer_version("1", branch: "original-branch").and_return(:consumer_version) }
12
+ let(:new_branch_name) { "new-branch" }
13
+ let(:pacticipant_service) { class_double("PactBroker::Pacticipants::Service").as_stubbed_const }
14
+ let(:repository) { BranchVersionRepository.new }
15
+
16
+ subject { repository.add_branch(version, new_branch_name).version.refresh }
17
+
18
+ it "calls the pacticipant_service.maybe_set_main_branch" do
19
+ expect(pacticipant_service).to receive(:maybe_set_main_branch).with(instance_of(PactBroker::Domain::Pacticipant), new_branch_name)
20
+ subject
21
+ end
22
+
23
+ context "when the branch does not already exist" do
24
+ it "default auto_created to false" do
25
+ subject
26
+ expect(PactBroker::Versions::BranchVersion.last.auto_created).to be false
27
+ end
28
+
29
+ it "creates a branch" do
30
+ expect { subject }.to change { PactBroker::Versions::Branch.count }.by(1)
31
+ end
32
+
33
+ it "creates a branch_version" do
34
+ expect { subject }.to change { PactBroker::Versions::BranchVersion.count }.by(1)
35
+ end
36
+
37
+ it "adds the branch_version to the version" do
38
+ expect(subject.branch_versions.count).to eq 2
39
+ expect(subject.branch_versions.last.branch_name).to eq "new-branch"
40
+ end
41
+
42
+ it "updates the branch head" do
43
+ branch_head = subject.pacticipant.branch_head_for("new-branch")
44
+ expect(branch_head.version.id).to eq subject.refresh.id
45
+ end
46
+
47
+ context "when auto_created is true" do
48
+ subject { repository.add_branch(version, new_branch_name, auto_created: true) }
49
+
50
+ it "default auto_created to false" do
51
+ subject
52
+ expect(PactBroker::Versions::BranchVersion.last.auto_created).to be true
53
+ end
54
+ end
55
+ end
56
+
57
+ context "when the branch and branch version do already exist" do
58
+ let(:new_branch_name) { "original-branch" }
59
+
60
+ it "does not creates a branch" do
61
+ expect { subject }.to_not change { PactBroker::Versions::Branch.order(:name).collect(&:name) }
62
+ end
63
+
64
+ it "does not create a branch_version" do
65
+ expect { subject }.to change { PactBroker::Versions::BranchVersion.count }.by(0)
66
+ end
67
+
68
+ it "keeps the branch_version on the version" do
69
+ expect(subject.branch_versions.count).to eq 1
70
+ expect(subject.branch_versions.first.branch_name).to eq "original-branch"
71
+ end
72
+
73
+ it "does not change the branch head" do
74
+ branch_head = subject.pacticipant.branch_head_for("original-branch")
75
+ expect(branch_head.version).to eq subject
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,27 @@
1
+ require "pact_broker/versions/branch_version"
2
+
3
+ module PactBroker
4
+ module Versions
5
+ describe BranchVersion do
6
+ describe "#latest?" do
7
+ before do
8
+ td.create_consumer("Foo")
9
+ .create_consumer_version("2", branch: "foo")
10
+ .create_consumer_version("3", branch: "foo")
11
+ end
12
+
13
+ context "when it is the latest version for the branch" do
14
+ subject { td.find_version("Foo", "3").branch_versions.first }
15
+
16
+ its(:latest?) { is_expected.to be true }
17
+ end
18
+
19
+ context "when it is not the latest version for the branch" do
20
+ subject { td.find_version("Foo", "2").branch_versions.first }
21
+
22
+ its(:latest?) { is_expected.to be false }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -63,8 +63,7 @@ module PactBroker
63
63
 
64
64
  describe "#delete_by_id" do
65
65
  let!(:version) do
66
- TestDataBuilder.new
67
- .create_consumer
66
+ td.create_consumer("Foo")
68
67
  .create_consumer_version("1.2.3")
69
68
  .create_consumer_version("4.5.6")
70
69
  .and_return(:consumer_version)
@@ -75,6 +74,35 @@ module PactBroker
75
74
  it "deletes the version" do
76
75
  expect { subject }.to change{ PactBroker::Domain::Version.count }.by(-1)
77
76
  end
77
+
78
+ context "when the deleted version is the latest for a branch" do
79
+ let!(:version) do
80
+ td.create_consumer("Foo")
81
+ .create_consumer_version("1.2.3", branch: "main")
82
+ .create_consumer_version("4.5.6", branch: "main")
83
+ .and_return(:consumer_version)
84
+ end
85
+
86
+ it "updates the branch head" do
87
+ subject
88
+ expect(td.find_pacticipant("Foo").branch_head_for("main").version.number).to eq "1.2.3"
89
+ end
90
+ end
91
+
92
+ context "when the deleted version is the latest and last for a branch" do
93
+ let!(:version) do
94
+ td.create_consumer("Foo")
95
+ .create_consumer_version("4.5.6", branch: "main")
96
+ .and_return(:consumer_version)
97
+ end
98
+
99
+ it "leaves the branch, but deletes the branch head (not sure about this, but thinking the branch creation date is handy for the WIP/pending calculation)" do
100
+ subject
101
+ foo = td.find_pacticipant("Foo")
102
+ expect(foo.branches.collect(&:name)).to include "main"
103
+ expect(td.find_pacticipant("Foo").branch_head_for("main")).to be nil
104
+ end
105
+ end
78
106
  end
79
107
 
80
108
  describe "#find_by_pacticipant_name_and_number" do
@@ -83,8 +111,7 @@ module PactBroker
83
111
 
84
112
  context "when the version exists" do
85
113
  before do
86
- TestDataBuilder.new
87
- .create_consumer("Another Consumer")
114
+ td.create_consumer("Another Consumer")
88
115
  .create_consumer(pacticipant_name)
89
116
  .create_consumer_version(version_number)
90
117
  .create_consumer_version_tag("prod")
@@ -121,6 +148,64 @@ module PactBroker
121
148
  end
122
149
  end
123
150
 
151
+ describe "#create_or_update" do
152
+ before do
153
+ td.subtract_day
154
+ .create_consumer("Foo")
155
+ .create_consumer_version(version_number, branch: "original-branch", build_url: "original-build-url")
156
+ .create_consumer_version_tag("dev")
157
+ end
158
+
159
+ let(:pacticipant) { td.and_return(:consumer) }
160
+ let(:version_number) { "1234" }
161
+ let(:tags) { nil }
162
+ let(:open_struct_version) { OpenStruct.new(build_url: new_build_url, tags: tags) }
163
+ let(:new_build_url) { "new-build-url" }
164
+
165
+ subject { Repository.new.create_or_update(pacticipant, version_number, open_struct_version) }
166
+
167
+ context "with empty properties" do
168
+ let(:open_struct_version) { OpenStruct.new }
169
+
170
+ it "does not overwrite missing values the values" do
171
+ expect(subject.build_url).to eq "original-build-url"
172
+ end
173
+
174
+ it "does not change the tags" do
175
+ expect { subject }.to_not change { PactBroker::Domain::Version.for("Foo", "1234").tags }
176
+ end
177
+ end
178
+
179
+ context "when there are tags specified" do
180
+ let(:tags) { [ OpenStruct.new(name: "main")] }
181
+
182
+ it "overwrites the tags" do
183
+ expect(subject.tags.count).to eq 1
184
+ expect(subject.tags.first.name).to eq "main"
185
+ end
186
+ end
187
+
188
+ it "does not change the created date" do
189
+ expect { subject }.to_not change { PactBroker::Domain::Version.for("Foo", "1234").created_at }
190
+ end
191
+
192
+ it "does change the updated date" do
193
+ expect { subject }.to change { PactBroker::Domain::Version.for("Foo", "1234").updated_at }
194
+ end
195
+
196
+ it "maintains the order" do
197
+ expect { subject }.to_not change { PactBroker::Domain::Version.for("Foo", "1234").order }
198
+ end
199
+
200
+ context "when the version does not already exist" do
201
+ let(:version) { OpenStruct.new(number: "555", branch: "new-branch") }
202
+
203
+ it "sets the order" do
204
+ expect(subject.order).to_not be nil
205
+ end
206
+ end
207
+ end
208
+
124
209
  describe "#create_or_overwrite" do
125
210
  before do
126
211
  td.subtract_day
@@ -132,12 +217,12 @@ module PactBroker
132
217
  let(:pacticipant) { td.and_return(:consumer) }
133
218
  let(:version_number) { "1234" }
134
219
  let(:tags) { nil }
135
- let(:open_struct_version) { OpenStruct.new(branch: "new-branch", tags: tags) }
220
+ let(:open_struct_version) { OpenStruct.new(tags: tags) }
136
221
 
137
222
  subject { Repository.new.create_or_overwrite(pacticipant, version_number, open_struct_version) }
138
223
 
139
224
  it "overwrites the values" do
140
- expect(subject.branch).to eq "new-branch"
225
+ expect(subject.branch_names).to eq ["original-branch"]
141
226
  expect(subject.build_url).to eq nil
142
227
  end
143
228