Skip to content

Commit

Permalink
Merge branch 'feat/show-badge-markdown' into webhook-status
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Sep 17, 2017
2 parents 384cddd + e5f08ad commit 477021c
Show file tree
Hide file tree
Showing 24 changed files with 253 additions and 52 deletions.
4 changes: 4 additions & 0 deletions lib/pact_broker/api/pact_broker_urls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ def triggered_webhook_logs_url triggered_webhook, base_url
"#{base_url}/webhooks/#{triggered_webhook.webhook_uuid}/trigger/#{triggered_webhook.trigger_uuid}/logs"
end

def badge_url_for_latest_pact pact, base_url = ''
"#{latest_pact_url(base_url, pact)}/badge.svg"
end

def hal_browser_url target_url
"/hal-browser/browser.html#" + target_url
end
Expand Down
50 changes: 47 additions & 3 deletions lib/pact_broker/api/renderers/html_pact_renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ class NotAPactError < StandardError; end

include PactBroker::Logging

def self.call pact
new(pact).call
def self.call pact, options = {}
new(pact, options).call
end

def initialize pact
def initialize pact, options = {}
@json_content = pact.json_content
@pact = pact
@options = options
end

def call
Expand All @@ -40,12 +41,17 @@ def head
<link rel='stylesheet' type='text/css' href='/stylesheets/pact.css'>
<link rel='stylesheet' type='text/css' href='/stylesheets/github-json.css'>
<script src='/javascripts/highlight.pack.js'></script>
<script src='/javascripts/jquery-2.1.1.min.js'></script>
<script src='/js/bootstrap.min.js'></script>
<script src='/javascripts/pact.js'></script>
<script>hljs.initHighlightingOnLoad();</script>"
end

def pact_metadata
"<div class='pact-metadata'>
<ul>
#{badge_list_item}
#{badge_markdown_item}
<li>
<span class='name'>#{@pact.consumer.name} version:</span>
<span class='value'>#{@pact.consumer_version_number}#{tags}</span>
Expand All @@ -64,6 +70,36 @@ def pact_metadata
</div>"
end

def badge_list_item
"<li class='badge'>
<img src='#{badge_url}'/>
</li>
"
end

def badge_markdown_item
"<li class='badge-markdown' style='display:none'>
<textarea rows='3' cols='100'>#{badge_markdown}</textarea>
</li>"
end

def badge_markdown
warning = if badges_protected?
"If the broker is protected by authentication, set `enable_public_badge_access` to true in the configuration to enable badges to be embedded in a markdown file.\n"
else
""
end
"#{warning}[![#{@pact.consumer.name}/#{@pact.provider.name} Pact Status](#{badge_url})](#{badge_target_url})"
end

def badges_protected?
!PactBroker.configuration.enable_public_badge_access
end

def base_url
@options[:base_url] || ''
end

def title
"Pact between #{@pact.consumer.name} and #{@pact.provider.name}"
end
Expand All @@ -80,6 +116,14 @@ def pact_url
PactBroker::Api::PactBrokerUrls.pact_url '', @pact
end

def badge_target_url
base_url
end

def badge_url
@options[:badge_url]
end

def tags
if @pact.consumer_version_tag_names.any?
" (#{@pact.consumer_version_tag_names.join(", ")})"
Expand Down
6 changes: 3 additions & 3 deletions lib/pact_broker/api/resources/badge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def content_types_provided
end

def resource_exists?
PactBroker.configuration.enable_badge_resources
true
end

def is_authorized?(authorization_header)
true
super || PactBroker.configuration.enable_public_badge_access
end

def forbidden?
Expand All @@ -31,7 +31,7 @@ def forbidden?
private

def to_svg
badges_service.pact_verification_badge pact, label, initials, verification_status
badge_service.pact_verification_badge pact, label, initials, verification_status
end

def pact
Expand Down
2 changes: 1 addition & 1 deletion lib/pact_broker/api/resources/base_resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def encode(body)
end

def resource_url
request.uri.to_s
request.uri.to_s.gsub(/\?.*/, '')
end

def decorator_context options = {}
Expand Down
6 changes: 5 additions & 1 deletion lib/pact_broker/api/resources/latest_pact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ def to_json
end

def to_html
PactBroker.configuration.html_pact_renderer.call(pact)
PactBroker.configuration.html_pact_renderer.call(
pact, {
base_url: base_url,
badge_url: "#{resource_url}/badge.svg"
})
end

def pact
Expand Down
6 changes: 5 additions & 1 deletion lib/pact_broker/api/resources/pact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@ def to_json
end

def to_html
PactBroker.configuration.html_pact_renderer.call(pact)
PactBroker.configuration.html_pact_renderer.call(
pact, {
base_url: base_url,
badge_url: badge_url_for_latest_pact(pact, base_url)
})
end

def delete_resource
Expand Down
31 changes: 26 additions & 5 deletions lib/pact_broker/badges/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Service
include PactBroker::Logging

SPACE_DASH_UNDERSCORE = /[\s_\-]/
CACHE = {}

def pact_verification_badge pact, label, initials, verification_status
return static_svg(pact, verification_status) unless pact
Expand All @@ -23,6 +24,10 @@ def pact_verification_badge pact, label, initials, verification_status
dynamic_svg(title, status, color) || static_svg(pact, verification_status)
end

def clear_cache
CACHE.clear
end

private

def badge_title pact, label, initials
Expand Down Expand Up @@ -79,7 +84,7 @@ def dynamic_svg left_text, right_text, color
response = do_request(uri)
response.code == '200' ? response.body : nil
rescue StandardError => e
log_error e, "Error retrieving badge from #{uri}"
logger.error "Error retrieving badge from #{uri} due to #{e.class} - #{e.message}"
nil
end
end
Expand All @@ -95,11 +100,27 @@ def escape_text text
end

def do_request(uri)
request = Net::HTTP::Get.new(uri)
Net::HTTP.start(uri.hostname, uri.port,
use_ssl: uri.scheme == 'https', read_timeout: 1000) do |http|
http.request request
with_cache uri do
request = Net::HTTP::Get.new(uri)
Net::HTTP.start(uri.hostname, uri.port,
use_ssl: uri.scheme == 'https',
read_timeout: 3,
open_timeout: 1,
ssl_timeout: 1,
continue_timeout: 1) do |http|
http.request request
end
end
end

def with_cache uri
if !(response = CACHE[uri])
response = yield
if response.code == '200'
CACHE[uri] = response
end
end
response
end

def static_svg pact, verification_status
Expand Down
17 changes: 11 additions & 6 deletions lib/pact_broker/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ def self.reset_configuration

class Configuration

SAVABLE_SETTING_NAMES = [:order_versions_by_date, :use_case_sensitive_resource_names, :enable_badge_resources, :shields_io_base_url]
SAVABLE_SETTING_NAMES = [:order_versions_by_date, :use_case_sensitive_resource_names, :enable_public_badge_access, :shields_io_base_url]

attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser
attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
attr_accessor :semver_formats
attr_accessor :enable_badge_resources, :shields_io_base_url
attr_accessor :webhook_retry_schedule
attr_accessor :enable_public_badge_access, :shields_io_base_url
attr_accessor :webhook_retry_schedule
attr_writer :logger

def initialize
Expand All @@ -40,7 +40,7 @@ def self.default_configuration
config.use_hal_browser = true
config.validate_database_connection_config = true
config.enable_diagnostic_endpoints = true
config.enable_badge_resources = false # For security
config.enable_public_badge_access = false # For security
config.shields_io_base_url = "https://img.shields.io".freeze
config.use_case_sensitive_resource_names = true
config.html_pact_renderer = default_html_pact_render
Expand All @@ -54,9 +54,9 @@ def self.default_configuration
end

def self.default_html_pact_render
lambda { |pact|
lambda { |pact, options|
require 'pact_broker/api/renderers/html_pact_renderer'
PactBroker::Api::Renderers::HtmlPactRenderer.call pact
PactBroker::Api::Renderers::HtmlPactRenderer.call pact, options
}
end

Expand Down Expand Up @@ -108,6 +108,11 @@ def after_resource &block
end
end

def enable_badge_resources= enable_badge_resources
puts "Pact Broker configuration property `enable_badge_resources` is deprecated. Please use `enable_public_badge_access`"
self.enable_public_badge_access = enable_badge_resources
end

def save_to_database
# Can't require a Sequel::Model class before the connection has been set
require 'pact_broker/config/save'
Expand Down
2 changes: 1 addition & 1 deletion lib/pact_broker/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def verification_service
Verifications::Service
end

def badges_service
def badge_service
require 'pact_broker/badges/service'
Badges::Service
end
Expand Down
5 changes: 5 additions & 0 deletions public/javascripts/pact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
$( document ).ready(function() {
$('.badge').click(function(){
$('.badge-markdown').toggle();
});
});
15 changes: 14 additions & 1 deletion public/stylesheets/pact.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,17 @@ div.pact-metadata span.name {

pre {
font-size: 1em
}
}

li.badge {
cursor: pointer;
}

li.badge > img {
cursor: pointer;
height: 20px;
}

div.badge-markdown {
background-color: #f8f8f8
}
2 changes: 1 addition & 1 deletion spec/features/get_latest_pact_badge_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe "get latest pact badge" do

before do
PactBroker.configuration.enable_badge_resources = true
PactBroker.configuration.enable_public_badge_access = true
TestDataBuilder.new
.create_consumer('consumer')
.create_provider('provider')
Expand Down
2 changes: 1 addition & 1 deletion spec/features/get_latest_tagged_pact_badge_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe "get latest tagged pact badge" do

before do
PactBroker.configuration.enable_badge_resources = true
PactBroker.configuration.enable_public_badge_access = true
PactBroker.configuration.shields_io_base_url = nil
TestDataBuilder.new
.create_consumer('consumer')
Expand Down
2 changes: 1 addition & 1 deletion spec/features/get_latest_untagged_pact_badge_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
describe "get latest untagged pact badge" do

before do
PactBroker.configuration.enable_badge_resources = true
PactBroker.configuration.enable_public_badge_access = true
PactBroker.configuration.shields_io_base_url = nil
TestDataBuilder.new
.create_consumer('consumer')
Expand Down
28 changes: 27 additions & 1 deletion spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Renderers
before do
ENV['BACKUP_TZ'] = ENV['TZ']
ENV['TZ'] = "Australia/Melbourne"
PactBroker.configuration.enable_public_badge_access = true
end

after do
Expand All @@ -21,12 +22,18 @@ module Renderers
let(:json_content) { load_fixture('renderer_pact.json') }
let(:pact) { double('pact', json_content: json_content, consumer_version_number: '1.2.3', consumer: consumer, provider: provider, consumer_version_tag_names: ['prod', 'master'], created_at: created_at)}
let(:pact_url) { '/pact/url' }
let(:options) do
{
base_url: 'http://base',
badge_url: 'http://badge'
}
end

before do
allow(PactBroker::Api::PactBrokerUrls).to receive(:pact_url).with('', pact).and_return(pact_url)
end

subject { HtmlPactRenderer.call pact }
subject { HtmlPactRenderer.call pact, options }

describe ".call" do
it "renders the pact as HTML" do
Expand All @@ -44,6 +51,25 @@ module Renderers
expect(subject).to match /prod, master/
end

it "renders the badge image" do
expect(subject).to include "<img src='http://badge'/>"
end

it "renders a text area with the badge markdown" do
expect(subject).to include "<textarea"
expect(subject).to include "[![Consumer/Provider Pact Status](http://badge)](http://base)"
end

context "when enable_public_badge_access is false" do
before do
PactBroker.configuration.enable_public_badge_access = false
end

it "renders a message instructing the user to turn public access on" do
expect(subject).to include "set `enable_public_badge_access` to true in the configuration"
end
end

context "when the content is not a valid pact, but is still JSON" do
before do
allow(pact).to receive(:content_hash).and_return(content_hash)
Expand Down
Loading

0 comments on commit 477021c

Please sign in to comment.