Skip to content

Commit

Permalink
feat: created dashboard API
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Jan 15, 2018
1 parent d4fc8a6 commit 044bab7
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 1 deletion.
1 change: 1 addition & 0 deletions lib/pact_broker/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ module PactBroker
add ['matrix', 'provider', :provider_name, 'latest', :provider_tag, 'consumer', :consumer_name, 'latest', :tag, 'badge'], Api::Resources::MatrixBadge, {resource_name: "matrix_tag_badge"}
add ['matrix'], Api::Resources::Matrix, {resource_name: "matrix"}

add ['dashboard'], Api::Resources::Dashboard, {resource_name: "dashboard"}
add [], Api::Resources::Index, {resource_name: "index"}
end
end
Expand Down
131 changes: 131 additions & 0 deletions lib/pact_broker/api/decorators/dashboard_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
require 'ostruct'
require 'pact_broker/api/pact_broker_urls'

module PactBroker
module Api
module Decorators
class DashboardDecorator
include PactBroker::Api::PactBrokerUrls

def initialize(index_items)
@index_items = index_items
end

def to_json(options)
to_hash(options).to_json
end

def to_hash(options)
{
items: items(index_items, options[:user_options][:base_url])
}
end

private

attr_reader :index_items

def items(index_items, base_url)
index_items.collect do | index_item |
index_item_hash(index_item.consumer, index_item.provider, index_item.consumer_version, index_item, base_url)
end
end

def index_item_hash(consumer, provider, consumer_version, index_item, base_url)
{
consumer: consumer_hash(index_item, consumer, consumer_version, base_url),
provider: provider_hash(index_item, provider, base_url),
pact: pact_hash(index_item, base_url),
latestVerificationResult: verification_hash(index_item, base_url),
verificationStatus: index_item.verification_status.to_s,
webhookStatus: index_item.webhook_status.to_s,
latestWebhookExecution: latest_webhook_execution(index_item, base_url),
_links: links(index_item, base_url)

}
end

def consumer_hash(index_item, consumer, consumer_version, base_url)
{
name: index_item.consumer_name,
version: {
number: index_item.consumer_version_number,
_links: {
self: {
href: version_url(base_url, index_item.consumer_version)
}
}
},
_links: {
self: {
href: pacticipant_url(base_url, index_item.consumer)
}
}
}
end

def provider_hash(index_item, provider, base_url)
hash = {
name: index_item.provider_name,
version: nil,
_links: {
self: {
href: pacticipant_url(base_url, index_item.provider)
}
}
}

if index_item.latest_verification
hash[:version] = { number: index_item.provider_version_number }
end

hash
end

def pact_hash(index_item, base_url)
{
createdAt: index_item.latest_pact.created_at.to_datetime.xmlschema,
_links: {
self: {
href: pact_url(base_url, index_item.latest_pact)
}
}
}
end

def verification_hash(index_item, base_url)
if index_item.latest_verification
{
success: index_item.latest_verification.success,
verifiedAt: index_item.latest_verification.created_at.to_datetime.xmlschema,
_links: {
self: {
href: verification_url(index_item.latest_verification, base_url)
}
}
}
else
nil
end
end

def latest_webhook_execution(index_item, base_url)
if index_item.last_webhook_execution_date
{
triggeredAt: index_item.last_webhook_execution_date.to_datetime.xmlschema
}
end
end

def links(index_item, base_url)
{
'pb:webhook-status' => {
title: "Status of webhooks for #{index_item.consumer_name}/#{index_item.provider_name} pact",
href: webhooks_status_url(index_item.consumer, index_item.provider, base_url)
}
}
end
end
end
end
end
7 changes: 7 additions & 0 deletions lib/pact_broker/api/resources/dashboard.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'pact_broker/api/resources/base_resource'
require 'pact_broker/api/decorators/dashboard_decorator'

module PactBroker
module Api
Expand All @@ -15,7 +16,13 @@ def allowed_methods
end

def to_json
PactBroker::Api::Decorators::DashboardDecorator.new(index_items).to_json(user_options: decorator_context)
end

private

def index_items
index_service.find_index_items
end
end
end
Expand Down
6 changes: 5 additions & 1 deletion lib/pact_broker/domain/index_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module PactBroker
module Domain
class IndexItem

attr_reader :consumer, :provider, :latest_pact, :latest_verification, :webhooks
attr_reader :consumer, :provider, :latest_pact, :latest_verification, :webhooks, :triggered_webhooks

def initialize consumer, provider, latest_pact = nil, latest = true, latest_verification = nil, webhooks = [], triggered_webhooks = [], tags = []
@consumer = consumer
Expand Down Expand Up @@ -54,6 +54,10 @@ def consumer_version_number
@latest_pact.consumer_version_number
end

def consumer_version
@latest_pact.consumer_version
end

def provider_version_number
@latest_verification ? @latest_verification.provider_version_number : nil
end
Expand Down
1 change: 1 addition & 0 deletions pact_broker.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Gem::Specification.new do |gem|
gem.add_runtime_dependency 'table_print', '~> 1.5'

gem.add_development_dependency 'pact', '~>1.14'
gem.add_development_dependency 'rspec-pact-matchers', '~>0.1'
gem.add_development_dependency 'bundler-audit', '~>0.4'
gem.add_development_dependency 'sqlite3', '~>1.3'
gem.add_development_dependency 'pry-byebug'
Expand Down
61 changes: 61 additions & 0 deletions spec/fixtures/dashboard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"items": [
{
"_links": {
"pb:webhook-status": {
"href": "webhooks_status_url",
"title": "Status of webhooks for Foo/Bar pact"
}
},
"consumer": {
"_links": {
"self": {
"href": "consumer_url"
}
},
"name": "Foo",
"version": {
"_links": {
"self": {
"href": "consumer_version_url"
}
},
"number": "1"
}
},
"latestVerificationResult": {
"_links": {
"self": {
"href": "verification_url"
}
},
"success": true,
"verifiedAt": "2018-01-01T00:00:00+00:00"
},
"latestWebhookExecution": {
"triggeredAt": "2018-01-01T00:00:00+00:00"
},
"pact": {
"_links": {
"self": {
"href": "pact_url"
}
},
"createdAt": "2018-01-01T00:00:00+00:00"
},
"provider": {
"_links": {
"self": {
"href": "provider_url"
}
},
"name": "Bar",
"version": {
"number": "2"
}
},
"verificationStatus": "wiffle",
"webhookStatus": "blah"
}
]
}
73 changes: 73 additions & 0 deletions spec/lib/pact_broker/api/decorators/dashboard_decorator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'pact_broker/api/decorators/dashboard_decorator'

module PactBroker
module Api
module Decorators
describe DashboardDecorator do
let(:index_item) do
instance_double('PactBroker::Domain::IndexItem',
consumer: consumer,
provider: provider,
consumer_name: consumer.name,
provider_name: provider.name,
latest_pact: pact,
latest_verification: verification,
provider_version: provider_version,
consumer_version: consumer_version,
last_webhook_execution_date: last_webhook_execution_date,
webhook_status: 'blah',
verification_status: 'wiffle',
provider_version_number: provider_version.number,
consumer_version_number: consumer_version.number
)
end
let(:consumer) { instance_double('PactBroker::Domain::Pacticipant', name: 'Foo') }
let(:provider) { instance_double('PactBroker::Domain::Pacticipant', name: 'Bar') }
let(:pact) { instance_double('PactBroker::Domain::Pact', created_at: DateTime.new(2018)) }
let(:verification) { instance_double('PactBroker::Domain::Verification', success: true, created_at: DateTime.new(2018)) }
let(:consumer_version) { instance_double('PactBroker::Domain::Version', number: '1', pacticipant: consumer) }
let(:provider_version) { instance_double('PactBroker::Domain::Version', number: '2', pacticipant: provider) }
let(:last_webhook_execution_date) { Date.new(2018) }
let(:base_url) { 'http://example.org' }
let(:options) { { user_options: { base_url: base_url } } }
let(:dashboard_json) { DashboardDecorator.new([index_item]).to_json(options) }

before do
allow_any_instance_of(DashboardDecorator).to receive(:pact_url).with(base_url, pact).and_return('pact_url')
allow_any_instance_of(DashboardDecorator).to receive(:verification_url).with(verification, base_url).and_return('verification_url')
allow_any_instance_of(DashboardDecorator).to receive(:pacticipant_url).with(base_url, consumer).and_return('consumer_url')
allow_any_instance_of(DashboardDecorator).to receive(:pacticipant_url).with(base_url, provider).and_return('provider_url')
allow_any_instance_of(DashboardDecorator).to receive(:version_url).with(base_url, consumer_version).and_return('consumer_version_url')
allow_any_instance_of(DashboardDecorator).to receive(:webhooks_status_url).with(consumer, provider, base_url).and_return('webhooks_status_url')
end

let(:expected_hash) { JSON.parse(File.read('spec/fixtures/dashboard.json')) }

subject { JSON.parse(dashboard_json) }

it "creates some json" do
expect(subject).to match_pact(expected_hash, {allow_unexpected_keys: false})
end

context "when the pact has never been verified" do
let(:verification) { nil }

it "has a null last verification and provider version" do
expected_hash['items'][0]['latestVerificationResult'] = nil
expected_hash['items'][0]['provider']['version'] = nil
expect(subject).to match_pact(expected_hash, {allow_unexpected_keys: false})
end
end

context "when no webhooks have been executed" do
let(:last_webhook_execution_date) { nil }

it "has a null latestWebhookExecution" do
expected_hash['items'][0]['latestWebhookExecution'] = nil
expect(subject).to match_pact(expected_hash, {allow_unexpected_keys: false})
end
end
end
end
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
require 'rack/test'
require 'pact_broker/api'
require 'rspec/its'
require 'rspec/pact/matchers'
require 'sucker_punch/testing/inline'
require 'webmock/rspec'

Expand Down

0 comments on commit 044bab7

Please sign in to comment.