highrise 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +38 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.mkdn +21 -29
  5. data/Rakefile +6 -31
  6. data/autotest/discover.rb +1 -3
  7. data/examples/config_initializers_highrise.rb +1 -9
  8. data/examples/sample.rb +0 -1
  9. data/highrise.gemspec +24 -117
  10. data/lib/highrise.rb +6 -5
  11. data/lib/highrise/account.rb +0 -1
  12. data/lib/highrise/base.rb +15 -3
  13. data/lib/highrise/comment.rb +1 -2
  14. data/lib/highrise/company.rb +3 -2
  15. data/lib/highrise/deal.rb +4 -1
  16. data/lib/highrise/deal_category.rb +3 -0
  17. data/lib/highrise/group.rb +1 -2
  18. data/lib/highrise/kase.rb +13 -2
  19. data/lib/highrise/membership.rb +1 -2
  20. data/lib/highrise/pagination.rb +8 -1
  21. data/lib/highrise/party.rb +11 -0
  22. data/lib/highrise/person.rb +1 -4
  23. data/lib/highrise/recording.rb +5 -0
  24. data/lib/highrise/searchable.rb +22 -0
  25. data/lib/highrise/subject.rb +6 -0
  26. data/lib/highrise/tag.rb +0 -5
  27. data/lib/highrise/taggable.rb +4 -1
  28. data/lib/highrise/task_category.rb +3 -0
  29. data/lib/highrise/version.rb +3 -0
  30. data/spec/highrise/account_spec.rb +5 -11
  31. data/spec/highrise/base_spec.rb +45 -10
  32. data/spec/highrise/comment_spec.rb +2 -11
  33. data/spec/highrise/company_spec.rb +10 -72
  34. data/spec/highrise/deal_category_spec.rb +13 -0
  35. data/spec/highrise/deal_spec.rb +16 -13
  36. data/spec/highrise/email_spec.rb +7 -19
  37. data/spec/highrise/group_spec.rb +2 -11
  38. data/spec/highrise/kase_spec.rb +10 -18
  39. data/spec/highrise/membership_spec.rb +2 -11
  40. data/spec/highrise/note_spec.rb +8 -17
  41. data/spec/highrise/pagination_behavior.rb +20 -0
  42. data/spec/highrise/pagination_spec.rb +4 -6
  43. data/spec/highrise/party_spec.rb +16 -0
  44. data/spec/highrise/person_spec.rb +23 -80
  45. data/spec/highrise/recording_spec.rb +13 -0
  46. data/spec/highrise/searchable_behavior.rb +13 -0
  47. data/spec/highrise/searchable_spec.rb +8 -0
  48. data/spec/highrise/subject_spec.rb +20 -35
  49. data/spec/highrise/tag_spec.rb +8 -13
  50. data/spec/highrise/taggable_behavior.rb +27 -0
  51. data/spec/highrise/taggable_spec.rb +9 -0
  52. data/spec/highrise/task_category_spec.rb +13 -0
  53. data/spec/highrise/task_spec.rb +6 -18
  54. data/spec/highrise/user_spec.rb +11 -28
  55. data/spec/spec_helper.rb +9 -18
  56. metadata +55 -42
  57. data/CHANGELOG +0 -131
  58. data/VERSION.yml +0 -5
  59. data/install.rb +0 -1
  60. data/lib/cachable.rb +0 -83
  61. data/spec/cachable_spec.rb +0 -84
  62. data/spec/spec.opts +0 -7
  63. data/uninstall.rb +0 -1
data/lib/highrise/deal.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  module Highrise
2
2
  class Deal < Subject
3
-
3
+ def update_status(status)
4
+ raise ArgumentError, "status must be one of 'pending', 'won', or 'lost'" unless %w[pending won lost].include?(status)
5
+ self.put(:status, :status => {:name => status})
6
+ end
4
7
  end
5
8
  end
@@ -0,0 +1,3 @@
1
+ module Highrise
2
+ class DealCategory < Base; end
3
+ end
@@ -1,4 +1,3 @@
1
1
  module Highrise
2
- class Group < Base
3
- end
2
+ class Group < Base; end
4
3
  end
data/lib/highrise/kase.rb CHANGED
@@ -1,8 +1,19 @@
1
1
  module Highrise
2
2
  class Kase < Subject
3
+ def open!
4
+ update_attribute(:closed_at, nil)
5
+ end
6
+
3
7
  def close!
4
- self.closed_at = Time.now.utc
5
- save
8
+ update_attribute(:closed_at, Time.now.utc)
9
+ end
10
+
11
+ def self.open
12
+ Kase.find(:all, :from => "/kases/open.xml")
13
+ end
14
+
15
+ def self.closed
16
+ Kase.find(:all, :from => "/kases/closed.xml")
6
17
  end
7
18
  end
8
19
  end
@@ -1,4 +1,3 @@
1
1
  module Highrise
2
- class Membership < Base
3
- end
2
+ class Membership < Base; end
4
3
  end
@@ -11,12 +11,19 @@ module Highrise
11
11
  records
12
12
  end
13
13
 
14
+ # This only is usefull for company, person & recordings, but should be safely ignored by other classes
15
+ def find_all_across_pages_since(time)
16
+ find_all_across_pages(:params => { :since => time.utc.strftime("%Y%m%d%H%M%S") })
17
+ end
18
+
19
+ private
20
+
14
21
  def each(options = {})
15
22
  options[:params] ||= {}
16
23
  options[:params][:n] = 0
17
24
 
18
25
  loop do
19
- if (records = self.find(:all, options)).any?
26
+ if (records = self.find(:all, options)).try(:any?)
20
27
  records.each { |record| yield record }
21
28
  options[:params][:n] += records.size
22
29
  else
@@ -0,0 +1,11 @@
1
+ module Highrise
2
+ class Party < Base
3
+ def self.recently_viewed
4
+ find(:all, :from => "/parties/recently_viewed.xml")
5
+ end
6
+
7
+ def self.deletions_since(time)
8
+ find(:all, :from => "/parties/deletions.xml", :params => { :since => time.utc.strftime("%Y%m%d%H%M%S") })
9
+ end
10
+ end
11
+ end
@@ -2,11 +2,8 @@ module Highrise
2
2
  class Person < Subject
3
3
  include Pagination
4
4
  include Taggable
5
+ include Searchable
5
6
 
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
7
  def company
11
8
  Company.find(company_id) if company_id
12
9
  end
@@ -0,0 +1,5 @@
1
+ module Highrise
2
+ class Recording < Base
3
+ include Pagination
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ module Highrise
2
+ module Searchable
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ # List By Search Criteria
9
+ # Ex: Highrise::Person.search(:email => "john.doe@example.com", :country => "CA")
10
+ # Available criteria are: city, state, country, zip, phone, email
11
+ def search(options = {})
12
+ search_params = options.inject({}) { |h, (k, v)| h["criteria[#{k}]"] = v; h }
13
+ # This might have to be changed in the future if other non-pagable resources become searchable
14
+ if self.respond_to?(:find_all_across_pages)
15
+ self.find_all_across_pages(:from => "/#{self.collection_name}/search.xml", :params => search_params)
16
+ else
17
+ self.find(:all, {:from => "/#{self.collection_name}/search.xml", :params => search_params})
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -9,6 +9,12 @@ module Highrise
9
9
  attrs[:subject_type] = self.label
10
10
  Note.create attrs
11
11
  end
12
+
13
+ def add_task(attrs={})
14
+ attrs[:subject_id] = self.id
15
+ attrs[:subject_type] = self.label
16
+ Task.create attrs
17
+ end
12
18
 
13
19
  def emails
14
20
  Email.find_all_across_pages(:from => "/#{self.class.collection_name}/#{id}/emails.xml")
data/lib/highrise/tag.rb CHANGED
@@ -3,10 +3,5 @@ module Highrise
3
3
  def ==(object)
4
4
  (object.instance_of?(self.class) && object.id == self.id && object.name == self.name)
5
5
  end
6
-
7
- # You can't find :one because that finds all *objects* with that tag
8
- def self.find_by_name(arg)
9
- tags = self.find(:all).detect{|tag| tag.name == arg}
10
- end
11
6
  end
12
7
  end
@@ -3,13 +3,16 @@ module Highrise
3
3
  def tags
4
4
  self.get(:tags)
5
5
  end
6
+
6
7
  def tag!(tag_name)
7
8
  self.post(:tags, :name => tag_name) unless tag_name.blank?
8
9
  end
10
+
9
11
  def untag!(tag_name)
10
12
  to_delete = self.tags.find{|tag| tag['name'] == tag_name} unless tag_name.blank?
11
13
  self.untag_id!(to_delete['id']) unless to_delete.nil?
12
- end
14
+ end
15
+ protected
13
16
  def untag_id!(tag_id)
14
17
  self.delete("tags/#{tag_id}")
15
18
  end
@@ -0,0 +1,3 @@
1
+ module Highrise
2
+ class TaskCategory < Base; end
3
+ end
@@ -0,0 +1,3 @@
1
+ module Highrise
2
+ VERSION = "3.0.0"
3
+ end
@@ -1,16 +1,10 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Highrise::Account do
4
- before(:each) do
5
- @account = Highrise::Account.new
6
- end
7
-
8
- it "should be instance of Highrise::Base" do
9
- @account.kind_of?(Highrise::Base).should be_true
10
- end
4
+ it { should be_a_kind_of Highrise::Base }
11
5
 
12
- it "should delegate to find(:one, :from => '/account.xml') when account is called" do
13
- Highrise::Account.should_receive(:find).with(:one, {:from => "/account.xml"}).and_return(@account)
14
- Highrise::Account.me.should == @account
6
+ it ".me" do
7
+ Highrise::Account.should_receive(:find).with(:one, {:from => "/account.xml"}).and_return(subject)
8
+ Highrise::Account.me.should == subject
15
9
  end
16
10
  end
@@ -1,13 +1,48 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
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
4
+ it { subject.should be_a_kind_of ActiveResource::Base }
5
+
6
+ describe "dynamic finder methods" do
7
+ context "without pagination" do
8
+ before do
9
+ @deal_one = Highrise::Base.new(:id => 1, :name => "A deal")
10
+ @deal_two = Highrise::Base.new(:id => 2, :name => "A deal")
11
+ @deal_three = Highrise::Base.new(:id => 3, :name => "Another deal")
12
+ Highrise::Base.should_receive(:find).with(:all).and_return([@deal_one, @deal_two, @deal_three])
13
+ end
14
+ it ".find_by_(attribute) finds one" do
15
+ Highrise::Base.find_by_name("A deal").should == @deal_one
16
+ end
17
+
18
+ it ".find_all_by_(attribute) finds all" do
19
+ Highrise::Base.find_all_by_name("A deal").should == [@deal_one, @deal_two]
20
+ end
21
+ end
22
+
23
+ context "with pagination" do
24
+ before do
25
+ class PaginatedBaseClass < Highrise::Base; include Highrise::Pagination; end
26
+ @john_doe = PaginatedBaseClass.new(:id => 1, :first_name => "John")
27
+ @john_baker = PaginatedBaseClass.new(:id => 2, :first_name => "John")
28
+ @joe_smith = PaginatedBaseClass.new(:id => 3, :first_name => "Joe")
29
+ PaginatedBaseClass.should_receive(:find_all_across_pages).and_return([@john_doe, @john_baker, @joe_smith])
30
+ end
31
+ it ".find_by_(attribute) finds one" do
32
+ PaginatedBaseClass.find_by_first_name("John").should == @john_doe
33
+ end
34
+
35
+ it ".find_all_by_(attribute) finds all" do
36
+ PaginatedBaseClass.find_all_by_first_name("John").should == [@john_doe, @john_baker]
37
+ end
38
+ end
39
+
40
+ it "expects arguments to the finder" do
41
+ expect { Highrise::Base.find_all_by_first_name }.to raise_error(ArgumentError)
42
+ end
43
+
44
+ it "falls back to regular method missing" do
45
+ expect { Highrise::Base.any_other_method }.to raise_error(NoMethodError)
46
+ end
11
47
  end
12
-
13
- end
48
+ end
@@ -1,14 +1,5 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
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
-
4
+ it { should be_a_kind_of Highrise::Base }
14
5
  end
@@ -1,79 +1,17 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
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
4
+ subject { Highrise::Company.new(:id => 1) }
28
5
 
29
- describe "people" do
30
-
31
- it "should delegate to Highrise::Person.find with correct params" do
32
- Highrise::Person.should_receive(:find).with(:all, {:from=>"/companies/1/people.xml"}).and_return("people")
33
- @company.people.should == "people"
34
- end
6
+ it { should be_a_kind_of Highrise::Base }
7
+ it_should_behave_like "a paginated class"
8
+ it_should_behave_like "a taggable class"
9
+ it_should_behave_like "a searchable class"
35
10
 
11
+ it "#people" do
12
+ Highrise::Person.should_receive(:find_all_across_pages).with(:from=>"/companies/1/people.xml").and_return("people")
13
+ subject.people.should == "people"
36
14
  end
37
15
 
38
- describe ".tags" do
39
-
40
- it "should return an array of all tags for that company." do
41
- @company.should_receive(:get).with(:tags).and_return(@tags)
42
- @company.tags.should == @tags
43
- end
44
-
45
- end
46
-
47
- describe "tag!(tag_name)" do
48
-
49
- it "should create a tag for this company." do
50
- @company.should_receive(:post).with(:tags, :name => "client" ).and_return(true)
51
- @company.tag!("client").should be_true
52
- end
53
-
54
- end
55
-
56
- describe "untag!(tag_name)" do
57
-
58
- it "should delete a tag for this company." do
59
- @company.should_receive(:get).with(:tags).and_return(@tags)
60
- @company.should_receive(:delete).with("tags/414578").and_return(true)
61
- @company.untag!("cliente").should be_true
62
- end
63
-
64
- end
65
-
66
- describe ".label" do
67
- it "should return 'Party' for label" do
68
- @company.label.should == 'Party'
69
- end
70
- end
71
-
72
- describe ".add_note" do
73
- it "should delegate to Highrise::Note.create with correct params" do
74
- Highrise::Note.should_receive(:create).with({:body=>"body", :subject_id=>1, :subject_type=>'Party'}).and_return(mock('note'))
75
- @company.add_note :body=>'body'
76
- end
77
- end
78
-
16
+ it { subject.label.should == 'Party' }
79
17
  end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Highrise::DealCategory do
4
+ subject { Highrise::DealCategory.new(:id => 1, :name => "Deal Category") }
5
+
6
+ it { should be_a_kind_of Highrise::Base }
7
+
8
+ it ".find_by_name" do
9
+ deal_category = Highrise::DealCategory.new(:id => 2, :name => "Another Deal Category")
10
+ Highrise::DealCategory.should_receive(:find).with(:all).and_return([deal_category, subject])
11
+ Highrise::DealCategory.find_by_name("Deal Category").should == subject
12
+ end
13
+ end
@@ -1,20 +1,23 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Highrise::Deal do
4
-
5
- before(:each) do
6
- @deal = Highrise::Deal.new(:id => 1)
7
- end
4
+ subject { Highrise::Deal.new(:id => 1) }
5
+
6
+ it { should be_a_kind_of Highrise::Subject }
8
7
 
9
- it "should be instance of Highrise::Subject" do
10
- @deal.kind_of?(Highrise::Subject).should be_true
8
+ it ".add_note" do
9
+ Highrise::Note.should_receive(:create).with({:body=>"body", :subject_id=>1, :subject_type=>'Deal'}).and_return(mock('note'))
10
+ subject.add_note :body=>'body'
11
11
  end
12
12
 
13
- describe ".add_note" do
14
- it "should delegate to Highrise::Note.create with correct params" do
15
- Highrise::Note.should_receive(:create).with({:body=>"body", :subject_id=>1, :subject_type=>'Deal'}).and_return(mock('note'))
16
- @deal.add_note :body=>'body'
13
+ describe ".update_status" do
14
+ it { expect { subject.update_status("invalid") }.to raise_error(ArgumentError) }
15
+
16
+ %w[pending won lost].each do |status|
17
+ it "updates status to #{status}" do
18
+ subject.should_receive(:put).with(:status, :status => {:name => status})
19
+ subject.update_status(status)
20
+ end
17
21
  end
18
22
  end
19
-
20
- end
23
+ end
@@ -1,25 +1,13 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Highrise::Email do
4
+ it { should be_a_kind_of Highrise::Base }
4
5
 
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
6
+ it_should_behave_like "a paginated class"
12
7
 
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
-
8
+ it "#comments" do
9
+ subject.should_receive(:email_id).and_return(1)
10
+ Highrise::Comment.should_receive(:find).with(:all, {:from=>"/emails/1/comments.xml"}).and_return("comments")
11
+ subject.comments.should == "comments"
21
12
  end
22
-
23
-
24
-
25
13
  end