hubspot-ruby 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +17 -5
- data/Rakefile +3 -13
- data/hubspot-ruby.gemspec +1 -1
- data/lib/hubspot-ruby.rb +3 -0
- data/lib/hubspot/company.rb +27 -0
- data/lib/hubspot/railtie.rb +0 -1
- data/lib/tasks/{properties.rake → hubspot.rake} +0 -0
- data/spec/lib/hubspot/blog_spec.rb +98 -64
- data/spec/lib/hubspot/company_properties_spec.rb +2 -2
- data/spec/lib/hubspot/company_spec.rb +27 -3
- data/spec/lib/hubspot/contact_list_spec.rb +2 -2
- data/spec/lib/hubspot/contact_properties_spec.rb +2 -2
- data/spec/lib/hubspot/contact_spec.rb +44 -26
- data/spec/lib/hubspot/deal_pipeline_spec.rb +85 -0
- data/spec/lib/hubspot/deal_properties_spec.rb +2 -2
- data/spec/lib/hubspot/form_spec.rb +1 -1
- data/spec/lib/hubspot/utils_spec.rb +4 -4
- data/spec/lib/tasks/hubspot_spec.rb +100 -0
- data/spec/spec_helper.rb +0 -14
- data/spec/support/cassette_helper.rb +1 -1
- data/spec/support/hubspot_api_helpers.rb +9 -0
- data/spec/support/rake.rb +46 -0
- data/spec/support/vcr.rb +15 -0
- metadata +9 -12
- data/spec/lib/tasks/properties_spec.rb +0 -90
- data/spec/live/companies_integration_spec.rb +0 -31
- data/spec/live/companies_properties_integration_spec.rb +0 -120
- data/spec/live/contacts_integration_spec.rb +0 -24
- data/spec/live/contacts_properties_integration_spec.rb +0 -120
- data/spec/live/deal_pipeline_spec.rb +0 -35
- data/spec/live/deal_properties_integration_spec.rb +0 -123
- data/spec/live/deals_integration_spec.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 371e11640e32bc9b2ba0bb54f3fbdfd3b84dcb5f4be69fd0d4e89163fdf544bb
|
4
|
+
data.tar.gz: 8f27026960fb8cc21c1f25c76dba6a26e4c33be192a635728a939284f52bea09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bed3f9319a9dc8db09aa7a050d3724055e502cece3a2b3400c19fb7125fb4a38c1cf5366deff6e22f7ff34fc9db69d380c29e4f18df69763d422941efcd47019
|
7
|
+
data.tar.gz: 64b3ddc122391b6d3fd44ec0cbe123ae92b306a632ebce366a9a43ee7acee0ef705e919c8d05661d6906e6d2454435352fc5b5c7422bd58d9320adc92ac5f4f7
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# HubSpot REST API wrappers for ruby
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/adimichele/hubspot-ruby.svg?branch=v0-stable)](https://travis-ci.org/adimichele/hubspot-ruby)
|
4
|
+
|
3
5
|
Wraps the HubSpot REST API for convenient access from ruby applications.
|
4
6
|
|
5
7
|
Documentation for the HubSpot REST API can be found here: https://developers.hubspot.com/docs/endpoints
|
@@ -132,13 +134,23 @@ Hubspot::Deal.create!(nil, [company.vid], [contact.vid], pipeline: 'default', de
|
|
132
134
|
|
133
135
|
### Testing
|
134
136
|
|
135
|
-
|
137
|
+
This project uses [VCR] to test interactions with the HubSpot API.
|
138
|
+
VCR records HTTP requests and replays them during future tests.
|
139
|
+
|
140
|
+
To run the tests, run `bundle exec rake` or `bundle exec rspec`.
|
141
|
+
|
142
|
+
By default, the VCR recording mode is set to `:none`, which allows recorded
|
143
|
+
requests to be re-played but raises for any new request. This prevents the test
|
144
|
+
suite from issuing unexpected HTTP requests.
|
136
145
|
|
137
|
-
|
138
|
-
|
139
|
-
|
146
|
+
To add a new test or update a VCR recording, run the test with the `VCR_RECORD`
|
147
|
+
environment variable:
|
148
|
+
|
149
|
+
```sh
|
150
|
+
VCR_RECORD=1 bundle exec rspec spec
|
151
|
+
```
|
140
152
|
|
141
|
-
|
153
|
+
[VCR]: https://github.com/vcr/vcr
|
142
154
|
|
143
155
|
## Disclaimer
|
144
156
|
|
data/Rakefile
CHANGED
@@ -14,20 +14,10 @@ require 'rake'
|
|
14
14
|
require 'rspec/core'
|
15
15
|
require 'rspec/core/rake_task'
|
16
16
|
|
17
|
-
|
18
|
-
RSpec::Core::RakeTask.new(:quick) do |spec|
|
19
|
-
spec.pattern = FileList['spec/**/*_spec.rb'].select{ |s| !s.match("/live/") }
|
20
|
-
end
|
21
|
-
RSpec::Core::RakeTask.new(:live) do |spec|
|
22
|
-
spec.pattern = FileList['spec/live/*_spec.rb']
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
|
-
spec.pattern = FileList['spec/**/*_spec.rb']
|
28
|
-
end
|
17
|
+
RSpec::Core::RakeTask.new(:spec)
|
29
18
|
|
30
|
-
|
19
|
+
desc "Default: runs the full test suite."
|
20
|
+
task default: :spec
|
31
21
|
|
32
22
|
require 'rdoc/task'
|
33
23
|
Rake::RDocTask.new do |rdoc|
|
data/hubspot-ruby.gemspec
CHANGED
data/lib/hubspot-ruby.rb
CHANGED
data/lib/hubspot/company.rb
CHANGED
@@ -40,6 +40,33 @@ module Hubspot
|
|
40
40
|
response['results'].map { |c| new(c) }
|
41
41
|
end
|
42
42
|
|
43
|
+
# Find all companies by created date (descending)
|
44
|
+
# recently_updated [boolean] (for querying all accounts by modified time)
|
45
|
+
# count [Integer] for pagination
|
46
|
+
# offset [Integer] for pagination
|
47
|
+
# {http://developers.hubspot.com/docs/methods/companies/get_companies_created}
|
48
|
+
# {http://developers.hubspot.com/docs/methods/companies/get_companies_modified}
|
49
|
+
# @return [Object], you can get:
|
50
|
+
# response.results for [Array]
|
51
|
+
# response.hasMore for [Boolean]
|
52
|
+
# response.offset for [Integer]
|
53
|
+
def all_with_offset(opts = {})
|
54
|
+
recently_updated = opts.delete(:recently_updated) { false }
|
55
|
+
|
56
|
+
path = if recently_updated
|
57
|
+
RECENTLY_MODIFIED_COMPANIES_PATH
|
58
|
+
else
|
59
|
+
RECENTLY_CREATED_COMPANIES_PATH
|
60
|
+
end
|
61
|
+
|
62
|
+
response = Hubspot::Connection.get_json(path, opts)
|
63
|
+
response_with_offset = {}
|
64
|
+
response_with_offset['results'] = response['results'].map { |c| new(c) }
|
65
|
+
response_with_offset['hasMore'] = response['hasMore']
|
66
|
+
response_with_offset['offset'] = response['offset']
|
67
|
+
response_with_offset
|
68
|
+
end
|
69
|
+
|
43
70
|
# Finds a list of companies by domain
|
44
71
|
# {https://developers.hubspot.com/docs/methods/companies/search_companies_by_domain}
|
45
72
|
# @param domain [String] company domain to search by
|
data/lib/hubspot/railtie.rb
CHANGED
File without changes
|
@@ -1,18 +1,9 @@
|
|
1
1
|
require 'timecop'
|
2
2
|
|
3
3
|
describe Hubspot do
|
4
|
-
let(:example_blog_hash) do
|
5
|
-
VCR.use_cassette("blog_list", record: :none) do
|
6
|
-
url = Hubspot::Connection.send(:generate_url, Hubspot::Blog::BLOG_LIST_PATH)
|
7
|
-
resp = HTTParty.get(url, format: :json)
|
8
|
-
resp.parsed_response["objects"].first
|
9
|
-
end
|
10
|
-
end
|
11
|
-
let(:created_range_params) { { created__gt: false, created__range: (Time.now..Time.now + 2.years) } }
|
12
|
-
|
13
4
|
before do
|
14
5
|
Hubspot.configure(hapikey: "demo")
|
15
|
-
Timecop.freeze(Time.
|
6
|
+
Timecop.freeze(Time.utc(2012, 'Oct', 10))
|
16
7
|
end
|
17
8
|
|
18
9
|
after do
|
@@ -20,97 +11,140 @@ describe Hubspot do
|
|
20
11
|
end
|
21
12
|
|
22
13
|
describe Hubspot::Blog do
|
23
|
-
|
24
14
|
describe ".list" do
|
25
|
-
|
26
|
-
|
15
|
+
it "returns a list of blogs" do
|
16
|
+
VCR.use_cassette("blog_list") do
|
17
|
+
result = Hubspot::Blog.list
|
27
18
|
|
28
|
-
|
29
|
-
|
19
|
+
assert_requested :get, hubspot_api_url("/content/api/v2/blogs?hapikey=demo")
|
20
|
+
expect(result).to be_kind_of(Array)
|
21
|
+
expect(result.first).to be_a(Hubspot::Blog)
|
22
|
+
end
|
30
23
|
end
|
31
24
|
end
|
32
25
|
|
33
26
|
describe ".find_by_id" do
|
34
|
-
|
27
|
+
it "retrieves a blog by id" do
|
28
|
+
VCR.use_cassette("blog_list") do
|
29
|
+
id = 351076997
|
30
|
+
result = Hubspot::Blog.find_by_id(id)
|
35
31
|
|
36
|
-
|
37
|
-
|
38
|
-
|
32
|
+
assert_requested :get, hubspot_api_url("/content/api/v2/blogs/#{id}?hapikey=demo")
|
33
|
+
expect(result).to be_a(Hubspot::Blog)
|
34
|
+
end
|
39
35
|
end
|
40
36
|
end
|
41
37
|
|
42
|
-
describe "#
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
38
|
+
describe "#[]" do
|
39
|
+
it "returns the value for the given key" do
|
40
|
+
data = {
|
41
|
+
"id" => 123,
|
42
|
+
"name" => "Demo",
|
43
|
+
}
|
44
|
+
blog = Hubspot::Blog.new(data)
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
expect(blog["id"]).to eq(data["id"])
|
47
|
+
expect(blog["name"]).to eq(data["name"])
|
48
|
+
end
|
51
49
|
|
52
|
-
|
50
|
+
context "when the value is unknown" do
|
51
|
+
it "returns nil" do
|
52
|
+
blog = Hubspot::Blog.new({})
|
53
53
|
|
54
|
-
|
55
|
-
pending 'This test does not pass reliably'
|
56
|
-
blog.posts.length.should be(14)
|
54
|
+
expect(blog["nope"]).to be_nil
|
57
55
|
end
|
56
|
+
end
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
describe "#posts" do
|
60
|
+
it "returns published blog posts created in the last 2 months" do
|
61
|
+
VCR.use_cassette("blog_posts/all_blog_posts") do
|
62
|
+
blog_id = 123
|
63
|
+
created_gt = timestamp_in_milliseconds(Time.now - 2.months)
|
64
|
+
blog = Hubspot::Blog.new({ "id" => blog_id })
|
65
|
+
|
66
|
+
result = blog.posts
|
62
67
|
|
63
|
-
|
64
|
-
|
68
|
+
assert_requested :get, hubspot_api_url("/content/api/v2/blog-posts?content_group_id=#{blog_id}&created__gt=#{created_gt}&hapikey=demo&order_by=-created&state=PUBLISHED")
|
69
|
+
expect(result).to be_kind_of(Array)
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
+
it "includes given parameters in the request" do
|
74
|
+
VCR.use_cassette("blog_posts/filter_blog_posts") do
|
75
|
+
blog_id = 123
|
76
|
+
created_gt = timestamp_in_milliseconds(Time.now - 2.months)
|
77
|
+
blog = Hubspot::Blog.new({ "id" => 123 })
|
78
|
+
|
79
|
+
result = blog.posts({ state: "DRAFT" })
|
73
80
|
|
74
|
-
|
75
|
-
|
76
|
-
created_timestamps = blog.posts({order_by: '+created'}.merge(created_range_params)).map { |post| post['created'] }
|
77
|
-
expect(created_timestamps.sort).to eq(created_timestamps)
|
81
|
+
assert_requested :get, hubspot_api_url("/content/api/v2/blog-posts?content_group_id=#{blog_id}&created__gt=#{created_gt}&hapikey=demo&order_by=-created&state=DRAFT")
|
82
|
+
expect(result).to be_kind_of(Array)
|
78
83
|
end
|
79
84
|
end
|
80
85
|
|
81
|
-
it "
|
82
|
-
|
83
|
-
|
86
|
+
it "raises when given an unknown state" do
|
87
|
+
blog = Hubspot::Blog.new({})
|
88
|
+
|
89
|
+
expect {
|
90
|
+
blog.posts({ state: "unknown" })
|
91
|
+
}.to raise_error(Hubspot::InvalidParams, "State parameter was invalid")
|
84
92
|
end
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
88
96
|
describe Hubspot::BlogPost do
|
89
|
-
|
97
|
+
describe "#created_at" do
|
98
|
+
it "returns the created timestamp as a Time" do
|
99
|
+
timestamp = timestamp_in_milliseconds(Time.now)
|
100
|
+
blog_post = Hubspot::BlogPost.new({ "created" => timestamp })
|
90
101
|
|
91
|
-
|
92
|
-
VCR.use_cassette("one_month_blog_posts_filter_state", record: :none) do
|
93
|
-
blog = Hubspot::Blog.new(example_blog_hash)
|
94
|
-
blog.posts(created_range_params).first
|
102
|
+
expect(blog_post.created_at).to eq(Time.at(timestamp/1000))
|
95
103
|
end
|
96
104
|
end
|
97
105
|
|
98
|
-
|
99
|
-
|
100
|
-
|
106
|
+
describe ".find_by_blog_post_id" do
|
107
|
+
it "retrieves a blog post by id" do
|
108
|
+
VCR.use_cassette "blog_posts" do
|
109
|
+
blog_post_id = 422192866
|
101
110
|
|
102
|
-
|
103
|
-
|
104
|
-
|
111
|
+
result = Hubspot::BlogPost.find_by_blog_post_id(blog_post_id)
|
112
|
+
|
113
|
+
assert_requested :get, hubspot_api_url("/content/api/v2/blog-posts/#{blog_post_id}?hapikey=demo")
|
114
|
+
expect(result).to be_a(Hubspot::BlogPost)
|
115
|
+
end
|
116
|
+
end
|
105
117
|
end
|
106
118
|
|
107
|
-
|
108
|
-
|
109
|
-
|
119
|
+
describe "#topics" do
|
120
|
+
it "returns the list of topics" do
|
121
|
+
VCR.use_cassette "blog_posts" do
|
122
|
+
blog_post = Hubspot::BlogPost.find_by_blog_post_id(422192866)
|
123
|
+
|
124
|
+
topics = blog_post.topics
|
125
|
+
|
126
|
+
expect(topics).to be_kind_of(Array)
|
127
|
+
expect(topics.first).to be_a(Hubspot::Topic)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "when the blog post does not have topics" do
|
132
|
+
it "returns an empty list" do
|
133
|
+
blog_post = Hubspot::BlogPost.new({ "topic_ids" => [] })
|
110
134
|
|
111
|
-
|
112
|
-
|
135
|
+
topics = blog_post.topics
|
136
|
+
|
137
|
+
expect(topics).to be_empty
|
138
|
+
end
|
113
139
|
end
|
114
140
|
end
|
115
141
|
end
|
142
|
+
|
143
|
+
def hubspot_api_url(path)
|
144
|
+
URI.join(Hubspot::Config.base_url, path)
|
145
|
+
end
|
146
|
+
|
147
|
+
def timestamp_in_milliseconds(time)
|
148
|
+
time.to_i * 1000
|
149
|
+
end
|
116
150
|
end
|
@@ -15,13 +15,13 @@ describe Hubspot::CompanyProperties do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:example_groups) do
|
18
|
-
VCR.use_cassette('groups_example'
|
18
|
+
VCR.use_cassette('groups_example') do
|
19
19
|
HTTParty.get('https://api.hubapi.com/companies/v2/groups?hapikey=demo').parsed_response
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
let(:example_properties) do
|
24
|
-
VCR.use_cassette('properties_example'
|
24
|
+
VCR.use_cassette('properties_example') do
|
25
25
|
HTTParty.get('https://api.hubapi.com/companies/v2/properties?hapikey=demo').parsed_response
|
26
26
|
end
|
27
27
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
describe Hubspot::Contact do
|
2
2
|
let(:example_company_hash) do
|
3
|
-
VCR.use_cassette("company_example"
|
3
|
+
VCR.use_cassette("company_example") do
|
4
4
|
HTTParty.get("https://api.hubapi.com/companies/v2/companies/21827084?hapikey=demo").parsed_response
|
5
5
|
end
|
6
6
|
end
|
7
7
|
let(:company_with_contacts_hash) do
|
8
|
-
VCR.use_cassette("company_with_contacts"
|
8
|
+
VCR.use_cassette("company_with_contacts") do
|
9
9
|
HTTParty.get("https://api.hubapi.com/companies/v2/companies/115200636?hapikey=demo").parsed_response
|
10
10
|
end
|
11
11
|
end
|
@@ -132,10 +132,34 @@ describe Hubspot::Contact do
|
|
132
132
|
expect(last['name']).to eql 'Xge5rbdt2zm'
|
133
133
|
end
|
134
134
|
|
135
|
-
it 'must filter only 2
|
135
|
+
it 'must filter only 2 companies' do
|
136
136
|
copmanies = Hubspot::Company.all(count: 2)
|
137
137
|
expect(copmanies.size).to eql 2
|
138
138
|
end
|
139
|
+
|
140
|
+
context 'all_with_offset' do
|
141
|
+
it 'should return companies with offset and hasMore' do
|
142
|
+
response = Hubspot::Company.all_with_offset
|
143
|
+
expect(response['results'].size).to eq(20)
|
144
|
+
|
145
|
+
first = response['results'].first
|
146
|
+
last = response['results'].last
|
147
|
+
|
148
|
+
expect(first).to be_a Hubspot::Company
|
149
|
+
expect(first.vid).to eq(42866817)
|
150
|
+
expect(first['name']).to eql 'name'
|
151
|
+
expect(last).to be_a Hubspot::Company
|
152
|
+
expect(last.vid).to eql 42861017
|
153
|
+
expect(last['name']).to eql 'Xge5rbdt2zm'
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'must filter only 2 companies' do
|
157
|
+
response = Hubspot::Company.all_with_offset(count: 2)
|
158
|
+
expect(response['results'].size).to eq(2)
|
159
|
+
expect(response['hasMore']).to be_truthy
|
160
|
+
expect(response['offset']).to eq(2)
|
161
|
+
end
|
162
|
+
end
|
139
163
|
end
|
140
164
|
|
141
165
|
context 'recent companies' do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
describe Hubspot::ContactList do
|
2
2
|
let(:example_contact_list_hash) do
|
3
|
-
VCR.use_cassette("contact_list_example"
|
3
|
+
VCR.use_cassette("contact_list_example") do
|
4
4
|
HTTParty.get("https://api.hubapi.com/contacts/v1/lists/1?hapikey=demo").parsed_response
|
5
5
|
end
|
6
6
|
end
|
@@ -9,7 +9,7 @@ describe Hubspot::ContactList do
|
|
9
9
|
let(:dynamic_list) { Hubspot::ContactList.all(dynamic: true, count: 1).first }
|
10
10
|
|
11
11
|
let(:example_contact_hash) do
|
12
|
-
VCR.use_cassette("contact_example"
|
12
|
+
VCR.use_cassette("contact_example") do
|
13
13
|
HTTParty.get("https://api.hubapi.com/contacts/v1/contact/email/testingapis@hubspot.com/profile?hapikey=demo").parsed_response
|
14
14
|
end
|
15
15
|
end
|
@@ -15,13 +15,13 @@ describe Hubspot::ContactProperties do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:example_groups) do
|
18
|
-
VCR.use_cassette('groups_example'
|
18
|
+
VCR.use_cassette('groups_example') do
|
19
19
|
HTTParty.get('https://api.hubapi.com/contacts/v2/groups?hapikey=demo').parsed_response
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
let(:example_properties) do
|
24
|
-
VCR.use_cassette('properties_example'
|
24
|
+
VCR.use_cassette('properties_example') do
|
25
25
|
HTTParty.get('https://api.hubapi.com/contacts/v2/properties?hapikey=demo').parsed_response
|
26
26
|
end
|
27
27
|
end
|