Skip to content

Commit

Permalink
feat: add badge url for 'can I deploy latest version of branch to env…
Browse files Browse the repository at this point in the history
…ionment' endpoint
  • Loading branch information
bethesque committed Feb 28, 2022
1 parent b901d56 commit 086b8c1
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 87 deletions.
2 changes: 1 addition & 1 deletion lib/pact_broker/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def self.build_api(application_context = PactBroker::ApplicationContext.default_
add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number, "tags", :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"}
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions", :version_number], Api::Resources::BranchVersion, { resource_name: "branch_version" }
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironment, { resource_name: "can_i_deploy_latest_branch_version_to_environment" }
#add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name, "badge"], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironment, { resource_name: "can_i_deploy_latest_branch_version_to_environment_badge" }
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name, "badge"], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironmentBadge, { resource_name: "can_i_deploy_latest_branch_version_to_environment_badge" }

# Webhooks
add ["webhooks", "provider", :provider_name, "consumer", :consumer_name ], Api::Resources::PacticipantWebhooks, {resource_name: "pacticipant_webhooks"}
Expand Down
4 changes: 0 additions & 4 deletions lib/pact_broker/api/resources/badge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ def pseudo_branch_verification_status
@pseudo_branch_verification_status ||= PactBroker::Verifications::PseudoBranchStatus.new(pact, latest_verification).to_sym
end

def label
request.query["label"]
end

def initials
request.query["initials"] == "true"
end
Expand Down
11 changes: 11 additions & 0 deletions lib/pact_broker/api/resources/badge_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ def moved_temporarily?
badge_service.error_badge_url("error", ErrorResponseBodyGenerator.display_message(e, "reference: #{PactBroker::Errors.generate_error_reference}"))
end
end

def badge_url
raise NotImplementedError
end

private

def label
lab = request.query["label"]
lab && !lab.empty? ? lab : nil
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
require "pact_broker/api/resources/matrix"
require "pact_broker/matrix/can_i_deploy_query_schema"
require "pact_broker/matrix/parse_can_i_deploy_query"
require "pact_broker/api/decorators/matrix_decorator"
require "pact_broker/api/decorators/matrix_text_decorator"

module PactBroker
module Api
module Resources
class CanIDeployPacticipantVersionByBranchToEnvironment < Matrix
def resource_exists?
!!(version && environment)
class CanIDeployPacticipantVersionByBranchToEnvironment < BaseResource
def allowed_methods
["GET", "OPTIONS"]
end

def malformed_request?
false
def content_types_provided
[
["application/hal+json", :to_json],
["text/plain", :to_text]
]
end

def resource_exists?
!!(version && environment)
end

def policy_name
:'matrix::can_i_deploy'
:'versions::version'
end

private
Expand All @@ -37,6 +46,14 @@ def options
}
end

def to_json
decorator_class(:matrix_decorator).new(results).to_json(decorator_options)
end

def results
@results ||= matrix_service.can_i_deploy(selectors, options)
end

def version
@version ||= version_service.find_latest_by_pacticipant_name_and_branch_name(identifier_from_path[:pacticipant_name], identifier_from_path[:branch_name])
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment"

module PactBroker
module Api
module Resources
class CanIDeployPacticipantVersionByBranchToEnvironmentBadge < CanIDeployPacticipantVersionByBranchToEnvironment
include BadgeMethods

private

def badge_url
if pacticipant && version && environment
badge_service.can_i_deploy_badge_url(identifier_from_path[:branch_name], identifier_from_path[:environment_name], label, results.deployable?)
elsif pacticipant.nil?
badge_service.error_badge_url("pacticipant", "not found")
elsif version.nil?
if branch_service.find_branch(identifier_from_path.slice(:pacticipant_name, :branch_name)).nil?
badge_service.error_badge_url("branch", "not found")
else
badge_service.error_badge_url("version", "not found")
end
else
badge_service.error_badge_url("environment", "not found")
end
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def resource_exists?
end

def policy_name
:'matrix::can_i_deploy'
:'versions::version'
end

def malformed_request?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,8 @@
module PactBroker
module Api
module Resources
class CanIDeployPacticipantVersionByTagToTagBadge < BaseResource
class CanIDeployPacticipantVersionByTagToTagBadge < CanIDeployPacticipantVersionByTagToTag
include BadgeMethods
def initialize
super
selector = PactBroker::Matrix::UnresolvedSelector.new(pacticipant_name: pacticipant_name, latest: true, tag: identifier_from_path[:tag])
@options = {
latestby: "cvp",
latest: true,
tag: identifier_from_path[:to]
}
@selectors = [selector]
end

def badge_url
if pacticipant
Expand All @@ -26,26 +16,9 @@ def badge_url
badge_service.error_badge_url("version", "not found")
end
else
badge_service.error_badge_url(selectors.first.pacticipant_name, "not found")
badge_service.error_badge_url("pacticipant", "not found")
end
end

private

attr_reader :selectors, :options

def results
@results ||= matrix_service.can_i_deploy(selectors, options)
end

def version
@version ||= version_service.find_by_pacticipant_name_and_latest_tag(identifier_from_path[:pacticipant_name], identifier_from_path[:tag])
end

def label
lab = request.query["label"]
lab && !lab.empty? ? lab : nil
end
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions lib/pact_broker/versions/branch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ class Branch < Sequel::Model(:branches)
plugin :insert_ignore, identifying_columns: [:name, :pacticipant_id]

associate(:many_to_one, :pacticipant, :class => "PactBroker::Domain::Pacticipant", :key => :pacticipant_id, :primary_key => :id)

dataset_module do
include PactBroker::Repositories::Helpers
end
end
end
end
Expand Down
10 changes: 10 additions & 0 deletions lib/pact_broker/versions/branch_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ def self.find_or_create_branch_version(pacticipant_name:, branch_name:, version_
version = version_repository.find_by_pacticipant_id_and_number_or_create(pacticipant.id, version_number)
branch_version_repository.add_branch(version, branch_name)
end

def self.find_branch(pacticipant_name:, branch_name:)
Branch
.select_all_qualified
.join(:pacticipants, { Sequel[:branches][:pacticipant_id] => Sequel[:pacticipants][:id] }) do
PactBroker::Repositories::Helpers.name_like(Sequel[:pacticipants][:name], pacticipant_name)
end
.where(Sequel[:branches][:name] => branch_name)
.single_record
end
end
end
end
22 changes: 22 additions & 0 deletions spec/features/can_i_deploy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@
expect(subject).to be_a_hal_json_success_response
expect(response_body[:matrix]).to be_instance_of(Array)
end

context "the badge" do
subject { get("/pacticipants/Foo/latest-version/dev/can-i-deploy/to/prod/badge") }

it "returns a redirect URL" do
expect(subject.status).to eq 307
expect(subject.headers["Location"]).to start_with("https://img.shields.io/badge/")
expect(subject.headers["Location"]).to match(/dev/)
expect(subject.headers["Location"]).to match(/prod/)
end
end
end

context "using the URL format for branch/environment" do
Expand All @@ -37,6 +48,17 @@
expect(subject).to be_a_hal_json_success_response
expect(response_body[:matrix]).to be_instance_of(Array)
end

context "the badge" do
subject { get("/pacticipants/Foo/branches/main/latest-version/can-i-deploy/to-environment/prod/badge") }

it "returns a redirect URL" do
expect(subject.status).to eq 307
expect(subject.headers["Location"]).to start_with("https://img.shields.io/badge/")
expect(subject.headers["Location"]).to match(/main/)
expect(subject.headers["Location"]).to match(/prod/)
end
end
end

context "with a validation error" do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
require "pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment_badge"

module PactBroker
module Api
module Resources
describe CanIDeployPacticipantVersionByBranchToEnvironmentBadge do
before do
allow_any_instance_of(described_class).to receive(:branch_service).and_return(branch_service)
allow_any_instance_of(described_class).to receive(:badge_service).and_return(badge_service)

allow(branch_service).to receive(:find_branch).and_return(branch)
allow(badge_service). to receive(:can_i_deploy_badge_url).and_return("http://badge_url")
allow(badge_service). to receive(:error_badge_url).and_return("http://error_badge_url")

allow_any_instance_of(CanIDeployPacticipantVersionByBranchToEnvironmentBadge).to receive(:pacticipant).and_return(pacticipant)
allow_any_instance_of(CanIDeployPacticipantVersionByBranchToEnvironmentBadge).to receive(:version).and_return(version)
allow_any_instance_of(CanIDeployPacticipantVersionByBranchToEnvironmentBadge).to receive(:environment).and_return(environment)
allow_any_instance_of(CanIDeployPacticipantVersionByBranchToEnvironmentBadge).to receive(:results).and_return(results)
end

let(:branch_service) { class_double("PactBroker::Versions::BranchService").as_stubbed_const }
let(:badge_service) { class_double("PactBroker::Badges::Service").as_stubbed_const }

let(:pacticipant) { double("pacticipant") }
let(:version) { double("version") }
let(:environment) { double("environment") }
let(:branch) { double("branch") }
let(:results) { instance_double("PactBroker::Matrix::QueryResultsWithDeploymentStatusSummary", deployable?: true )}

let(:path) { "/pacticipants/Foo/branches/main/latest-version/can-i-deploy/to-environment/dev/badge" }

subject { get(path, { label: "custom-label" }) }

context "when everything is found" do
it "return the badge URL" do
expect(badge_service). to receive(:can_i_deploy_badge_url).with("main", "dev", "custom-label", true)
expect(subject.headers["Location"]).to eq "http://badge_url"
end
end

context "when the pacticipant is not found" do
let(:pacticipant) { nil }

it "returns an error badge URL" do
expect(badge_service).to receive(:error_badge_url).with("pacticipant", "not found")
expect(subject.headers["Location"]).to eq "http://error_badge_url"
end
end

context "when the version is not found and the branch is not found" do
let(:version) { nil }
let(:branch) { nil }

it "returns an error badge URL" do
expect(badge_service).to receive(:error_badge_url).with("branch", "not found")
expect(subject.headers["Location"]).to eq "http://error_badge_url"
end
end

context "when the version is not found and the branch is found" do
let(:version) { nil }

it "returns an error badge URL" do
expect(badge_service).to receive(:error_badge_url).with("version", "not found")
expect(subject.headers["Location"]).to eq "http://error_badge_url"
end
end

context "when the environment is not found" do
let(:environment) { nil }

it "returns an error badge URL" do
expect(badge_service).to receive(:error_badge_url).with("environment", "not found")
expect(subject.headers["Location"]).to eq "http://error_badge_url"
end
end
end
end
end
end
Loading

0 comments on commit 086b8c1

Please sign in to comment.