diff --git a/app/graphql/connections/cursor_connection.rb b/app/graphql/connections/cursor_connection.rb index 6177bff2e..34db4fb56 100644 --- a/app/graphql/connections/cursor_connection.rb +++ b/app/graphql/connections/cursor_connection.rb @@ -51,6 +51,17 @@ module Connections # # last: 2, order: desc => first 2 # -> d1, d2 + def limit_and_inverted(first: nil, last: nil, after: nil, before: nil, order: nil) + limit = [first, last, max_page_size].compact.min + 1 + inverted = last.present? || before.present? + + if order == :desc && after.nil? && before.nil? + inverted = !inverted + end + + [limit, inverted] + end + def load_nodes @nodes ||= begin ensure_valid_params diff --git a/spec/graphql/connections/cursor_connection_spec.rb b/spec/graphql/connections/cursor_connection_spec.rb new file mode 100644 index 000000000..57ef64b89 --- /dev/null +++ b/spec/graphql/connections/cursor_connection_spec.rb @@ -0,0 +1,60 @@ +RSpec.describe Connections::CursorConnection do + describe '.limit_and_inverted' do + let(:max_page_size) { 100 } + + subject do + cursor = Connections::CursorConnection.new(Dossier) + allow(cursor).to receive(:max_page_size).and_return(max_page_size) + limit, inverted = cursor.send(:limit_and_inverted, **args) + { limit:, inverted: } + end + + context 'without explicit args' do + let(:args) { { } } + + it { is_expected.to eq(limit: max_page_size + 1, inverted: false) } + end + + context 'when asked for 2 first elements' do + let(:args) { { first: 2 } } + + it { is_expected.to eq(limit: 3, inverted: false) } + end + + context 'when asked for 2 first elements, in order desc' do + let(:args) { { first: 2, order: :desc} } + + it { is_expected.to eq(limit: 3, inverted: true) } + end + + context 'when exceeding the max_page_size' do + let(:args) { { first: max_page_size + 1 } } + + it { is_expected.to eq(limit: max_page_size + 1, inverted: false) } + end + + context 'when asked for 2 last elements' do + let(:args) { { last: 2 } } + + it { is_expected.to eq(limit: 3, inverted: true) } + end + + context 'when asked for 2 last elements, in order desc' do + let(:args) { { last: 2, order: :desc} } + + it { is_expected.to eq(limit: 3, inverted: false) } + end + + context '' do + let(:args) { { after: :after, first: 2 } } + + it { is_expected.to eq(limit: 3, inverted: false) } + end + + context '' do + let(:args) { { before: :before, first: 2 } } + + it { is_expected.to eq(limit: 3, inverted: true) } + end + end +end