highrise 1.0.2
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.
- data/README.mkdn +94 -0
- data/VERSION.yml +3 -0
- data/lib/cachable.rb +88 -0
- data/lib/highrise.rb +18 -0
- data/lib/highrise/base.rb +7 -0
- data/lib/highrise/comment.rb +4 -0
- data/lib/highrise/company.rb +14 -0
- data/lib/highrise/email.rb +9 -0
- data/lib/highrise/group.rb +4 -0
- data/lib/highrise/kase.rb +8 -0
- data/lib/highrise/membership.rb +4 -0
- data/lib/highrise/note.rb +9 -0
- data/lib/highrise/pagination.rb +29 -0
- data/lib/highrise/person.rb +26 -0
- data/lib/highrise/subject.rb +15 -0
- data/lib/highrise/tag.rb +18 -0
- data/lib/highrise/taggable.rb +17 -0
- data/lib/highrise/task.rb +11 -0
- data/lib/highrise/user.rb +7 -0
- data/spec/cachable_spec.rb +66 -0
- data/spec/highrise/base_spec.rb +13 -0
- data/spec/highrise/comment_spec.rb +14 -0
- data/spec/highrise/company_spec.rb +68 -0
- data/spec/highrise/email_spec.rb +25 -0
- data/spec/highrise/group_spec.rb +14 -0
- data/spec/highrise/kase_spec.rb +25 -0
- data/spec/highrise/membership_spec.rb +14 -0
- data/spec/highrise/note_spec.rb +23 -0
- data/spec/highrise/pagination_spec.rb +10 -0
- data/spec/highrise/person_spec.rb +81 -0
- data/spec/highrise/subject_spec.rb +43 -0
- data/spec/highrise/tag_spec.rb +24 -0
- data/spec/highrise/task_spec.rb +23 -0
- data/spec/highrise/user_spec.rb +30 -0
- data/spec/spec.opts +8 -0
- data/spec/spec_helper.rb +20 -0
- metadata +118 -0
data/README.mkdn
ADDED
@@ -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
|
data/VERSION.yml
ADDED
data/lib/cachable.rb
ADDED
@@ -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
|
data/lib/highrise.rb
ADDED
@@ -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,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,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
|
data/lib/highrise/tag.rb
ADDED
@@ -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,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
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -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
|
+
|