intercom 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -55,7 +55,7 @@ The API supports:
55
55
 
56
56
  ==== Notes
57
57
 
58
- Intercom::Note.create(:email => "bob@example.com", :body => "This is the text of the note"
58
+ Intercom::Note.create(:email => "bob@example.com", :body => "This is the text of the note")
59
59
 
60
60
  === Errors
61
61
 
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rake/clean'
4
4
 
5
5
  Rake::TestTask.new("spec:unit") do |spec|
6
6
  spec.libs.push "lib"
7
+ spec.libs.push "spec"
7
8
  spec.libs.push "spec/unit"
8
9
  spec.test_files = FileList['spec/unit/**/*_spec.rb']
9
10
  spec.warning = true
@@ -11,6 +12,7 @@ end
11
12
 
12
13
  Rake::TestTask.new("spec:integration") do |spec|
13
14
  spec.libs.push "lib"
15
+ spec.libs.push "spec"
14
16
  spec.test_files = FileList['spec/integration/**/*_spec.rb']
15
17
  spec.warning = true
16
18
  end
@@ -1,3 +1,6 @@
1
+ 0.0.12
2
+ - add support for multiple endpoints, with failover on service unavailable / socket connect timeout. (only relevant to customers who must use static ip addresses to access our API)
3
+
1
4
  0.0.11
2
5
  - add support for creating notes on users
3
6
 
@@ -6,9 +6,9 @@ require "intercom/version"
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "intercom"
8
8
  spec.version = Intercom::VERSION
9
- spec.authors = ["Ben McRedmond", "Ciaran Lee", "Darragh Curran",]
10
- spec.email = ["ben@intercom.io", "ciaran@intercom.io", "darragh@intercom.io"]
11
- spec.homepage = "http://www.intercom.io"
9
+ spec.authors = ["Ben McRedmond", "Ciaran Lee", "Darragh Curran", "Jeff Gardner"]
10
+ spec.email = ["ben@intercom.io", "ciaran@intercom.io", "darragh@intercom.io", "jeff@intercom.io"]
11
+ spec.homepage = "https://www.intercom.io"
12
12
  spec.summary = %q{Ruby bindings for the Intercom API}
13
13
  spec.description = %Q{Intercom (https://www.intercom.io) is a customer relationship management and messaging tool for web app owners. This library wraps the api provided by Intercom. See http://docs.intercom.io/api for more details. }
14
14
 
@@ -22,6 +22,8 @@ require "json"
22
22
  module Intercom
23
23
  @hostname = "api.intercom.io"
24
24
  @protocol = "https"
25
+ @endpoints = nil
26
+ @current_endpoint = nil
25
27
  @app_id = nil
26
28
  @api_key = nil
27
29
 
@@ -44,28 +46,58 @@ module Intercom
44
46
  end
45
47
 
46
48
  private
47
- def self.url_for_path(path)
48
- raise ArgumentError, "You must set both Intercom.app_id and Intercom.api_key to use this client. See https://github.com/intercom/intercom for usage examples." if [@app_id, @api_key].any?(&:nil?)
49
- "#{protocol}://#{@app_id}:#{@api_key}@#{hostname}/v1/#{path}"
49
+ def self.target_base_url
50
+ raise ArgumentError, "You must set both Intercom.app_id and Intercom.api_key to use this client. See https://github.com/intercom/intercom-ruby for usage examples." if [@app_id, @api_key].any?(&:nil?)
51
+ basic_auth_part = "#{@app_id}:#{@api_key}@"
52
+ current_endpoint.gsub(/(https?:\/\/)(.*)/, "\\1#{basic_auth_part}\\2")
53
+ end
54
+
55
+ def self.send_request_to_path(request)
56
+ request.execute(target_base_url)
57
+ rescue Intercom::ServiceUnavailableError => e
58
+ if endpoints.length > 1
59
+ retry_on_alternative_endpoint(request)
60
+ else
61
+ raise e
62
+ end
63
+ end
64
+
65
+ def self.retry_on_alternative_endpoint(request)
66
+ @current_endpoint = alternative_random_endpoint
67
+ request.execute(target_base_url)
68
+ end
69
+
70
+ def self.current_endpoint
71
+ return @current_endpoint if @current_endpoint && @endpoint_randomized_at > (Time.now - (60 * 5))
72
+ @endpoint_randomized_at = Time.now
73
+ @current_endpoint = random_endpoint
74
+ end
75
+
76
+ def self.random_endpoint
77
+ endpoints.shuffle.first
78
+ end
79
+
80
+ def self.alternative_random_endpoint
81
+ (endpoints.shuffle - [@current_endpoint]).first
50
82
  end
51
83
 
52
84
  def self.post(path, payload_hash)
53
- Intercom::Request.post(url_for_path(path), payload_hash).execute
85
+ send_request_to_path(Intercom::Request.post(path, payload_hash))
54
86
  end
55
87
 
56
88
  def self.delete(path, payload_hash)
57
- Intercom::Request.delete(url_for_path(path), payload_hash).execute
89
+ send_request_to_path(Intercom::Request.delete(path, payload_hash))
58
90
  end
59
91
 
60
92
  def self.put(path, payload_hash)
61
- Intercom::Request.put(url_for_path(path), payload_hash).execute
93
+ send_request_to_path(Intercom::Request.put(path, payload_hash))
62
94
  end
63
95
 
64
96
  def self.get(path, params)
65
- Intercom::Request.get(url_for_path(path), params).execute
97
+ send_request_to_path(Intercom::Request.get(path, params))
66
98
  end
67
99
 
68
- def self.check_required_params(params, path=nil)
100
+ def self.check_required_params(params, path=nil) #nodoc
69
101
  return if path.eql?("users")
70
102
  raise ArgumentError.new("Expected params Hash, got #{params.class}") unless params.is_a?(Hash)
71
103
  raise ArgumentError.new("Either email or user_id must be specified") unless params.keys.any? { |key| %W(email user_id).include?(key.to_s) }
@@ -75,18 +107,32 @@ module Intercom
75
107
  @protocol
76
108
  end
77
109
 
78
- def self.protocol=(override)
110
+ def self.protocol=(override) #nodoc
79
111
  @protocol = override
80
112
  end
81
113
 
82
- def self.hostname
114
+ def self.hostname #nodoc
83
115
  @hostname
84
116
  end
85
117
 
86
- def self.hostname=(override)
118
+ def self.hostname=(override) #nodoc
87
119
  @hostname = override
88
120
  end
89
121
 
122
+ def self.endpoint=(endpoint) #nodoc
123
+ self.endpoints = [endpoint]
124
+ @current_endpoint = nil
125
+ end
126
+
127
+ def self.endpoints=(endpoints) #nodoc
128
+ @endpoints = endpoints
129
+ @current_endpoint = nil
130
+ end
131
+
132
+ def self.endpoints
133
+ @endpoints || ["#{@protocol}://#{hostname}"]
134
+ end
135
+
90
136
  # Raised when the credentials you provide don't match a valid account on Intercom.
91
137
  # Check that you have set <b>Intercom.app_id=</b> and <b>Intercom.api_key=</b> correctly.
92
138
  class AuthenticationError < StandardError;
@@ -96,6 +142,10 @@ module Intercom
96
142
  class ServerError < StandardError;
97
143
  end
98
144
 
145
+ # Raised when we reach socket connect timeout
146
+ class ServiceUnavailableError < StandardError;
147
+ end
148
+
99
149
  # Raised when requesting resources on behalf of a user that doesn't exist in your application on Intercom.
100
150
  class ResourceNotFound < StandardError;
101
151
  end
@@ -30,7 +30,7 @@ module Intercom
30
30
  ##
31
31
  # Records that a user has interacted with your application, including the 'location' within the app they used
32
32
  def save
33
- response = Intercom.post("users/impressions", to_hash)
33
+ response = Intercom.post("/v1/users/impressions", to_hash)
34
34
  self.update_from_api_response(response)
35
35
  end
36
36
 
@@ -23,14 +23,14 @@ module Intercom
23
23
  # @return [Message]
24
24
  def self.find(params)
25
25
  requires_parameters(params, %W(thread_id))
26
- api_response = Intercom.get("users/message_threads", params)
26
+ api_response = Intercom.get("/v1/users/message_threads", params)
27
27
  MessageThread.from_api(api_response)
28
28
  end
29
29
 
30
30
  # Finds all Messages to show a particular user
31
31
  # @return [Array<Message>]
32
32
  def self.find_all(params)
33
- response = Intercom.get("users/message_threads", params)
33
+ response = Intercom.get("/v1/users/message_threads", params)
34
34
  response.map { |message| MessageThread.from_api(message) }
35
35
  end
36
36
 
@@ -50,7 +50,7 @@ module Intercom
50
50
 
51
51
  # @return [Message]
52
52
  def save(method=:post)
53
- response = Intercom.send(method, "users/message_threads", to_hash)
53
+ response = Intercom.send(method, "/v1/users/message_threads", to_hash)
54
54
  self.update_from_api_response(response)
55
55
  end
56
56
 
@@ -28,7 +28,7 @@ module Intercom
28
28
  ##
29
29
  # Records a note on a user of your application
30
30
  def save
31
- response = Intercom.post("users/notes", to_hash)
31
+ response = Intercom.post("/v1/users/notes", to_hash)
32
32
  self.update_from_api_response(response)
33
33
  end
34
34
 
@@ -3,43 +3,37 @@ require 'net/https'
3
3
 
4
4
  module Intercom
5
5
  class Request
6
- attr_accessor :uri, :net_http_method
6
+ attr_accessor :path, :net_http_method
7
7
 
8
- def initialize(uri, net_http_method)
9
- set_common_headers(net_http_method, uri)
10
-
11
- self.uri = uri
8
+ def initialize(path, net_http_method)
9
+ self.path = path
12
10
  self.net_http_method = net_http_method
13
11
  end
14
12
 
15
- def set_common_headers(method, uri)
16
- method.basic_auth(CGI.unescape(uri.user), CGI.unescape(uri.password))
13
+ def set_common_headers(method, base_uri)
14
+ method.basic_auth(CGI.unescape(base_uri.user), CGI.unescape(base_uri.password))
17
15
  method.add_field('Accept', 'application/json')
18
16
  method.add_field('AcceptEncoding', 'gzip, deflate')
19
17
  end
20
18
 
21
- def self.get(url, params)
22
- uri = URI.parse(url)
23
- new(uri, Net::HTTP::Get.new(append_query_string_to_url(uri.path, params), default_headers))
19
+ def self.get(path, params)
20
+ new(path, Net::HTTP::Get.new(append_query_string_to_url(path, params), default_headers))
24
21
  end
25
22
 
26
- def self.post(url, form_data)
27
- uri = URI.parse(url)
28
- new(uri, method_with_body(Net::HTTP::Post, uri, form_data))
23
+ def self.post(path, form_data)
24
+ new(path, method_with_body(Net::HTTP::Post, path, form_data))
29
25
  end
30
26
 
31
- def self.delete(url, params)
32
- uri = URI.parse(url)
33
- new(uri, Net::HTTP::Delete.new(append_query_string_to_url(uri.path, params), default_headers))
27
+ def self.delete(path, params)
28
+ new(path, Net::HTTP::Delete.new(append_query_string_to_url(path, params), default_headers))
34
29
  end
35
30
 
36
- def self.put(url, form_data)
37
- uri = URI.parse(url)
38
- new(uri, method_with_body(Net::HTTP::Put, uri, form_data))
31
+ def self.put(path, form_data)
32
+ new(path, method_with_body(Net::HTTP::Put, path, form_data))
39
33
  end
40
34
 
41
- def self.method_with_body(http_method, uri, params)
42
- request = http_method.send(:new, uri.request_uri, default_headers)
35
+ def self.method_with_body(http_method, path, params)
36
+ request = http_method.send(:new, path, default_headers)
43
37
  request.body = params.to_json
44
38
  request["Content-Type"] = "application/json"
45
39
  request
@@ -49,25 +43,29 @@ module Intercom
49
43
  {'Accept-Encoding' => 'gzip, deflate', 'Accept' => 'application/json'}
50
44
  end
51
45
 
52
- def client
46
+ def client(uri)
53
47
  net = Net::HTTP.new(uri.host, uri.port)
54
48
  if uri.is_a?(URI::HTTPS)
55
- net.use_ssl = uri.is_a?(URI::HTTPS)
49
+ net.use_ssl = true
56
50
  net.verify_mode = OpenSSL::SSL::VERIFY_PEER
57
51
  net.ca_file = File.join(File.dirname(__FILE__), '../data/cacert.pem')
58
52
  end
59
53
  net.read_timeout = 30
60
- net.open_timeout = 10
54
+ net.open_timeout = 3
61
55
  net
62
56
  end
63
57
 
64
- def execute
65
- client.start do |http|
58
+ def execute(target_base_url=nil)
59
+ base_uri = URI.parse(target_base_url)
60
+ set_common_headers(net_http_method, base_uri)
61
+ client(base_uri).start do |http|
66
62
  response = http.request(net_http_method)
67
63
  raise_errors_on_failure(response)
68
64
  decoded = decode(response['content-encoding'], response.body)
69
65
  JSON.parse(decoded)
70
66
  end
67
+ rescue Timeout::Error
68
+ raise Intercom::ServiceUnavailableError
71
69
  end
72
70
 
73
71
  def decode(content_encoding, body)
@@ -80,6 +78,8 @@ module Intercom
80
78
  raise Intercom::ResourceNotFound
81
79
  elsif res.code.to_i.eql?(401)
82
80
  raise Intercom::AuthenticationError
81
+ elsif res.code.to_i.eql?(503)
82
+ raise Intercom::ServiceUnavailableError
83
83
  elsif res.code.to_i.eql?(500)
84
84
  raise Intercom::ServerError
85
85
  end
@@ -6,7 +6,7 @@ module Intercom
6
6
  end
7
7
 
8
8
  def set_time_at(attribute_name, time)
9
- @attributes[attribute_name.to_s] = time.to_i
9
+ @attributes[attribute_name.to_s] = (time.nil?) ? nil : time.to_i
10
10
  end
11
11
  end
12
- end
12
+ end
@@ -30,7 +30,7 @@ module Intercom
30
30
  #
31
31
  # @return [User]
32
32
  def self.find(params)
33
- response = Intercom.get("users", params)
33
+ response = Intercom.get("/v1/users", params)
34
34
  User.from_api(response)
35
35
  end
36
36
 
@@ -91,14 +91,14 @@ module Intercom
91
91
  # This operation is not idempotent.
92
92
  # @return [User]
93
93
  def self.delete(params)
94
- response = Intercom.delete("users", params)
94
+ response = Intercom.delete("/v1/users", params)
95
95
  User.from_api(response)
96
96
  end
97
97
 
98
98
  # instance method alternative to #create
99
99
  # @return [User]
100
100
  def save
101
- response = Intercom.post("users", to_hash)
101
+ response = Intercom.post("/v1/users", to_hash)
102
102
  self.update_from_api_response(response)
103
103
  end
104
104
 
@@ -19,7 +19,7 @@ module Intercom
19
19
  class UserCollectionProxy
20
20
  # @return [Integer] number of users tracked on Intercom for this application
21
21
  def count
22
- response = Intercom.get("users", {:per_page => 1})
22
+ response = Intercom.get("/v1/users", {:per_page => 1})
23
23
  response["total_count"]
24
24
  end
25
25
 
@@ -29,7 +29,7 @@ module Intercom
29
29
  page = 1
30
30
  fetch_another_page = true
31
31
  while fetch_another_page
32
- current_page = Intercom.get("users", {:page => page})
32
+ current_page = Intercom.get("/v1/users", {:page => page})
33
33
  current_page["users"].each do |user|
34
34
  block.call User.from_api(user)
35
35
  end
@@ -1,3 +1,3 @@
1
1
  module Intercom #:nodoc:
2
- VERSION = "0.0.11"
2
+ VERSION = "0.0.12"
3
3
  end
@@ -1,10 +1,10 @@
1
- require 'intercom'
2
- require 'minitest/autorun'
1
+ require "spec_helper"
3
2
 
4
3
  describe "api.intercom.io dummy data requests" do
5
4
  before :each do
6
5
  Intercom.app_id = "dummy-app-id"
7
6
  Intercom.api_key = "dummy-secret-key"
7
+ Intercom.endpoint = "https://api.intercom.io"
8
8
  end
9
9
 
10
10
  it "should get all user" do
@@ -53,4 +53,17 @@ describe "api.intercom.io dummy data requests" do
53
53
  note.html.must_equal "<p>This is a note</p>"
54
54
  note.user.email.must_equal "somebody@example.com"
55
55
  end
56
+
57
+ it "should failover to good endpoint when first one is un-reachable" do
58
+ Intercom.endpoints = unshuffleable_array(["http://127.0.0.7", "https://api.intercom.io"])
59
+ user = Intercom::User.find(:email => "somebody@example.com")
60
+ user.name.must_equal "Somebody"
61
+ end
62
+
63
+ it "should raise error when endpoint(s) are un-reachable" do
64
+ Intercom.endpoints = ["http://127.0.0.7"]
65
+ proc { Intercom::User.find(:email => "somebody@example.com")}.must_raise Intercom::ServiceUnavailableError
66
+ Intercom.endpoints = ["http://127.0.0.7", "http://127.0.0.6"]
67
+ proc { Intercom::User.find(:email => "somebody@example.com")}.must_raise Intercom::ServiceUnavailableError
68
+ end
56
69
  end
@@ -97,4 +97,11 @@ def capture_exception(&block)
97
97
  rescue => e
98
98
  return e
99
99
  end
100
+ end
101
+
102
+ def unshuffleable_array(array)
103
+ def array.shuffle
104
+ self
105
+ end
106
+ array
100
107
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe "/v1/impressions" do
4
4
  it "creates a good impression" do
5
- Intercom.expects(:post).with("users/impressions", {"email" => "jo@example.com", "location" => "/some/path/in/my/app"}).returns({"unread_messages" => 10})
5
+ Intercom.expects(:post).with("/v1/users/impressions", {"email" => "jo@example.com", "location" => "/some/path/in/my/app"}).returns({"unread_messages" => 10})
6
6
  impression = Intercom::Impression.create("email" => "jo@example.com", "location" => "/some/path/in/my/app")
7
7
  impression.unread_messages.must_equal 10
8
8
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe "/v1/messages_threads" do
4
4
  it "loads messages for a user" do
5
- Intercom.expects(:get).with("users/message_threads", {"email" => "bo@example.com"}).returns(test_messages)
5
+ Intercom.expects(:get).with("/v1/users/message_threads", {"email" => "bo@example.com"}).returns(test_messages)
6
6
  message_threads = Intercom::MessageThread.find_all("email" => "bo@example.com")
7
7
  message_threads.size.must_equal 2
8
8
  message_threads.first.messages.size.must_equal 3
@@ -10,25 +10,25 @@ describe "/v1/messages_threads" do
10
10
  end
11
11
 
12
12
  it "loads message for a thread id" do
13
- Intercom.expects(:get).with("users/message_threads", {"email" => "bo@example.com", "thread_id" => 123}).returns(test_message)
13
+ Intercom.expects(:get).with("/v1/users/message_threads", {"email" => "bo@example.com", "thread_id" => 123}).returns(test_message)
14
14
  message_thread = Intercom::MessageThread.find("email" => "bo@example.com", "thread_id" => 123)
15
15
  message_thread.messages.size.must_equal 3
16
16
  end
17
17
 
18
18
  it "creates a new message" do
19
- Intercom.expects(:post).with("users/message_threads", {"email" => "jo@example.com", "body" => "Hello World"}).returns(test_message)
19
+ Intercom.expects(:post).with("/v1/users/message_threads", {"email" => "jo@example.com", "body" => "Hello World"}).returns(test_message)
20
20
  message_thread = Intercom::MessageThread.create("email" => "jo@example.com", "body" => "Hello World")
21
21
  message_thread.messages.size.must_equal 3
22
22
  end
23
23
 
24
24
  it "creates a comment on existing thread" do
25
- Intercom.expects(:post).with("users/message_threads", {"email" => "jo@example.com", "body" => "Hello World", "thread_id" => 123}).returns(test_message)
25
+ Intercom.expects(:post).with("/v1/users/message_threads", {"email" => "jo@example.com", "body" => "Hello World", "thread_id" => 123}).returns(test_message)
26
26
  message_thread = Intercom::MessageThread.create("email" => "jo@example.com", "body" => "Hello World", "thread_id" => 123)
27
27
  message_thread.messages.size.must_equal 3
28
28
  end
29
29
 
30
30
  it "marks a thread as read... " do
31
- Intercom.expects(:put).with("users/message_threads", {"read" => true, "email" => "jo@example.com", "thread_id" => 123}).returns(test_message)
31
+ Intercom.expects(:put).with("/v1/users/message_threads", {"read" => true, "email" => "jo@example.com", "thread_id" => 123}).returns(test_message)
32
32
  message_thread = Intercom::MessageThread.mark_as_read("email" => "jo@example.com", "thread_id" => 123)
33
33
  message_thread.messages.size.must_equal 3
34
34
  end
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe "/v1/notes" do
4
4
  it "creates a note" do
5
- Intercom.expects(:post).with("users/notes", {"body" => "Note to leave on user"}).returns({"html" => "<p>Note to leave on user</p>", "created_at" => 1234567890})
5
+ Intercom.expects(:post).with("/v1/users/notes", {"body" => "Note to leave on user"}).returns({"html" => "<p>Note to leave on user</p>", "created_at" => 1234567890})
6
6
  note = Intercom::Note.create("body" => "Note to leave on user")
7
7
  note.html.must_equal "<p>Note to leave on user</p>"
8
8
  end
@@ -6,27 +6,27 @@ describe Intercom::UserCollectionProxy do
6
6
  end
7
7
 
8
8
  it "supports each" do
9
- Intercom.expects(:get).with("users", {:page => 1}).returns(page_of_users)
9
+ Intercom.expects(:get).with("/v1/users", {:page => 1}).returns(page_of_users)
10
10
  emails = []
11
11
  Intercom::User.all.each { |user| emails << user.email }
12
12
  emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
13
13
  end
14
14
 
15
15
  it "supports map" do
16
- Intercom.expects(:get).with("users", {:page => 1}).returns(page_of_users).twice
16
+ Intercom.expects(:get).with("/v1/users", {:page => 1}).returns(page_of_users).twice
17
17
  Intercom::User.all.map { |user| user.email }.must_equal %W(user1@example.com user2@example.com user3@example.com)
18
18
  Intercom::User.all.collect { |user| user.email }.must_equal %W(user1@example.com user2@example.com user3@example.com)
19
19
  end
20
20
 
21
21
  it "yields each user to the block" do
22
- Intercom.expects(:get).with("users", {:per_page => 1}).returns(page_of_users(1,1))
22
+ Intercom.expects(:get).with("/v1/users", {:per_page => 1}).returns(page_of_users(1,1))
23
23
  Intercom::User.all.count.must_equal 3
24
24
  end
25
25
 
26
26
  it "loads multiple pages" do
27
- Intercom.expects(:get).with("users", {:page => 1}).returns(page_of_users(1, 1))
28
- Intercom.expects(:get).with("users", {:page => 2}).returns(page_of_users(2, 1))
29
- Intercom.expects(:get).with("users", {:page => 3}).returns(page_of_users(3, 1))
27
+ Intercom.expects(:get).with("/v1/users", {:page => 1}).returns(page_of_users(1, 1))
28
+ Intercom.expects(:get).with("/v1/users", {:page => 2}).returns(page_of_users(2, 1))
29
+ Intercom.expects(:get).with("/v1/users", {:page => 3}).returns(page_of_users(3, 1))
30
30
  Intercom::User.all.map { |user| user.email }.must_equal %W(user1@example.com user2@example.com user3@example.com)
31
31
  end
32
32
  end
@@ -84,7 +84,7 @@ describe "Intercom::User" do
84
84
  end
85
85
 
86
86
  it "fetches a user" do
87
- Intercom.expects(:get).with("users", {"email" => "bo@example.com"}).returns(test_user)
87
+ Intercom.expects(:get).with("/v1/users", {"email" => "bo@example.com"}).returns(test_user)
88
88
  user = Intercom::User.find("email" => "bo@example.com")
89
89
  user.email.must_equal "bob@example.com"
90
90
  user.name.must_equal "Joe Schmoe"
@@ -93,23 +93,23 @@ describe "Intercom::User" do
93
93
 
94
94
  it "saves a user" do
95
95
  user = Intercom::User.new("email" => "jo@example.com", :user_id => "i-1224242")
96
- Intercom.expects(:post).with("users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
96
+ Intercom.expects(:post).with("/v1/users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
97
97
  user.save
98
98
  end
99
99
 
100
100
  it "deletes a user" do
101
- Intercom.expects(:delete).with("users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
101
+ Intercom.expects(:delete).with("/v1/users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
102
102
  Intercom::User.delete("email" => "jo@example.com", "user_id" => "i-1224242")
103
103
  end
104
104
 
105
105
  it "can use User.create for convenience" do
106
- Intercom.expects(:post).with("users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
106
+ Intercom.expects(:post).with("/v1/users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
107
107
  user = Intercom::User.create("email" => "jo@example.com", :user_id => "i-1224242")
108
108
  user.email.must_equal "jo@example.com"
109
109
  end
110
110
 
111
111
  it "updates the @user with attributes as set by the server" do
112
- Intercom.expects(:post).with("users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242", "session_count" => 4})
112
+ Intercom.expects(:post).with("/v1/users", {"email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242", "session_count" => 4})
113
113
  user = Intercom::User.create("email" => "jo@example.com", :user_id => "i-1224242")
114
114
  user.session_count.must_equal 4
115
115
  end
@@ -123,6 +123,12 @@ describe "Intercom::User" do
123
123
  end
124
124
  end
125
125
 
126
+ it "allows setting dates to nil without converting them to 0" do
127
+ Intercom.expects(:post).with("/v1/users", {"email" => "jo@example.com", "created_at" => nil}).returns({"email" => "jo@example.com"})
128
+ user = Intercom::User.create("email" => "jo@example.com", "created_at" => nil)
129
+ user.created_at.must_equal nil
130
+ end
131
+
126
132
  it "sets/gets rw keys" do
127
133
  params = {"email" => "me@example.com", :user_id => "abc123", "name" => "Bob Smith", "last_seen_ip" => "1.2.3.4", "last_seen_user_agent" => "ie6", "created_at" => Time.now}
128
134
  user = Intercom::User.new(params)
@@ -152,4 +158,4 @@ describe "Intercom::User" do
152
158
  Intercom::User.expects(:find).with(:user_id => "abc123")
153
159
  Intercom::User.find_by_user_id("abc123")
154
160
  end
155
- end
161
+ end
@@ -14,11 +14,11 @@ describe Intercom do
14
14
  it "raises ArgumentError if no app_id or api_key specified" do
15
15
  Intercom.app_id = nil
16
16
  Intercom.api_key = nil
17
- proc { Intercom.url_for_path("something") }.must_raise ArgumentError, "You must set both Intercom.app_id and Intercom.api_key to use this client. See https://github.com/intercom/intercom-ruby for usage examples."
17
+ proc { Intercom.target_base_url }.must_raise ArgumentError, "You must set both Intercom.app_id and Intercom.api_key to use this client. See https://github.com/intercom/intercom-ruby for usage examples."
18
18
  end
19
19
 
20
20
  it "defaults to https to api.intercom.io" do
21
- Intercom.url_for_path("some/resource/path").must_equal "https://abc123:super-secret-key@api.intercom.io/v1/some/resource/path"
21
+ Intercom.target_base_url.must_equal "https://abc123:super-secret-key@api.intercom.io"
22
22
  end
23
23
 
24
24
  it "raises ResourceNotFound if get a 404" do
@@ -29,6 +29,7 @@ describe Intercom do
29
29
  before do
30
30
  @protocol = Intercom.protocol
31
31
  @hostname = Intercom.hostname
32
+ Intercom.endpoints = nil
32
33
  end
33
34
 
34
35
  after do
@@ -39,11 +40,35 @@ describe Intercom do
39
40
  it "allows overriding of the endpoint and protocol" do
40
41
  Intercom.protocol = "http"
41
42
  Intercom.hostname = "localhost:3000"
42
- Intercom.url_for_path("some/resource/path").must_equal "http://abc123:super-secret-key@localhost:3000/v1/some/resource/path"
43
+ Intercom.target_base_url.must_equal "http://abc123:super-secret-key@localhost:3000"
44
+ end
45
+
46
+ it "prefers endpoints" do
47
+ Intercom.endpoint = "https://localhost:7654"
48
+ Intercom.target_base_url.must_equal "https://abc123:super-secret-key@localhost:7654"
49
+ Intercom.endpoints = unshuffleable_array(["http://example.com","https://localhost:7654"])
50
+ Intercom.target_base_url.must_equal "http://abc123:super-secret-key@example.com"
51
+ end
52
+
53
+ it "has endpoints" do
54
+ Intercom.endpoints.must_equal ["https://api.intercom.io"]
55
+ Intercom.endpoints = ["http://example.com","https://localhost:7654"]
56
+ Intercom.endpoints.must_equal ["http://example.com","https://localhost:7654"]
57
+ end
58
+
59
+ it "should randomize endpoints if last checked endpoint is > 5 minutes ago" do
60
+ Intercom.instance_variable_set(:@current_endpoint, "http://start")
61
+ Intercom.instance_variable_set(:@endpoints, ["http://alternative"])
62
+ Intercom.instance_variable_set(:@endpoint_randomized_at, Time.now - 120)
63
+ Intercom.current_endpoint.must_equal "http://start"
64
+ Intercom.instance_variable_set(:@endpoint_randomized_at, Time.now - 360)
65
+ Intercom.current_endpoint.must_equal "http://alternative"
66
+ Intercom.instance_variable_get(:@endpoint_randomized_at).to_i.must_be_close_to Time.now.to_i
43
67
  end
44
68
  end
45
69
  end
46
70
 
71
+
47
72
  it "checks for email or user id" do
48
73
  proc { Intercom.check_required_params("else") }.must_raise ArgumentError, "Expected params Hash, got String"
49
74
  proc { Intercom.check_required_params(:something => "else") }.must_raise ArgumentError, "Either email or user_id must be specified"
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: intercom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ben McRedmond
9
9
  - Ciaran Lee
10
10
  - Darragh Curran
11
+ - Jeff Gardner
11
12
  autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2013-01-30 00:00:00.000000000 Z
15
+ date: 2013-02-07 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: minitest
@@ -68,6 +69,7 @@ email:
68
69
  - ben@intercom.io
69
70
  - ciaran@intercom.io
70
71
  - darragh@intercom.io
72
+ - jeff@intercom.io
71
73
  executables: []
72
74
  extensions: []
73
75
  extra_rdoc_files: []
@@ -94,6 +96,7 @@ files:
94
96
  - lib/intercom/user_resource.rb
95
97
  - lib/intercom/version.rb
96
98
  - spec/integration/intercom_api_integration_spec.rb
99
+ - spec/spec_helper.rb
97
100
  - spec/unit/intercom/impression_spec.rb
98
101
  - spec/unit/intercom/message_thread_spec.rb
99
102
  - spec/unit/intercom/note_spec.rb
@@ -102,8 +105,7 @@ files:
102
105
  - spec/unit/intercom/user_resource_spec.rb
103
106
  - spec/unit/intercom/user_spec.rb
104
107
  - spec/unit/intercom_spec.rb
105
- - spec/unit/spec_helper.rb
106
- homepage: http://www.intercom.io
108
+ homepage: https://www.intercom.io
107
109
  licenses: []
108
110
  post_install_message:
109
111
  rdoc_options: []
@@ -129,6 +131,7 @@ specification_version: 3
129
131
  summary: Ruby bindings for the Intercom API
130
132
  test_files:
131
133
  - spec/integration/intercom_api_integration_spec.rb
134
+ - spec/spec_helper.rb
132
135
  - spec/unit/intercom/impression_spec.rb
133
136
  - spec/unit/intercom/message_thread_spec.rb
134
137
  - spec/unit/intercom/note_spec.rb
@@ -137,4 +140,3 @@ test_files:
137
140
  - spec/unit/intercom/user_resource_spec.rb
138
141
  - spec/unit/intercom/user_spec.rb
139
142
  - spec/unit/intercom_spec.rb
140
- - spec/unit/spec_helper.rb