hubspot-ruby 0.5.0 → 0.6.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.
- 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
@@ -1,6 +1,6 @@
|
|
1
|
-
describe Hubspot::Contact do
|
1
|
+
RSpec.describe Hubspot::Contact do
|
2
2
|
let(:example_contact_hash) do
|
3
|
-
VCR.use_cassette('contact_example'
|
3
|
+
VCR.use_cassette('contact_example') do
|
4
4
|
HTTParty.get('https://api.hubapi.com/contacts/v1/contact/email/testingapis@hubspot.com/profile?hapikey=demo').parsed_response
|
5
5
|
end
|
6
6
|
end
|
@@ -52,34 +52,52 @@ describe Hubspot::Contact do
|
|
52
52
|
end
|
53
53
|
|
54
54
|
describe '.createOrUpdate' do
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
context "when the contact already exists" do
|
56
|
+
it "updates the contact" do
|
57
|
+
VCR.use_cassette("contacts/update_contact") do
|
58
|
+
existing_contact = Hubspot::Contact.create!("contact@example.com")
|
59
|
+
email = existing_contact.email
|
60
|
+
new_email = "new_email@example.com"
|
61
|
+
params = { email: new_email }
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
contact = Hubspot::Contact.createOrUpdate(email, params)
|
64
|
+
|
65
|
+
assert_requested :post, hubspot_api_url("/contacts/v1/contact/createOrUpdate/email/#{email}?hapikey=demo")
|
66
|
+
expect(contact).to be_a(Hubspot::Contact)
|
67
|
+
expect(contact.email).to eq(new_email)
|
68
|
+
|
69
|
+
contact.destroy!
|
70
|
+
end
|
69
71
|
end
|
70
72
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
|
74
|
+
context "when the contact does not exist" do
|
75
|
+
it "creates the contact" do
|
76
|
+
VCR.use_cassette("contacts/create_contact") do
|
77
|
+
email = "new_contact@example.com"
|
78
|
+
params = { firstname: "Leslie", lastname: "Knope" }
|
79
|
+
|
80
|
+
contact = Hubspot::Contact.createOrUpdate(email, params)
|
81
|
+
|
82
|
+
assert_requested :post, hubspot_api_url("/contacts/v1/contact/createOrUpdate/email/#{email}?hapikey=demo")
|
83
|
+
|
84
|
+
expect(contact).to be_a(Hubspot::Contact)
|
85
|
+
expect(contact.email).to eq(email)
|
86
|
+
expect(contact[:firstname]).to eq(params[:firstname])
|
87
|
+
expect(contact[:lastname]).to eq(params[:lastname])
|
88
|
+
|
89
|
+
contact.destroy!
|
90
|
+
end
|
91
|
+
end
|
77
92
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
93
|
+
|
94
|
+
context "with an invalid email" do
|
95
|
+
it "raises an error" do
|
96
|
+
VCR.use_cassette("contact_create_or_update_invalid_email") do
|
97
|
+
expect {
|
98
|
+
Hubspot::Contact.createOrUpdate("not_an_email")
|
99
|
+
}.to raise_error(Hubspot::RequestError)
|
100
|
+
end
|
83
101
|
end
|
84
102
|
end
|
85
103
|
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
|
@@ -15,13 +15,13 @@ describe Hubspot::DealProperties do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:example_groups) do
|
18
|
-
VCR.use_cassette('deal_groups_example'
|
18
|
+
VCR.use_cassette('deal_groups_example') do
|
19
19
|
HTTParty.get('https://api.hubapi.com/deals/v1/groups?hapikey=demo').parsed_response
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
let(:example_properties) do
|
24
|
-
VCR.use_cassette('deal_properties_example'
|
24
|
+
VCR.use_cassette('deal_properties_example') do
|
25
25
|
HTTParty.get('https://api.hubapi.com/deals/v1/properties?hapikey=demo').parsed_response
|
26
26
|
end
|
27
27
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
describe Hubspot::Form do
|
2
2
|
let(:guid) { '78c2891f-ebdd-44c0-bd94-15c012bbbfbf' } # '561d9ce9-bb4c-45b4-8e32-21cdeaa3a7f0'
|
3
3
|
let(:example_form_hash) do
|
4
|
-
VCR.use_cassette('form_example'
|
4
|
+
VCR.use_cassette('form_example') do
|
5
5
|
HTTParty.get("https://api.hubapi.com#{Hubspot::Form::FORMS_PATH}/#{guid}/?hapikey=demo").parsed_response
|
6
6
|
end
|
7
7
|
end
|
@@ -31,13 +31,13 @@ describe Hubspot::Utils do
|
|
31
31
|
|
32
32
|
describe '.compare_property_lists for ContactProperties' do
|
33
33
|
let(:example_groups) do
|
34
|
-
VCR.use_cassette('groups_example'
|
34
|
+
VCR.use_cassette('groups_example') do
|
35
35
|
HTTParty.get('https://api.hubapi.com/contacts/v2/groups?hapikey=demo').parsed_response
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
let(:example_properties) do
|
40
|
-
VCR.use_cassette('properties_example'
|
40
|
+
VCR.use_cassette('properties_example') do
|
41
41
|
HTTParty.get('https://api.hubapi.com/contacts/v2/properties?hapikey=demo').parsed_response
|
42
42
|
end
|
43
43
|
end
|
@@ -80,13 +80,13 @@ describe Hubspot::Utils do
|
|
80
80
|
|
81
81
|
describe '.compare_property_lists for DealProperties' do
|
82
82
|
let(:example_groups) do
|
83
|
-
VCR.use_cassette('deal_groups_example'
|
83
|
+
VCR.use_cassette('deal_groups_example') do
|
84
84
|
HTTParty.get('https://api.hubapi.com/deals/v1/groups?hapikey=demo').parsed_response
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
88
|
let(:example_properties) do
|
89
|
-
VCR.use_cassette('deal_properties_example'
|
89
|
+
VCR.use_cassette('deal_properties_example') do
|
90
90
|
HTTParty.get('https://api.hubapi.com/deals/v1/properties?hapikey=demo').parsed_response
|
91
91
|
end
|
92
92
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "rake"
|
2
|
+
require "stringio"
|
3
|
+
require "tempfile"
|
4
|
+
|
5
|
+
RSpec.describe "hubspot rake tasks", type: :rake do
|
6
|
+
let(:hapikey) { "demo" }
|
7
|
+
|
8
|
+
describe "hubspot:dump_properties" do
|
9
|
+
it "writes the class properties and groups to the given file" do
|
10
|
+
VCR.use_cassette("dump_contact_properties_and_groups") do
|
11
|
+
file = Tempfile.new ""
|
12
|
+
|
13
|
+
invoke_rake_task("hubspot:dump_properties", ["contact", file, hapikey])
|
14
|
+
|
15
|
+
result = JSON.parse(File.read(file))
|
16
|
+
|
17
|
+
expect(result.count).to be > 0
|
18
|
+
expect(result['groups'].count).to be > 0
|
19
|
+
expect(result['properties'].count).to be > 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "given an unknown class" do
|
24
|
+
it "raises an error" do
|
25
|
+
file = Tempfile.new ""
|
26
|
+
|
27
|
+
expected_error_msg = ':kind must be either "contact" or "deal"'
|
28
|
+
|
29
|
+
expect do
|
30
|
+
invoke_rake_task(
|
31
|
+
"hubspot:dump_properties",
|
32
|
+
["unknown_class", file, hapikey]
|
33
|
+
)
|
34
|
+
end.to raise_error(ArgumentError, expected_error_msg)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "hubspot:restore_properties" do
|
40
|
+
context "when the class properties match the existing properties" do
|
41
|
+
it "should not need to make any changes" do
|
42
|
+
VCR.use_cassette("restore_contact_properties_and_groups") do
|
43
|
+
file = build_file_with_matching_properties("contact")
|
44
|
+
|
45
|
+
results = capture_stdout do
|
46
|
+
invoke_rake_task(
|
47
|
+
"hubspot:restore_properties",
|
48
|
+
["contact", file, hapikey]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(results).not_to include("Created: ")
|
53
|
+
expect(results).not_to include("Updated: ")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when a file is not provided" do
|
59
|
+
it "raises an error" do
|
60
|
+
missing_file = ""
|
61
|
+
expected_error_msg = ":file is a required parameter"
|
62
|
+
|
63
|
+
expect do
|
64
|
+
invoke_rake_task(
|
65
|
+
"hubspot:restore_properties",
|
66
|
+
["contact", missing_file, hapikey]
|
67
|
+
)
|
68
|
+
end.to raise_error(ArgumentError, expected_error_msg)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "given an unknown class" do
|
73
|
+
it "raises an error" do
|
74
|
+
file = Tempfile.new ""
|
75
|
+
expected_error_msg = ':kind must be either "contact" or "deal"'
|
76
|
+
|
77
|
+
expect do
|
78
|
+
invoke_rake_task(
|
79
|
+
"hubspot:restore_properties",
|
80
|
+
["unknown_class", file, hapikey]
|
81
|
+
)
|
82
|
+
end.to raise_error(ArgumentError, expected_error_msg)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def build_file_with_matching_properties(klass)
|
88
|
+
file = Tempfile.new ""
|
89
|
+
invoke_rake_task("hubspot:dump_properties", ["contact", file, hapikey])
|
90
|
+
file
|
91
|
+
end
|
92
|
+
|
93
|
+
def capture_stdout
|
94
|
+
previous, $stdout = $stdout, StringIO.new
|
95
|
+
yield
|
96
|
+
$stdout.string
|
97
|
+
ensure
|
98
|
+
$stdout = previous
|
99
|
+
end
|
100
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,17 +13,11 @@ end
|
|
13
13
|
require 'rspec'
|
14
14
|
require 'webmock/rspec'
|
15
15
|
require 'hubspot-ruby'
|
16
|
-
require 'vcr'
|
17
16
|
|
18
17
|
# Requires supporting files with custom matchers and macros, etc,
|
19
18
|
# in ./support/ and its subdirectories.
|
20
19
|
Dir["#{RSPEC_ROOT}/support/**/*.rb"].each {|f| require f}
|
21
20
|
|
22
|
-
VCR.configure do |c|
|
23
|
-
c.cassette_library_dir = "#{RSPEC_ROOT}/fixtures/vcr_cassettes"
|
24
|
-
c.hook_into :webmock
|
25
|
-
end
|
26
|
-
|
27
21
|
RSpec.configure do |config|
|
28
22
|
config.mock_with :rr
|
29
23
|
|
@@ -31,14 +25,6 @@ RSpec.configure do |config|
|
|
31
25
|
Hubspot::Config.reset!
|
32
26
|
end
|
33
27
|
|
34
|
-
config.around(:each, live: true) do |example|
|
35
|
-
VCR.turn_off!
|
36
|
-
WebMock.disable!
|
37
|
-
example.run
|
38
|
-
WebMock.enable!
|
39
|
-
VCR.turn_on!
|
40
|
-
end
|
41
|
-
|
42
28
|
config.extend CassetteHelper
|
43
29
|
config.extend TestsHelper
|
44
30
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module CassetteHelper
|
2
2
|
def self.extended(base)
|
3
3
|
base.around do |spec|
|
4
|
-
VCR.insert_cassette(_cassette
|
4
|
+
VCR.insert_cassette(_cassette) if defined?(_cassette) && _cassette
|
5
5
|
spec.run
|
6
6
|
VCR.eject_cassette if defined?(_cassette) && _cassette
|
7
7
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "rake"
|
2
|
+
|
3
|
+
module RakeHelpers
|
4
|
+
def invoke_rake_task(name, args = [])
|
5
|
+
RakeTask.new(name).invoke(*args)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class RakeTask
|
10
|
+
def initialize(name)
|
11
|
+
@task_name = name
|
12
|
+
prep_environment
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate :invoke, to: :task
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :task_name
|
20
|
+
|
21
|
+
def prep_environment
|
22
|
+
Rake.application = rake
|
23
|
+
Rake.load_rakefile(full_task_path)
|
24
|
+
Rake::Task.define_task(:environment)
|
25
|
+
end
|
26
|
+
|
27
|
+
def full_task_path
|
28
|
+
"#{root_path}/lib/tasks/#{task_name.split(':').first}.rake"
|
29
|
+
end
|
30
|
+
|
31
|
+
def root_path
|
32
|
+
File.expand_path('../..', __dir__)
|
33
|
+
end
|
34
|
+
|
35
|
+
def task
|
36
|
+
rake[task_name]
|
37
|
+
end
|
38
|
+
|
39
|
+
def rake
|
40
|
+
@_rake ||= Rake::Application.new
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
RSpec.configure do |config|
|
45
|
+
config.include RakeHelpers, type: :rake
|
46
|
+
end
|
data/spec/support/vcr.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "vcr"
|
2
|
+
|
3
|
+
def vcr_record_mode
|
4
|
+
if ENV["VCR_RECORD"] == "1"
|
5
|
+
:new_episodes
|
6
|
+
else
|
7
|
+
:none
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
VCR.configure do |c|
|
12
|
+
c.cassette_library_dir = "#{RSPEC_ROOT}/fixtures/vcr_cassettes"
|
13
|
+
c.hook_into :webmock
|
14
|
+
c.default_cassette_options = { record: vcr_record_mode }
|
15
|
+
end
|