pact_broker 2.18.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +7 -0
  3. data/CHANGELOG.md +21 -0
  4. data/README.md +5 -2
  5. data/example/example_data.sql +2 -0
  6. data/lib/pact_broker/api.rb +5 -0
  7. data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +8 -0
  8. data/lib/pact_broker/api/decorators/provider_pacts_decorator.rb +12 -7
  9. data/lib/pact_broker/api/pact_broker_urls.rb +4 -0
  10. data/lib/pact_broker/api/resources/badge.rb +3 -1
  11. data/lib/pact_broker/api/resources/error_handler.rb +5 -1
  12. data/lib/pact_broker/api/resources/error_test.rb +2 -2
  13. data/lib/pact_broker/api/resources/index.rb +13 -1
  14. data/lib/pact_broker/api/resources/latest_provider_pacts.rb +7 -19
  15. data/lib/pact_broker/api/resources/pact_content_diff.rb +14 -2
  16. data/lib/pact_broker/api/resources/pact_version.rb +13 -0
  17. data/lib/pact_broker/api/resources/provider_pacts.rb +45 -0
  18. data/lib/pact_broker/api/resources/version.rb +1 -1
  19. data/lib/pact_broker/domain/verification.rb +1 -2
  20. data/lib/pact_broker/error.rb +1 -0
  21. data/lib/pact_broker/matrix/repository.rb +39 -28
  22. data/lib/pact_broker/matrix/service.rb +2 -6
  23. data/lib/pact_broker/pacts/diff.rb +24 -13
  24. data/lib/pact_broker/pacts/pact_params.rb +10 -0
  25. data/lib/pact_broker/pacts/repository.rb +18 -0
  26. data/lib/pact_broker/pacts/service.rb +4 -0
  27. data/lib/pact_broker/pacts/sort_verifiable_content.rb +41 -0
  28. data/lib/pact_broker/ui/controllers/error_test.rb +1 -1
  29. data/lib/pact_broker/ui/controllers/matrix.rb +5 -6
  30. data/lib/pact_broker/ui/views/matrix/show.haml +15 -17
  31. data/lib/pact_broker/verifications/repository.rb +3 -3
  32. data/lib/pact_broker/version.rb +1 -1
  33. data/lib/pact_broker/versions/repository.rb +11 -1
  34. data/lib/pact_broker/versions/service.rb +2 -2
  35. data/public/javascripts/matrix.js +40 -33
  36. data/spec/features/get_pact_version.rb +13 -0
  37. data/spec/features/get_provider_pacts_spec.rb +33 -12
  38. data/spec/lib/pact_broker/api/decorators/pacticipant_decorator_spec.rb +12 -1
  39. data/spec/lib/pact_broker/api/decorators/provider_pacts_decorator_spec.rb +57 -0
  40. data/spec/lib/pact_broker/api/pact_broker_urls_spec.rb +16 -0
  41. data/spec/lib/pact_broker/api/resources/badge_spec.rb +3 -3
  42. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +19 -1
  43. data/spec/lib/pact_broker/api/resources/latest_provider_pacts_spec.rb +52 -0
  44. data/spec/lib/pact_broker/api/resources/provider_pacts_spec.rb +75 -0
  45. data/spec/lib/pact_broker/matrix/repository_spec.rb +52 -0
  46. data/spec/lib/pact_broker/matrix/service_spec.rb +1 -17
  47. data/spec/lib/pact_broker/pacts/diff_spec.rb +34 -7
  48. data/spec/lib/pact_broker/pacts/pact_params_spec.rb +33 -8
  49. data/spec/lib/pact_broker/pacts/repository_spec.rb +65 -1
  50. data/spec/lib/pact_broker/pacts/sort_verifiable_content_spec.rb +25 -0
  51. data/spec/lib/pact_broker/verifications/repository_spec.rb +44 -17
  52. data/spec/lib/pact_broker/versions/repository_spec.rb +2 -2
  53. data/spec/support/test_data_builder.rb +4 -0
  54. data/tasks/rspec.rake +6 -4
  55. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: be2a40680787302de6ff629cc8522bed68b57c86
4
- data.tar.gz: e5fe341fb89a53b5a5b93ba801bfaad429fa34d6
3
+ metadata.gz: 4a315c4d4db3576fad3d6fbb76104b211382b36d
4
+ data.tar.gz: 88587d68f58299bd29b576172ce920c60bc4a2d7
5
5
  SHA512:
6
- metadata.gz: 40bbfae215d62a2bbed81cdcae2e76236f1c952d5a7b274cb9811052b1a03e29b81e4feb344be5f7e62827c009d913ed057e6a3b0a8006b3a769774b2062c495
7
- data.tar.gz: e7867be0091b5ca6e2748f032c0964f1a2409ecdb1f7d578f8dbdf071f6f35c7d4706f82a8333dc37133566027cb951436c3e18752388cb8d7bb3b40475d761f
6
+ metadata.gz: d061e082b1b76232f88f8a0d5e6f21bd53a9c1f1dd84ff1694ee5066ab62468c1d36c123bcb19c0f52f9663db318d14ce0c4aef0366e2f6961cef9975b85a7fb
7
+ data.tar.gz: 5db882315d0172d445f4966dece781605ceb818e7a4527710d0d5ca5721030950148bab308552c688dc51b077022935c8e66d2f0e85f96b32e4df6ed3c0fbb13
@@ -1,3 +1,10 @@
1
+ # Pre issue-raising checklist
2
+
3
+ I have already (please mark the applicable with an `x`):
4
+
5
+ * [ ] Upgraded to the latest Pact Broker OR
6
+ * [ ] Checked the CHANGELOG to see if the issue I am about to raise has been fixed
7
+
1
8
  ## Software versions
2
9
 
3
10
  * **pact-broker gem version:** eg 2.3.1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ <a name="v2.19.0"></a>
2
+ ### v2.19.0 (2018-05-03)
3
+
4
+
5
+ #### Features
6
+
7
+ * create endpoint to compare arbitrary pact versions, ignoring interaction/message order ([15f0688](/../../commit/15f0688))
8
+ * add endpoint to retrieve a pact version by its pact content sha ([a519731](/../../commit/a519731))
9
+ * include pact revision number and verification number in badge svg comment ([82b59ef](/../../commit/82b59ef))
10
+ * add pb:version-tag relation to pacticipant resource ([0704772](/../../commit/0704772))
11
+ * create endpoints for retrieving all pact versions for a provider, with and without a tag. ([d7011b2](/../../commit/d7011b2))
12
+ * update matrix UI to allow _all_ versions with a particular tag to be specified ([278b3ea](/../../commit/278b3ea))
13
+ * allow matrix to be queried for _all_ versions with a given tag ([cac3023](/../../commit/cac3023))
14
+
15
+
16
+ #### Bug Fixes
17
+
18
+ * correct logic for finding latest verification for revised pacts ([8fb28ee](/../../commit/8fb28ee))
19
+ * do not invoke error reporters for validation errors ([57eed65](/../../commit/57eed65))
20
+
21
+
1
22
  <a name="v2.18.0"></a>
2
23
  ### v2.18.0 (2018-04-05)
3
24
 
data/README.md CHANGED
@@ -138,12 +138,15 @@ You can use the [Pact Broker Docker image][docker] or [Terraform on AWS][terrafo
138
138
 
139
139
  * Are you sure you don't just want to use the [Pact Broker Docker image][docker]? No Docker at your company yet? Ah well, keep reading.
140
140
  * Create a PostgreSQL (recommended) or MySQL (not recommended, see following note) database.
141
- * __Note:__ It is recommended to use __PostgreSQL__ as it will support JSON search features that are planned in the future, however MySQL the other [semi supported](https://github.com/pact-foundation/pact_broker/issues/33) database.
141
+ * __Note:__ It is recommended to use __PostgreSQL__ as it will support JSON search features that are planned in the future, however MySQL the other [semi supported](https://github.com/pact-foundation/pact_broker/issues/33) database.
142
142
  * Check the [travis.yml][travisyml] file to make sure you're using the version of the database that we're currently running our tests against.
143
143
  * If you're using PostgreSQL (did we mention this was _recommended!_) you'll find the database creation script in the [example/config.ru](https://github.com/pact-foundation/pact_broker/blob/master/example/config.ru).
144
- * Install ruby 2.2.0 or later and bundler >= 1.12.0 (if you've come this far, I'm assuming you know how to do both of these. Did I mention there was a [Docker][docker] image?)
144
+ * Install ruby 2.2.0 or later (ruby 2.4 is recommended) and bundler >= 1.12.0 (if you've come this far, I'm assuming you know how to do both of these. Did I mention there was a [Docker][docker] image?)
145
145
  * Copy the [pact\_broker](https://github.com/DiUS/pact_broker-docker/tree/master/pact_broker) directory from the Pact Broker Docker project. This will have the recommended settings for database connections, logging, basic auth etc. Note that the Docker image uses Phusion Passenger as the web application server in front of the Pact Broker Ruby application, which is the recommended set up.
146
146
  * Modify the config.ru and Gemfile as desired (eg. choose database driver gem, set your database credentials. Use the "pg" gem if using Postgres and the "mysql2" gem if using MySQL)
147
+ * example Sequel configuration for postgres `{adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}`
148
+ * example Sequel configuration for mysql `{adapter: "mysql2", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}`
149
+ `
147
150
  * Please ensure you use `encoding: 'utf8'` in your Sequel options to avoid encoding issues.
148
151
  * For production usage, use a web application server like [Phusion Passenger](https://www.phusionpassenger.com) or [Nginx](http://nginx.org/) to serve the Pact Broker application. You'll need to read up on the documentation for these yourself as it is beyond the scope of this documentation. See the [wiki][reverse-proxy-docs] for instructions on using a reverse proxy with SSL.
149
152
  * Deploy to your location of choice.
@@ -14,4 +14,6 @@ INSERT INTO pact_publications VALUES(1,1,1,1,1,'2014-11-18 06:28:36.340041');
14
14
  INSERT INTO pact_publications VALUES(2,2,1,1,3,'2015-01-19 22:15:10.969518');
15
15
  INSERT INTO pact_publications VALUES(3,3,1,1,1,'2016-11-08 22:45:37.291839');
16
16
  INSERT INTO pact_publications VALUES(4,4,3,1,4,'2017-05-23 06:10:23.252829');
17
+ INSERT INTO materialized_matrix SELECT * FROM matrix;
18
+ INSERT INTO materialized_head_matrix SELECT * FROM head_matrix;
17
19
  COMMIT;
@@ -13,8 +13,11 @@ module PactBroker
13
13
 
14
14
  # Pacts
15
15
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication"}
16
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha], Api::Resources::PactVersion, {resource_name: "pact_publication"}
16
17
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number, 'previous-distinct'], Api::Resources::PreviousDistinctPactVersion, {resource_name: "previous_distinct_pact_version"}
17
18
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number, 'diff', 'previous-distinct'], Api::Resources::PactContentDiff, {resource_name: "previous_distinct_pact_version_diff"}
19
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number, 'diff', 'version', :comparison_consumer_version], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_consumer_version"}
20
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'diff', 'pact-version', :comparison_pact_version_sha], Api::Resources::PactContentDiff, {resource_name: "pact_version_diff_by_pact_version_sha"}
18
21
 
19
22
  # Verifications
20
23
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'pact-version', :pact_version_sha, 'verification-results'], Api::Resources::Verifications, {resource_name: "verification_results"}
@@ -29,6 +32,8 @@ module PactBroker
29
32
  # Latest pacts
30
33
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest'], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"}
31
34
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest', :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"}
35
+ add ['pacts', 'provider', :provider_name], Api::Resources::ProviderPacts, {resource_name: "provider_pact_publications"}
36
+ add ['pacts', 'provider', :provider_name, 'tag', :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"}
32
37
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'latest-untagged'], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
33
38
  add ['pacts', 'provider', :provider_name, 'latest'], Api::Resources::LatestProviderPacts, {resource_name: "latest_provider_pact_publications"}
34
39
  add ['pacts', 'provider', :provider_name, 'latest', :tag], Api::Resources::LatestProviderPacts, {resource_name: "latest_tagged_provider_pact_publications"}
@@ -25,6 +25,14 @@ module PactBroker
25
25
  versions_url(options[:base_url], represented)
26
26
  end
27
27
 
28
+ link :'pb:version-tag' do | options |
29
+ {
30
+ title: "Get, create or delete a tag for a version of #{represented.name}",
31
+ href: templated_tag_url_for_pacticipant(represented.name, options[:base_url]),
32
+ templated: true
33
+ }
34
+ end
35
+
28
36
  # TODO deprecate in v3
29
37
  # URL isn't implemented
30
38
  # link 'latest-version' do | options |
@@ -2,19 +2,15 @@ require_relative 'base_decorator'
2
2
  require_relative 'pact_version_decorator'
3
3
 
4
4
  module PactBroker
5
-
6
5
  module Api
7
-
8
6
  module Decorators
9
-
10
-
11
7
  class ProviderPactsDecorator < BaseDecorator
12
8
 
13
9
  link :self do | context |
14
10
  suffix = context[:tag] ? " with tag '#{context[:tag]}'" : ""
15
11
  {
16
12
  href: context[:resource_url],
17
- title: "Latest pact versions for the provider #{context[:provider_name]}#{suffix}"
13
+ title: context[:title]
18
14
  }
19
15
  end
20
16
 
@@ -25,16 +21,25 @@ module PactBroker
25
21
  }
26
22
  end
27
23
 
28
- links :'pacts' do | context |
24
+ links :'pb:pacts' do | context |
29
25
  represented.collect do | pact |
30
26
  {
31
27
  :href => pact_url(context[:base_url], pact),
32
28
  :title => pact.name,
33
- :name => pact.consumer.name
29
+ :name => pact.consumer_name
34
30
  }
35
31
  end
36
32
  end
37
33
 
34
+ links :'pacts' do | context |
35
+ represented.collect do | pact |
36
+ {
37
+ :href => pact_url(context[:base_url], pact),
38
+ :title => 'DEPRECATED - please use the pb:pacts relation',
39
+ :name => pact.consumer_name
40
+ }
41
+ end
42
+ end
38
43
  end
39
44
  end
40
45
  end
@@ -128,6 +128,10 @@ module PactBroker
128
128
  "#{tags_url(base_url, tag.version)}/#{tag.name}"
129
129
  end
130
130
 
131
+ def templated_tag_url_for_pacticipant pacticipant_name, base_url = ""
132
+ pacticipant_url_from_params({pacticipant_name: pacticipant_name}, base_url) + "/versions/{version}/tags/{tag}"
133
+ end
134
+
131
135
  def label_url label, base_url
132
136
  "#{labels_url(label.pacticipant, base_url)}/#{label.name}"
133
137
  end
@@ -58,8 +58,10 @@ module PactBroker
58
58
 
59
59
  def comment
60
60
  consumer_version_number = pact ? pact.consumer_version_number : "?"
61
+ pact_revision = pact ? pact.revision_number : "?"
61
62
  provider_version_number = latest_verification ? latest_verification.provider_version_number : "?"
62
- "<!-- #{identifier_from_path[:consumer_name]} version #{consumer_version_number} #{identifier_from_path[:provider_name]} version #{provider_version_number} -->\n"
63
+ verification_number = latest_verification ? latest_verification.number : "?"
64
+ "<!-- #{identifier_from_path[:consumer_name]} version #{consumer_version_number} revision #{pact_revision} #{identifier_from_path[:provider_name]} version #{provider_version_number} number #{verification_number} -->\n"
63
65
  end
64
66
  end
65
67
  end
@@ -12,7 +12,11 @@ module PactBroker
12
12
  logger.error e
13
13
  logger.error e.backtrace
14
14
  response.body = {:message => e.message, :backtrace => e.backtrace }.to_json
15
- report e, request
15
+ report(e, request) if reportable?(e)
16
+ end
17
+
18
+ def self.reportable? e
19
+ !e.is_a?(PactBroker::Error)
16
20
  end
17
21
 
18
22
  def self.report e, request
@@ -24,11 +24,11 @@ module PactBroker
24
24
  end
25
25
 
26
26
  def to_json
27
- raise PactBroker::Error.new("Don't panic. This is a test API error.")
27
+ raise PactBroker::TestError.new("Don't panic. This is a test API error.")
28
28
  end
29
29
 
30
30
  def from_json
31
- raise PactBroker::Error.new("Don't panic. This is a test API error.")
31
+ raise PactBroker::TestError.new("Don't panic. This is a test API error.")
32
32
  end
33
33
  end
34
34
  end
@@ -50,7 +50,19 @@ module PactBroker
50
50
  'pb:latest-provider-pacts-with-tag' =>
51
51
  {
52
52
  href: base_url + '/pacts/provider/{provider}/latest/{tag}',
53
- title: 'Latest pacts by provider with the specified tag',
53
+ title: 'Latest pacts for provider with the specified tag',
54
+ templated: true
55
+ },
56
+ 'pb:provider-pacts-with-tag' =>
57
+ {
58
+ href: base_url + '/pacts/provider/{provider}/tag/{tag}',
59
+ title: 'All pact versions for the provider with the specified consumer version tag',
60
+ templated: true
61
+ },
62
+ 'pb:provider-pacts' =>
63
+ {
64
+ href: base_url + '/pacts/provider/{provider}',
65
+ title: 'All pact versions for the specified provider',
54
66
  templated: true
55
67
  },
56
68
  'pb:latest-version' => {
@@ -1,33 +1,21 @@
1
- require 'pact_broker/api/resources/base_resource'
1
+ require 'pact_broker/api/resources/provider_pacts'
2
2
  require 'pact_broker/configuration'
3
3
  require 'pact_broker/api/decorators/provider_pacts_decorator'
4
4
 
5
5
  module PactBroker
6
6
  module Api
7
7
  module Resources
8
-
9
- class LatestProviderPacts < BaseResource
10
-
11
- def content_types_provided
12
- [["application/hal+json", :to_json]]
13
- end
14
-
15
- def allowed_methods
16
- ["GET"]
17
- end
18
-
19
- def resource_exists?
20
- pacticipant_service.find_pacticipant_by_name(provider_name)
21
- end
22
-
23
- def to_json
24
- PactBroker::Api::Decorators::ProviderPactsDecorator.new(pacts).to_json(user_options: decorator_context(identifier_from_path))
25
- end
8
+ class LatestProviderPacts < ProviderPacts
9
+ private
26
10
 
27
11
  def pacts
28
12
  pact_service.find_latest_pact_versions_for_provider provider_name, tag: identifier_from_path[:tag]
29
13
  end
30
14
 
15
+ def resource_title
16
+ suffix = identifier_from_path[:tag] ? " with consumer version tag '#{identifier_from_path[:tag]}'" : ""
17
+ "Latest pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}"
18
+ end
31
19
  end
32
20
  end
33
21
  end
@@ -20,7 +20,7 @@ module PactBroker
20
20
  end
21
21
 
22
22
  def to_text
23
- output = PactBroker::Pacts::Diff.new.process pact_params.merge(base_url: base_url)
23
+ output = PactBroker::Pacts::Diff.new.process pact_params.merge(base_url: base_url), comparison_pact_params, raw: false
24
24
  response.body = output
25
25
  end
26
26
 
@@ -29,7 +29,19 @@ module PactBroker
29
29
  end
30
30
 
31
31
  def pact_params
32
- @pact_params ||= PactBroker::Pacts::PactParams.from_request request, path_info
32
+ @pact_params ||= PactBroker::Pacts::PactParams.from_path_info identifier_from_path
33
+ end
34
+
35
+ def comparison_pact_params
36
+ if identifier_from_path[:comparison_consumer_version_number] || identifier_from_path[:comparison_pact_version_sha]
37
+ comparison_identifier_from_path = identifier_from_path.merge(
38
+ consumer_version_number: identifier_from_path[:comparison_consumer_version_number],
39
+ pact_version_sha: identifier_from_path[:comparison_pact_version_sha],
40
+ base_url: base_url)
41
+ PactBroker::Pacts::PactParams.from_path_info(comparison_identifier_from_path)
42
+ else
43
+ nil
44
+ end
33
45
  end
34
46
  end
35
47
  end
@@ -0,0 +1,13 @@
1
+ require 'pact_broker/api/resources/pact'
2
+
3
+ module PactBroker
4
+ module Api
5
+ module Resources
6
+ class PactVersion < Pact
7
+ def allowed_methods
8
+ ["GET"]
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ require 'pact_broker/api/resources/base_resource'
2
+ require 'pact_broker/configuration'
3
+ require 'pact_broker/api/decorators/provider_pacts_decorator'
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Resources
8
+ class ProviderPacts < BaseResource
9
+
10
+ def content_types_provided
11
+ [["application/hal+json", :to_json]]
12
+ end
13
+
14
+ def allowed_methods
15
+ ["GET"]
16
+ end
17
+
18
+ def resource_exists?
19
+ pacticipant_service.find_pacticipant_by_name(provider_name)
20
+ end
21
+
22
+ def to_json
23
+ PactBroker::Api::Decorators::ProviderPactsDecorator.new(pacts).to_json(to_json_options)
24
+ end
25
+
26
+ private
27
+
28
+ def pacts
29
+ pact_service.find_pact_versions_for_provider provider_name, tag: identifier_from_path[:tag]
30
+ end
31
+
32
+ def to_json_options
33
+ {
34
+ user_options: decorator_context(identifier_from_path.merge(title: resource_title))
35
+ }
36
+ end
37
+
38
+ def resource_title
39
+ suffix = identifier_from_path[:tag] ? " with consumer version tag '#{identifier_from_path[:tag]}'" : ""
40
+ "All pact versions for the provider #{identifier_from_path[:provider_name]}#{suffix}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -35,7 +35,7 @@ module PactBroker
35
35
 
36
36
  def version
37
37
  if path_info[:tag]
38
- @version ||= version_service.find_by_pacticpant_name_and_latest_tag(path_info[:pacticipant_name], path_info[:tag])
38
+ @version ||= version_service.find_by_pacticipant_name_and_latest_tag(path_info[:pacticipant_name], path_info[:tag])
39
39
  elsif path_info[:pacticipant_version_number]
40
40
  @version ||= version_service.find_by_pacticipant_name_and_number path_info
41
41
  else
@@ -46,8 +46,7 @@ module PactBroker
46
46
 
47
47
  def tag tag_name
48
48
  filter = name_like(Sequel.qualify(:tags, :name), tag_name)
49
- join(:pact_publications, {pact_version_id: :pact_version_id})
50
- .join(:tags, {version_id: :consumer_version_id}).where(filter)
49
+ join(:tags, { version_id: :consumer_version_id }).where(filter)
51
50
  end
52
51
 
53
52
  def untagged
@@ -1,5 +1,6 @@
1
1
  module PactBroker
2
2
 
3
3
  class Error < StandardError; end
4
+ class TestError < StandardError; end
4
5
 
5
6
  end
@@ -78,8 +78,6 @@ module PactBroker
78
78
  lines.sort
79
79
  end
80
80
 
81
-
82
-
83
81
  def apply_latestby options, selectors, lines
84
82
  return lines unless options[:latestby]
85
83
  group_by_columns = case options[:latestby]
@@ -134,21 +132,19 @@ module PactBroker
134
132
  end
135
133
 
136
134
  def resolve_selectors(selectors, options)
137
- selectors = look_up_versions_for_latest_and_tag(selectors, options)
138
-
139
- if options[:latest]
140
- apply_latest_and_tag_to_inferred_selectors(selectors, options)
135
+ resolved_selectors = look_up_version_numbers(selectors, options)
136
+ if options[:latest] || options[:tag]
137
+ apply_latest_and_tag_to_inferred_selectors(resolved_selectors, options)
141
138
  else
142
- selectors
139
+ resolved_selectors
143
140
  end
144
141
  end
145
142
 
146
- # Find the version number for selectors with the latest (tagged) version specified
147
- def look_up_versions_for_latest_and_tag(selectors, options)
143
+ # Find the version number for selectors with the latest and/or tag specified
144
+ def look_up_version_numbers(selectors, options)
148
145
  selectors.collect do | selector |
149
- # resource validation currently stops tag being specified without latest=true
150
146
  if selector[:tag] && selector[:latest]
151
- version = version_repository.find_by_pacticpant_name_and_latest_tag(selector[:pacticipant_name], selector[:tag])
147
+ version = version_repository.find_by_pacticipant_name_and_latest_tag(selector[:pacticipant_name], selector[:tag])
152
148
  raise Error.new("Could not find version with tag #{selector[:tag].inspect} for #{selector[:pacticipant_name]}") unless version
153
149
  # validation in resource should ensure we always have a version
154
150
  {
@@ -161,25 +157,38 @@ module PactBroker
161
157
  pacticipant_name: selector[:pacticipant_name],
162
158
  pacticipant_version_number: version.number
163
159
  }
160
+ elsif selector[:tag]
161
+ # validation in resource should ensure we always have at least one version
162
+ versions = version_repository.find_by_pacticipant_name_and_tag(selector[:pacticipant_name], selector[:tag])
163
+ versions.collect do | version |
164
+ {
165
+ pacticipant_name: selector[:pacticipant_name],
166
+ pacticipant_version_number: version.number
167
+ }
168
+ end
164
169
  else
165
170
  selector.dup
166
171
  end
167
- end.collect do | selector |
168
- if selector[:pacticipant_name]
169
- pacticipant = PactBroker::Domain::Pacticipant.find(name: selector[:pacticipant_name])
170
- selector[:pacticipant_id] = pacticipant ? pacticipant.id : nil
171
- end
172
+ end.flatten.compact.collect do | selector |
173
+ add_ids(selector)
174
+ end
175
+ end
172
176
 
173
- if selector[:pacticipant_name] && selector[:pacticipant_version_number]
174
- version = version_repository.find_by_pacticipant_name_and_number(selector[:pacticipant_name], selector[:pacticipant_version_number])
175
- selector[:pacticipant_version_id] = version ? version.id : nil
176
- end
177
+ def add_ids(selector)
178
+ if selector[:pacticipant_name]
179
+ pacticipant = PactBroker::Domain::Pacticipant.find(name: selector[:pacticipant_name])
180
+ selector[:pacticipant_id] = pacticipant ? pacticipant.id : nil
181
+ end
177
182
 
178
- if selector[:pacticipant_version_number].nil?
179
- selector[:pacticipant_version_id] = nil
180
- end
181
- selector
183
+ if selector[:pacticipant_name] && selector[:pacticipant_version_number]
184
+ version = version_repository.find_by_pacticipant_name_and_number(selector[:pacticipant_name], selector[:pacticipant_version_number])
185
+ selector[:pacticipant_version_id] = version ? version.id : nil
182
186
  end
187
+
188
+ if selector[:pacticipant_version_number].nil?
189
+ selector[:pacticipant_version_id] = nil
190
+ end
191
+ selector
183
192
  end
184
193
 
185
194
  # eg. when checking to see if Foo version 2 can be deployed to prod,
@@ -190,13 +199,15 @@ module PactBroker
190
199
  inferred_names = all_pacticipant_names - specified_names
191
200
 
192
201
  inferred_selectors = inferred_names.collect do | pacticipant_name |
193
- {
202
+ selector = {
194
203
  pacticipant_name: pacticipant_name,
195
- latest: options[:latest]
196
- }.tap { |it| it[:tag] = options[:tag] if options[:tag] }
204
+ }
205
+ selector[:tag] = options[:tag] if options[:tag]
206
+ selector[:latest] = options[:latest] if options[:latest]
207
+ selector
197
208
  end
198
209
 
199
- selectors + look_up_versions_for_latest_and_tag(inferred_selectors, options)
210
+ selectors + look_up_version_numbers(inferred_selectors, options)
200
211
  end
201
212
 
202
213
  def all_pacticipant_names_in_specified_matrix(selectors, options)