From 338b883ff6e60de551c61288ddd84c5f6352350e Mon Sep 17 00:00:00 2001 From: Beth Skurrie Date: Fri, 24 Nov 2023 20:38:22 +1100 Subject: [PATCH] feat: add latest version for branch endpoint --- lib/pact_broker/api.rb | 1 + .../api/decorators/branch_decorator.rb | 2 +- .../api/decorators/version_decorator.rb | 2 +- lib/pact_broker/api/pact_broker_urls.rb | 4 ++++ .../api/resources/latest_version.rb | 2 ++ .../get_latest_version_for_branch_spec.rb | 18 ++++++++++++++++++ ...acticipant_branches_decorator.approved.json | 2 +- .../api/decorators/version_decorator_spec.rb | 6 +++--- spec/support/all_routes_spec_support.yml | 1 + 9 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 spec/features/get_latest_version_for_branch_spec.rb diff --git a/lib/pact_broker/api.rb b/lib/pact_broker/api.rb index 3954a1ce4..4e7cefa00 100644 --- a/lib/pact_broker/api.rb +++ b/lib/pact_broker/api.rb @@ -97,6 +97,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"], Api::Resources::PacticipantBranches, {resource_name: "pacticipant_branches"} add ["pacticipants", :pacticipant_name, "branches", :branch_name], Api::Resources::Branch, { resource_name: "branch" } + add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version"], Api::Resources::LatestVersion, { resource_name: "latest_pacticipant_version_for_branch" } 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::CanIDeployPacticipantVersionByBranchToEnvironmentBadge, { resource_name: "can_i_deploy_latest_branch_version_to_environment_badge" } diff --git a/lib/pact_broker/api/decorators/branch_decorator.rb b/lib/pact_broker/api/decorators/branch_decorator.rb index a53f4d2db..9f7fee210 100644 --- a/lib/pact_broker/api/decorators/branch_decorator.rb +++ b/lib/pact_broker/api/decorators/branch_decorator.rb @@ -18,7 +18,7 @@ class BranchDecorator < BaseDecorator link "pb:latest-version" do | user_options | { title: "Latest version for branch", - href: branch_versions_url(represented, user_options.fetch(:base_url)) + "?size=1" + href: latest_version_for_branch_url(represented, user_options.fetch(:base_url)) } end diff --git a/lib/pact_broker/api/decorators/version_decorator.rb b/lib/pact_broker/api/decorators/version_decorator.rb index 2c7585739..7026fad7b 100644 --- a/lib/pact_broker/api/decorators/version_decorator.rb +++ b/lib/pact_broker/api/decorators/version_decorator.rb @@ -21,7 +21,7 @@ class VersionDecorator < BaseDecorator { title: "Version", name: represented.number, - href: version_url(options.fetch(:base_url), represented) + href: options.fetch(:resource_url) } end diff --git a/lib/pact_broker/api/pact_broker_urls.rb b/lib/pact_broker/api/pact_broker_urls.rb index 3ce937d9d..81aa06755 100644 --- a/lib/pact_broker/api/pact_broker_urls.rb +++ b/lib/pact_broker/api/pact_broker_urls.rb @@ -243,6 +243,10 @@ def branch_version_url(branch_version, base_url = "") "#{branch_versions_url(branch_version.branch, base_url)}/#{url_encode(branch_version.version_number)}" end + def latest_version_for_branch_url(branch, base_url = "") + "#{branch_url(branch, base_url)}/latest-version" + end + def templated_tag_url_for_pacticipant pacticipant_name, base_url = "" pacticipant_url_from_params({ pacticipant_name: pacticipant_name }, base_url) + "/versions/{version}/tags/{tag}" end diff --git a/lib/pact_broker/api/resources/latest_version.rb b/lib/pact_broker/api/resources/latest_version.rb index bac4ab7a2..430410fd8 100644 --- a/lib/pact_broker/api/resources/latest_version.rb +++ b/lib/pact_broker/api/resources/latest_version.rb @@ -17,6 +17,8 @@ def allowed_methods def version if identifier_from_path[:tag] @version ||= version_service.find_by_pacticipant_name_and_latest_tag(identifier_from_path[:pacticipant_name], identifier_from_path[:tag]) + elsif identifier_from_path[:branch_name] + @version ||= version_service.find_latest_by_pacticipant_name_and_branch_name(identifier_from_path[:pacticipant_name], identifier_from_path[:branch_name]) else @version ||= version_service.find_latest_by_pacticpant_name(identifier_from_path) end diff --git a/spec/features/get_latest_version_for_branch_spec.rb b/spec/features/get_latest_version_for_branch_spec.rb new file mode 100644 index 000000000..64bdefd52 --- /dev/null +++ b/spec/features/get_latest_version_for_branch_spec.rb @@ -0,0 +1,18 @@ +describe "Get latest version for branch" do + before do + td.create_consumer("Foo") + .create_consumer_version("1", branch: "main") + .create_consumer_version("2", branch: "main") + .create_consumer_version("3", branch: "not-main") + end + let(:path) { PactBroker::Api::PactBrokerUrls.latest_version_for_branch_url(PactBroker::Versions::Branch.order(:id).first) } + let(:rack_env) { { "CONTENT_TYPE" => "application/json" } } + + subject { get(path, {}, rack_env) } + + it { is_expected.to be_a_hal_json_success_response } + + it "returns the latest version for the branch" do + expect(JSON.parse(subject.body)["number"]).to eq "2" + end +end diff --git a/spec/fixtures/approvals/pacticipant_branches_decorator.approved.json b/spec/fixtures/approvals/pacticipant_branches_decorator.approved.json index 6f719defe..4a3204790 100644 --- a/spec/fixtures/approvals/pacticipant_branches_decorator.approved.json +++ b/spec/fixtures/approvals/pacticipant_branches_decorator.approved.json @@ -11,7 +11,7 @@ }, "pb:latest-version": { "title": "Latest version for branch", - "href": "http://example.org/pacticipants/Foo/branches/main/versions?size=1" + "href": "http://example.org/pacticipants/Foo/branches/main/latest-version" } } } diff --git a/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb b/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb index 22c00e4d3..98b5297a9 100644 --- a/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb +++ b/spec/lib/pact_broker/api/decorators/version_decorator_spec.rb @@ -48,13 +48,13 @@ module Decorators end let(:base_url) { "http://example.org" } - let(:options) { { user_options: { base_url: base_url, environments: environments } } } + let(:options) { { user_options: { base_url: base_url, resource_url: "resource_url", environments: environments } } } let(:decorator) { VersionDecorator.new(version) } subject { JSON.parse(decorator.to_json(options), symbolize_names: true) } it "includes a link to itself" do - expect(subject[:_links][:self][:href]).to eq "http://example.org/pacticipants/Consumer/versions/1.2.3" + expect(subject[:_links][:self][:href]).to eq "resource_url" end it "includes the version number in the link" do @@ -125,7 +125,7 @@ module Decorators end context "when the environments option is not present" do - let(:options) { { user_options: { base_url: base_url } } } + let(:options) { { user_options: { base_url: base_url, resource_url: "resource_url" } } } it "does not include the pb:record-deployment or pb:record-release" do expect(subject[:_links]).to_not have_key(:'pb:record-deployment') diff --git a/spec/support/all_routes_spec_support.yml b/spec/support/all_routes_spec_support.yml index f99f47597..7dff8b0a2 100644 --- a/spec/support/all_routes_spec_support.yml +++ b/spec/support/all_routes_spec_support.yml @@ -40,6 +40,7 @@ requests_which_are_exected_to_have_no_policy_record: - pacticipant_label PUT - pacticipant_label DELETE - latest_pacticipant_version GET + - latest_pacticipant_version_for_branch GET - latest_tagged_pacticipant_version GET - can_i_deploy_latest_tagged_version_to_tag GET - can_i_deploy_latest_tagged_version_to_tag_badge GET