From 5b2aca25f0919feb0e9b0512414987fa304ea182 Mon Sep 17 00:00:00 2001 From: Ryan Murphy Date: Sun, 17 Sep 2023 13:13:29 -0400 Subject: [PATCH] 27: Add pagination support (Ruby) --- ruby/bin/github_repo_cloner | 4 ++-- ruby/lib/clone_all_handler.rb | 21 +++++++++++++++++++ ...clone_handler.rb => clone_page_handler.rb} | 11 +++++----- ruby/spec/clone_all_handler_spec.rb | 18 ++++++++++++++++ ...ler_spec.rb => clone_page_handler_spec.rb} | 21 ++++++++++--------- 5 files changed, 58 insertions(+), 17 deletions(-) create mode 100644 ruby/lib/clone_all_handler.rb rename ruby/lib/{clone_handler.rb => clone_page_handler.rb} (76%) create mode 100644 ruby/spec/clone_all_handler_spec.rb rename ruby/spec/{clone_handler_spec.rb => clone_page_handler_spec.rb} (84%) diff --git a/ruby/bin/github_repo_cloner b/ruby/bin/github_repo_cloner index a68df1f..69653a0 100755 --- a/ruby/bin/github_repo_cloner +++ b/ruby/bin/github_repo_cloner @@ -1,5 +1,5 @@ #!/usr/bin/env ruby -require_relative '../lib/clone_handler' +require_relative '../lib/clone_all_handler' -CloneHandler.new(ARGV.first).call +CloneAllHandler.new(ARGV.first).call diff --git a/ruby/lib/clone_all_handler.rb b/ruby/lib/clone_all_handler.rb new file mode 100644 index 0000000..d8094de --- /dev/null +++ b/ruby/lib/clone_all_handler.rb @@ -0,0 +1,21 @@ +require_relative 'clone_page_handler' + +class CloneAllHandler + def initialize(username) + @username = username + @page = 1 + @has_next_page = true + end + + def call + while has_next_page + self.has_next_page = ClonePageHandler.new(username, page).call + self.page += 1 + end + end + + private + + attr_reader :username + attr_accessor :page, :has_next_page +end diff --git a/ruby/lib/clone_handler.rb b/ruby/lib/clone_page_handler.rb similarity index 76% rename from ruby/lib/clone_handler.rb rename to ruby/lib/clone_page_handler.rb index b7f6e4a..2acf302 100644 --- a/ruby/lib/clone_handler.rb +++ b/ruby/lib/clone_page_handler.rb @@ -1,23 +1,24 @@ require 'json' require 'net/http' -class CloneHandler - def initialize(username) +class ClonePageHandler + def initialize(username, page) @username = username + @page = page end def call - return unless clonable? + return false unless clonable? Kernel.system(clone_command) end private - attr_reader :username + attr_reader :username, :page def info_uri - URI("https://api.github.com/users/#{username}/repos") + URI("https://api.github.com/users/#{username}/repos?page=#{page}") end def response diff --git a/ruby/spec/clone_all_handler_spec.rb b/ruby/spec/clone_all_handler_spec.rb new file mode 100644 index 0000000..8cd5ace --- /dev/null +++ b/ruby/spec/clone_all_handler_spec.rb @@ -0,0 +1,18 @@ +require 'clone_all_handler' +require 'clone_page_handler' + +RSpec.describe CloneAllHandler do + describe '#call' do + let(:username) { 'murjax' } + + subject(:call) { described_class.new(username).call } + + it 'calls ClonePageHandler with each page until blank page reached' do + expect(ClonePageHandler).to receive(:new).with(username, 1).and_return(OpenStruct.new(call: true)) + expect(ClonePageHandler).to receive(:new).with(username, 2).and_return(OpenStruct.new(call: true)) + expect(ClonePageHandler).to receive(:new).with(username, 3).and_return(OpenStruct.new(call: false)) + + call + end + end +end diff --git a/ruby/spec/clone_handler_spec.rb b/ruby/spec/clone_page_handler_spec.rb similarity index 84% rename from ruby/spec/clone_handler_spec.rb rename to ruby/spec/clone_page_handler_spec.rb index b47e43f..a19607a 100644 --- a/ruby/spec/clone_handler_spec.rb +++ b/ruby/spec/clone_page_handler_spec.rb @@ -1,20 +1,21 @@ -require 'clone_handler' +require 'clone_page_handler' require 'json' require 'net/http' -RSpec.describe CloneHandler do +RSpec.describe ClonePageHandler do describe '#call' do let(:username) { 'murjax' } + let(:page) { 2 } let(:clone_url1) { 'https://github.com/murjax/spring_engine.git' } let(:clone_url2) { 'https://github.com/murjax/burger_bot.git' } let(:name1) { 'spring_engine' } let(:name2) { 'burger_bot' } - let(:repo_info_url) { "https://api.github.com/users/#{username}/repos" } + let(:repo_info_url) { "https://api.github.com/users/#{username}/repos?page=#{page}" } let(:repo_info_uri) { URI(repo_info_url) } let(:serialized_response_body) { JSON.generate(response_body) } let(:response) { OpenStruct.new(code: code, body: serialized_response_body) } - subject(:call) { described_class.new(username).call } + subject(:call) { described_class.new(username, page).call } context 'valid username with repos' do let(:response_body) do @@ -30,9 +31,9 @@ it 'runs clone commands' do expect(Net::HTTP).to receive(:get_response).with(repo_info_uri).and_return(response) - expect(Kernel).to receive(:system).with(final_command) + expect(Kernel).to receive(:system).with(final_command).and_return(true) - call + expect(call).to eq(true) end end @@ -44,7 +45,7 @@ expect(Net::HTTP).to receive(:get_response).with(repo_info_uri).and_return(response) expect(Kernel).not_to receive(:system) - call + expect(call).to eq(false) end end @@ -56,7 +57,7 @@ expect(Net::HTTP).to receive(:get_response).with(repo_info_uri).and_return(response) expect(Kernel).not_to receive(:system) - call + expect(call).to eq(false) end end @@ -67,7 +68,7 @@ expect(Net::HTTP).not_to receive(:get_response) expect(Kernel).not_to receive(:system) - call + expect(call).to eq(false) end end @@ -78,7 +79,7 @@ expect(Net::HTTP).not_to receive(:get_response) expect(Kernel).not_to receive(:system) - call + expect(call).to eq(false) end end end