Skip to content

Commit 40f3e02

Browse files
committed
feat: add hal+json endpoint for listing integrations
1 parent 634ccd5 commit 40f3e02

File tree

9 files changed

+164
-2
lines changed

9 files changed

+164
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Sequel.migration do
2+
up do
3+
create_view(:integrations,
4+
from(:pact_publications)
5+
.select(
6+
:consumer_id,
7+
Sequel[:c][:name].as(:consumer_name),
8+
:provider_id,
9+
Sequel[:p][:name].as(:provider_name)
10+
).distinct
11+
.join(:pacticipants, {:id => :consumer_id}, {:table_alias => :c, implicit_qualifier: :pact_publications})
12+
.join(:pacticipants, {:id => :provider_id}, {:table_alias => :p, implicit_qualifier: :pact_publications})
13+
14+
)
15+
end
16+
17+
down do
18+
drop_view(:integrations)
19+
end
20+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require_relative 'base_decorator'
2+
3+
module PactBroker
4+
module Api
5+
module Decorators
6+
class IntegrationDecorator < BaseDecorator
7+
property :consumer do
8+
property :name
9+
end
10+
11+
property :provider do
12+
property :name
13+
end
14+
end
15+
end
16+
end
17+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require_relative 'base_decorator'
2+
require_relative 'integration_decorator'
3+
4+
module PactBroker
5+
module Api
6+
module Decorators
7+
class IntegrationsDecorator < BaseDecorator
8+
collection :entries, as: :integrations, embedded: true, :extend => PactBroker::Api::Decorators::IntegrationDecorator
9+
10+
link :self do | context |
11+
{
12+
href: context[:resource_url],
13+
title: "All integrations"
14+
}
15+
end
16+
end
17+
end
18+
end
19+
end

lib/pact_broker/api/resources/integrations.rb

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
require 'pact_broker/api/resources/base_resource'
22
require 'pact_broker/api/renderers/integrations_dot_renderer'
3+
require 'pact_broker/api/decorators/integrations_decorator'
34

45
module PactBroker
56
module Api
67
module Resources
78
class Integrations < BaseResource
89
def content_types_provided
9-
[["text/vnd.graphviz", :to_dot]]
10+
[
11+
["text/vnd.graphviz", :to_dot],
12+
["application/hal+json", :to_json]
13+
]
1014
end
1115

1216
def allowed_methods
@@ -17,8 +21,12 @@ def to_dot
1721
PactBroker::Api::Renderers::IntegrationsDotRenderer.call(integrations)
1822
end
1923

24+
def to_json
25+
PactBroker::Api::Decorators::IntegrationsDecorator.new(integrations).to_json(user_options: decorator_context)
26+
end
27+
2028
def integrations
21-
pact_service.find_latest_pacts
29+
integration_service.find_all
2230
end
2331

2432
def delete_resource
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
require 'pact_broker/db'
2+
3+
module PactBroker
4+
module Integrations
5+
class Integration < Sequel::Model
6+
associate(:many_to_one, :consumer, :class => "PactBroker::Domain::Pacticipant", :key => :consumer_id, :primary_key => :id)
7+
associate(:many_to_one, :provider, :class => "PactBroker::Domain::Pacticipant", :key => :provider_id, :primary_key => :id)
8+
end
9+
end
10+
end

lib/pact_broker/integrations/service.rb

+5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'pact_broker/services'
22
require 'pact_broker/repositories'
33
require 'pact_broker/logging'
4+
require 'pact_broker/integrations/integration'
45

56
module PactBroker
67
module Integrations
@@ -9,6 +10,10 @@ class Service
910
extend PactBroker::Services
1011
include PactBroker::Logging
1112

13+
def self.find_all
14+
PactBroker::Integrations::Integration.eager(:consumer).eager(:provider).all
15+
end
16+
1217
def self.delete(consumer_name, provider_name)
1318
consumer = pacticipant_service.find_pacticipant_by_name(consumer_name)
1419
provider = pacticipant_service.find_pacticipant_by_name(provider_name)
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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' => 'application/hal+json' } }
11+
12+
it { is_expected.to be_a_hal_json_success_response }
13+
14+
it "returns a json body with embedded integrations" do
15+
expect(JSON.parse(subject.body)["_embedded"]["integrations"]).to be_a(Array)
16+
end
17+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'pact_broker/api/decorators/integration_decorator'
2+
require 'pact_broker/integrations/integration'
3+
4+
module PactBroker
5+
module Api
6+
module Decorators
7+
describe IntegrationDecorator do
8+
let(:integration) do
9+
instance_double(PactBroker::Integrations::Integration,
10+
consumer: consumer,
11+
provider: provider
12+
)
13+
end
14+
let(:consumer) { double("consumer", name: "the consumer") }
15+
let(:provider) { double("provider", name: "the provider") }
16+
17+
let(:expected_hash) do
18+
{
19+
"consumer" => {
20+
"name" => "the consumer"
21+
},
22+
"provider" => {
23+
"name" => "the provider"
24+
}
25+
}
26+
end
27+
28+
let(:json) { IntegrationDecorator.new(integration).to_json }
29+
subject { JSON.parse(json) }
30+
31+
it "generates a hash" do
32+
expect(subject).to match_pact expected_hash
33+
end
34+
end
35+
end
36+
end
37+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
require 'pact_broker/api/decorators/integrations_decorator'
2+
3+
module PactBroker
4+
module Api
5+
module Decorators
6+
describe IntegrationsDecorator do
7+
before do
8+
allow(IntegrationDecorator).to receive(:new).and_return(integration_decorator)
9+
end
10+
let(:integration_decorator) { instance_double(IntegrationDecorator).as_null_object }
11+
let(:integration) { double('integration') }
12+
let(:integrations_decorator) { IntegrationsDecorator.new([integration]) }
13+
let(:options) { { user_options: { resource_url: 'http://example.org/integrations' } } }
14+
15+
let(:json) { integrations_decorator.to_json(options) }
16+
17+
subject { JSON.parse(json) }
18+
19+
it "includes a list of integrations" do
20+
expect(subject["_embedded"]["integrations"]).to be_an(Array)
21+
end
22+
23+
it "includes a link to itself" do
24+
expect(subject["_links"]["self"]["href"]).to eq "http://example.org/integrations"
25+
end
26+
end
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)