hubspot-api-ruby 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/Gemfile +3 -0
  4. data/Guardfile +9 -0
  5. data/LICENSE.txt +18 -0
  6. data/README.md +295 -0
  7. data/RELEASING.md +6 -0
  8. data/Rakefile +32 -0
  9. data/hubspot-api-ruby.gemspec +42 -0
  10. data/lib/hubspot-api-ruby.rb +39 -0
  11. data/lib/hubspot/blog.rb +98 -0
  12. data/lib/hubspot/collection.rb +41 -0
  13. data/lib/hubspot/company.rb +160 -0
  14. data/lib/hubspot/company_properties.rb +59 -0
  15. data/lib/hubspot/config.rb +63 -0
  16. data/lib/hubspot/connection.rb +152 -0
  17. data/lib/hubspot/contact.rb +110 -0
  18. data/lib/hubspot/contact_list.rb +129 -0
  19. data/lib/hubspot/contact_properties.rb +59 -0
  20. data/lib/hubspot/deal.rb +173 -0
  21. data/lib/hubspot/deal_pipeline.rb +58 -0
  22. data/lib/hubspot/deal_properties.rb +59 -0
  23. data/lib/hubspot/deprecator.rb +7 -0
  24. data/lib/hubspot/engagement.rb +222 -0
  25. data/lib/hubspot/event.rb +21 -0
  26. data/lib/hubspot/exceptions.rb +18 -0
  27. data/lib/hubspot/file.rb +38 -0
  28. data/lib/hubspot/form.rb +95 -0
  29. data/lib/hubspot/oauth.rb +50 -0
  30. data/lib/hubspot/owner.rb +57 -0
  31. data/lib/hubspot/paged_collection.rb +35 -0
  32. data/lib/hubspot/properties.rb +123 -0
  33. data/lib/hubspot/railtie.rb +10 -0
  34. data/lib/hubspot/resource.rb +270 -0
  35. data/lib/hubspot/subscription.rb +37 -0
  36. data/lib/hubspot/topic.rb +37 -0
  37. data/lib/hubspot/utils.rb +127 -0
  38. data/lib/tasks/hubspot.rake +53 -0
  39. data/spec/factories/companies.rb +9 -0
  40. data/spec/factories/contacts.rb +10 -0
  41. data/spec/lib/hubspot-ruby_spec.rb +12 -0
  42. data/spec/lib/hubspot/blog_spec.rb +150 -0
  43. data/spec/lib/hubspot/company_properties_spec.rb +410 -0
  44. data/spec/lib/hubspot/company_spec.rb +340 -0
  45. data/spec/lib/hubspot/config_spec.rb +87 -0
  46. data/spec/lib/hubspot/connection_spec.rb +214 -0
  47. data/spec/lib/hubspot/contact_list_spec.rb +301 -0
  48. data/spec/lib/hubspot/contact_properties_spec.rb +245 -0
  49. data/spec/lib/hubspot/contact_spec.rb +223 -0
  50. data/spec/lib/hubspot/deal_pipeline_spec.rb +85 -0
  51. data/spec/lib/hubspot/deal_properties_spec.rb +262 -0
  52. data/spec/lib/hubspot/deal_spec.rb +185 -0
  53. data/spec/lib/hubspot/deprecator_spec.rb +15 -0
  54. data/spec/lib/hubspot/engagement_spec.rb +177 -0
  55. data/spec/lib/hubspot/event_spec.rb +33 -0
  56. data/spec/lib/hubspot/file_spec.rb +38 -0
  57. data/spec/lib/hubspot/form_spec.rb +189 -0
  58. data/spec/lib/hubspot/owner_spec.rb +56 -0
  59. data/spec/lib/hubspot/properties_spec.rb +45 -0
  60. data/spec/lib/hubspot/resource_spec.rb +54 -0
  61. data/spec/lib/hubspot/topic_spec.rb +23 -0
  62. data/spec/lib/hubspot/utils_spec.rb +164 -0
  63. data/spec/lib/tasks/hubspot_spec.rb +119 -0
  64. data/spec/shared_examples/saveable_resource.rb +45 -0
  65. data/spec/shared_examples/updateable_resource.rb +87 -0
  66. data/spec/spec_helper.rb +44 -0
  67. data/spec/support/capture_output.rb +21 -0
  68. data/spec/support/cassette_helper.rb +19 -0
  69. data/spec/support/hubspot_api_helpers.rb +13 -0
  70. data/spec/support/rake.rb +46 -0
  71. data/spec/support/tests_helper.rb +17 -0
  72. data/spec/support/vcr.rb +16 -0
  73. metadata +369 -0
@@ -0,0 +1,223 @@
1
+ RSpec.describe Hubspot::Contact do
2
+
3
+ before{ Hubspot.configure(hapikey: 'demo') }
4
+
5
+ it_behaves_like "a saveable resource", :contact do
6
+ def set_property(contact)
7
+ contact.firstname = "foobar"
8
+ end
9
+ end
10
+
11
+ it_behaves_like "an updateable resource", :contact do
12
+ let(:changed_properties) { { firstname: "foobar" } }
13
+ let(:overlapping_properties) { { firstname: "asdf", lastname: "qwer" } }
14
+ end
15
+
16
+ describe '.find' do
17
+ context 'with a valid ID' do
18
+ cassette
19
+
20
+ let(:company) { create :company }
21
+ let(:contact) { create :contact, associatedcompanyid: company.id }
22
+ subject { described_class.find contact.id }
23
+
24
+ it 'finds the contact' do
25
+ expect(subject).to be_a(described_class)
26
+ expect(subject.id).to eq(contact.id)
27
+ end
28
+ end
29
+
30
+ context 'with an invalid ID' do
31
+ cassette
32
+
33
+ subject { described_class.find 0 }
34
+
35
+ it 'raises an error' do
36
+ expect {
37
+ subject
38
+ }.to raise_error(Hubspot::RequestError, /contact does not exist/)
39
+ end
40
+ end
41
+ end
42
+
43
+ describe '.create' do
44
+ context 'without properties' do
45
+ cassette
46
+
47
+ let(:email) { Faker::Internet.safe_email("#{(0..3).map { (65 + rand(26)).chr }.join}#{Time.new.to_i.to_s[-5..-1]}") }
48
+ subject { described_class.create email }
49
+
50
+ it 'creates a new contact' do
51
+ expect(subject).to be_a(described_class)
52
+ expect(subject.id).not_to be_nil
53
+ end
54
+ end
55
+
56
+ context 'with properties' do
57
+ cassette
58
+
59
+ let(:email) { Faker::Internet.safe_email("#{(0..3).map { (65 + rand(26)).chr }.join}#{Time.new.to_i.to_s[-5..-1]}") }
60
+ let(:firstname) { "Allison" }
61
+ let(:properties) { { firstname: firstname } }
62
+
63
+ subject { described_class.create email, properties }
64
+
65
+ it 'creates a new contact' do
66
+ expect(subject).to be_a(described_class)
67
+ expect(subject.id).not_to be_nil
68
+ end
69
+
70
+ it 'has the property set' do
71
+ expect(subject.firstname).to eq(firstname)
72
+ end
73
+
74
+ it 'is persisted' do
75
+ expect(subject).to be_persisted
76
+ end
77
+ end
78
+
79
+ context 'with an existing email address' do
80
+ cassette
81
+
82
+ let(:contact) { create :contact }
83
+ let(:email) { contact.email }
84
+
85
+ subject { described_class.create email }
86
+
87
+ it 'raises an error' do
88
+ expect {
89
+ subject
90
+ }.to raise_error(Hubspot::RequestError)
91
+ end
92
+ end
93
+
94
+ context 'with an invalid email address' do
95
+ cassette
96
+
97
+ let(:email) { 'an_invalid_email' }
98
+
99
+ subject { described_class.create email }
100
+
101
+ it 'raises an error' do
102
+ expect {
103
+ subject
104
+ }.to raise_error(Hubspot::RequestError)
105
+ end
106
+ end
107
+ end
108
+
109
+ describe '.find_by_email' do
110
+ cassette
111
+
112
+ let(:contact) { create :contact }
113
+
114
+ subject { described_class.find_by_email contact.email }
115
+
116
+ it 'finds the contact' do
117
+ expect(subject).to be_a(described_class)
118
+ expect(subject.id).to eq(contact.id)
119
+ end
120
+
121
+ it 'is persisted' do
122
+ expect(subject).to be_persisted
123
+ end
124
+ end
125
+
126
+ describe '.find_by_user_token' do
127
+ cassette
128
+
129
+ let(:contact) { create :contact }
130
+ subject { described_class.find_by_user_token contact.utk }
131
+
132
+ it 'finds the contact' do
133
+ skip 'need a contact with a user token'
134
+ expect(subject).to be_a(described_class)
135
+ expect(subject.id).to eq(contact.id)
136
+ end
137
+ end
138
+
139
+ describe '.search' do
140
+ cassette
141
+
142
+ context 'when the query returns contacts' do
143
+ subject { described_class.search 'com' }
144
+
145
+ it 'has contacts' do
146
+ expect(subject).not_to be_empty
147
+ expect(subject.first).to be_a(described_class)
148
+ end
149
+ end
150
+
151
+ context 'when the query returns no contacts' do
152
+ subject { described_class.search '123xyz' }
153
+
154
+ it 'has no contacts' do
155
+ expect(subject).to be_empty
156
+ end
157
+
158
+ it 'does not have more' do
159
+ expect(subject.more?).to be_falsey
160
+ end
161
+
162
+ it 'does not have a next page' do
163
+ expect(subject.next_page?).to be_falsey
164
+ end
165
+ end
166
+ end
167
+
168
+ describe '.merge' do
169
+ context 'with valid contact ids' do
170
+ cassette
171
+
172
+ let!(:contact1) { create :contact }
173
+ let!(:contact2) { create :contact }
174
+
175
+ subject { described_class.merge contact1.id, contact2.id }
176
+
177
+ it 'succeeds' do
178
+ expect(subject).to be_truthy
179
+ end
180
+ end
181
+
182
+ context 'with invalid contact ids' do
183
+ cassette
184
+
185
+ subject { described_class.merge 1, 2 }
186
+
187
+ it 'raises an error' do
188
+ expect {
189
+ subject
190
+ }.to raise_error(Hubspot::RequestError)
191
+ end
192
+ end
193
+ end
194
+
195
+ describe '#merge' do
196
+ context 'with a valid contact' do
197
+ cassette
198
+
199
+ let!(:contact1) { create :contact }
200
+ let!(:contact2) { create :contact }
201
+
202
+ subject { contact1.merge(contact2) }
203
+
204
+ it 'succeeds' do
205
+ expect(subject).to be_truthy
206
+ end
207
+ end
208
+
209
+ context 'with an invalid contact' do
210
+ cassette
211
+
212
+ let!(:contact1) { create :contact }
213
+
214
+ subject { contact1.merge(1) }
215
+
216
+ it 'raises an error' do
217
+ expect {
218
+ subject
219
+ }.to raise_error(Hubspot::RequestError)
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,85 @@
1
+ RSpec.describe Hubspot::DealPipeline do
2
+ before do
3
+ Hubspot.configure hapikey: 'demo'
4
+ end
5
+
6
+ describe ".find" do
7
+ it "retrieves a record by id" do
8
+ VCR.use_cassette("find_deal_pipeline") do
9
+ deal_pipeline = Hubspot::DealPipeline.create!(label: "New Pipeline")
10
+ id = deal_pipeline.pipeline_id
11
+
12
+ result = Hubspot::DealPipeline.find(deal_pipeline.pipeline_id)
13
+
14
+ assert_requested :get, hubspot_api_url("/deals/v1/pipelines/#{id}")
15
+ expect(result).to be_a(Hubspot::DealPipeline)
16
+
17
+ deal_pipeline.destroy!
18
+ end
19
+ end
20
+ end
21
+
22
+ describe ".all" do
23
+ it "returns a list" do
24
+ VCR.use_cassette("all_deal_pipelines") do
25
+ deal_pipeline = Hubspot::DealPipeline.create!(label: "New Pipeline")
26
+
27
+ results = Hubspot::DealPipeline.all
28
+
29
+ assert_requested :get, hubspot_api_url("/deals/v1/pipelines")
30
+ expect(results).to be_kind_of(Array)
31
+ expect(results.first).to be_a(Hubspot::DealPipeline)
32
+
33
+ deal_pipeline.destroy!
34
+ end
35
+ end
36
+ end
37
+
38
+ describe ".create!" do
39
+ it "creates a new record" do
40
+ VCR.use_cassette("create_deal_pipeline") do
41
+ result = Hubspot::DealPipeline.create!(label: "New Pipeline")
42
+
43
+ assert_requested :post, hubspot_api_url("/deals/v1/pipelines")
44
+ expect(result).to be_a(Hubspot::DealPipeline)
45
+
46
+ result.destroy!
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "#destroy!" do
52
+ it "deletes the record" do
53
+ VCR.use_cassette("delete_deal_pipeline") do
54
+ deal_pipeline = Hubspot::DealPipeline.create!(label: "New Pipeline")
55
+ id = deal_pipeline.pipeline_id
56
+
57
+ result = deal_pipeline.destroy!
58
+
59
+ assert_requested :delete, hubspot_api_url("/deals/v1/pipelines/#{id}")
60
+ expect(result).to be_a(HTTParty::Response)
61
+ end
62
+ end
63
+ end
64
+
65
+ describe "#[]" do
66
+ it "returns the stage at the specified index" do
67
+ data = {
68
+ "stages" => [
69
+ {"active": true, "label": "New Lead"},
70
+ {"active": true, "label": "Proposal"},
71
+ ],
72
+ }
73
+
74
+ deal_pipeline = Hubspot::DealPipeline.new(data)
75
+
76
+ result = deal_pipeline[0]
77
+
78
+ expect(result).to eq(data["stages"][0])
79
+ end
80
+ end
81
+
82
+ def hubspot_api_url(path)
83
+ URI.join(Hubspot::Config.base_url, path, "?hapikey=demo")
84
+ end
85
+ end
@@ -0,0 +1,262 @@
1
+ describe Hubspot::DealProperties do
2
+ describe '.add_default_parameters' do
3
+ let(:opts) { {} }
4
+ subject { Hubspot::DealProperties.add_default_parameters(opts) }
5
+ context 'default parameters' do
6
+ context 'without property parameter' do
7
+ its([:property]) { should == 'email' }
8
+ end
9
+
10
+ context 'with property parameter' do
11
+ let(:opts) { {property: 'dealname' } }
12
+ its([:property]) { should == 'dealname'}
13
+ end
14
+ end
15
+ end
16
+
17
+ let(:example_groups) do
18
+ VCR.use_cassette('deal_groups_example') do
19
+ HTTParty.get('https://api.hubapi.com/deals/v1/groups?hapikey=demo').parsed_response
20
+ end
21
+ end
22
+
23
+ let(:example_properties) do
24
+ VCR.use_cassette('deal_properties_example') do
25
+ HTTParty.get('https://api.hubapi.com/deals/v1/properties?hapikey=demo').parsed_response
26
+ end
27
+ end
28
+
29
+ before { Hubspot.configure(hapikey: 'demo') }
30
+
31
+ describe 'Properties' do
32
+ describe '.all' do
33
+ context 'with no filter' do
34
+ cassette 'deal_all_properties'
35
+
36
+ it 'should return all properties' do
37
+ expect(Hubspot::DealProperties.all).to eql(example_properties)
38
+ end
39
+ end
40
+
41
+ let(:groups) { %w(calltrackinginfo emailinformation) }
42
+
43
+ context 'with included groups' do
44
+ cassette 'deal_properties_in_groups'
45
+
46
+ it 'should return properties for the specified group[s]' do
47
+ response = Hubspot::DealProperties.all({}, { include: groups })
48
+ response.each { |p| expect(groups.include?(p['groupName'])).to be true }
49
+ end
50
+ end
51
+
52
+ context 'with excluded groups' do
53
+ cassette 'deal_properties_not_in_groups'
54
+
55
+ it 'should return properties for the non-specified group[s]' do
56
+ response = Hubspot::DealProperties.all({}, { exclude: groups })
57
+ response.each { |p| expect(groups.include?(p['groupName'])).to be false }
58
+ end
59
+ end
60
+ end
61
+
62
+ let(:params) { {
63
+ 'name' => 'my_new_property',
64
+ 'label' => 'This is my new property',
65
+ 'description' => 'How much money do you have?',
66
+ 'groupName' => 'dealinformation',
67
+ 'type' => 'string',
68
+ 'fieldType' => 'text',
69
+ 'hidden' => false,
70
+ 'options' => [{
71
+ 'description' => '',
72
+ 'value' => 'Over $50K',
73
+ 'readOnly' => false,
74
+ 'label' => 'Over $50K',
75
+ 'displayOrder' => 0,
76
+ 'hidden' => false,
77
+ 'doubleData' => 0.0
78
+ },
79
+ {
80
+ 'description' => '',
81
+ 'value' => 'Under $50K',
82
+ 'readOnly' => false,
83
+ 'label' => 'Under $50K',
84
+ 'displayOrder' => 1,
85
+ 'hidden' => false,
86
+ 'doubleData' => 0.0
87
+ }],
88
+ 'deleted' => false,
89
+ 'displayOrder' => 0,
90
+ 'formField' => true,
91
+ 'readOnlyValue' => false,
92
+ 'readOnlyDefinition' => false,
93
+ 'mutableDefinitionNotDeletable' => false,
94
+ 'calculated' => false,
95
+ 'externalOptions' => false,
96
+ 'displayMode' => 'current_value'
97
+ } }
98
+
99
+ describe '.create!' do
100
+ context 'with no valid parameters' do
101
+ cassette 'deal_fail_to_create_property'
102
+
103
+ it 'should return nil' do
104
+ expect(Hubspot::DealProperties.create!({})).to be(nil)
105
+ end
106
+ end
107
+
108
+ context 'with all valid parameters' do
109
+ cassette 'deal_create_property'
110
+
111
+ it 'should return the valid parameters' do
112
+ response = Hubspot::DealProperties.create!(params)
113
+ expect(Hubspot::DealProperties.same?(params, response)).to be true
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '.update!' do
119
+ context 'with no valid parameters' do
120
+
121
+ it 'should return nil ' do
122
+ expect(Hubspot::DealProperties.update!(params['name'], {})).to be(nil)
123
+ end
124
+ end
125
+
126
+ context 'with mixed parameters' do
127
+ cassette 'deal_update_property'
128
+
129
+ it 'should return the valid parameters' do
130
+ params['description'] = 'What is their favorite flavor?'
131
+
132
+ response = Hubspot::DealProperties.update!(params['name'], params)
133
+ expect(Hubspot::DealProperties.same?(response, params)).to be true
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '.delete!' do
139
+ let(:name) { params['name'] }
140
+
141
+ context 'with existing property' do
142
+ cassette 'deal_delete_property'
143
+
144
+ it 'should return nil' do
145
+ expect(Hubspot::DealProperties.delete!(name)).to eq(nil)
146
+ end
147
+ end
148
+
149
+ context 'with non-existent property' do
150
+ cassette 'deal_delete_non_property'
151
+
152
+ it 'should raise an error' do
153
+ expect { Hubspot::DealProperties.delete!(name) }.to raise_error(Hubspot::RequestError)
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ describe 'Groups' do
160
+ describe '.groups' do
161
+ context 'with no filter' do
162
+ cassette 'deal_all_groups'
163
+
164
+ it 'should return all groups' do
165
+ expect(Hubspot::DealProperties.groups).to eql(example_groups)
166
+ end
167
+ end
168
+
169
+ let(:groups) { %w(calltrackinginfo emailinformation) }
170
+
171
+ context 'with included groups' do
172
+ cassette 'deal_groups_included'
173
+
174
+ it 'should return the specified groups' do
175
+ response = Hubspot::DealProperties.groups({}, { include: groups })
176
+ response.each { |p| expect(groups.include?(p['name'])).to be true }
177
+ end
178
+ end
179
+
180
+ context 'with excluded groups' do
181
+ cassette 'deal_groups_not_excluded'
182
+
183
+ it 'should return groups that were not excluded' do
184
+ response = Hubspot::DealProperties.groups({}, { exclude: groups })
185
+ response.each { |p| expect(groups.include?(p['name'])).to be false }
186
+ end
187
+ end
188
+ end
189
+
190
+ let(:params) { { 'name' => 'ff_group1', 'displayName' => 'Test Group One', 'displayOrder' => 100, 'badParam' => 99 } }
191
+
192
+ describe '.create_group!' do
193
+ context 'with no valid parameters' do
194
+ it 'should return nil' do
195
+ expect(Hubspot::DealProperties.create_group!({})).to be(nil)
196
+ end
197
+ end
198
+
199
+ context 'with mixed parameters' do
200
+ cassette 'deal_create_group'
201
+
202
+ it 'should return the valid parameters' do
203
+ response = Hubspot::DealProperties.create_group!(params)
204
+ expect(Hubspot::DealProperties.same?(response, params)).to be true
205
+ end
206
+ end
207
+
208
+ context 'with some valid parameters' do
209
+ cassette 'deal_create_group_some_params'
210
+
211
+ let(:sub_params) { params.select { |k, _| k != 'displayName' } }
212
+
213
+ it 'should return the valid parameters' do
214
+ params['name'] = 'ff_group234'
215
+ response = Hubspot::DealProperties.create_group!(sub_params)
216
+ expect(Hubspot::DealProperties.same?(response, sub_params)).to be true
217
+ end
218
+ end
219
+ end
220
+
221
+ describe '.update_group!' do
222
+ context 'with no valid parameters' do
223
+
224
+ it 'should return nil ' do
225
+ expect(Hubspot::DealProperties.update_group!(params['name'], {})).to be(nil)
226
+ end
227
+ end
228
+
229
+ context 'with mixed parameters' do
230
+ cassette 'deal_update_group'
231
+
232
+ it 'should return the valid parameters' do
233
+ params['displayName'] = 'Test Group OneA'
234
+
235
+ response = Hubspot::DealProperties.update_group!(params['name'], params)
236
+ expect(Hubspot::DealProperties.same?(response, params)).to be true
237
+ end
238
+ end
239
+
240
+ end
241
+
242
+ describe '.delete_group!' do
243
+ let(:name) { params['name'] }
244
+
245
+ context 'with existing group' do
246
+ cassette 'deal_delete_group'
247
+
248
+ it 'should return nil' do
249
+ expect(Hubspot::DealProperties.delete_group!(name)).to eq(nil)
250
+ end
251
+ end
252
+
253
+ context 'with non-existent group' do
254
+ cassette 'deal_delete_non_group'
255
+
256
+ it 'should raise an error' do
257
+ expect { Hubspot::DealProperties.delete_group!(name) }.to raise_error(Hubspot::RequestError)
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end