Skip to content

Commit

Permalink
feat: paginate pacticipant versions
Browse files Browse the repository at this point in the history
Closes: #355
  • Loading branch information
bethesque committed Oct 1, 2020
1 parent 6e2f1a8 commit f489ba7
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 21 deletions.
4 changes: 2 additions & 2 deletions lib/pact_broker/api/decorators/decorator_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ module PactBroker
module Api
module Decorators
class DecoratorContext < Hash

attr_reader :base_url, :resource_url, :resource_title, :env
attr_reader :base_url, :resource_url, :resource_title, :env, :query_string

def initialize base_url, resource_url, env, options = {}
@base_url = self[:base_url] = base_url
@resource_url = self[:resource_url] = resource_url
@resource_title = self[:resource_title] = options[:resource_title]
@env = self[:env] = env
@query_string = self[:query_string] = (env['QUERY_STRING'] && !env['QUERY_STRING'].empty? ? env['QUERY_STRING'] : nil)
merge!(options)
end

Expand Down
34 changes: 34 additions & 0 deletions lib/pact_broker/api/decorators/pagination_links.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'roar/decorator'
require 'roar/json/hal'

module PactBroker
module Api
module Decorators
module PaginationLinks
include Roar::JSON::HAL
include Roar::JSON::HAL::Links

link :next do | context |
if represented.respond_to?(:current_page) &&
represented.respond_to?(:page_count) &&
represented.current_page < represented.page_count
{
href: context[:resource_url] + "?pageSize=#{represented.page_size}&pageNumber=#{represented.current_page + 1}",
title: "Next page"
}

end
end

link :previous do | context |
if represented.respond_to?(:first_page?) && !represented.first_page?
{
href: context[:resource_url] + "?pageSize=#{represented.page_size}&pageNumber=#{represented.current_page - 1}",
title: "Previous page"
}
end
end
end
end
end
end
6 changes: 5 additions & 1 deletion lib/pact_broker/api/decorators/versions_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require_relative 'base_decorator'
require_relative 'version_decorator'
require_relative 'pagination_links'

module PactBroker
module Api
Expand All @@ -9,12 +10,15 @@ class VersionsDecorator < BaseDecorator
collection :entries, as: :versions, embedded: true, :extend => PactBroker::Api::Decorators::VersionDecorator

link :self do | context |
href = append_query_if_present(context[:resource_url], context[:query_string])
{
href: context[:resource_url],
href: href,
title: "All application versions of #{context[:pacticipant_name]}"
}
end

include PaginationLinks

link :'pb:pacticipant' do | context |
{
href: pacticipant_url(context[:base_url], OpenStruct.new(name: context[:pacticipant_name])),
Expand Down
8 changes: 8 additions & 0 deletions lib/pact_broker/api/pact_broker_urls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ def url_encode param
ERB::Util.url_encode param
end

def append_query_if_present(url, query)
if query && query.size > 0
url + "?#{query}"
else
url
end
end

private

def representable_pact pact
Expand Down
13 changes: 12 additions & 1 deletion lib/pact_broker/api/resources/versions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,23 @@ def to_json
end

def versions
@versions ||= pacticipant_service.find_all_pacticipant_versions_in_reverse_order pacticipant_name
@versions ||= pacticipant_service.find_all_pacticipant_versions_in_reverse_order(pacticipant_name, pagination_options)
end

def policy_name
:'versions::versions'
end

def pagination_options
if request.query['pageNumber'] || request.query['pageSize']
{
page_number: request.query['pageNumber']&.to_i || 1,
page_size: request.query['pageSize']&.to_i || 100
}
else
nil
end
end
end
end
end
Expand Down
9 changes: 9 additions & 0 deletions lib/pact_broker/doc/views/pacticipant/versions.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Pacticipant versions

Allowed methods: `GET`

Path: `/pacticipants/{pacticipant}/versions`

A list of pacticipant versions in order from newest to oldest.

To paginate, append `?pageNumber=x&pageSize=x` and follow the `next` relation until it is no longer present.
11 changes: 6 additions & 5 deletions lib/pact_broker/pacticipants/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Pacticipants
class Repository

include PactBroker::Repositories::Helpers
include PactBroker::Repositories

def find_by_name name
pacticipants = PactBroker::Domain::Pacticipant.where(name_like(:name, name)).all
Expand Down Expand Up @@ -35,11 +36,11 @@ def find options = {}
query.order_ignore_case(Sequel[:pacticipants][:name]).eager(:labels).eager(:latest_version).all
end

def find_all_pacticipant_versions_in_reverse_order name
PactBroker::Domain::Version.select_all_qualified
.join(:pacticipants, {id: :pacticipant_id})
.where(name_like(:name, name))
.reverse_order(:order)
def find_all_pacticipant_versions_in_reverse_order name, pagination_options = nil
pacticipant = pacticipant_repository.find_by_name!(name)
query = PactBroker::Domain::Version.where(pacticipant: pacticipant).reverse_order(:order)
query = query.paginate(pagination_options[:page_number], pagination_options[:page_size]) if pagination_options
query
end

def find_by_name_or_create name
Expand Down
4 changes: 2 additions & 2 deletions lib/pact_broker/pacticipants/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def self.find options
pacticipant_repository.find options
end

def self.find_all_pacticipant_versions_in_reverse_order name
pacticipant_repository.find_all_pacticipant_versions_in_reverse_order(name)
def self.find_all_pacticipant_versions_in_reverse_order name, pagination_options = nil
pacticipant_repository.find_all_pacticipant_versions_in_reverse_order(name, pagination_options)
end

def self.find_pacticipant_repository_url_by_pacticipant_name name
Expand Down
8 changes: 8 additions & 0 deletions spec/features/get_versions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
it "returns a list of links to the versions" do
expect(last_response_body[:_links][:"versions"].size).to eq 2
end

context "with pagination options" do
subject { get(path, { 'pageSize' => '1', 'pageNumber' => '1' }) }

it "paginates the response" do
expect(last_response_body[:_links][:"versions"].size).to eq 1
end
end
end

context "when the pacticipant does not exist" do
Expand Down
23 changes: 14 additions & 9 deletions spec/lib/pact_broker/api/decorators/versions_decorator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,38 @@
require 'pact_broker/domain/version'

module PactBroker

module Api

module Decorators

describe VersionsDecorator do

let(:options) { {base_url: 'http://example.org', pacticipant_name: "Consumer" }}
let(:options) { { resource_url: 'http://versions', base_url: 'http://example.org', pacticipant_name: "Consumer", query_string: query_string}}
let(:query_string) { nil }
let(:versions) { [] }

subject { JSON.parse VersionsDecorator.new(versions).to_json(user_options: options), symbolize_names: true }

context "with no versions" do
let(:versions) { [] }
context "with no query string" do
its([:_links, :self, :href]) { is_expected.to eq 'http://versions' }
end

context "with a query string" do
let(:query_string) { 'foo=bar' }
its([:_links, :self, :href]) { is_expected.to eq 'http://versions?foo=bar' }
end

context "with no versions" do
it "doesn't blow up" do
subject
end
end

context "with versions" do
let(:version) do
let!(:version) do
TestDataBuilder.new
.create_consumer("Consumer")
.create_consumer_version("1.2.3")
.create_consumer_version_tag("prod")
PactBroker::Versions::Repository.new.find_by_pacticipant_name_and_number "Consumer", "1.2.3"
.and_return(:consumer_version)
end
let(:versions) { [version] }

Expand All @@ -37,7 +43,6 @@ module Decorators
expect(subject[:_embedded][:versions].size).to eq 1
end
end

end
end
end
Expand Down
9 changes: 8 additions & 1 deletion spec/lib/pact_broker/pacticipants/repository_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,15 @@ module Pacticipants
it "returns all the application versions for the given consumer" do
expect(subject.collect(&:number)).to eq ["4.5.6", "1.2.3"]
end
end

context "with pagination options" do
subject { Repository.new.find_all_pacticipant_versions_in_reverse_order "Foo", page_number: 1, page_size: 1 }

it "paginates the query" do
expect(subject.collect(&:number)).to eq ["4.5.6"]
end
end
end
end
end
end

0 comments on commit f489ba7

Please sign in to comment.