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
@@ -1,9 +1,9 @@
1
- require "pact_broker/api/contracts/verifiable_pacts_json_query_schema"
1
+ require "pact_broker/api/contracts/pacts_for_verification_json_query_schema"
2
2
 
3
3
  module PactBroker
4
4
  module Api
5
5
  module Contracts
6
- describe VerifiablePactsJSONQuerySchema do
6
+ describe PactsForVerificationJSONQuerySchema do
7
7
  before do
8
8
  allow(PactBroker::Deployments::EnvironmentService).to receive(:find_by_name).and_return(environment)
9
9
  end
@@ -25,7 +25,7 @@ module PactBroker
25
25
  }]
26
26
  end
27
27
 
28
- subject { VerifiablePactsJSONQuerySchema.(params) }
28
+ subject { PactsForVerificationJSONQuerySchema.(params) }
29
29
 
30
30
  context "when the params are valid" do
31
31
  it "has no errors" do
@@ -1,9 +1,9 @@
1
- require "pact_broker/api/contracts/verifiable_pacts_query_schema"
1
+ require "pact_broker/api/contracts/pacts_for_verification_query_string_schema"
2
2
 
3
3
  module PactBroker
4
4
  module Api
5
5
  module Contracts
6
- describe VerifiablePactsQuerySchema do
6
+ describe PactsForVerificationQueryStringSchema do
7
7
  let(:params) do
8
8
  {
9
9
  provider_version_tags: provider_version_tags,
@@ -20,7 +20,7 @@ module PactBroker
20
20
  }]
21
21
  end
22
22
 
23
- subject { VerifiablePactsQuerySchema.(params) }
23
+ subject { PactsForVerificationQueryStringSchema.(params) }
24
24
 
25
25
  context "when the params are valid" do
26
26
  it "has no errors" do
@@ -21,9 +21,9 @@ module PactBroker
21
21
  webhook_status: "blah",
22
22
  pseudo_branch_verification_status: "wiffle",
23
23
  provider_version_number: provider_version.number,
24
- provider_version_branch: provider_version.branch,
24
+ provider_version_branches: ["main"],
25
25
  consumer_version_number: consumer_version.number,
26
- consumer_version_branch: consumer_version.branch,
26
+ consumer_version_branches: ["main"],
27
27
  tag_names: ["prod"],
28
28
  latest_verification_latest_tags: [double("tag", name: "dev", latest?: true)]
29
29
  )
@@ -32,8 +32,8 @@ module PactBroker
32
32
  let(:provider) { instance_double("PactBroker::Domain::Pacticipant", name: "Bar") }
33
33
  let(:pact) { instance_double("PactBroker::Domain::Pact", created_at: created_at) }
34
34
  let(:verification) { instance_double("PactBroker::Domain::Verification", success: true, created_at: created_at) }
35
- let(:consumer_version) { instance_double("PactBroker::Domain::Version", number: "1", pacticipant: consumer, branch: "main") }
36
- let(:provider_version) { instance_double("PactBroker::Domain::Version", number: "2", pacticipant: provider, branch: "main") }
35
+ let(:consumer_version) { instance_double("PactBroker::Domain::Version", number: "1", pacticipant: consumer) }
36
+ let(:provider_version) { instance_double("PactBroker::Domain::Version", number: "2", pacticipant: provider) }
37
37
  let(:last_webhook_execution_date) { created_at }
38
38
  let(:base_url) { "http://example.org" }
39
39
  let(:options) { { user_options: { base_url: base_url } } }
@@ -67,7 +67,7 @@ module PactBroker
67
67
  subject { JSON.parse(dashboard_json) }
68
68
 
69
69
  it "creates some json" do
70
- expect(subject).to match_pact(expected_hash, {allow_unexpected_keys: false})
70
+ expect(subject).to match_pact(expected_hash, { allow_unexpected_keys: false })
71
71
  end
72
72
 
73
73
  context "when the pact has never been verified" do
@@ -76,7 +76,7 @@ module PactBroker
76
76
  it "has a null last verification and provider version" do
77
77
  expected_hash["items"][0]["latestVerificationResult"] = nil
78
78
  expected_hash["items"][0]["provider"]["version"] = nil
79
- expect(subject).to match_pact(expected_hash, {allow_unexpected_keys: false})
79
+ expect(subject).to match_pact(expected_hash, { allow_unexpected_keys: false })
80
80
  end
81
81
  end
82
82
 
@@ -85,7 +85,7 @@ module PactBroker
85
85
 
86
86
  it "has a null latestWebhookExecution" do
87
87
  expected_hash["items"][0]["latestWebhookExecution"] = nil
88
- expect(subject).to match_pact(expected_hash, {allow_unexpected_keys: false})
88
+ expect(subject).to match_pact(expected_hash, { allow_unexpected_keys: false })
89
89
  end
90
90
  end
91
91
  end
@@ -10,6 +10,7 @@ module PactBroker
10
10
  describe "to_json" do
11
11
  before do
12
12
  allow_any_instance_of(ReasonDecorator).to receive(:to_s).and_return("foo")
13
+ allow_any_instance_of(PactBroker::Api::PactBrokerUrls).to receive(:branch_version_url).and_return("branch_version_url")
13
14
  end
14
15
  let(:verification_date) { DateTime.new(2017, 12, 31) }
15
16
  let(:pact_created_at) { DateTime.new(2017, 1, 1) }
@@ -20,13 +21,13 @@ module PactBroker
20
21
  {
21
22
  consumer_name: "Consumer",
22
23
  consumer_version_number: "1.0.0",
23
- consumer_version_branch: "main",
24
+ consumer_version_branch_versions: consumer_version_branch_versions,
24
25
  consumer_version_tags: consumer_version_tags,
25
26
  provider_version_tags: provider_version_tags,
26
27
  pact_version_sha: "1234",
27
28
  pact_created_at: pact_created_at,
28
29
  provider_version_number: "4.5.6",
29
- provider_version_branch: "feat/x",
30
+ provider_version_branch_versions: provider_version_branch_versions,
30
31
  provider_name: "Provider",
31
32
  success: row_1_success,
32
33
  verification_number: 1,
@@ -40,12 +41,12 @@ module PactBroker
40
41
  {
41
42
  consumer_name: "Consumer",
42
43
  consumer_version_number: "1.0.0",
43
- consumer_version_branch: "main",
44
+ consumer_version_branch_versions: [],
44
45
  consumer_version_tags: [],
45
46
  pact_version_sha: "1234",
46
47
  pact_created_at: pact_created_at,
47
48
  provider_version_number: nil,
48
- provider_version_branch: nil,
49
+ provider_version_branch_versions: [],
49
50
  provider_name: "Provider",
50
51
  success: row_2_success,
51
52
  verification_number: nil,
@@ -65,6 +66,12 @@ module PactBroker
65
66
  version: {
66
67
  number: "1.0.0",
67
68
  branch: "main",
69
+ branches: [
70
+ name: "main",
71
+ _links: {
72
+
73
+ }
74
+ ],
68
75
  _links: {
69
76
  self: {
70
77
  href: "http://example.org/pacticipants/Consumer/versions/1.0.0"
@@ -141,6 +148,10 @@ module PactBroker
141
148
 
142
149
  let(:consumer_version) { double("consumer version", number: "1.0.0", pacticipant: double("consumer", name: "Consumer")) }
143
150
 
151
+ let(:consumer_version_branch_versions) do
152
+ [ instance_double("PactBroker::Versions::BranchVersion", branch_name: "main", latest?: true) ]
153
+ end
154
+
144
155
  let(:consumer_version_tags) do
145
156
  [
146
157
  double("tag", name: "prod", latest?: true, version: consumer_version, created_at: DateTime.now )
@@ -149,6 +160,10 @@ module PactBroker
149
160
 
150
161
  let(:provider_version) { double("provider version", number: "4.5.6", pacticipant: double("provider", name: "Provider")) }
151
162
 
163
+ let(:provider_version_branch_versions) do
164
+ [ instance_double("PactBroker::Versions::BranchVersion", branch_name: "feat/x", latest?: true) ]
165
+ end
166
+
152
167
  let(:provider_version_tags) do
153
168
  [
154
169
  double("tag", name: "master", latest?: false, version: provider_version, created_at: DateTime.now)
@@ -1,14 +1,14 @@
1
- require "pact_broker/api/decorators/verifiable_pacts_query_decorator"
1
+ require "pact_broker/api/decorators/pacts_for_verification_query_decorator"
2
2
 
3
3
  module PactBroker
4
4
  module Api
5
5
  module Decorators
6
- describe VerifiablePactsQueryDecorator do
6
+ describe PactsForVerificationQueryDecorator do
7
7
 
8
8
  let(:provider_version_tags) { %w[dev] }
9
9
  let(:provider_version_branch) { "main" }
10
10
 
11
- subject { VerifiablePactsQueryDecorator.new(OpenStruct.new).from_hash(params) }
11
+ subject { PactsForVerificationQueryDecorator.new(OpenStruct.new).from_hash(params) }
12
12
 
13
13
  context "when parsing JSON params" do
14
14
  let(:params) do
@@ -8,7 +8,6 @@ module PactBroker
8
8
  describe "from_json" do
9
9
  let(:hash) do
10
10
  {
11
- branch: "branch",
12
11
  buildUrl: "buildUrl",
13
12
  tags: [{ name: "main" }]
14
13
  }
@@ -17,7 +16,6 @@ module PactBroker
17
16
  subject { VersionDecorator.new(OpenStruct.new).from_json(hash.to_json) }
18
17
 
19
18
  it "sets the properties" do
20
- expect(subject.branch).to eq "branch"
21
19
  expect(subject.build_url).to eq "buildUrl"
22
20
  expect(subject.tags.first.name).to eq "main"
23
21
  end
@@ -32,7 +30,7 @@ module PactBroker
32
30
  TestDataBuilder.new
33
31
  .create_consumer("Consumer")
34
32
  .create_provider("providerA")
35
- .create_consumer_version("1.2.3")
33
+ .create_consumer_version("1.2.3", branch: "main")
36
34
  .create_consumer_version_tag("prod")
37
35
  .create_pact
38
36
  .create_provider("ProviderB")
@@ -85,6 +83,12 @@ module PactBroker
85
83
  expect(subject[:_embedded][:tags].first[:name]).to eq "prod"
86
84
  end
87
85
 
86
+ it "includes the branches" do
87
+ expect(subject[:_embedded][:branches]).to be_instance_of(Array)
88
+ expect(subject[:_embedded][:branches].first[:name]).to eq "main"
89
+ expect(subject[:_embedded][:branches].first[:latest]).to eq true
90
+ end
91
+
88
92
  it "includes the timestamps" do
89
93
  expect(subject[:createdAt]).to_not be nil
90
94
  end
@@ -39,7 +39,7 @@ module PactBroker
39
39
 
40
40
  it "sets the version branch" do
41
41
  subject
42
- expect(PactBroker::Domain::Version.order(:id).last.branch).to eq "main"
42
+ expect(PactBroker::Domain::Version.order(:id).last.branch_names).to include "main"
43
43
  end
44
44
 
45
45
  it "returns a results object" do
@@ -60,6 +60,27 @@ module PactBroker
60
60
  expect(subject.notices.find{ |log| log.type == "success" && log.text.include?(" published ") }).to_not be nil
61
61
  end
62
62
  end
63
+
64
+ context "when no branch is specified but tags are" do
65
+ before do
66
+ allow(PactBroker.configuration).to receive(:use_first_tag_as_branch).and_return(true)
67
+ end
68
+
69
+ let(:contracts_to_publish) do
70
+ ContractsToPublish.from_hash(
71
+ pacticipant_name: "Foo",
72
+ pacticipant_version_number: "1",
73
+ tags: ["a", "b"],
74
+ branch: nil,
75
+ contracts: contracts
76
+ )
77
+ end
78
+
79
+ it "uses the first tag as the branch" do
80
+ subject
81
+ expect(PactBroker::Domain::Version.order(:id).last.branch_versions.collect(&:branch_name)).to eq ["a"]
82
+ end
83
+ end
63
84
  end
64
85
 
65
86
  context "when the pact already exists" do
@@ -74,8 +95,8 @@ module PactBroker
74
95
  expect { subject }.to change { PactBroker::Domain::Version.order(:id).last.tags.count}.from(1).to(3)
75
96
  end
76
97
 
77
- it "updates the branch (TODO this should add to the branches when branches is updated to be a collection)" do
78
- expect { subject }.to change { PactBroker::Domain::Version.order(:id).last.branch}.from("feat/x").to("main")
98
+ it "adds the branch to the existing version" do
99
+ expect { subject }.to change { PactBroker::Domain::Version.order(:id).last.branch_versions.collect(&:branch_name)}.from(["feat/x"]).to(["feat/x", "main"])
79
100
  end
80
101
 
81
102
  context "when the write mode is overwrite" do
@@ -0,0 +1,57 @@
1
+ require "pact_broker/db/data_migrations/create_branches"
2
+
3
+ module PactBroker
4
+ module DB
5
+ module DataMigrations
6
+ describe CreateBranches do
7
+ let(:db) { PactBroker::Domain::Version.db }
8
+
9
+ subject { CreateBranches.call(db) }
10
+
11
+ context "when there are no branch objects" do
12
+ before do
13
+ td.create_pacticipant("Foo")
14
+ .create_version("1")
15
+ .create_version("2")
16
+ .create_version("3")
17
+ .create_pacticipant("Bar")
18
+ .create_version("10")
19
+ .create_version("11")
20
+ .create_version("12")
21
+
22
+ db[:versions].where(number: ["1", "2"]).update(branch: "main")
23
+ db[:versions].where(number: ["10", "11"]).update(branch: "main")
24
+ end
25
+
26
+ it "creates the missing branch versions" do
27
+ subject
28
+ expect(db[:branches].count).to eq 2
29
+ expect(db[:branch_heads].count).to eq 2
30
+ expect(db[:branch_versions].count).to eq 4
31
+ expect(db[:branch_heads].order(:branch_id).first[:version_id]).to eq db[:versions].where(number: "2").single_record[:id]
32
+ expect(db[:branch_heads].order(:branch_id).last[:version_id]).to eq db[:versions].where(number: "11").single_record[:id]
33
+ end
34
+ end
35
+
36
+ context "when there is a branch already" do
37
+ before do
38
+ td.create_pacticipant("Foo")
39
+ .create_version("1", branch: "main")
40
+ .create_version("2")
41
+ .create_version("3", branch: "main")
42
+ .create_version("4")
43
+ db[:versions].where(number: ["1", "2"]).update(branch: "main")
44
+ end
45
+
46
+ it "creates the missing branch versionsq" do
47
+ subject
48
+ expect(db[:branches].count).to eq 1
49
+ expect(db[:branch_heads].count).to eq 1
50
+ expect(db[:branch_versions].count).to eq 3
51
+ expect(db[:branch_heads].order(:branch_id).last[:version_id]).to eq db[:versions].where(number: "3").single_record[:id]
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -13,7 +13,7 @@ module PactBroker
13
13
  allow(webhook_executions).to receive(:sort).and_return(webhook_executions)
14
14
  end
15
15
 
16
- subject { IndexItem.create(nil, nil, nil, true, nil, [], webhook_executions) }
16
+ subject { IndexItem.create(nil, nil, nil, nil, true, nil, [], webhook_executions) }
17
17
 
18
18
  it "returns the created_at date of the last execution" do
19
19
  expect(subject.last_webhook_execution_date).to eq DateTime.new(2015)
@@ -402,40 +402,6 @@ module PactBroker
402
402
  end
403
403
  end
404
404
 
405
- describe "latest_version_for_branch" do
406
- before do
407
- td.create_consumer("Foo")
408
- .create_consumer_version("1", branch: "main")
409
- .create_consumer_version("2", branch: "main")
410
- .create_consumer_version("3", branch: "feat/x")
411
- .create_consumer_version("4", branch: "feat/x")
412
- .create_consumer_version("5")
413
- end
414
-
415
- subject { Version.order(:order) }
416
-
417
- it "lazy loads" do
418
- expect(subject.all[0].latest_version_for_branch.number).to eq "2"
419
- expect(subject.all[2].latest_version_for_branch.number).to eq "4"
420
- expect(subject.all[4].latest_version_for_branch).to eq nil
421
- end
422
-
423
- it "eager loads" do
424
- all = subject.eager(:latest_version_for_branch).all
425
-
426
- expect(all[0].associations[:latest_version_for_branch]).to_not be nil
427
- expect(all[1].associations[:latest_version_for_branch]).to_not be nil
428
- expect(all[2].associations[:latest_version_for_branch]).to_not be nil
429
- expect(all[3].associations[:latest_version_for_branch]).to_not be nil
430
- expect(all[4].associations.fetch(:latest_version_for_branch)).to be nil
431
-
432
- expect(all[0].latest_version_for_branch.number).to eq "2"
433
- expect(all[1].latest_version_for_branch.number).to eq "2"
434
- expect(all[2].latest_version_for_branch.number).to eq "4"
435
- expect(all[4].latest_version_for_branch).to eq nil
436
- end
437
- end
438
-
439
405
  describe "#latest_pact_publication" do
440
406
  let!(:pact) do
441
407
  TestDataBuilder.new
@@ -492,7 +458,7 @@ module PactBroker
492
458
  context "when there is no branch" do
493
459
  let(:version) { Version.for("Foo", "3") }
494
460
 
495
- it { is_expected.to be nil }
461
+ it { is_expected.to be false }
496
462
  end
497
463
  end
498
464
 
@@ -24,7 +24,8 @@ module PactBroker
24
24
  end
25
25
 
26
26
  its([:pacticipantVersions, :count]) { is_expected.to eq 2 }
27
- its([:pacticipantVersions, :withBranchSetCount]) { is_expected.to eq 1 }
27
+ its([:pacticipantVersions, :withBranchCount]) { is_expected.to eq 1 }
28
+ its([:pacticipantVersions, :withUserCreatedBranchCount]) { is_expected.to eq 1 }
28
29
  end
29
30
 
30
31
  describe "environments, deployed versions, released versions" do
@@ -46,6 +47,7 @@ module PactBroker
46
47
  its([:environments, :count]) { is_expected.to eq 1 }
47
48
  its([:deployedVersions, :count]) { is_expected.to eq 2 }
48
49
  its([:deployedVersions, :currentlyDeployedCount]) { is_expected.to eq 1 }
50
+ its([:deployedVersions, :userCreatedCount]) { is_expected.to eq 2 }
49
51
  its([:releasedVersions, :count]) { is_expected.to eq 3 }
50
52
  its([:releasedVersions, :currentlySupportedCount]) { is_expected.to eq 2 }
51
53
  end
@@ -64,6 +66,7 @@ module PactBroker
64
66
  .create_provider
65
67
  .create_consumer_version
66
68
  .create_pact(json_content: { foo: "bar" }.to_json)
69
+ PactBroker::Pacts::PactVersion.dataset.update(interactions_count: nil, messages_count: nil)
67
70
  end
68
71
 
69
72
  it "includes a count of the number of interactions in the overall latest pacts" do
@@ -23,11 +23,14 @@ module PactBroker
23
23
  .create_consumer("FooZ")
24
24
  .create_consumer_version("6", branch: "main", comment: "latest, different consumer")
25
25
  .create_pact
26
+ .revise_pact
26
27
  .set_now(Date.new(2020, 1, 6))
27
28
  .create_consumer_version("7", comment: "No branch")
28
29
  .create_pact
29
30
  .set_now(Date.new(2020, 1, 7))
30
31
  .create_consumer_version("8", branch: "main", comment: "No pact")
32
+ .create_provider("NotBar")
33
+ .create_pact
31
34
  end
32
35
 
33
36
  subject { PactPublication.latest_by_consumer_branch.all }
@@ -35,27 +38,30 @@ module PactBroker
35
38
  let(:foo) { PactBroker::Domain::Pacticipant.where(name: "Foo").single_record }
36
39
  let(:bar) { PactBroker::Domain::Pacticipant.where(name: "Bar").single_record }
37
40
  let(:foo_z) { PactBroker::Domain::Pacticipant.where(name: "FooZ").single_record }
41
+ let(:not_bar) { td.find_pacticipant("NotBar") }
38
42
 
39
43
  it "returns the latest pact publications for each consumer/branch" do
40
- expect(subject.size).to eq 3
44
+ expect(subject.size).to eq 4
41
45
 
42
- expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch] == "main" }.consumer_version.number).to eq "3"
43
- expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch] == "feat/x" }.consumer_version.number).to eq "4"
44
- expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp[:branch] == "main" }.consumer_version.number).to eq "6"
46
+ expect(subject.find { |pp| pp.consumer_id == foo.id && pp.provider_id == bar.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "3"
47
+ expect(subject.find { |pp| pp.consumer_id == foo.id && pp.provider_id == bar.id && pp[:branch_name] == "feat/x" }.consumer_version.number).to eq "4"
48
+ expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp.provider_id == bar.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "6"
49
+ expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp.provider_id == bar.id && pp[:branch_name] == "main" }.revision_number).to eq 2
50
+ expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp.provider_id == not_bar.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "8"
45
51
  end
46
52
 
47
53
  it "does not return extra columns" do
48
- expect(subject.first.values.keys.sort).to eq (PactPublication.columns + [:branch]).sort
54
+ expect(subject.first.values.keys.sort).to eq (PactPublication.columns + [:branch_name]).sort
49
55
  end
50
56
 
51
57
  context "chained with created after" do
52
58
  subject { PactPublication.created_after(DateTime.new(2020, 1, 3)).latest_by_consumer_branch.all }
53
59
 
54
- its(:size) { is_expected.to eq 2 }
60
+ its(:size) { is_expected.to eq 3 }
55
61
 
56
62
  it "returns the right versions" do
57
- expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch] == "feat/x" }.consumer_version.number).to eq "4"
58
- expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp[:branch] == "main" }.consumer_version.number).to eq "6"
63
+ expect(subject.find { |pp| pp.consumer_id == foo.id && pp[:branch_name] == "feat/x" }.consumer_version.number).to eq "4"
64
+ expect(subject.find { |pp| pp.consumer_id == foo_z.id && pp.provider_id == not_bar.id && pp[:branch_name] == "main" }.consumer_version.number).to eq "8"
59
65
  end
60
66
  end
61
67
  end
@@ -68,6 +74,7 @@ module PactBroker
68
74
  .create_pact
69
75
  .create_consumer_version("2", branch: "main")
70
76
  .create_pact
77
+ .revise_pact
71
78
  .create_consumer_version("3", branch: "feat-x")
72
79
  .create_pact
73
80
  .create_consumer("Foo2")
@@ -86,6 +93,7 @@ module PactBroker
86
93
  expect(all.first.consumer.name).to eq "Foo"
87
94
  expect(all.first.provider.name).to eq "Bar"
88
95
  expect(all.first.consumer_version.number).to eq "2"
96
+ expect(all.first.revision_number).to eq 2
89
97
 
90
98
  expect(all.last.consumer.name).to eq "Foo2"
91
99
  expect(all.last.provider.name).to eq "Bar2"
@@ -93,7 +101,7 @@ module PactBroker
93
101
  end
94
102
 
95
103
  it "does not return extra columns" do
96
- expect(subject.first.values.keys.sort).to eq (PactPublication.columns + [:branch]).sort
104
+ expect(subject.first.values.keys.sort).to eq (PactPublication.columns + [:branch_name]).sort
97
105
  end
98
106
 
99
107
  context "when columns are already selected" do
@@ -170,6 +178,7 @@ module PactBroker
170
178
  .create_pact
171
179
  .create_consumer_version("3", tag_names: ["feat/x"])
172
180
  .create_pact
181
+ .revise_pact
173
182
  .create_consumer("Foo2")
174
183
  .create_provider("Bar2")
175
184
  .create_consumer_version("10", tag_names: ["main"])
@@ -183,6 +192,7 @@ module PactBroker
183
192
  it "returns the latest by consumer/provider" do
184
193
  all = subject.all.sort_by{ | pact_publication | pact_publication.consumer_version.order }
185
194
  expect(all.size).to eq 2
195
+ expect(all.first.revision_number).to eq 2
186
196
  end
187
197
 
188
198
  it "does not return extra columns" do
@@ -236,7 +246,7 @@ module PactBroker
236
246
 
237
247
  subject { PactPublication.latest_for_consumer_tag("main") }
238
248
 
239
- it "returns the latest pacts for the tags with the specified name (for any consumer/provider)" do
249
+ it "returns the pacts for the latest versions with the specified tags with the specified name (for any consumer/provider)" do
240
250
  all = subject.all.sort_by{ |pact_publication| pact_publication.consumer_version.order }
241
251
  expect(all.size).to eq 2
242
252
  expect(all.first.consumer.name).to eq "Foo"
@@ -252,6 +262,95 @@ module PactBroker
252
262
  expect(subject.all.first.values.keys.sort).to eq (PactPublication.columns + [:tag_name]).sort
253
263
  end
254
264
 
265
+ context "when the latest version with the tag does not have a pact" do
266
+ before do
267
+ td.use_consumer("Foo")
268
+ .create_consumer_version("12", tag_names: ["main"])
269
+ .use_consumer("Foo2")
270
+ .create_consumer_version("12", tag_names: ["main"])
271
+ end
272
+
273
+ it "returns the latest pact that belongs to a version with the specified tag" do
274
+ expect(subject.all.size).to eq 2
275
+ end
276
+ end
277
+
278
+ context "when columns are already selected" do
279
+ subject { PactPublication.select(Sequel[:pact_publications][:id]).latest_for_consumer_tag("main") }
280
+
281
+ it "does not override them" do
282
+ expect(subject.all.first.values.keys).to eq [:id]
283
+ end
284
+ end
285
+
286
+ context "when chained" do
287
+ it "works" do
288
+ all = PactPublication.for_provider(td.find_pacticipant("Bar")).latest_for_consumer_tag("main").all
289
+ expect(all.first.provider.name).to eq "Bar"
290
+ end
291
+ end
292
+ end
293
+
294
+ describe "for_latest_consumer_versions_with_tag" do
295
+ before do
296
+ td.create_consumer("Foo")
297
+ .create_provider("Bar")
298
+ .create_consumer_version("1", tag_names: ["main"])
299
+ .create_pact
300
+ .create_consumer_version("2", tag_names: ["main"])
301
+ .create_pact
302
+ .revise_pact
303
+ .create_consumer_version("3", tag_names: ["feat/x"])
304
+ .create_pact
305
+ .create_consumer("Foo2")
306
+ .create_provider("Bar2")
307
+ .create_consumer_version("10", tag_names: ["main"])
308
+ .create_pact
309
+ .create_consumer_version("11", tag_names: ["main"])
310
+ .create_pact
311
+ end
312
+
313
+ subject { PactPublication.for_latest_consumer_versions_with_tag("main") }
314
+
315
+ it "returns the pacts for the latest versions with the specified tags with the specified name (for any consumer/provider)" do
316
+ all = subject.all.sort_by{ |pact_publication| pact_publication.consumer_version.order }
317
+ expect(all.size).to eq 2
318
+ expect(all.first.consumer.name).to eq "Foo"
319
+ expect(all.first.provider.name).to eq "Bar"
320
+ expect(all.first.consumer_version.number).to eq "2"
321
+
322
+ expect(all.last.consumer.name).to eq "Foo2"
323
+ expect(all.last.provider.name).to eq "Bar2"
324
+ expect(all.last.consumer_version.number).to eq "11"
325
+ end
326
+
327
+ it "does not return extra columns" do
328
+ expect(subject.all.first.values.keys.sort).to eq (PactPublication.columns + [:tag_name]).sort
329
+ end
330
+
331
+ context "when the latest version with the tag does not have a pact" do
332
+ before do
333
+ td.use_consumer("Foo")
334
+ .create_consumer_version("12", tag_names: ["main"])
335
+ .use_consumer("Foo2")
336
+ .create_consumer_version("12", tag_names: ["main"])
337
+ end
338
+
339
+ it "returns an empty list" do
340
+ expect(subject.all).to eq []
341
+ end
342
+
343
+ context "with the feature_toggle disabled" do
344
+ before do
345
+ allow(PactBroker).to receive(:feature_enabled?).with(:fix_issue_494).and_return(false)
346
+ end
347
+
348
+ it "returns pacts" do
349
+ expect(subject.all.size).to eq 2
350
+ end
351
+ end
352
+ end
353
+
255
354
  context "when columns are already selected" do
256
355
  subject { PactPublication.select(Sequel[:pact_publications][:id]).latest_for_consumer_tag("main") }
257
356