hubspot-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "activesupport", ">=3.0.0"
7
+ gem "httparty", ">=0.10.0"
8
+
9
+ # Add dependencies to develop your gem here.
10
+ # Include everything needed to run rake, tests, features, etc.
11
+ group :development do
12
+ gem "rspec"
13
+ gem "rr"
14
+ gem "webmock"
15
+ gem "vcr"
16
+ gem "rdoc"
17
+ gem "bundler"
18
+ gem "jeweler"
19
+ gem "simplecov"
20
+ gem "awesome_print"
21
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,59 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.2.12)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ addressable (2.3.2)
8
+ awesome_print (1.1.0)
9
+ crack (0.3.2)
10
+ diff-lcs (1.1.3)
11
+ git (1.2.5)
12
+ httparty (0.10.2)
13
+ multi_json (~> 1.0)
14
+ multi_xml (>= 0.5.2)
15
+ i18n (0.6.1)
16
+ jeweler (1.8.4)
17
+ bundler (~> 1.0)
18
+ git (>= 1.2.5)
19
+ rake
20
+ rdoc
21
+ json (1.7.7)
22
+ multi_json (1.6.1)
23
+ multi_xml (0.5.3)
24
+ rake (10.0.3)
25
+ rdoc (3.12.1)
26
+ json (~> 1.4)
27
+ rr (1.0.4)
28
+ rspec (2.12.0)
29
+ rspec-core (~> 2.12.0)
30
+ rspec-expectations (~> 2.12.0)
31
+ rspec-mocks (~> 2.12.0)
32
+ rspec-core (2.12.2)
33
+ rspec-expectations (2.12.1)
34
+ diff-lcs (~> 1.1.3)
35
+ rspec-mocks (2.12.2)
36
+ simplecov (0.7.1)
37
+ multi_json (~> 1.0)
38
+ simplecov-html (~> 0.7.1)
39
+ simplecov-html (0.7.1)
40
+ vcr (2.4.0)
41
+ webmock (1.9.0)
42
+ addressable (>= 2.2.7)
43
+ crack (>= 0.1.7)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ activesupport (>= 3.0.0)
50
+ awesome_print
51
+ bundler
52
+ httparty (>= 0.10.0)
53
+ jeweler
54
+ rdoc
55
+ rr
56
+ rspec
57
+ simplecov
58
+ vcr
59
+ webmock
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Omada Health, Inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # HubSpot REST API wrappers for ruby
2
+
3
+ Wraps the HubSpot REST API for convenient access from ruby applications.
4
+
5
+ Documentation for the HubSpot REST API can be found here: https://developers.hubspot.com/docs/endpoints
6
+
7
+ ## Setup
8
+
9
+ gem install hubspot-ruby
10
+
11
+ Or with bundler,
12
+
13
+ ```ruby
14
+ gem "hubspot-ruby"
15
+ ```
16
+
17
+ Before using the library, you must initialize it with your HubSpot API key. If you're using Rails, put this code in an
18
+ initializer:
19
+
20
+ ```ruby
21
+ Hubspot.configure(hapikey: "YOUR_API_KEY")
22
+ ```
23
+
24
+ If you're have a HubSpot account, you can get your api key by logging in and visiting this url: https://app.hubspot.com/keys/get
25
+
26
+ ### Note about authentication
27
+
28
+ For now, this library only supports authentication with a HubSpot API key (aka "hapikey"). OAuth is not yet supported.
29
+
30
+ ## Usage
31
+
32
+ Not much is supported yet, but that will change. Here's what you can do for now:
33
+
34
+ ### Find a contact
35
+
36
+ These methods will return a `Hubspot::Contact` object if successful, `nil` otherwise:
37
+
38
+ ```ruby
39
+ Hubspot::Contact.find_by_email("email@address.com")
40
+ Hubspot::Contact.find_by_id(12345) # Pass the contact VID
41
+ ```
42
+
43
+ ### Update a contact
44
+
45
+ Given an instance of `Hubspot::Contact`, update its attributes with:
46
+
47
+ ```ruby
48
+ contact.update!({firstname: "First", lastname: "Last"})
49
+ ```
50
+
51
+ ## Contributing to hubspot-ruby
52
+
53
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
54
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
55
+ * Fork the project.
56
+ * Start a feature/bugfix branch.
57
+ * Commit and push until you are happy with your contribution.
58
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
59
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
60
+
61
+ ### Testing
62
+
63
+ All tests can be run with `rake spec`. Isolate fast-running tests with `rake spec:quick`.
64
+
65
+ GET requests are pretty easy to test with VCR, but for POST/PUT requests, you probably want to update verify the state
66
+ of a live HubSpot instance. To do this, please add "live" tests to `spec/live/`, using the rspec label `live: true` in
67
+ order to disable VCR.
68
+
69
+ "Live" tests can be isolated with `rake spec:live`.
70
+
71
+ ## Disclaimer
72
+
73
+ This project and the code therein was not created by and is not supported by HubSpot, Inc or any of its affiliates.
74
+
75
+ ## Copyright
76
+
77
+ Copyright (c) 2013 Omada Health Inc. See LICENSE.txt for further details.
78
+
data/Rakefile ADDED
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ require './lib/hubspot/version.rb'
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
18
+ gem.name = "hubspot-ruby"
19
+ gem.homepage = "http://github.com/omadahealth/hubspot-ruby"
20
+ #gem.license = "MIT"
21
+ gem.summary = %Q{hubspot-ruby is a wrapper for the HubSpot REST API}
22
+ gem.description = %Q{hubspot-ruby is a wrapper for the HubSpot REST API}
23
+ gem.email = "andrew@omadahealth.com"
24
+ gem.authors = ["Andrew DiMichele"]
25
+ gem.version = Hubspot::Version::STRING
26
+
27
+ # dependencies defined in Gemfile
28
+ gem.add_dependency "activesupport", ">=3.0.0"
29
+ gem.add_dependency "httparty", ">=0.10.0"
30
+ end
31
+ Jeweler::RubygemsDotOrgTasks.new
32
+
33
+ require 'rspec/core'
34
+ require 'rspec/core/rake_task'
35
+
36
+ namespace :spec do
37
+ RSpec::Core::RakeTask.new(:quick) do |spec|
38
+ spec.pattern = FileList['spec/**/*_spec.rb'].select{ |s| !s.match("/live/") }
39
+ end
40
+ RSpec::Core::RakeTask.new(:live) do |spec|
41
+ spec.pattern = FileList['spec/live/*_spec.rb']
42
+ end
43
+ end
44
+
45
+ RSpec::Core::RakeTask.new(:spec) do |spec|
46
+ spec.pattern = FileList['spec/**/*_spec.rb']
47
+ end
48
+
49
+ task :default => :spec
50
+
51
+ require 'rdoc/task'
52
+ Rake::RDocTask.new do |rdoc|
53
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
54
+
55
+ rdoc.rdoc_dir = 'rdoc'
56
+ rdoc.title = "hubspot-ruby #{version}"
57
+ rdoc.rdoc_files.include('README*')
58
+ rdoc.rdoc_files.include('lib/**/*.rb')
59
+ end
@@ -0,0 +1,97 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "hubspot-ruby"
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Andrew DiMichele"]
12
+ s.date = "2013-02-18"
13
+ s.description = "hubspot-ruby is a wrapper for the HubSpot REST API"
14
+ s.email = "andrew@omadahealth.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "hubspot-ruby.gemspec",
28
+ "lib/hubspot-ruby.rb",
29
+ "lib/hubspot/config.rb",
30
+ "lib/hubspot/contact.rb",
31
+ "lib/hubspot/utils.rb",
32
+ "lib/hubspot/version.rb",
33
+ "spec/fixtures/vcr_cassettes/example_contact.yml",
34
+ "spec/fixtures/vcr_cassettes/find_contact_by_email.yml",
35
+ "spec/fixtures/vcr_cassettes/find_contact_by_id.yml",
36
+ "spec/fixtures/vcr_cassettes/update_contact.yml",
37
+ "spec/lib/hubspot-ruby_spec.rb",
38
+ "spec/lib/hubspot/config_spec.rb",
39
+ "spec/lib/hubspot/contact_spec.rb",
40
+ "spec/lib/hubspot/utils_spec.rb",
41
+ "spec/live/contacts_integration_spec.rb",
42
+ "spec/spec_helper.rb"
43
+ ]
44
+ s.homepage = "http://github.com/omadahealth/hubspot-ruby"
45
+ s.require_paths = ["lib"]
46
+ s.rubygems_version = "1.8.25"
47
+ s.summary = "hubspot-ruby is a wrapper for the HubSpot REST API"
48
+
49
+ if s.respond_to? :specification_version then
50
+ s.specification_version = 3
51
+
52
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
54
+ s.add_runtime_dependency(%q<httparty>, [">= 0.10.0"])
55
+ s.add_development_dependency(%q<rspec>, [">= 0"])
56
+ s.add_development_dependency(%q<rr>, [">= 0"])
57
+ s.add_development_dependency(%q<webmock>, [">= 0"])
58
+ s.add_development_dependency(%q<vcr>, [">= 0"])
59
+ s.add_development_dependency(%q<rdoc>, [">= 0"])
60
+ s.add_development_dependency(%q<bundler>, [">= 0"])
61
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
62
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
63
+ s.add_development_dependency(%q<awesome_print>, [">= 0"])
64
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
65
+ s.add_runtime_dependency(%q<httparty>, [">= 0.10.0"])
66
+ else
67
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
68
+ s.add_dependency(%q<httparty>, [">= 0.10.0"])
69
+ s.add_dependency(%q<rspec>, [">= 0"])
70
+ s.add_dependency(%q<rr>, [">= 0"])
71
+ s.add_dependency(%q<webmock>, [">= 0"])
72
+ s.add_dependency(%q<vcr>, [">= 0"])
73
+ s.add_dependency(%q<rdoc>, [">= 0"])
74
+ s.add_dependency(%q<bundler>, [">= 0"])
75
+ s.add_dependency(%q<jeweler>, [">= 0"])
76
+ s.add_dependency(%q<simplecov>, [">= 0"])
77
+ s.add_dependency(%q<awesome_print>, [">= 0"])
78
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
79
+ s.add_dependency(%q<httparty>, [">= 0.10.0"])
80
+ end
81
+ else
82
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
83
+ s.add_dependency(%q<httparty>, [">= 0.10.0"])
84
+ s.add_dependency(%q<rspec>, [">= 0"])
85
+ s.add_dependency(%q<rr>, [">= 0"])
86
+ s.add_dependency(%q<webmock>, [">= 0"])
87
+ s.add_dependency(%q<vcr>, [">= 0"])
88
+ s.add_dependency(%q<rdoc>, [">= 0"])
89
+ s.add_dependency(%q<bundler>, [">= 0"])
90
+ s.add_dependency(%q<jeweler>, [">= 0"])
91
+ s.add_dependency(%q<simplecov>, [">= 0"])
92
+ s.add_dependency(%q<awesome_print>, [">= 0"])
93
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
94
+ s.add_dependency(%q<httparty>, [">= 0.10.0"])
95
+ end
96
+ end
97
+
@@ -0,0 +1,10 @@
1
+ require 'active_support/core_ext'
2
+ require 'httparty'
3
+ require 'hubspot/config'
4
+ require 'hubspot/contact'
5
+
6
+ module Hubspot
7
+ def self.configure(config={})
8
+ Hubspot::Config.configure(config)
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ module Hubspot
2
+ class Config
3
+ class << self
4
+ attr_reader :hapikey
5
+ attr_reader :base_url
6
+
7
+ def configure(config)
8
+ config.stringify_keys!
9
+ @hapikey = config["hapikey"]
10
+ @base_url = config["base_url"] || "https://api.hubapi.com"
11
+ self
12
+ end
13
+
14
+ def reset!
15
+ @hapikey = nil
16
+ @base_url = "https://api.hubapi.com"
17
+ end
18
+ end
19
+
20
+ reset!
21
+ end
22
+ end
@@ -0,0 +1,58 @@
1
+ require 'hubspot/utils'
2
+ require 'httparty'
3
+
4
+ module Hubspot
5
+ class Contact
6
+ GET_CONTACT_BY_EMAIL_PATH = "/contacts/v1/contact/email/:contact_email/profile"
7
+ GET_CONTACT_BY_ID_PATH = "/contacts/v1/contact/vid/:contact_id/profile"
8
+ UPDATE_CONTACT_PATH = "/contacts/v1/contact/vid/:contact_id/profile"
9
+
10
+ class << self
11
+ def find_by_email(email)
12
+ url = Hubspot::Utils.generate_url(GET_CONTACT_BY_EMAIL_PATH, {contact_email: email})
13
+ resp = HTTParty.get(url)
14
+ if resp.code == 200
15
+ Hubspot::Contact.new(resp.parsed_response)
16
+ else
17
+ nil
18
+ end
19
+ end
20
+
21
+ def find_by_id(vid)
22
+ url = Hubspot::Utils.generate_url(GET_CONTACT_BY_ID_PATH, {contact_id: vid})
23
+ resp = HTTParty.get(url)
24
+ if resp.code == 200
25
+ Hubspot::Contact.new(resp.parsed_response)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+ end
31
+
32
+ attr_reader :properties
33
+ attr_reader :vid
34
+
35
+ def initialize(response_hash)
36
+ @properties = Hubspot::Utils.properties_to_hash(response_hash["properties"])
37
+ @vid = response_hash["vid"]
38
+ end
39
+
40
+ def [](property)
41
+ @properties[property]
42
+ end
43
+
44
+ def email
45
+ @properties["email"]
46
+ end
47
+
48
+ def update!(params)
49
+ params.stringify_keys!
50
+ url = Hubspot::Utils.generate_url(UPDATE_CONTACT_PATH, {contact_id: vid})
51
+ query = {"properties" => Hubspot::Utils.hash_to_properties(params)}
52
+ resp = HTTParty.post(url, body: query.to_json)
53
+ raise(Hubspot::RequestError.new(resp.response)) unless resp.success?
54
+ @properties.merge!(params)
55
+ self
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,43 @@
1
+ module Hubspot
2
+ class ConfigurationError < StandardError; end
3
+ class MissingInterpolation < StandardError; end
4
+ class RequestError < StandardError; end
5
+
6
+ class Utils
7
+ class << self
8
+ # Parses the hubspot properties format into a key-value hash
9
+ def properties_to_hash(props)
10
+ newprops = {}
11
+ props.each{ |k,v| newprops[k] = v["value"] }
12
+ newprops
13
+ end
14
+
15
+ # Turns a hash into the hubspot properties format
16
+ def hash_to_properties(hash)
17
+ hash.map{ |k,v| {"property" => k.to_s, "value" => v}}
18
+ end
19
+
20
+ # Generate the API URL for the request
21
+ #
22
+ # @param path [String] The path of the request with leading "/". Parts starting with a ":" will be interpolated
23
+ # @param params [Hash] params to be included in the query string or interpolated into the url.
24
+ #
25
+ # @return [String]
26
+ #
27
+ def generate_url(path, params={})
28
+ raise Hubspot::ConfigurationError.new("'hapikey' not configured") unless Hubspot::Config.hapikey
29
+ params["hapikey"] = Hubspot::Config.hapikey
30
+ ipath = path.clone
31
+ params.each do |k,v|
32
+ if ipath.match(":#{k}")
33
+ ipath.gsub!(":#{k}",v.to_s)
34
+ params.delete(k)
35
+ end
36
+ end
37
+ raise(Hubspot::MissingInterpolation.new("Interpolation not resolved")) if ipath =~ /:/
38
+ query = params.map{ |k,v| "#{k}=#{v}" }.join("&")
39
+ Hubspot::Config.base_url + ipath + "?" + query
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,9 @@
1
+ module Hubspot
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+
7
+ STRING = [MAJOR, MINOR, PATCH].compact.join('.')
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.hubapi.com/contacts/v1/contact/email/testingapis@hubspot.com/profile?hapikey=demo
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Access-Control-Allow-Credentials:
16
+ - 'false'
17
+ Content-Type:
18
+ - application/json;charset=UTF-8
19
+ Date:
20
+ - Sun, 17 Feb 2013 21:25:47 GMT
21
+ Server:
22
+ - Apache-Coyote/1.1
23
+ Content-Length:
24
+ - '4526'
25
+ Connection:
26
+ - keep-alive
27
+ body:
28
+ encoding: US-ASCII
29
+ string: ! '{"vid":82325,"canonical-vid":82325,"portal-id":62515,"profile-token":"AO_T-mOFl-EsboE0zgQW128L0RgCNNG8B5dPZhYfs7wWibbeR0hPcNdip07vdlt8TTWgDKqvLs-7XByciZlyBnA6_P7AR66hspzqIoBuh2fWiQa231_UEvVohe-lkdfQYv8iCtnAMNVq","profile-url":"https://app.hubspot.com/contacts/62515/lists/public/contact/_AO_T-mOFl-EsboE0zgQW128L0RgCNNG8B5dPZhYfs7wWibbeR0hPcNdip07vdlt8TTWgDKqvLs-7XByciZlyBnA6_P7AR66hspzqIoBuh2fWiQa231_UEvVohe-lkdfQYv8iCtnAMNVq/","properties":{"firstname":{"value":"Test","versions":[{"timestamp":1338305440003,"selected":false,"source-label":"FirstName","value":"Test","source-type":"FORM","source-id":"bc65112f47c2469e90f5951213a66110"}]},"lastname":{"value":"Contact","versions":[{"timestamp":1338305440003,"selected":false,"source-label":"LastName","value":"Contact","source-type":"FORM","source-id":"bc65112f47c2469e90f5951213a66110"}]},"phone":{"value":"555-555-2262","versions":[{"timestamp":1338305440003,"selected":false,"source-label":"Phone","value":"555-555-2262","source-type":"FORM","source-id":"bc65112f47c2469e90f5951213a66110"}]},"hs_analytics_num_visits":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_referrer":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_linkedin_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_url":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_last_engagement":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_num_broadcast_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"hs_social_facebook_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"createdate":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"API","source-id":null,"source-label":null,"timestamp":1345062449002,"selected":false}]},"hs_social_twitter_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_url":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_referrer":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_num_event_completions":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"hs_analytics_source":{"value":"OFFLINE","versions":[{"value":"OFFLINE","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_google_plus_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"email":{"value":"testingapis@hubspot.com","versions":[{"value":"testingapis@hubspot.com","source-type":"CONTACTS_WEB","source-id":"dadams@hubspot.com","source-label":null,"timestamp":1345062449008,"selected":false}]},"hs_analytics_last_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_num_page_views":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source_data_2":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source_data_1":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_visit_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]}},"form-submissions":[],"list-memberships":[],"identity-profiles":[{"vid":82325,"identities":[{"type":"EMAIL","value":"testingapis@hubspot.com","timestamp":1345062449327},{"type":"LEAD_GUID","value":"c0da5c41-f289-4642-910c-9aa2b0fba245","timestamp":1345062449333}]}]}'
30
+ http_version:
31
+ recorded_at: Sun, 17 Feb 2013 21:25:47 GMT
32
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,59 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.hubapi.com/contacts/v1/contact/email/testingapis@hubspot.com/profile?hapikey=demo
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Access-Control-Allow-Credentials:
16
+ - 'false'
17
+ Content-Type:
18
+ - application/json;charset=UTF-8
19
+ Date:
20
+ - Mon, 18 Feb 2013 00:27:11 GMT
21
+ Server:
22
+ - Apache-Coyote/1.1
23
+ Content-Length:
24
+ - '4857'
25
+ Connection:
26
+ - keep-alive
27
+ body:
28
+ encoding: US-ASCII
29
+ string: ! '{"vid":82325,"canonical-vid":82325,"portal-id":62515,"profile-token":"AO_T-mOEnUzEVVZQVj3XwZCiE87gPcrjLaNbtQmsuVg5c7YUx7BIfMF48rHWdEvZSEpbpX-V7Qz46i0z1hk7KQyH41DJZLQPB2F-aH8qrG1EW-mIZxHl-QmK9Ffo4ILZrKoOwwr3qqZw","profile-url":"https://app.hubspot.com/contacts/62515/lists/public/contact/_AO_T-mOEnUzEVVZQVj3XwZCiE87gPcrjLaNbtQmsuVg5c7YUx7BIfMF48rHWdEvZSEpbpX-V7Qz46i0z1hk7KQyH41DJZLQPB2F-aH8qrG1EW-mIZxHl-QmK9Ffo4ILZrKoOwwr3qqZw/","properties":{"hs_analytics_num_visits":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_referrer":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_linkedin_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_url":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_last_engagement":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_num_broadcast_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"hs_social_facebook_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"createdate":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"API","source-id":null,"source-label":null,"timestamp":1345062449002,"selected":false}]},"lastname":{"value":"Cunningham","versions":[{"value":"Cunningham","source-type":"API","source-id":null,"source-label":null,"timestamp":1361146313002,"selected":false}]},"hs_social_twitter_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"firstname":{"value":"Steve","versions":[{"value":"Steve","source-type":"API","source-id":null,"source-label":null,"timestamp":1361146313002,"selected":false}]},"hs_analytics_first_url":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source":{"value":"OFFLINE","versions":[{"value":"OFFLINE","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_referrer":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_num_event_completions":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"hs_social_google_plus_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"email":{"value":"testingapis@hubspot.com","versions":[{"value":"testingapis@hubspot.com","source-type":"CONTACTS_WEB","source-id":"dadams@hubspot.com","source-label":null,"timestamp":1345062449008,"selected":false}]},"hs_analytics_last_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_num_page_views":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source_data_2":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source_data_1":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_visit_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]}},"form-submissions":[],"list-memberships":[],"identity-profiles":[{"vid":82325,"identities":[{"type":"EMAIL","value":"testingapis@hubspot.com","timestamp":1345062449327},{"type":"LEAD_GUID","value":"c0da5c41-f289-4642-910c-9aa2b0fba245","timestamp":1345062449333}]}]}'
30
+ http_version:
31
+ recorded_at: Mon, 18 Feb 2013 00:27:11 GMT
32
+ - request:
33
+ method: get
34
+ uri: https://api.hubapi.com/contacts/v1/contact/email/notacontact@test.com/profile?hapikey=demo
35
+ body:
36
+ encoding: US-ASCII
37
+ string: ''
38
+ headers: {}
39
+ response:
40
+ status:
41
+ code: 404
42
+ message: Not Found
43
+ headers:
44
+ Content-Type:
45
+ - application/json;charset=UTF-8
46
+ Date:
47
+ - Mon, 18 Feb 2013 00:27:11 GMT
48
+ Server:
49
+ - Apache-Coyote/1.1
50
+ Content-Length:
51
+ - '95'
52
+ Connection:
53
+ - keep-alive
54
+ body:
55
+ encoding: US-ASCII
56
+ string: ! '{"status":"error","message":"resource not found","guid":"c1ff8266-2bff-4278-9717-d4db2ea429cc"}'
57
+ http_version:
58
+ recorded_at: Mon, 18 Feb 2013 00:27:11 GMT
59
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,59 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.hubapi.com/contacts/v1/contact/vid/82325/profile?hapikey=demo
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Access-Control-Allow-Credentials:
16
+ - 'false'
17
+ Content-Type:
18
+ - application/json;charset=UTF-8
19
+ Date:
20
+ - Mon, 18 Feb 2013 00:35:33 GMT
21
+ Server:
22
+ - Apache-Coyote/1.1
23
+ Content-Length:
24
+ - '4857'
25
+ Connection:
26
+ - keep-alive
27
+ body:
28
+ encoding: US-ASCII
29
+ string: ! '{"vid":82325,"canonical-vid":82325,"portal-id":62515,"profile-token":"AO_T-mMbtNq2RnAUjbHWrHMch5z4aOs7MBYrtC9WGDpghGH-X3L3ZuRjqPAj5LhRh5C17U-jCRLDOUi1hcvLdzqFAo1-vyCmW82-pXxzMA2uZpEjXNmn_9duS1o9GryBETCHoMLpzijw","profile-url":"https://app.hubspot.com/contacts/62515/lists/public/contact/_AO_T-mMbtNq2RnAUjbHWrHMch5z4aOs7MBYrtC9WGDpghGH-X3L3ZuRjqPAj5LhRh5C17U-jCRLDOUi1hcvLdzqFAo1-vyCmW82-pXxzMA2uZpEjXNmn_9duS1o9GryBETCHoMLpzijw/","properties":{"hs_analytics_num_visits":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_referrer":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_linkedin_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_url":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_last_engagement":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_social_num_broadcast_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"hs_social_facebook_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"createdate":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"API","source-id":null,"source-label":null,"timestamp":1345062449002,"selected":false}]},"lastname":{"value":"Cunningham","versions":[{"value":"Cunningham","source-type":"API","source-id":null,"source-label":null,"timestamp":1361146313002,"selected":false}]},"hs_social_twitter_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"firstname":{"value":"Steve","versions":[{"value":"Steve","source-type":"API","source-id":null,"source-label":null,"timestamp":1361146313002,"selected":false}]},"hs_analytics_first_url":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source":{"value":"OFFLINE","versions":[{"value":"OFFLINE","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_referrer":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_num_event_completions":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"hs_social_google_plus_clicks":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]},"email":{"value":"testingapis@hubspot.com","versions":[{"value":"testingapis@hubspot.com","source-type":"CONTACTS_WEB","source-id":"dadams@hubspot.com","source-label":null,"timestamp":1345062449008,"selected":false}]},"hs_analytics_last_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_num_page_views":{"value":"0","versions":[{"value":"0","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_first_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source_data_2":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_source_data_1":{"value":"","versions":[{"value":"","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1345067864004,"selected":false}]},"hs_analytics_last_visit_timestamp":{"value":"1345062449327","versions":[{"value":"1345062449327","source-type":"ANALYTICS","source-id":null,"source-label":null,"timestamp":1348916431004,"selected":false}]}},"form-submissions":[],"list-memberships":[],"identity-profiles":[{"vid":82325,"identities":[{"type":"EMAIL","value":"testingapis@hubspot.com","timestamp":1345062449327},{"type":"LEAD_GUID","value":"c0da5c41-f289-4642-910c-9aa2b0fba245","timestamp":1345062449333}]}]}'
30
+ http_version:
31
+ recorded_at: Mon, 18 Feb 2013 00:35:33 GMT
32
+ - request:
33
+ method: get
34
+ uri: https://api.hubapi.com/contacts/v1/contact/vid/9999999/profile?hapikey=demo
35
+ body:
36
+ encoding: US-ASCII
37
+ string: ''
38
+ headers: {}
39
+ response:
40
+ status:
41
+ code: 404
42
+ message: Not Found
43
+ headers:
44
+ Content-Type:
45
+ - application/json;charset=UTF-8
46
+ Date:
47
+ - Mon, 18 Feb 2013 00:35:34 GMT
48
+ Server:
49
+ - Apache-Coyote/1.1
50
+ Content-Length:
51
+ - '95'
52
+ Connection:
53
+ - keep-alive
54
+ body:
55
+ encoding: US-ASCII
56
+ string: ! '{"status":"error","message":"resource not found","guid":"4710ce10-c3c7-4f35-ae2c-4c4f182325a6"}'
57
+ http_version:
58
+ recorded_at: Mon, 18 Feb 2013 00:35:34 GMT
59
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,66 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.hubapi.com/contacts/v1/contact/vid/82325/profile?hapikey=demo
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ! '{"properties":[{"property":"firstname","value":"Steve"},{"property":"lastname","value":"Cunningham"}]}'
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 204
13
+ message: No Content
14
+ headers:
15
+ Access-Control-Allow-Credentials:
16
+ - 'false'
17
+ Date:
18
+ - Mon, 18 Feb 2013 00:11:53 GMT
19
+ Server:
20
+ - Apache-Coyote/1.1
21
+ Connection:
22
+ - keep-alive
23
+ body:
24
+ encoding: US-ASCII
25
+ string: ''
26
+ http_version:
27
+ recorded_at: Mon, 18 Feb 2013 00:11:53 GMT
28
+ - request:
29
+ method: post
30
+ uri: https://api.hubapi.com/contacts/v1/contact/vid/invalid/profile?hapikey=demo
31
+ body:
32
+ encoding: US-ASCII
33
+ string: ! '{"properties":[{"property":"firstname","value":"Steve"},{"property":"lastname","value":"Cunningham"}]}'
34
+ headers: {}
35
+ response:
36
+ status:
37
+ code: 404
38
+ message: Not Found
39
+ headers:
40
+ Content-Type:
41
+ - text/html;charset=utf-8
42
+ Date:
43
+ - Mon, 18 Feb 2013 00:11:54 GMT
44
+ Server:
45
+ - Apache-Coyote/1.1
46
+ Content-Length:
47
+ - '979'
48
+ Connection:
49
+ - keep-alive
50
+ body:
51
+ encoding: US-ASCII
52
+ string: ! '<html><head><title>Apache Tomcat/6.0.30 - Error report</title><style><!--H1
53
+ {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;}
54
+ H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;}
55
+ H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;}
56
+ BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;}
57
+ B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;}
58
+ P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A
59
+ {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP
60
+ Status 404 - Not Found</h1><HR size="1" noshade="noshade"><p><b>type</b> Status
61
+ report</p><p><b>message</b> <u>Not Found</u></p><p><b>description</b> <u>The
62
+ requested resource (Not Found) is not available.</u></p><HR size="1" noshade="noshade"><h3>Apache
63
+ Tomcat/6.0.30</h3></body></html>'
64
+ http_version:
65
+ recorded_at: Mon, 18 Feb 2013 00:11:54 GMT
66
+ recorded_with: VCR 2.4.0
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hubspot do
4
+ describe "#configure" do
5
+ it "delegates a call to Hubspot::Config.configure" do
6
+ mock(Hubspot::Config).configure({hapikey: "demo"})
7
+ Hubspot.configure hapikey: "demo"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hubspot::Config do
4
+ describe "#configure" do
5
+ let(:config){ {hapikey: "demo", base_url: "http://api.hubapi.com/v2"} }
6
+ subject{ Hubspot::Config.configure(config) }
7
+
8
+ it "changes the hapikey config" do
9
+ expect{ subject }.to change(Hubspot::Config, :hapikey).to("demo")
10
+ end
11
+
12
+ it "changes the base_url" do
13
+ expect{ subject }.to change(Hubspot::Config, :base_url).to("http://api.hubapi.com/v2")
14
+ end
15
+
16
+ it "sets a default value for base_url" do
17
+ Hubspot::Config.base_url.should == "https://api.hubapi.com"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hubspot::Contact do
4
+ let(:example_contact_hash) do
5
+ VCR.use_cassette("example_contact", record: :none) do
6
+ HTTParty.get("https://api.hubapi.com/contacts/v1/contact/email/testingapis@hubspot.com/profile?hapikey=demo").parsed_response
7
+ end
8
+ end
9
+
10
+ before{ Hubspot.configure(hapikey: "demo") }
11
+
12
+ describe "#initialize" do
13
+ subject{ Hubspot::Contact.new(example_contact_hash) }
14
+ it{ should be_an_instance_of Hubspot::Contact }
15
+ its(["email"]){ should == "testingapis@hubspot.com" }
16
+ its(["firstname"]){ should == "Test" }
17
+ its(["lastname"]){ should == "Contact" }
18
+ its(["phone"]){ should == "555-555-2262" }
19
+ its(:vid){ should == 82325 }
20
+ end
21
+
22
+ describe ".find_by_email" do
23
+ before{ VCR.insert_cassette("find_contact_by_email", record: :new_episodes) }
24
+ after{ VCR.eject_cassette }
25
+ subject{ Hubspot::Contact.find_by_email(email) }
26
+
27
+ context "when the contact is found" do
28
+ let(:email){ "testingapis@hubspot.com" }
29
+ it{ should be_an_instance_of Hubspot::Contact }
30
+ its(:vid){ should == 82325 }
31
+ end
32
+
33
+ context "when the contact cannot be found" do
34
+ let(:email){ "notacontact@test.com" }
35
+ it{ should be_nil }
36
+ end
37
+ end
38
+
39
+ describe ".find_by_id" do
40
+ before{ VCR.insert_cassette("find_contact_by_id", record: :new_episodes) }
41
+ after{ VCR.eject_cassette }
42
+ subject{ Hubspot::Contact.find_by_id(vid) }
43
+
44
+ context "when the contact is found" do
45
+ let(:vid){ 82325 }
46
+ it{ should be_an_instance_of Hubspot::Contact }
47
+ its(:email){ should == "testingapis@hubspot.com" }
48
+ end
49
+
50
+ context "when the contact cannot be found" do
51
+ let(:vid){ 9999999 }
52
+ it{ should be_nil }
53
+ end
54
+ end
55
+
56
+ describe "#update!" do
57
+ before{ VCR.insert_cassette("update_contact", record: :new_episodes) }
58
+ after{ VCR.eject_cassette }
59
+ let(:contact){ Hubspot::Contact.new(example_contact_hash) }
60
+ let(:params){ {firstname: "Steve", lastname: "Cunningham"} }
61
+ subject{ contact.update!(params) }
62
+
63
+ it{ should be_an_instance_of Hubspot::Contact }
64
+ its(["firstname"]){ should == "Steve" }
65
+ its(["lastname"]){ should == "Cunningham" }
66
+
67
+ context "when the request is not successful" do
68
+ let(:contact){ Hubspot::Contact.new({"vid" => "invalid", "properties" => {}})}
69
+ it "raises an error" do
70
+ expect{ subject }.to raise_error Hubspot::RequestError
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hubspot::Utils do
4
+ describe ".properties_to_hash" do
5
+ let(:properties) do
6
+ {
7
+ "email" => {"value" => "email@address.com"},
8
+ "firstname" => {"value" => "Bob"},
9
+ "lastname" => {"value" => "Smith"}
10
+ }
11
+ end
12
+ subject{ Hubspot::Utils.properties_to_hash(properties) }
13
+ its(["email"]){ should == "email@address.com" }
14
+ its(["firstname"]){ should == "Bob" }
15
+ its(["lastname"]){ should == "Smith" }
16
+ end
17
+
18
+ describe ".hash_to_properties" do
19
+ let(:hash) do
20
+ {
21
+ "email" => "email@address.com",
22
+ "firstname" => "Bob",
23
+ "lastname" => "Smith"
24
+ }
25
+ end
26
+ subject{ Hubspot::Utils.hash_to_properties(hash) }
27
+ it{ should be_an_instance_of Array }
28
+ its(:length){ should == 3 }
29
+ it{ should include({"property" => "email", "value" => "email@address.com"}) }
30
+ it{ should include({"property" => "firstname", "value" => "Bob"}) }
31
+ it{ should include({"property" => "lastname", "value" => "Smith"}) }
32
+ end
33
+
34
+ describe ".generate_url" do
35
+ let(:path){ "/test/:email/profile" }
36
+ let(:params){{}}
37
+ subject{ Hubspot::Utils.generate_url(path, params) }
38
+ before{ Hubspot.configure(hapikey: "demo") }
39
+
40
+ context "when configure hasn't been called" do
41
+ before{ Hubspot::Config.reset! }
42
+ it "raises a config exception" do
43
+ expect{ subject }.to raise_error Hubspot::ConfigurationError
44
+ end
45
+ end
46
+
47
+ context "with interpolations but no params" do
48
+ it "raises an interpolation exception" do
49
+ expect{ subject }.to raise_error Hubspot::MissingInterpolation
50
+ end
51
+ end
52
+
53
+ context "with an interpolated param" do
54
+ let(:params){ {email: "email@address.com"} }
55
+ it{ should == "https://api.hubapi.com/test/email@address.com/profile?hapikey=demo" }
56
+ end
57
+
58
+ context "with multiple interpolated params" do
59
+ let(:path){ "/test/:email/:id/profile" }
60
+ let(:params){{email: "email@address.com", id: 1234}}
61
+ it{ should == "https://api.hubapi.com/test/email@address.com/1234/profile?hapikey=demo" }
62
+ end
63
+
64
+ context "with query params" do
65
+ let(:params){{email: "email@address.com", id: 1234}}
66
+ it{ should == "https://api.hubapi.com/test/email@address.com/profile?id=1234&hapikey=demo" }
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Contacts API Live test", live: true do
4
+ before do
5
+ Hubspot.configure hapikey: "demo"
6
+ end
7
+
8
+ it "finds and updates a contact" do
9
+ contact = Hubspot::Contact.find_by_email "testingapis@hubspot.com"
10
+ contact.update! firstname: "Clint", lastname: "Eastwood"
11
+ contact = Hubspot::Contact.find_by_id contact.vid
12
+ contact["firstname"].should == "Clint"
13
+ contact["lastname"].should == "Eastwood"
14
+ end
15
+ end
@@ -0,0 +1,40 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ RSPEC_ROOT = File.dirname(__FILE__)
4
+ GEM_ROOT = File.expand_path("..", RSPEC_ROOT)
5
+
6
+ require 'simplecov'
7
+ SimpleCov.root GEM_ROOT
8
+ SimpleCov.start do
9
+ add_filter "/spec/"
10
+ end
11
+
12
+ require 'rspec'
13
+ require 'webmock/rspec'
14
+ require 'hubspot-ruby'
15
+ require 'vcr'
16
+
17
+ # Requires supporting files with custom matchers and macros, etc,
18
+ # in ./support/ and its subdirectories.
19
+ Dir["#{RSPEC_ROOT}/support/**/*.rb"].each {|f| require f}
20
+
21
+ VCR.configure do |c|
22
+ c.cassette_library_dir = "#{RSPEC_ROOT}/fixtures/vcr_cassettes"
23
+ c.hook_into :webmock
24
+ end
25
+
26
+ RSpec.configure do |config|
27
+ config.mock_with :rr
28
+
29
+ config.after(:each) do
30
+ Hubspot::Config.reset!
31
+ end
32
+
33
+ config.around(:each, live: true) do |example|
34
+ VCR.turn_off!
35
+ WebMock.disable!
36
+ example.run
37
+ WebMock.enable!
38
+ VCR.turn_on!
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,280 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hubspot-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew DiMichele
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: httparty
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.10.0
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.10.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rr
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: webmock
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: vcr
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rdoc
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: bundler
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: jeweler
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: simplecov
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ - !ruby/object:Gem::Dependency
175
+ name: awesome_print
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>='
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ! '>='
188
+ - !ruby/object:Gem::Version
189
+ version: '0'
190
+ - !ruby/object:Gem::Dependency
191
+ name: activesupport
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: 3.0.0
198
+ type: :runtime
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ! '>='
204
+ - !ruby/object:Gem::Version
205
+ version: 3.0.0
206
+ - !ruby/object:Gem::Dependency
207
+ name: httparty
208
+ requirement: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - ! '>='
212
+ - !ruby/object:Gem::Version
213
+ version: 0.10.0
214
+ type: :runtime
215
+ prerelease: false
216
+ version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: 0.10.0
222
+ description: hubspot-ruby is a wrapper for the HubSpot REST API
223
+ email: andrew@omadahealth.com
224
+ executables: []
225
+ extensions: []
226
+ extra_rdoc_files:
227
+ - LICENSE.txt
228
+ - README.md
229
+ files:
230
+ - .document
231
+ - .rspec
232
+ - Gemfile
233
+ - Gemfile.lock
234
+ - LICENSE.txt
235
+ - README.md
236
+ - Rakefile
237
+ - hubspot-ruby.gemspec
238
+ - lib/hubspot-ruby.rb
239
+ - lib/hubspot/config.rb
240
+ - lib/hubspot/contact.rb
241
+ - lib/hubspot/utils.rb
242
+ - lib/hubspot/version.rb
243
+ - spec/fixtures/vcr_cassettes/example_contact.yml
244
+ - spec/fixtures/vcr_cassettes/find_contact_by_email.yml
245
+ - spec/fixtures/vcr_cassettes/find_contact_by_id.yml
246
+ - spec/fixtures/vcr_cassettes/update_contact.yml
247
+ - spec/lib/hubspot-ruby_spec.rb
248
+ - spec/lib/hubspot/config_spec.rb
249
+ - spec/lib/hubspot/contact_spec.rb
250
+ - spec/lib/hubspot/utils_spec.rb
251
+ - spec/live/contacts_integration_spec.rb
252
+ - spec/spec_helper.rb
253
+ homepage: http://github.com/omadahealth/hubspot-ruby
254
+ licenses: []
255
+ post_install_message:
256
+ rdoc_options: []
257
+ require_paths:
258
+ - lib
259
+ required_ruby_version: !ruby/object:Gem::Requirement
260
+ none: false
261
+ requirements:
262
+ - - ! '>='
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ segments:
266
+ - 0
267
+ hash: 3359032865728179848
268
+ required_rubygems_version: !ruby/object:Gem::Requirement
269
+ none: false
270
+ requirements:
271
+ - - ! '>='
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
274
+ requirements: []
275
+ rubyforge_project:
276
+ rubygems_version: 1.8.25
277
+ signing_key:
278
+ specification_version: 3
279
+ summary: hubspot-ruby is a wrapper for the HubSpot REST API
280
+ test_files: []