Skip to content

Commit ac60908

Browse files
committed
feat: allow integrations to be exported in dot format (text/vnd.graphviz)
1 parent 9ac2ba9 commit ac60908

File tree

8 files changed

+132
-0
lines changed

8 files changed

+132
-0
lines changed

lib/pact_broker/api.rb

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ module PactBroker
8383

8484
add ['dashboard'], Api::Resources::Dashboard, {resource_name: "dashboard"}
8585
add ['test','error'], Api::Resources::ErrorTest, {resource_name: "error_test"}
86+
87+
add ['integrations'], Api::Resources::Integrations, {resource_name: "integrations"}
8688
add [], Api::Resources::Index, {resource_name: "index"}
8789
end
8890
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module PactBroker
2+
module Api
3+
module Renderers
4+
class IntegrationsDotRenderer
5+
def initialize(integrations)
6+
@integrations = integrations
7+
end
8+
9+
def self.call(integrations)
10+
new(integrations).call
11+
end
12+
13+
def call
14+
"digraph { ranksep=3; ratio=auto; overlap=false; node [ shape = plaintext, fontname = Helvetica ];
15+
#{integrations_graph}
16+
}
17+
"
18+
end
19+
20+
private
21+
22+
attr_reader :integrations
23+
24+
def integrations_graph
25+
integrations
26+
.collect{ | integration| " #{escape_name(integration.consumer_name)} -> #{escape_name(integration.provider_name)}" }
27+
.join("\n")
28+
end
29+
30+
def escape_name(name)
31+
name.gsub(" ", "_")
32+
end
33+
end
34+
end
35+
end
36+
end

lib/pact_broker/api/resources/index.rb

+5
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ def links
8383
title: 'Webhooks',
8484
templated: false
8585
},
86+
'pb:integrations' => {
87+
href: base_url + '/integrations',
88+
title: 'Integrations',
89+
templated: false
90+
},
8691
'beta:pending-provider-pacts' =>
8792
{
8893
href: base_url + '/pacts/provider/{provider}/pending',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
require 'pact_broker/api/resources/base_resource'
2+
require 'pact_broker/api/renderers/integrations_dot_renderer'
3+
4+
module PactBroker
5+
module Api
6+
module Resources
7+
class Integrations < BaseResource
8+
def content_types_provided
9+
[["text/vnd.graphviz", :to_dot]]
10+
end
11+
12+
def allowed_methods
13+
["GET", "OPTIONS"]
14+
end
15+
16+
def to_dot
17+
PactBroker::Api::Renderers::IntegrationsDotRenderer.call(integrations)
18+
end
19+
20+
def integrations
21+
pact_service.find_latest_pacts
22+
end
23+
end
24+
end
25+
end
26+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Integrations
2+
3+
Allowed methods: `GET`
4+
5+
Content types: `text/vnd.graphviz`
6+
7+
A list of all the integrations (consumer/provider pairs) stored in the Pact Broker.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
describe "Get integrations dot file" do
2+
before do
3+
TestDataBuilder.new
4+
.create_pact_with_hierarchy("Foo", "1", "Bar")
5+
end
6+
7+
let(:path) { "/integrations" }
8+
let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) }
9+
10+
subject { get path, nil, {'HTTP_ACCEPT' => 'text/vnd.graphviz' }; last_response }
11+
12+
it "returns a 200 OK" do
13+
expect(subject.status).to eq 200
14+
end
15+
16+
it "returns a dot file content type" do
17+
expect(subject.headers['Content-Type']).to eq 'text/vnd.graphviz;charset=utf-8'
18+
end
19+
20+
it "returns dot file content" do
21+
expect(subject.body).to include "Foo -> Bar"
22+
end
23+
end

spec/fixtures/expected.gv

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
digraph { ranksep=3; ratio=auto; overlap=false; node [ shape = plaintext, fontname = Helvetica ];
2+
Foo -> Bar
3+
Wiffle -> Foo_Thing
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'pact_broker/api/renderers/integrations_dot_renderer'
2+
3+
module PactBroker
4+
module Api
5+
module Renderers
6+
describe IntegrationsDotRenderer do
7+
8+
# TODO work out how to handle apostrophes etc
9+
10+
let(:integrations) do
11+
[
12+
double('integration', consumer_name: "Foo", provider_name: "Bar"),
13+
double('integration', consumer_name: "Wiffle", provider_name: "Foo Thing")
14+
]
15+
end
16+
17+
let(:expected_content) { load_fixture('expected.gv') }
18+
19+
describe "#call" do
20+
subject { IntegrationsDotRenderer.call(integrations) }
21+
22+
it "renders a dot file" do
23+
expect(subject).to eq expected_content
24+
end
25+
end
26+
end
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)