highrise 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,94 @@
1
+ # Highrise (1.0)
2
+
3
+ ## What is it?
4
+
5
+ This gem provides a set of classes to access information on [Highrise][h] via the published [API][api]:
6
+
7
+ Comment, Company, Email, Group, Case, Membership, Note, Person, Subject, Tag, Task, User.
8
+
9
+ All these classes are inherited from ActiveResouce::Base. Refer to the [ActiveResouce][ar] documentation for more information.
10
+
11
+ ## Installing
12
+
13
+ gem install tapajos-highrise
14
+
15
+ ### Dependencies (see the Rakefile or run <code>rake check_dependencies</code>)
16
+
17
+ ### Documentation
18
+
19
+ I'm on [rdoc.info][rdoc] and here're some [metrics][devver]
20
+
21
+ ### Configure your key
22
+
23
+ require 'rubygems'
24
+ require 'highrise'
25
+
26
+ Highrise::Base.site = 'http://your_api:login@your_site.highrisehq.com/'
27
+
28
+ or
29
+
30
+ Highrise::Base.site = 'http://your_site.highrisehq.com'
31
+ Highrise::Base.user = 'api-auth-token'
32
+
33
+ and, if you want [caching][c]:
34
+
35
+ Highrise::Base.cache_store= <your normal ActiveSupport::Caching options>
36
+
37
+ If you are using this in a Rails application, putting this code in a config/initializers/highrise.rb
38
+ file is recommended. See config_initializers_highrise.rb in the examples/ directory.
39
+
40
+ ## Usage
41
+
42
+ @tags = Highrise::Tag.find(:all)
43
+
44
+ @people = Highrise::Person.find_all_across_pages(:params => {:tag_id => 12345})
45
+
46
+ @person.tag!("VIP")
47
+
48
+ ## License
49
+
50
+ This code is free to be used under the terms of the [MIT license][mit].
51
+
52
+ ## Bugs, Issues, Kudos and Catcalls
53
+
54
+ Comments are welcome. Send your feedback through the [issue tracker on GitHub][i]
55
+
56
+ ## Authors
57
+
58
+ * [Marcos Tapajós][mt]
59
+ * [Ken Mayer][km]
60
+
61
+ ## Contributors
62
+
63
+ * [Nicolas Bianco][nb]
64
+ * [Luis Gustavo][lg]
65
+ * [Thiago Lelis][tl]
66
+
67
+ ## Shameless advertisement
68
+
69
+ This plugin is brought to you by [Improve It][ii].
70
+
71
+ ## Special Thanks
72
+
73
+ [Rails Envy Podcast Episode #77][re] for mentioning
74
+ [How to Cache Anything With ActiveSupport][rh] on the very *day* I started writing the cache code. Thank you, Rein
75
+ for writing an excellent tutorial and [posting your source][e] on GitHub.
76
+
77
+ [api]: http://developer.37signals.com/highrise
78
+ [ar]: http://api.rubyonrails.org/classes/ActiveResource/Base.html
79
+ [c]: http://api.rubyonrails.org/classes/ActiveSupport/Cache
80
+ [co]: http://github.com/kmayer
81
+ [e]: http://github.com/primedia/endeca/tree/master
82
+ [h]: http://www.highrisehq.com/
83
+ [i]: http://github.com/kmayer/highrise/issues
84
+ [ii]: http://www.improveit.com.br/en
85
+ [km]: http://github.com/kmayer
86
+ [lg]: http://github.com/luisbebop
87
+ [mit]:http://www.opensource.org/licenses/mit-license.php
88
+ [mt]: http://www.improveit.com.br/en/company/tapajos
89
+ [nb]: http://github.com/slainer86
90
+ [re]: http://www.railsenvy.com/2009/4/29/rails-envy-podcast-episode-077-04-29-2009
91
+ [rh]: http://reinh.com/blog/2009/04/27/how-to-cache-anything-with-activesupport.html
92
+ [tl]: http://github.com/ThiagoLelis
93
+ [rdoc]: http://rdoc.info/projects/kmayer/highrise
94
+ [devver]: http://devver.net/caliper/stats?repo=git://github.com/kmayer/highrise
@@ -0,0 +1,3 @@
1
+ :minor: 0
2
+ :patch: 2
3
+ :major: 1
@@ -0,0 +1,88 @@
1
+ # Caching is a way to speed up slow ActiveResource queries by keeping the result of
2
+ # a request around to be reused by subsequent requests.
3
+ #
4
+ # Caching is turned OFF by default.
5
+ #
6
+ # == Usage
7
+ #
8
+ # require 'cachable'
9
+ #
10
+ # module CachedResource
11
+ # class Base < ActiveResource::Base
12
+ # include ::Cachable
13
+ # end
14
+ # end
15
+ #
16
+ #
17
+ # == Caching stores
18
+ #
19
+ # All the caching stores from ActiveSupport::Cache are available
20
+ # as backends for caching. See the Rails rdoc for more information on
21
+ # these stores
22
+ #
23
+ # === Configuration examples ('off' is the default):
24
+ # CachedResource.cache_store = ActiveSupport::Cache.lookup_store :memory_store
25
+ # CachedResource.cache_store = ActiveSupport::Cache.lookup_store :file_store, "/path/to/cache/directory"
26
+ # CachedResource.cache_store = ActiveSupport::Cache.lookup_store :drb_store, "druby://localhost:9192"
27
+ # CachedResource.cache_store = ActiveSupport::Cache.lookup_store :mem_cache_store, "localhost"
28
+ # CachedResource.cache_store = MyOwnStore.new("parameter")
29
+ #
30
+ # === If you are using a store that has write options, you can set them
31
+ # CachedResource.store_options = { :expires_in => 60.seconds }
32
+ #
33
+ # Note: To ensure that caching is turned off, set CachedResource.connection.cache_store = nil
34
+ #
35
+ # FYI: You can use this with *any* active resource interface, not just Highrise.
36
+
37
+ module Cachable
38
+ def self.included(base)
39
+ base.extend ClassMethods
40
+ base.class_eval do
41
+ class << self
42
+ alias_method_chain :find_every, :cache
43
+ alias_method_chain :find_single, :cache
44
+ end
45
+ end
46
+ end
47
+
48
+ module ClassMethods
49
+ attr_writer :cache_store, :store_options
50
+
51
+ def cache_store
52
+ @cache_store ||= nil
53
+ end
54
+
55
+ def store_options
56
+ @store_options ||= {}
57
+ end
58
+
59
+ def is_caching?
60
+ !@cache_store.nil?
61
+ end
62
+
63
+ private
64
+
65
+ # A little hacky -- we need to intercept the finds, but not get too deep inside the connection
66
+ def find_every_with_cache(options)
67
+ return find_every_without_cache(options) unless is_caching?
68
+ prefix_options, query_options = split_options(options[:params])
69
+ path = collection_path(prefix_options, query_options)
70
+ fetch(path) { find_every_without_cache(options)}
71
+ end
72
+
73
+ def find_single_with_cache(scope, options)
74
+ return find_single_without_cache(scope, options) unless is_caching?
75
+ prefix_options, query_options = split_options(options[:params])
76
+ path = element_path(scope, prefix_options, query_options)
77
+ fetch(path) { find_single_without_cache(scope, options)}
78
+ end
79
+
80
+ def cache_key(*args)
81
+ args.to_s
82
+ end
83
+
84
+ def fetch(args, &block)
85
+ cache_store.fetch(cache_key(args), store_options, &block).dup
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,18 @@
1
+ require 'active_resource'
2
+ $:.unshift(File.dirname(__FILE__))
3
+
4
+ require 'highrise/base'
5
+ require 'highrise/pagination'
6
+ require 'highrise/taggable'
7
+ require 'highrise/subject'
8
+ require 'highrise/comment'
9
+ require 'highrise/company'
10
+ require 'highrise/email'
11
+ require 'highrise/group'
12
+ require 'highrise/kase'
13
+ require 'highrise/membership'
14
+ require 'highrise/note'
15
+ require 'highrise/person'
16
+ require 'highrise/task'
17
+ require 'highrise/user'
18
+ require 'highrise/tag'
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../cachable'
2
+
3
+ module Highrise
4
+ class Base < ActiveResource::Base
5
+ include ::Cachable
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module Highrise
2
+ class Comment < Base
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ module Highrise
2
+ class Company < Subject
3
+ include Pagination
4
+ include Taggable
5
+
6
+ def self.find_all_across_pages_since(time)
7
+ find_all_across_pages(:params => { :since => time.utc.to_s(:db).gsub(/[^\d]/, '') })
8
+ end
9
+
10
+ def people
11
+ Person.find(:all, :from => "/companies/#{id}/people.xml")
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Highrise
2
+ class Email < Base
3
+ include Pagination
4
+
5
+ def comments
6
+ Comment.find(:all, :from => "/emails/#{email_id}/comments.xml")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module Highrise
2
+ class Group < Base
3
+ end
4
+ end
@@ -0,0 +1,8 @@
1
+ module Highrise
2
+ class Kase < Subject
3
+ def close!
4
+ self.closed_at = Time.now.utc
5
+ save
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ module Highrise
2
+ class Membership < Base
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ module Highrise
2
+ class Note < Base
3
+ include Pagination
4
+
5
+ def comments
6
+ Comment.find(:all, :from => "/notes/#{id}/comments.xml")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Highrise
2
+ module Pagination
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def find_all_across_pages(options = {})
9
+ records = []
10
+ each(options) { |record| records << record }
11
+ records
12
+ end
13
+
14
+ def each(options = {})
15
+ options[:params] ||= {}
16
+ options[:params][:n] = 0
17
+
18
+ loop do
19
+ if (records = self.find(:all, options)).any?
20
+ records.each { |record| yield record }
21
+ options[:params][:n] += records.size
22
+ else
23
+ break # no people included on that page, thus no more people total
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module Highrise
2
+ class Person < Subject
3
+ include Pagination
4
+ include Taggable
5
+
6
+ def self.find_all_across_pages_since(time)
7
+ find_all_across_pages(:params => { :since => time.utc.to_s(:db).gsub(/[^\d]/, '') })
8
+ end
9
+
10
+ def company
11
+ Company.find(company_id) if company_id
12
+ end
13
+
14
+ def name
15
+ "#{first_name rescue ''} #{last_name rescue ''}".strip
16
+ end
17
+
18
+ def address
19
+ contact_data.addresses.first
20
+ end
21
+
22
+ def web_address
23
+ contact_data.web_addresses.first
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module Highrise
2
+ class Subject < Base
3
+ def notes
4
+ Note.find_all_across_pages(:from => "/#{self.class.collection_name}/#{id}/notes.xml")
5
+ end
6
+
7
+ def emails
8
+ Email.find_all_across_pages(:from => "/#{self.class.collection_name}/#{id}/emails.xml")
9
+ end
10
+
11
+ def upcoming_tasks
12
+ Task.find(:all, :from => "/#{self.class.collection_name}/#{id}/tasks.xml")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module Highrise
2
+ class Tag < Base
3
+ @@tags = {}
4
+ def ==(object)
5
+ (object.instance_of?(self.class) && object.id == self.id && object.name == self.name)
6
+ end
7
+
8
+ def self.find_by_name(arg)
9
+ if @@tags == {}
10
+ self.find(:all).each do |tag|
11
+ @@tags[tag.id] = tag
12
+ @@tags[tag.name] = tag
13
+ end
14
+ end
15
+ @@tags[arg]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module Highrise
2
+ module Taggable
3
+ def tags
4
+ self.get(:tags)
5
+ end
6
+ def tag!(tag_name)
7
+ self.post(:tags, :name => tag_name) unless tag_name.blank?
8
+ end
9
+ def untag!(tag_name)
10
+ to_delete = self.tags.find{|tag| tag['name'] == tag_name} unless tag_name.blank?
11
+ self.untag_id!(to_delete['id']) unless to_delete.nil?
12
+ end
13
+ def untag_id!(tag_id)
14
+ self.delete("tags/#{tag_id}")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module Highrise
2
+ class Task < Base
3
+ # find(:all, :from => :upcoming)
4
+ # find(:all, :from => :assigned)
5
+ # find(:all, :from => :completed)
6
+
7
+ def complete!
8
+ load_attributes_from_response(post(:complete))
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Highrise
2
+ class User < Base
3
+ def join(group)
4
+ Membership.create(:user_id => id, :group_id => group.id)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,66 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Highrise::Base, "class configuration" do
4
+ before(:each) do
5
+ Highrise::Base.site = 'http://example.com.i:3000'
6
+ end
7
+
8
+ it "should tell us if caching is active" do
9
+ Highrise::Base.cache_store = ActiveSupport::Cache.lookup_store :memory_store
10
+ Highrise::Base.is_caching?.should == true
11
+ end
12
+
13
+ it "should tell us if caching is not active" do
14
+ Highrise::Base.cache_store = nil
15
+ Highrise::Base.is_caching?.should == false
16
+ end
17
+ end
18
+
19
+ describe Highrise::Base do
20
+ before(:all) do
21
+ Highrise::Base.site = 'http://example.com.i:3000'
22
+ Highrise::Base.cache_store = ActiveSupport::Cache.lookup_store :memory_store
23
+ end
24
+
25
+ after(:all) do
26
+ Highrise::Base.cache_store = :none
27
+ end
28
+
29
+ before(:each) do
30
+ @thing = Highrise::Base.new
31
+ @key = :key
32
+ Highrise::Base.stub!(:cache_key).and_return(@key)
33
+ end
34
+
35
+ context "when a cached response is available" do
36
+ before(:each) do
37
+ Highrise::Base.cache_store.write(@key, @thing)
38
+ end
39
+
40
+ it "should NOT make a request to the RESTful server" do
41
+ Highrise::Base.should_not_receive(:find_single_without_cache)
42
+ Highrise::Base.find(1)
43
+ end
44
+
45
+ it "should read from the cache" do
46
+ Highrise::Base.find(1).should == @thing
47
+ end
48
+ end
49
+
50
+ context "when a cached response is NOT available" do
51
+ before(:each) do
52
+ Highrise::Base.cache_store.delete(@key)
53
+ end
54
+
55
+ it "SHOULD perform an ARes request" do
56
+ Highrise::Base.should_receive(:find_single_without_cache).and_return(@thing)
57
+ Highrise::Base.find(1)
58
+ end
59
+
60
+ it "should cache the response using the caching key" do
61
+ Highrise::Base.should_receive(:find_single_without_cache).and_return(@thing)
62
+ Highrise::Base.find(1)
63
+ Highrise::Base.cache_store.read(@key).should == @thing
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,13 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Base do
4
+
5
+ before(:each) do
6
+ @base = Highrise::Base.new
7
+ end
8
+
9
+ it "should be instance of ActiveResource::Base" do
10
+ @base.kind_of?(ActiveResource::Base).should be_true
11
+ end
12
+
13
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Comment do
4
+
5
+ before(:each) do
6
+ @comment = Highrise::Comment.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @comment.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+
14
+ end
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Company do
4
+
5
+ before(:each) do
6
+ Highrise::Base.site = 'http://example.com.i:3000'
7
+ @company = Highrise::Company.new(:id => 1)
8
+ returning @tags = [] do
9
+ @tags << {'id' => "414578", 'name' => "cliente"}
10
+ @tags << {'id' => "414580", 'name' => "ged"}
11
+ @tags << {'id' => "414579", 'name' => "iepc"}
12
+ end
13
+ end
14
+
15
+ it "should be instance of Highrise::Base" do
16
+ @company.kind_of?(Highrise::Base).should be_true
17
+ end
18
+
19
+ describe ".find_all_across_pages_since" do
20
+
21
+ it "should delegate to find_all_across_pages with correct params" do
22
+ time = Time.parse("Wed Jan 14 15:43:11 -0200 2009")
23
+ Highrise::Company.should_receive(:find_all_across_pages).with({:params=>{:since=>"20090114174311"}}).and_return("result")
24
+ Highrise::Company.find_all_across_pages_since(time).should == "result"
25
+ end
26
+
27
+ end
28
+
29
+ describe "people" do
30
+
31
+ it "should delegate to Highrise::Person.find with correct params" do
32
+ @company.should_receive(:id).and_return(1)
33
+ Highrise::Person.should_receive(:find).with(:all, {:from=>"/companies/1/people.xml"}).and_return("people")
34
+ @company.people.should == "people"
35
+ end
36
+
37
+ end
38
+
39
+ describe ".tags" do
40
+
41
+ it "should return an array of all tags for that company." do
42
+ @company.should_receive(:get).with(:tags).and_return(@tags)
43
+ @company.tags.should == @tags
44
+ end
45
+
46
+ end
47
+
48
+ describe "tag!(tag_name)" do
49
+
50
+ it "should create a tag for this company." do
51
+ @company.should_receive(:post).with(:tags, :name => "client" ).and_return(true)
52
+ @company.tag!("client").should be_true
53
+ end
54
+
55
+ end
56
+
57
+ describe "untag!(tag_name)" do
58
+
59
+ it "should delete a tag for this company." do
60
+ @company.should_receive(:get).with(:tags).and_return(@tags)
61
+ @company.should_receive(:delete).with("tags/414578").and_return(true)
62
+ @company.untag!("cliente").should be_true
63
+ end
64
+
65
+ end
66
+
67
+
68
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Email do
4
+
5
+ before(:each) do
6
+ @mail = Highrise::Email.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @mail.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+ describe "comments" do
14
+
15
+ it "should delegate to Highrise::Comment.find with correct params" do
16
+ @mail.should_receive(:email_id).and_return(1)
17
+ Highrise::Comment.should_receive(:find).with(:all, {:from=>"/emails/1/comments.xml"}).and_return("comments")
18
+ @mail.comments.should == "comments"
19
+ end
20
+
21
+ end
22
+
23
+
24
+
25
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Group do
4
+
5
+ before(:each) do
6
+ @group = Highrise::Group.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @group.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+
14
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Kase do
4
+
5
+ before(:each) do
6
+ @kase = Highrise::Kase.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Subject" do
10
+ @kase.kind_of?(Highrise::Subject).should be_true
11
+ end
12
+
13
+ describe ".close!" do
14
+
15
+ it "should set close date and save" do
16
+ time = Time.parse("Wed Jan 14 15:43:11 -0200 2009")
17
+ Time.should_receive(:now).and_return(time)
18
+ @kase.should_receive(:closed_at=).with(time.utc)
19
+ @kase.should_receive(:save)
20
+ @kase.close!
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Membership do
4
+
5
+ before(:each) do
6
+ @member = Highrise::Membership.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @member.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+
14
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Note do
4
+
5
+ before(:each) do
6
+ @note = Highrise::Note.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @note.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+ describe "comments" do
14
+
15
+ it "should delegate to Highrise::Comment.find with correct params" do
16
+ @note.should_receive(:id).and_return(1)
17
+ Highrise::Comment.should_receive(:find).with(:all, {:from=>"/notes/1/comments.xml"}).and_return("comments")
18
+ @note.comments.should == "comments"
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Pagination do
4
+
5
+ it "should be tested" do
6
+ Highrise::Person.should_receive(:find).with(:all,{:params=>{:n=>0}}).and_return(["people"])
7
+ Highrise::Person.should_receive(:find).with(:all,{:params=>{:n=>1}}).and_return([])
8
+ Highrise::Person.find_all_across_pages.should == ["people"]
9
+ end
10
+ end
@@ -0,0 +1,81 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Person do
4
+
5
+ before(:each) do
6
+ Highrise::Base.site = 'http://example.com.i:3000'
7
+ @person = Highrise::Person.new(:id => 1)
8
+ returning @tags = [] do
9
+ @tags << {'id' => "414578", 'name' => "cliente"}
10
+ @tags << {'id' => "414587", 'name' => "walk"}
11
+ end
12
+ end
13
+
14
+ it "should be instance of Highrise::Subject" do
15
+ @person.kind_of?(Highrise::Subject).should be_true
16
+ end
17
+
18
+ describe ".find_all_across_pages_since" do
19
+
20
+ it "should delegate to find_all_across_pages with correct params" do
21
+ time = Time.parse("Wed Jan 14 15:43:11 -0200 2009")
22
+ Highrise::Person.should_receive(:find_all_across_pages).with({:params=>{:since=>"20090114174311"}}).and_return("result")
23
+ Highrise::Person.find_all_across_pages_since(time).should == "result"
24
+ end
25
+
26
+ end
27
+
28
+ describe ".company" do
29
+
30
+ it "should return nil when doesn't have company_id" do
31
+ @person.should_receive(:company_id).and_return(nil)
32
+ @person.company.should be_nil
33
+ end
34
+
35
+ it "should delegate to Highrise::Company when have company_id" do
36
+ @person.should_receive(:company_id).at_least(2).times.and_return(1)
37
+ Highrise::Company.should_receive(:find).with(1).and_return("company")
38
+ @person.company.should == "company"
39
+ end
40
+
41
+ end
42
+
43
+ describe ".name" do
44
+
45
+ it "should concat fist_name with last_name and strip" do
46
+ @person.should_receive(:first_name).and_return("Marcos")
47
+ @person.should_receive(:last_name).and_return("Tapajós ")
48
+ @person.name.should == "Marcos Tapajós"
49
+ end
50
+
51
+ end
52
+
53
+ describe ".tags" do
54
+
55
+ it "should return an array of all tags for that user." do
56
+ @person.should_receive(:get).with(:tags).and_return(@tags)
57
+ @person.tags.should == @tags
58
+ end
59
+
60
+ end
61
+
62
+ describe "tag!(tag_name)" do
63
+
64
+ it "should create a tag for this user." do
65
+ @person.should_receive(:post).with(:tags, :name => "Forum_User" ).and_return(true)
66
+ @person.tag!("Forum_User").should be_true
67
+ end
68
+
69
+ end
70
+
71
+ describe "untag!(tag_name)" do
72
+
73
+ it "should delete a tag for this user." do
74
+ @person.should_receive(:get).with(:tags).and_return(@tags)
75
+ @person.should_receive(:delete).with("tags/414578").and_return(true)
76
+ @person.untag!("cliente").should be_true
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Subject do
4
+
5
+ before(:each) do
6
+ @subject = Highrise::Subject.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @subject.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+ describe ".notes" do
14
+
15
+ it "should delegate to Highrise::Note with correct params" do
16
+ @subject.should_receive(:id).and_return(1)
17
+ Highrise::Note.should_receive(:find_all_across_pages).with({:from=>"/subjects/1/notes.xml"}).and_return("notes")
18
+ @subject.notes.should == "notes"
19
+ end
20
+
21
+ end
22
+
23
+ describe ".emails" do
24
+
25
+ it "should delegate to Highrise::Email with correct params" do
26
+ @subject.should_receive(:id).and_return(1)
27
+ Highrise::Email.should_receive(:find_all_across_pages).with({:from=>"/subjects/1/emails.xml"}).and_return("emails")
28
+ @subject.emails.should == "emails"
29
+ end
30
+
31
+ end
32
+
33
+ describe ".upcoming_tasks" do
34
+
35
+ it "should delegate to Highrise::Task with correct params" do
36
+ @subject.should_receive(:id).and_return(1)
37
+ Highrise::Task.should_receive(:find).with(:all, {:from=>"/subjects/1/tasks.xml"}).and_return("tasks")
38
+ @subject.upcoming_tasks.should == "tasks"
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Tag do
4
+
5
+ before(:each) do
6
+ Highrise::Base.site = 'http://example.com.i/'
7
+ @tag = Highrise::Tag.new(:id => 1, :name => "Name")
8
+ end
9
+
10
+ it "should be instance of Highrise::Base" do
11
+ @tag.kind_of?(Highrise::Base).should be_true
12
+ end
13
+
14
+ it "should support equality" do
15
+ tag = Highrise::Tag.new(:id => 1, :name => "Name")
16
+ @tag.should == tag
17
+ end
18
+
19
+ it "it should find_by_name" do
20
+ tag = Highrise::Tag.new(:id => 2, :name => "Next")
21
+ Highrise::Tag.should_receive(:find).with(:all).and_return([tag, @tag])
22
+ Highrise::Tag.find_by_name("Name").should == @tag
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::Task do
4
+
5
+ before(:each) do
6
+ @task = Highrise::Task.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @task.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+ describe ".complete!" do
14
+
15
+ it "should delegate to load_attributes_from_response" do
16
+ @task.should_receive(:load_attributes_from_response).with("post")
17
+ @task.should_receive(:post).with(:complete).and_return("post")
18
+ @task.complete!
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Highrise::User do
4
+
5
+ before(:each) do
6
+ @user = Highrise::User.new
7
+ end
8
+
9
+ it "should be instance of Highrise::Base" do
10
+ @user.kind_of?(Highrise::Base).should be_true
11
+ end
12
+
13
+ def join(group)
14
+ Membership.create(:user_id => id, :group_id => group.id)
15
+ end
16
+
17
+ describe ".joind" do
18
+
19
+ it "should delegate to Highrise::Membership.create" do
20
+ group_mock = mock("group")
21
+ group_mock.should_receive(:id).and_return(2)
22
+ @user.should_receive(:id).and_return(1)
23
+ Highrise::Membership.should_receive(:create).with({:user_id=>1, :group_id=>2})
24
+ @user.join(group_mock)
25
+ end
26
+
27
+ end
28
+
29
+
30
+ end
@@ -0,0 +1,8 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
7
+ -rubygems
8
+ --debugger
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../lib/highrise'
2
+
3
+ def turn_methods_public(klass, method_name = nil)
4
+ if method_name
5
+ klass.class_eval do
6
+ public method_name
7
+ end
8
+ else
9
+ turn_all_methods_public klass
10
+ end
11
+ end
12
+
13
+ def turn_all_methods_public(klass)
14
+ klass.class_eval do
15
+ private_instance_methods.each { |instance_method| public instance_method }
16
+ private_methods.each { |method| public_class_method method }
17
+ protected_instance_methods.each { |instance_method| public instance_method }
18
+ protected_methods.each { |method| public_class_method method }
19
+ end
20
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: highrise
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - "Marcos Tapaj\xC3\xB3s"
8
+ - Ken Mayer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-10-17 00:00:00 -03:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: activeresource
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "2.1"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "2.1"
35
+ version:
36
+ description: "\n\
37
+ Based on the original API module from DHH, http://developer.37signals.com/highrise/, this\n\
38
+ gem is a cleaned up, tested version of the same. Contributors have added support for tags \n\
39
+ which are not supported by the API directly\n\n\
40
+ Configure by adding the following:\n\n\
41
+ require 'highrise'\n\
42
+ Highrise::Base.site = 'http://your_site.highrisehq.com/'\n\
43
+ Highrise::Base.user = 'your_api_auth_token'\n "
44
+ email: marcos@tapajos.me, kmayer@bitwrangler.com
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ extra_rdoc_files: []
50
+
51
+ files:
52
+ - README.mkdn
53
+ - VERSION.yml
54
+ - lib/cachable.rb
55
+ - lib/highrise/base.rb
56
+ - lib/highrise/comment.rb
57
+ - lib/highrise/company.rb
58
+ - lib/highrise/email.rb
59
+ - lib/highrise/group.rb
60
+ - lib/highrise/kase.rb
61
+ - lib/highrise/membership.rb
62
+ - lib/highrise/note.rb
63
+ - lib/highrise/pagination.rb
64
+ - lib/highrise/person.rb
65
+ - lib/highrise/subject.rb
66
+ - lib/highrise/tag.rb
67
+ - lib/highrise/taggable.rb
68
+ - lib/highrise/task.rb
69
+ - lib/highrise/user.rb
70
+ - lib/highrise.rb
71
+ - spec/cachable_spec.rb
72
+ - spec/highrise/base_spec.rb
73
+ - spec/highrise/comment_spec.rb
74
+ - spec/highrise/company_spec.rb
75
+ - spec/highrise/email_spec.rb
76
+ - spec/highrise/group_spec.rb
77
+ - spec/highrise/kase_spec.rb
78
+ - spec/highrise/membership_spec.rb
79
+ - spec/highrise/note_spec.rb
80
+ - spec/highrise/pagination_spec.rb
81
+ - spec/highrise/person_spec.rb
82
+ - spec/highrise/subject_spec.rb
83
+ - spec/highrise/tag_spec.rb
84
+ - spec/highrise/task_spec.rb
85
+ - spec/highrise/user_spec.rb
86
+ - spec/spec.opts
87
+ - spec/spec_helper.rb
88
+ has_rdoc: true
89
+ homepage: http://github.com/tapajos/highrise
90
+ licenses: []
91
+
92
+ post_install_message:
93
+ rdoc_options:
94
+ - --inline-source
95
+ - --charset=UTF-8
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: "0"
103
+ version:
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: "0"
109
+ version:
110
+ requirements: []
111
+
112
+ rubyforge_project:
113
+ rubygems_version: 1.3.5
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: Ruby wrapper around Highrise API
117
+ test_files: []
118
+