Skip to content

Commit 5eda9c6

Browse files
author
Sebastian Wilgosz
committed
Fix bug with generating links for urls with query parameters included
1 parent e539967 commit 5eda9c6

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

Gemfile.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ PATH
44
jsom-pagination (0.1.1)
55
dry-struct (~> 1.3.0)
66
pagy (~> 3.8.3)
7+
rack
78

89
GEM
910
remote: https://rubygems.org/
@@ -40,6 +41,7 @@ GEM
4041
dry-logic (~> 1.0, >= 1.0.2)
4142
ice_nine (0.11.2)
4243
pagy (3.8.3)
44+
rack (2.2.3)
4345
rake (12.3.3)
4446
rspec (3.9.0)
4547
rspec-core (~> 3.9.0)

jsom-pagination.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Gem::Specification.new do |spec|
3939

4040
spec.add_dependency 'dry-struct', '~>1.3.0'
4141
spec.add_dependency 'pagy', '~>3.8.3'
42+
spec.add_dependency 'rack'
4243

4344
spec.add_development_dependency 'simplecov'
4445
spec.add_development_dependency 'simplecov-cobertura'

lib/jsom/pagination/links.rb

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require 'rack'
4+
35
module JSOM
46
module Pagination
57
class Links
@@ -30,12 +32,22 @@ def last
3032
attr_reader :page, :total_pages, :url
3133

3234
def initialize(page:, url:, total_pages:)
33-
@url = url
35+
@url = parse_url(url)
3436
@page = page
3537
@total_pages = total_pages
3638
generate_links
3739
end
3840

41+
def parse_url(url)
42+
uri = URI.parse(URI.unescape(url))
43+
url_params = Rack::Utils.parse_nested_query(
44+
uri.query
45+
).delete_if { |key, _value| key == 'page' }
46+
uri.query = to_query(url_params)
47+
uri.query = nil if uri.query.empty?
48+
uri
49+
end
50+
3951
def generate_links
4052
if page.number > 1
4153
@first = generate_url(1)
@@ -50,7 +62,8 @@ def generate_links
5062
end
5163

5264
def generate_url(page_number)
53-
[url, url_params(page_number)].reject(&:empty?).join('?')
65+
separator = url.to_s.include?('?') ? '&' : '?'
66+
[url.to_s, url_params(page_number)].reject(&:empty?).join(separator)
5467
end
5568

5669
def url_params(page_number)
@@ -61,12 +74,16 @@ def url_params(page_number)
6174
to_query(url_params)
6275
end
6376

64-
def to_query(obj, namespace = nil)
77+
def to_query(obj, namespace = '')
6578
query = obj.collect do |key, value|
6679
if value.is_a?(Hash)
67-
to_query(value, namespace ? "#{namespace}[#{key}]" : key)
80+
to_query(value, namespace.empty? ? key : "#{namespace}[#{key}]")
6881
else
69-
["#{namespace}[#{key}]", value].join('=')
82+
if namespace.empty?
83+
[key, value].join('=')
84+
else
85+
["#{namespace}[#{key}]", value].join('=')
86+
end
7087
end
7188
end.compact
7289

spec/jsom/pagination/links_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,25 @@ module Pagination
136136
last: 'https://example.com/articles?page[number]=3&page[size]=2'
137137
)
138138
end
139+
140+
it 'works when custom query parameters are passed in the URL' do
141+
url = 'https://example.com/articles?type=published&page[number]=2&page[size]=2'
142+
links = described_class.new(url: url, page: page, total_pages: 3)
143+
144+
expect(links.self).to eq('https://example.com/articles?type=published&page[number]=2&page[size]=2')
145+
expect(links.prev).to eq('https://example.com/articles?type=published&page[size]=2')
146+
expect(links.first).to eq('https://example.com/articles?type=published&page[size]=2')
147+
expect(links.next).to eq('https://example.com/articles?type=published&page[number]=3&page[size]=2')
148+
expect(links.last).to eq('https://example.com/articles?type=published&page[number]=3&page[size]=2')
149+
150+
expect(links.to_h).to eq(
151+
self: 'https://example.com/articles?type=published&page[number]=2&page[size]=2',
152+
prev: 'https://example.com/articles?type=published&page[size]=2',
153+
first: 'https://example.com/articles?type=published&page[size]=2',
154+
next: 'https://example.com/articles?type=published&page[number]=3&page[size]=2',
155+
last: 'https://example.com/articles?type=published&page[number]=3&page[size]=2'
156+
)
157+
end
139158
end
140159
end
141160
end

0 commit comments

Comments
 (0)