Skip to content

Commit 63ad373

Browse files
authored
Merge pull request rmosolgo#4780 from rmosolgo/fix-has-next-page-with-max-page-size
Fix hasNextPage when max_page_size is set
2 parents 1479664 + 5ac2281 commit 63ad373

File tree

6 files changed

+34
-18
lines changed

6 files changed

+34
-18
lines changed

lib/graphql/pagination/array_connection.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ def index_from_cursor(cursor)
3535
def load_nodes
3636
@nodes ||= begin
3737
sliced_nodes = if before && after
38-
end_idx = index_from_cursor(before)-1
38+
end_idx = index_from_cursor(before) - 2
3939
end_idx < 0 ? [] : items[index_from_cursor(after)..end_idx] || []
4040
elsif before
41-
end_idx = index_from_cursor(before)-2
41+
end_idx = index_from_cursor(before) - 2
4242
end_idx < 0 ? [] : items[0..end_idx] || []
4343
elsif after
4444
items[index_from_cursor(after)..-1] || []
@@ -56,7 +56,7 @@ def load_nodes
5656
false
5757
end
5858

59-
@has_next_page = if first
59+
@has_next_page = if first_value && first
6060
# There are more items after these items
6161
sliced_nodes.count > first
6262
elsif before

lib/graphql/pagination/relation_connection.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ def has_previous_page
2929

3030
def has_next_page
3131
if @has_next_page.nil?
32-
@has_next_page = if before_offset && before_offset > 0
33-
true
34-
elsif first
32+
@has_next_page = if first && first_value
3533
if @nodes && @nodes.count < first
3634
false
3735
else
3836
relation_larger_than(sliced_nodes, @sliced_nodes_offset, first)
3937
end
38+
elsif before_offset && before_offset > 0
39+
true
4040
else
4141
false
4242
end

spec/integration/mongoid/graphql/relay/mongo_relation_connection_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def get_last_cursor(result)
238238
# Max page size is applied _without_ `first`, also
239239
result = star_trek_query(query_string)
240240
assert_equal(2, result["data"]["federation"]["bases"]["edges"].size)
241-
assert_equal(true, result["data"]["federation"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is true when first is not specified")
241+
assert_equal(false, result["data"]["federation"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is false when first is not specified")
242242
end
243243

244244
it "applies to queries by `last`" do
@@ -297,7 +297,7 @@ def get_last_cursor(result)
297297
# Max page size is applied _without_ `first`, also
298298
result = star_trek_query(query_string)
299299
assert_equal(3, result["data"]["federation"]["bases"]["edges"].size)
300-
assert_equal(true, result["data"]["federation"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is true when first is not specified")
300+
assert_equal(false, result["data"]["federation"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is false when first is not specified")
301301
end
302302

303303
it "applies to queries by `last`" do

spec/integration/rails/graphql/relay/array_connection_spec.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,11 @@ def get_page_info(result, key = "bases")
108108
result = star_wars_query(query_string, { "after" => first_cursor, "first" => 2 })
109109
assert_equal(["Y-Wing", "A-Wing"], get_names(result))
110110

111-
# After the last result, find the next 2:
112-
second_cursor = get_last_cursor(result)
111+
third_cursor = get_last_cursor(result)
113112

114-
# There is only 2 results between the cursors
115-
result = star_wars_query(query_string, { "after" => first_cursor, "before" => second_cursor, "first" => 5 })
116-
assert_equal(["Y-Wing", "A-Wing"], get_names(result))
113+
# There is only 1 result between the cursors
114+
result = star_wars_query(query_string, { "after" => first_cursor, "before" => third_cursor, "first" => 5 })
115+
assert_equal(["Y-Wing"], get_names(result))
117116
end
118117

119118
it 'handles cursors beyond the bounds of the array' do
@@ -175,7 +174,7 @@ def get_names(result)
175174
# Max page size is applied _without_ `first`, also
176175
result = star_wars_query(query_string)
177176
assert_equal(["Yavin", "Echo Base"], get_names(result))
178-
assert_equal(true, get_page_info(result)["hasNextPage"], "hasNextPage is true when first is not specified")
177+
assert_equal(false, get_page_info(result)["hasNextPage"], "hasNextPage is false when first is not specified")
179178
end
180179

181180
it "applies to queries by `last`" do
@@ -235,7 +234,7 @@ def get_page_info(result)
235234
# Max page size is applied _without_ `first`, also
236235
result = star_wars_query(query_string)
237236
assert_equal(["Yavin", "Echo Base", "Secret Hideout"], get_names(result))
238-
assert_equal(true, get_page_info(result)["hasNextPage"], "hasNextPage is true when first is not specified")
237+
assert_equal(false, get_page_info(result)["hasNextPage"], "hasNextPage is false when first is not specified")
239238
end
240239

241240
it "applies to queries by `last`" do

spec/integration/rails/graphql/relay/relation_connection_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ def get_last_cursor(result)
287287
# Max page size is applied _without_ `first`, also
288288
result = star_wars_query(query_string)
289289
assert_equal(2, result["data"]["empire"]["bases"]["edges"].size)
290-
assert_equal(true, result["data"]["empire"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is true when first is not specified")
290+
assert_equal(false, result["data"]["empire"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is false when first is not specified")
291291
end
292292

293293
it "applies to queries by `last`" do
@@ -346,7 +346,7 @@ def get_last_cursor(result)
346346
# Max page size is applied _without_ `first`, also
347347
result = star_wars_query(query_string)
348348
assert_equal(3, result["data"]["empire"]["bases"]["edges"].size)
349-
assert_equal(true, result["data"]["empire"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is true when first is not specified")
349+
assert_equal(false, result["data"]["empire"]["bases"]["pageInfo"]["hasNextPage"], "hasNextPage is false when first is not specified")
350350
end
351351

352352
it "applies to queries by `last`" do

spec/support/connection_assertions.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,23 @@ def assert_names(expected_names, result)
243243
refute get_page_info(res3, "hasPreviousPage")
244244
end
245245

246+
it "returns empty lists for `after: 1` and `before: 2`" do
247+
res = exec_query(query_str, first: 2)
248+
assert_names(["Avocado", "Beet"], res)
249+
after_cursor = get_page_info(res, "startCursor")
250+
before_cursor = get_page_info(res, "endCursor")
251+
252+
res = exec_query(query_str, after: after_cursor, before: before_cursor)
253+
assert_equal true, get_page_info(res, "hasNextPage")
254+
assert_equal true, get_page_info(res, "hasPreviousPage")
255+
assert_names [], res
256+
257+
res = exec_query(query_str, after: after_cursor, before: before_cursor, first: 3)
258+
assert_equal false, get_page_info(res, "hasNextPage")
259+
assert_equal true, get_page_info(res, "hasPreviousPage")
260+
assert_names [], res
261+
end
262+
246263
it "handles out-of-bounds cursors" do
247264
# It treats negative cursors like zero
248265
bogus_negative_cursor = NonceEnabledEncoder.encode("-10")
@@ -300,7 +317,7 @@ def assert_names(expected_names, result)
300317
res = exec_query(query_str, {})
301318
# Neither first nor last was provided, so default_page_size was applied.
302319
assert_names(["Avocado", "Beet", "Cucumber", "Dill"], res)
303-
assert_equal true, get_page_info(res, "hasNextPage")
320+
assert_equal false, get_page_info(res, "hasNextPage")
304321
assert_equal false, get_page_info(res, "hasPreviousPage")
305322
end
306323

0 commit comments

Comments
 (0)