Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adds 'all pages' support for entries api #4

Merged
merged 2 commits into from

2 participants

@ckdake

I needed to be able to grab all pages of entries from the API and it didn't look like this gem did it already. The code is a little hacky but it does work and there is a test that passes.

@ryanlecompte
Owner

Great work. Thanks!

@ryanlecompte ryanlecompte merged commit 19b46c0 into ryanlecompte:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
10 README.rdoc
@@ -36,6 +36,11 @@ a sample API test account, which the following examples utilize.
puts "Entry #{entry.description} - #{entry.minutes} minutes"
end
+ # Fetch all entries on all pages
+ LetsFreckle::Entry.all(:all_pages => true).each do |entry|
+ puts "Entry #{entry.description} - #{entry.minutes} minutes"
+ end
+
# Search for entries from a specific start date and tags
LetsFreckle::Entry.find(:from => '2010-07-10', :tags => ['development', 'design']).each do |entry|
puts entry.description
@@ -56,6 +61,11 @@ a sample API test account, which the following examples utilize.
puts "User #{user.email} has following permissions: #{user.permissions}"
end
+== Development
+
+Bundler is used to manage dependencies. Use `bundle install` to get set up.
+Tests are written in rspec, use `bundle exec rspec spec/*` to run the tests.
+
== Note on Patches/Pull Requests
* Fork the project.
View
4 lib/letsfreckle/client_resource.rb
@@ -22,8 +22,8 @@ def base_api_url
"https://#{LetsFreckle.config.account_host}.letsfreckle.com"
end
- def relative_path_for(resource)
- "/api/#{resource}.xml?token=#{LetsFreckle.config.token}"
+ def relative_path_for(resource, page = nil)
+ "/api/#{resource}.xml?page=#{page.nil? ? 1 : page}&token=#{LetsFreckle.config.token}"
end
private
View
15 lib/letsfreckle/entry.rb
@@ -2,7 +2,20 @@ module LetsFreckle
class Entry < DelegateClass(Hashie::Mash)
extend ClientResource
- def self.all
+ def self.all(options = {})
+ if options[:all_pages]
+ collector = []
+ page = 1
+ while true do
+ response = get('entries', {:page => page})
+ page+=1
+ if response.empty?
+ return collector
+ else
+ collector.concat response
+ end
+ end
+ end
get('entries')
end
View
14 spec/letsfreckle/entry_spec.rb
@@ -16,5 +16,19 @@
first_entry = entries.first
first_entry.description.should == 'api test description'
end
+
+ it "should return all entries on all pages" do
+ LetsFreckle.configure do
+ username "username"
+ account_host "host"
+ token "secret"
+ end
+
+ stub_api_request('entries', {:page => 1})
+ stub_api_request('entries', {:page => 2})
+ stub_api_request('entries', {:page => 3})
+ entries = LetsFreckle::Entry.all(:all_pages => true)
+ entries.size.should == 4
+ end
end
end
View
55 spec/responses/entries1.xml.response
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entries type="array">
+ <entry>
+ <billable type="boolean">true</billable>
+ <created-at type="datetime">2011-05-25T13:15:35Z</created-at>
+ <date type="date">2011-11-25</date>
+ <description>api test description</description>
+ <description-text>freckle restful api test</description-text>
+ <id type="integer">986234</id>
+ <import-id type="integer" nil="true"></import-id>
+ <invoiced-at type="datetime" nil="true"></invoiced-at>
+ <minutes type="integer">30</minutes>
+ <project-id type="integer" nil="true"></project-id>
+ <project-invoice-id type="integer" nil="true"></project-invoice-id>
+ <recently-updated-at type="datetime">2011-05-25T13:15:35Z</recently-updated-at>
+ <time-from type="integer" nil="true"></time-from>
+ <time-to type="integer" nil="true"></time-to>
+ <updated-at type="datetime">2011-05-25T13:15:35Z</updated-at>
+ <url nil="true"></url>
+ <user-id type="integer">5543</user-id>
+ <tags type="array">
+ <tag>
+ <billable type="boolean">true</billable>
+ <id type="integer">23035</id>
+ <name>bulk import</name>
+ </tag>
+ </tags>
+ </entry>
+ <entry>
+ <billable type="boolean">true</billable>
+ <created-at type="datetime">2011-02-18T15:27:57Z</created-at>
+ <date type="date">2011-01-28</date>
+ <description>api test description</description>
+ <description-text></description-text>
+ <id type="integer">708805</id>
+ <import-id type="integer" nil="true"></import-id>
+ <invoiced-at type="datetime" nil="true"></invoiced-at>
+ <minutes type="integer">420</minutes>
+ <project-id type="integer">8475</project-id>
+ <project-invoice-id type="integer" nil="true"></project-invoice-id>
+ <recently-updated-at type="datetime">2011-02-18T15:27:57Z</recently-updated-at>
+ <time-from type="integer" nil="true"></time-from>
+ <time-to type="integer" nil="true"></time-to>
+ <updated-at type="datetime">2011-02-18T15:27:57Z</updated-at>
+ <url nil="true"></url>
+ <user-id type="integer">5543</user-id>
+ <tags type="array">
+ <tag>
+ <billable type="boolean">true</billable>
+ <id type="integer">123124</id>
+ <name>- instru</name>
+ </tag>
+ </tags>
+ </entry>
+</entries>
View
55 spec/responses/entries2.xml.response
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entries type="array">
+ <entry>
+ <billable type="boolean">true</billable>
+ <created-at type="datetime">2011-05-25T13:15:35Z</created-at>
+ <date type="date">2011-11-25</date>
+ <description>api test description</description>
+ <description-text>freckle restful api test</description-text>
+ <id type="integer">986234</id>
+ <import-id type="integer" nil="true"></import-id>
+ <invoiced-at type="datetime" nil="true"></invoiced-at>
+ <minutes type="integer">30</minutes>
+ <project-id type="integer" nil="true"></project-id>
+ <project-invoice-id type="integer" nil="true"></project-invoice-id>
+ <recently-updated-at type="datetime">2011-05-25T13:15:35Z</recently-updated-at>
+ <time-from type="integer" nil="true"></time-from>
+ <time-to type="integer" nil="true"></time-to>
+ <updated-at type="datetime">2011-05-25T13:15:35Z</updated-at>
+ <url nil="true"></url>
+ <user-id type="integer">5543</user-id>
+ <tags type="array">
+ <tag>
+ <billable type="boolean">true</billable>
+ <id type="integer">23035</id>
+ <name>bulk import</name>
+ </tag>
+ </tags>
+ </entry>
+ <entry>
+ <billable type="boolean">true</billable>
+ <created-at type="datetime">2011-02-18T15:27:57Z</created-at>
+ <date type="date">2011-01-28</date>
+ <description>api test description</description>
+ <description-text></description-text>
+ <id type="integer">708805</id>
+ <import-id type="integer" nil="true"></import-id>
+ <invoiced-at type="datetime" nil="true"></invoiced-at>
+ <minutes type="integer">420</minutes>
+ <project-id type="integer">8475</project-id>
+ <project-invoice-id type="integer" nil="true"></project-invoice-id>
+ <recently-updated-at type="datetime">2011-02-18T15:27:57Z</recently-updated-at>
+ <time-from type="integer" nil="true"></time-from>
+ <time-to type="integer" nil="true"></time-to>
+ <updated-at type="datetime">2011-02-18T15:27:57Z</updated-at>
+ <url nil="true"></url>
+ <user-id type="integer">5543</user-id>
+ <tags type="array">
+ <tag>
+ <billable type="boolean">true</billable>
+ <id type="integer">123124</id>
+ <name>- instru</name>
+ </tag>
+ </tags>
+ </entry>
+</entries>
View
3  spec/responses/entries3.xml.response
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entries type="array">
+</entries>
View
29 spec/support/webmock_helper.rb
@@ -1,17 +1,26 @@
module WebMockHelper
- def load_response(resource)
- File.read(File.join(File.dirname(__FILE__), '/../responses', "#{resource}.xml.response"))
+ def load_response(resource, options = {})
+ File.read(File.join(File.dirname(__FILE__), '/../responses', "#{resource}#{!options[:page] ? '' : options[:page]}.xml.response"))
end
- def url_for_resource(resource)
- "#{LetsFreckle::Entry.base_api_url}#{LetsFreckle::Entry.relative_path_for(resource)}"
+ def url_for_resource(resource, options = {})
+ "#{LetsFreckle::Entry.base_api_url}#{LetsFreckle::Entry.relative_path_for(resource, options[:page])}"
+ end
+
+ def headers_for_response(resource, options = {})
+ if resource == 'entries' && options[:page] && options[:page] == 1
+ return {'Link' => "<#{LetsFreckle::Entry.base_api_url}/api/entries.json?page=#{!options[:page] ? 0 : (options[:page] + 1)}&per_page=100>; rel=\"next\""}
+ end
+ {}
end
- def stub_api_request(resource)
- stub_http_request(:get, url_for_resource(resource)).
- with(:headers => { 'Accept' =>'*/*',
- 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
- 'User-Agent' =>'Ruby' }).
- to_return(:body => load_response(resource))
+ def stub_api_request(resource, options = {})
+ stub_http_request(:get, url_for_resource(resource, options)).
+ with(:headers => {
+ 'Accept' =>'*/*',
+ 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
+ 'User-Agent' =>'Ruby'
+ }).
+ to_return(:body => load_response(resource, options), :headers => headers_for_response(resource))
end
end
Something went wrong with that request. Please try again.