pact_broker-client 1.70.0 → 1.72.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,104 @@
1
+ require "pact_broker/client/base_command"
2
+ require "pact_broker/client/versions/create"
3
+ require 'pact_broker/client/colorize_notices'
4
+ require "base64"
5
+
6
+ module Pactflow
7
+ module Client
8
+ module ProviderContracts
9
+ class PublishTheOldWay < PactBroker::Client::BaseCommand
10
+ attr_reader :branch_name, :tags, :provider_name, :provider_version_number, :contract, :verification_results
11
+
12
+ def initialize(params, options, pact_broker_client_options)
13
+ super
14
+ @provider_name = params[:provider_name]
15
+ @provider_version_number = params[:provider_version_number]
16
+ @branch_name = params[:branch_name]
17
+ @tags = params[:tags] || []
18
+ @contract = params[:contract]
19
+ @verification_results = params[:verification_results]
20
+ end
21
+
22
+ private
23
+
24
+ def do_call
25
+ create_branch_version_and_tags
26
+ render_response(create_contract)
27
+ end
28
+
29
+ def render_response(res)
30
+ notices = [
31
+ { type: 'success', text: "Successfully published provider contract for #{provider_name} version #{provider_version_number} to PactFlow"},
32
+ ]
33
+ if res.body && res.body['_links'] && res.body['_links']['pf:ui']['href']
34
+ notices.concat([{ text: "View the uploaded contract at #{res.body['_links']['pf:ui']['href']}" }])
35
+ end
36
+ notices.concat(next_steps)
37
+ PactBroker::Client::CommandResult.new(true, PactBroker::Client::ColorizeNotices.call(notices.collect do |n|
38
+ OpenStruct.new(n)
39
+ end).join("\n"))
40
+ end
41
+
42
+ def next_steps
43
+ [
44
+ { type: 'prompt', text: 'Next steps:' },
45
+ { type: 'prompt',
46
+ text: ' * Check your application is safe to deploy - https://docs.pact.io/can_i_deploy' },
47
+ { text: " pact-broker can-i-deploy --pacticipant #{provider_name} --version #{provider_version_number} --to-environment <your environment name>" },
48
+ { type: 'prompt',
49
+ text: ' * Record deployment or release to specified environment (choose one) - https://docs.pact.io/go/record-deployment' },
50
+ { text: " pact-broker record-deployment --pacticipant #{provider_name} --version #{provider_version_number} --environment <your environment name>" },
51
+ { text: " pact-broker record-release --pacticipant #{provider_name} --version #{provider_version_number} --environment <your environment name>" }
52
+ ]
53
+ end
54
+
55
+ def create_branch_version_and_tags
56
+ if branch_name || tags.any?
57
+ pacticipant_version_params = {
58
+ pacticipant_name: provider_name,
59
+ version_number: provider_version_number,
60
+ branch_name: branch_name,
61
+ tags: tags
62
+ }
63
+ result = PactBroker::Client::Versions::Create.call(pacticipant_version_params, options, pact_broker_client_options)
64
+ if !result.success
65
+ raise PactBroker::Client::Error.new(result.message)
66
+ end
67
+ end
68
+ end
69
+
70
+ def create_contract
71
+ contract_path = "#{pact_broker_base_url}/contracts/provider/{provider}/version/{version}"
72
+ entrypoint = create_entry_point(contract_path, pact_broker_client_options)
73
+ entrypoint.expand(provider: provider_name, version: provider_version_number).put!(contract_params).response
74
+ end
75
+
76
+ def contract_params
77
+ verification_results_params = {
78
+ success: verification_results[:success],
79
+ content: verification_results[:content] ? encode_content(verification_results[:content]) : nil,
80
+ contentType: verification_results[:content_type],
81
+ format: verification_results[:format],
82
+ verifier: verification_results[:verifier],
83
+ verifierVersion: verification_results[:verifier_version]
84
+ }.compact
85
+
86
+ body_params = {
87
+ content: encode_content(contract[:content]),
88
+ contractType: contract[:specification],
89
+ contentType: contract[:content_type],
90
+ }.compact
91
+
92
+ if verification_results_params.any?
93
+ body_params[:verificationResults] = verification_results_params
94
+ end
95
+ body_params
96
+ end
97
+
98
+ def encode_content oas
99
+ Base64.strict_encode64(oas)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -27,12 +27,4 @@ Gem::Specification.new do |gem|
27
27
  gem.add_runtime_dependency 'thor', '>= 0.20', '< 2.0'
28
28
  gem.add_runtime_dependency 'rake', '~> 13.0' #For FileList
29
29
  gem.add_runtime_dependency 'dig_rb', '~> 1.0'
30
-
31
- gem.add_development_dependency 'fakefs', '~> 2.4'
32
- gem.add_development_dependency 'webmock', '~> 3.0'
33
- gem.add_development_dependency 'conventional-changelog', '~>1.3'
34
- gem.add_development_dependency 'pact', '~> 1.16'
35
- gem.add_development_dependency 'pact-support', '~> 1.16'
36
- gem.add_development_dependency 'approvals', '0.0.26'
37
- gem.add_development_dependency 'rspec-its', '~> 1.3'
38
30
  end
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -Eeuxo pipefail
4
+
5
+ bundle exec bin/pact-broker record-deployment \
6
+ --pacticipant "Pact Broker Client" --version $GITHUB_SHA \
7
+ --environment production
@@ -0,0 +1,81 @@
1
+ {
2
+ "consumer": {
3
+ "name": "Foo"
4
+ },
5
+ "provider": {
6
+ "name": "Bar"
7
+ },
8
+ "interactions": [
9
+ {
10
+ "description": "a request to list the latest pacts",
11
+ "providerState": "a pact between Condor and the Pricing Service exists",
12
+ "request": {
13
+ "method": "get",
14
+ "path": "/pacts/latest",
15
+ "headers": {
16
+ }
17
+ },
18
+ "response": {
19
+ "status": 200,
20
+ "headers": {
21
+ "Content-Type": "application/hal+json"
22
+ },
23
+ "body": {
24
+ "_links": {
25
+ "self": {
26
+ "href": "http://example.org/pacts/latest"
27
+ }
28
+ },
29
+ "pacts": [
30
+ {
31
+ "_links": {
32
+ "self": [
33
+ {
34
+ "href": "http://example.org/pacts/provider/Pricing%20Service/consumer/Condor/latest"
35
+ },
36
+ {
37
+ "href": "http://example.org/pacts/provider/Pricing%20Service/consumer/Condor/version/1.3.0"
38
+ }
39
+ ]
40
+ },
41
+ "_embedded": {
42
+ "consumer": {
43
+ "name": "Condor",
44
+ "_links": {
45
+ "self": {
46
+ "href": "http://example.org/pacticipants/Condor"
47
+ }
48
+ },
49
+ "_embedded": {
50
+ "version": {
51
+ "number": "1.3.0"
52
+ }
53
+ }
54
+ },
55
+ "provider": {
56
+ "_links": {
57
+ "self": {
58
+ "href": "http://example.org/pacticipants/Pricing%20Service"
59
+ }
60
+ },
61
+ "name": "Pricing Service"
62
+ }
63
+ }
64
+ }
65
+ ]
66
+ },
67
+ "matchingRules": {
68
+ "$.headers.Content-Type": {
69
+ "match": "regex",
70
+ "regex": "application\\/hal\\+json"
71
+ }
72
+ }
73
+ }
74
+ }
75
+ ],
76
+ "metadata": {
77
+ "pactSpecification": {
78
+ "version": "2.0.0"
79
+ }
80
+ }
81
+ }
@@ -1,5 +1,5 @@
1
- export PACT_BROKER_BASE_URL="http://localhost:9292"
2
- export PACT_BROKER_TOKEN="localhost"
1
+ export PACT_BROKER_BASE_URL=${PACT_BROKER_BASE_URL:-"http://localhost:9292"}
2
+ export PACT_BROKER_TOKEN=${PACT_BROKER_TOKEN:-"localhost"}
3
3
  #export PACT_BROKER_FEATURES=publish_pacts_using_old_api
4
4
 
5
5
  # bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
@@ -8,11 +8,11 @@ export PACT_BROKER_TOKEN="localhost"
8
8
  # --description "foo webhook" \
9
9
  # --contract-published
10
10
 
11
- bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
12
- --uuid d40f38c3-aaa3-47f5-9161-95csfadfsd7 \
13
- --description "This is quite a long description for a webhook that I hope will be truncated" \
14
- --request POST \
15
- --contract-published
11
+ # bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
12
+ # --uuid d40f38c3-aaa3-47f5-9161-95csfadfsd7 \
13
+ # --description "This is quite a long description for a webhook that I hope will be truncated" \
14
+ # --request POST \
15
+ # --contract-published
16
16
 
17
17
  # bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json spec/fixtures/foo-bar.json \
18
18
  # --consumer-app-version 1.2.12 \
@@ -29,10 +29,8 @@ bundle exec bin/pact-broker create-or-update-webhook http://localhost:9393 \
29
29
  # --contract-published
30
30
 
31
31
 
32
- bundle exec bin/pact-broker publish spec/pacts/pact_broker_client-pact_broker.json \
32
+ bundle exec bin/pact-broker publish scripts/foo-bar.json \
33
33
  --consumer-app-version 1.2.26 \
34
- --broker-base-url http://localhost:9292 \
35
- --broker-token localhost \
36
34
  --auto-detect-version-properties \
37
35
  --build-url http://mybuild \
38
36
  --branch master --tag foo5 --tag foo6
@@ -1,7 +1,7 @@
1
1
  export PACT_BROKER_BASE_URL=${PACT_BROKER_BASE_URL:-"http://localhost:9292"}
2
2
  bundle exec bin/pactflow publish-provider-contract \
3
3
  script/oas.yml \
4
- --provider Foo \
4
+ --provider Bar \
5
5
  --provider-app-version 1013b5650d61214e19f10558f97fb5a3bb082d44 \
6
6
  --branch main \
7
7
  --tag dev \
@@ -13,7 +13,7 @@ PACT_BROKER_COMMAND_GROUPS = [
13
13
  [PactBroker::Client::CLI::Broker, "Environments", %w[create-environment update-environment describe-environment delete-environment list-environments]],
14
14
  [PactBroker::Client::CLI::Broker, "Deployments", %w[record-deployment record-undeployment]],
15
15
  [PactBroker::Client::CLI::Broker, "Releases", %w[record-release record-support-ended]],
16
- [PactBroker::Client::CLI::Broker, "Matrix", %w[can-i-deploy]],
16
+ [PactBroker::Client::CLI::Broker, "Matrix", %w[can-i-deploy can-i-merge]],
17
17
  [PactBroker::Client::CLI::Broker, "Pacticipants", %w[create-or-update-pacticipant describe-pacticipant list-pacticipants]],
18
18
  [PactBroker::Client::CLI::Broker, "Webhooks", %w[create-webhook create-or-update-webhook test-webhook]],
19
19
  [PactBroker::Client::CLI::Broker, "Tags", %w[create-version-tag]],
@@ -0,0 +1,2 @@
1
+ some notice
2
+ some other notice
@@ -0,0 +1,53 @@
1
+ require "pactflow/client/cli/pactflow"
2
+
3
+ RSpec.describe "publish-provider-contract" do
4
+ let(:index_body_hash) do
5
+ {
6
+ _links: {
7
+ "pf:publish-provider-contract" => {
8
+ href: "http://broker/some-publish/{provider}"
9
+ }
10
+ }
11
+ }
12
+ end
13
+
14
+ let(:post_response_body) do
15
+ {
16
+ "notices"=>[{"text"=>"some notice", "type"=>"info"}, {"text"=>"some other notice", "type"=>"info"}]
17
+ }
18
+ end
19
+
20
+ let!(:index_request) do
21
+ stub_request(:get, "http://broker").to_return(status: 200, body: index_body_hash.to_json, headers: { "Content-Type" => "application/hal+json" } )
22
+ end
23
+
24
+ let!(:publish_request) do
25
+ stub_request(:post, "http://broker/some-publish/Bar").to_return(status: 200, body: post_response_body.to_json, headers: { "Content-Type" => "application/hal+json" } )
26
+ end
27
+
28
+ let(:parameters) do
29
+ %w{
30
+ publish-provider-contract
31
+ script/oas.yml
32
+ --provider Bar
33
+ --broker-base-url http://broker
34
+ --provider-app-version 1013b5650d61214e19f10558f97fb5a3bb082d44
35
+ --branch main
36
+ --tag dev
37
+ --specification oas
38
+ --content-type application/yml
39
+ --verification-exit-code 0
40
+ --verification-results script/verification-results.txt
41
+ --verification-results-content-type text/plain
42
+ --verification-results-format text
43
+ --verifier my-custom-tool
44
+ --verifier-version "1.0"
45
+ }
46
+ end
47
+
48
+ subject { capture(:stdout) { Pactflow::Client::CLI::Pactflow.start(parameters) } }
49
+
50
+ it "prints the notices" do
51
+ Approvals.verify(subject, :name => "publish_provider_contract", format: :txt)
52
+ end
53
+ end
@@ -0,0 +1,178 @@
1
+ require "pactflow/client/provider_contracts/publish"
2
+
3
+ module Pactflow
4
+ module Client
5
+ module ProviderContracts
6
+ describe Publish do
7
+ before do
8
+ allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:sleep)
9
+ allow_any_instance_of(PactBroker::Client::Hal::HttpClient).to receive(:default_max_tries).and_return(1)
10
+ end
11
+
12
+ let(:command_params) do
13
+ {
14
+ provider_name: "Bar",
15
+ provider_version_number: "1",
16
+ branch_name: "main",
17
+ tags: ["dev"],
18
+ build_url: "http://build",
19
+ contract: {
20
+ content: { "some" => "contract" }.to_yaml,
21
+ content_type: "application/yaml",
22
+ specification: "oas"
23
+ },
24
+ verification_results: {
25
+ success: true,
26
+ content: "some results",
27
+ content_type: "text/plain",
28
+ format: "text",
29
+ verifier: "my custom tool",
30
+ verifier_version: "1.0"
31
+ }
32
+ }
33
+ end
34
+
35
+ let(:options) do
36
+ {
37
+ verbose: false
38
+ }
39
+ end
40
+
41
+ let(:pact_broker_client_options) do
42
+ { pact_broker_base_url: "http://pactflow" }
43
+ end
44
+
45
+ let(:index_body_hash) do
46
+ {
47
+ _links: {
48
+ "pf:publish-provider-contract" => {
49
+ href: "http://pactflow/some-publish/{provider}"
50
+ }
51
+ }
52
+ }
53
+ end
54
+
55
+ let(:post_response_body) do
56
+ {
57
+ "notices"=>[{"text"=>"some notice", "type"=>"info"}]
58
+ }
59
+ end
60
+
61
+ let!(:index_request) do
62
+ stub_request(:get, "http://pactflow")
63
+ .to_return(
64
+ status: index_status,
65
+ body: index_body_hash.to_json,
66
+ headers: { "Content-Type" => "application/hal+json" }
67
+ )
68
+ end
69
+ let(:index_status) { 200 }
70
+
71
+ let!(:publish_request) do
72
+ stub_request(:post, "http://pactflow/some-publish/Bar")
73
+ .to_return(
74
+ status: publish_status,
75
+ body: post_response_body.to_json,
76
+ headers: { "Content-Type" => "application/hal+json" }
77
+ )
78
+ end
79
+ let(:publish_status) { 200 }
80
+
81
+ subject { Publish.call(command_params, options, pact_broker_client_options) }
82
+
83
+ context "when there is no relation pf:publish-provider-contract" do
84
+ before do
85
+ allow(PublishTheOldWay).to receive(:call).with(command_params, options, pact_broker_client_options).and_return(instance_double(PactBroker::Client::CommandResult))
86
+ end
87
+
88
+ let(:index_body_hash) do
89
+ {
90
+ _links: {}
91
+ }
92
+ end
93
+
94
+ it "publishes the provider contracts the old way" do
95
+ expect(PublishTheOldWay).to receive(:call).with(command_params, options, pact_broker_client_options)
96
+ subject
97
+ end
98
+ end
99
+
100
+ context "when the feature is disabled" do
101
+ before do
102
+ allow(ENV).to receive(:fetch).and_call_original
103
+ allow(ENV).to receive(:fetch).with("PACTFLOW_FEATURES", "").and_return("publish_provider_contracts_using_old_api")
104
+ end
105
+
106
+ it "publishes the provider contracts the old way" do
107
+ expect(PublishTheOldWay).to receive(:call).with(command_params, options, pact_broker_client_options)
108
+ subject
109
+ end
110
+ end
111
+
112
+ it "returns a result and message" do
113
+ expect(subject.success).to be true
114
+ expect(subject.message).to include("some notice")
115
+ end
116
+
117
+ it "colourises the notices" do
118
+ expect(PactBroker::Client::ColorizeNotices).to receive(:call).with([OpenStruct.new(text: "some notice", type: "info")]).and_return("coloured notices")
119
+ expect(subject.message).to eq "coloured notices"
120
+ end
121
+
122
+ context "when the output is json" do
123
+ let(:options) { { output: "json" } }
124
+
125
+ it "returns the raw response" do
126
+ expect(subject.message).to eq post_response_body.to_json
127
+ end
128
+ end
129
+
130
+ context "when there is an error retrieving the index" do
131
+ let(:index_status) { 500 }
132
+ let(:index_body_hash) { { "some" => "error" }}
133
+
134
+ it "returns an error result with the response body" do
135
+ expect(subject.success).to be false
136
+ expect(subject.message).to match(/some.*error/)
137
+ end
138
+ end
139
+
140
+ context "when there is an error response from publishing" do
141
+ let(:publish_status) { 400 }
142
+ let(:post_response_body) do
143
+ {
144
+ "some" => "error"
145
+ }
146
+ end
147
+
148
+ it "returns an error result with the response body" do
149
+ expect(subject.success).to be false
150
+ expect(subject.message).to match(/some.*error/)
151
+ end
152
+
153
+ context "when the output is json" do
154
+ let(:options) { { output: "json" } }
155
+
156
+ it "returns the raw response" do
157
+ expect(subject.message).to eq post_response_body.to_json
158
+ end
159
+ end
160
+ end
161
+
162
+ context "when there is an error response from publishing" do
163
+ let(:publish_status) { 400 }
164
+ let(:post_response_body) do
165
+ {
166
+ "some" => "error"
167
+ }
168
+ end
169
+
170
+ it "returns an error result with the response body" do
171
+ expect(subject.success).to be false
172
+ expect(subject.message).to match(/some.*error/)
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -6,6 +6,103 @@
6
6
  "name": "PactFlow"
7
7
  },
8
8
  "interactions": [
9
+ {
10
+ "description": "a request for the index resource",
11
+ "providerState": "the pb:publish-provider-contract relation exists in the index resource",
12
+ "request": {
13
+ "method": "GET",
14
+ "path": "/",
15
+ "headers": {
16
+ "Accept": "application/hal+json"
17
+ }
18
+ },
19
+ "response": {
20
+ "status": 200,
21
+ "headers": {
22
+ "Content-Type": "application/hal+json;charset=utf-8"
23
+ },
24
+ "body": {
25
+ "_links": {
26
+ "pf:publish-provider-contract": {
27
+ "href": "http://localhost:1235/HAL-REL-PLACEHOLDER-PF-PUBLISH-PROVIDER-CONTRACT-{provider}"
28
+ }
29
+ }
30
+ },
31
+ "matchingRules": {
32
+ "$.body._links.pf:publish-provider-contract.href": {
33
+ "match": "regex",
34
+ "regex": "http:\\/\\/.*{provider}"
35
+ }
36
+ }
37
+ }
38
+ },
39
+ {
40
+ "description": "a request to publish a provider contract",
41
+ "request": {
42
+ "method": "post",
43
+ "path": "/HAL-REL-PLACEHOLDER-PF-PUBLISH-PROVIDER-CONTRACT-Bar",
44
+ "headers": {
45
+ "Content-Type": "application/json",
46
+ "Accept": "application/hal+json"
47
+ },
48
+ "body": {
49
+ "pacticipantVersionNumber": "1",
50
+ "tags": [
51
+ "dev"
52
+ ],
53
+ "branch": "main",
54
+ "buildUrl": "http://build",
55
+ "contract": {
56
+ "content": "LS0tCnNvbWU6IGNvbnRyYWN0Cg==",
57
+ "contentType": "application/yaml",
58
+ "specification": "oas",
59
+ "selfVerificationResults": {
60
+ "success": true,
61
+ "content": "c29tZSByZXN1bHRz",
62
+ "contentType": "text/plain",
63
+ "format": "text",
64
+ "verifier": "my custom tool",
65
+ "verifierVersion": "1.0"
66
+ }
67
+ }
68
+ }
69
+ },
70
+ "response": {
71
+ "status": 200,
72
+ "headers": {
73
+ "Content-Type": "application/hal+json;charset=utf-8"
74
+ },
75
+ "body": {
76
+ "notices": [
77
+ {
78
+ "text": "some notice",
79
+ "type": "info"
80
+ }
81
+ ],
82
+ "_embedded": {
83
+ "version": {
84
+ "number": "1"
85
+ }
86
+ },
87
+ "_links": {
88
+ "pb:pacticipant-version-tags": [
89
+ {
90
+ }
91
+ ],
92
+ "pb:branch-version": {
93
+ }
94
+ }
95
+ },
96
+ "matchingRules": {
97
+ "$.body.notices": {
98
+ "min": 1
99
+ },
100
+ "$.body.notices[*].*": {
101
+ "match": "type"
102
+ }
103
+ }
104
+ }
105
+ },
9
106
  {
10
107
  "description": "a request to create a provider contract",
11
108
  "request": {
@@ -16,7 +113,7 @@
16
113
  "Accept": "application/hal+json"
17
114
  },
18
115
  "body": {
19
- "content": "LS0tCjpzb21lOiBjb250cmFjdAo=",
116
+ "content": "LS0tCnNvbWU6IGNvbnRyYWN0Cg==",
20
117
  "contractType": "oas",
21
118
  "contentType": "application/yaml",
22
119
  "verificationResults": {
@@ -47,7 +144,7 @@
47
144
  "Accept": "application/hal+json"
48
145
  },
49
146
  "body": {
50
- "content": "LS0tCjpzb21lOiBjb250cmFjdAo=",
147
+ "content": "LS0tCnNvbWU6IGNvbnRyYWN0Cg==",
51
148
  "contractType": "oas",
52
149
  "contentType": "application/yaml",
53
150
  "verificationResults": {
@@ -68,9 +165,14 @@
68
165
  "body": {
69
166
  "_links": {
70
167
  "pf:ui": {
71
- "href": "http://localhost:1235/contracts/bi-directional/provider/Bar/version/1/provider-contract"
168
+ "href": "some-url"
72
169
  }
73
170
  }
171
+ },
172
+ "matchingRules": {
173
+ "$.body._links.pf:ui.href": {
174
+ "match": "type"
175
+ }
74
176
  }
75
177
  }
76
178
  },
@@ -25,10 +25,12 @@ end
25
25
 
26
26
  module PactBrokerPactHelperMethods
27
27
 
28
+ # @param [String] relation eg "pb:pacticipant"
29
+ # @param [Array<String>] params eg ["Foo"]
28
30
  def placeholder_path(relation, params = [])
29
31
  path = "/HAL-REL-PLACEHOLDER-#{relation.gsub(':', '-').upcase}"
30
32
  if params.any?
31
- joined_params = params.collect{ |param| "{#{param}}"}.join("-")
33
+ joined_params = params.join("-")
32
34
  path = "#{path}-#{joined_params}"
33
35
  end
34
36
 
@@ -36,7 +38,19 @@ module PactBrokerPactHelperMethods
36
38
  end
37
39
 
38
40
  def placeholder_url(relation, params = [], mock_service = pact_broker)
39
- "#{mock_service.mock_service_base_url}#{placeholder_path(relation, params)}"
41
+ "#{mock_service.mock_service_base_url}#{placeholder_path_for_term(relation, params)}"
42
+ end
43
+
44
+ # @param [String] relation eg "pb:pacticipants"
45
+ # @param [Array<String>] params eg ["pacticipant"]
46
+ def placeholder_path_for_term(relation, params = [])
47
+ path = "/HAL-REL-PLACEHOLDER-#{relation.gsub(':', '-').upcase}"
48
+ if params.any?
49
+ joined_params = params.collect{ |param| "{#{param}}"}.join("-")
50
+ path = "#{path}-#{joined_params}"
51
+ end
52
+
53
+ path
40
54
  end
41
55
 
42
56
  def placeholder_url_term(relation, params = [], mock_service = pact_broker)