intercom 1.0.0 → 2.0.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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -8
  3. data/Gemfile +3 -0
  4. data/README.md +208 -52
  5. data/changes.txt +3 -0
  6. data/intercom.gemspec +2 -2
  7. data/lib/ext/hash.rb +18 -0
  8. data/lib/intercom.rb +38 -43
  9. data/lib/intercom/api_operations/count.rb +16 -0
  10. data/lib/intercom/api_operations/delete.rb +15 -0
  11. data/lib/intercom/api_operations/find.rb +22 -0
  12. data/lib/intercom/api_operations/find_all.rb +33 -0
  13. data/lib/intercom/api_operations/list.rb +17 -0
  14. data/lib/intercom/api_operations/load.rb +15 -0
  15. data/lib/intercom/api_operations/save.rb +44 -0
  16. data/lib/intercom/collection_proxy.rb +66 -0
  17. data/lib/intercom/company.rb +29 -0
  18. data/lib/intercom/conversation.rb +15 -0
  19. data/lib/intercom/count.rb +21 -0
  20. data/lib/intercom/errors.rb +52 -0
  21. data/lib/intercom/event.rb +4 -101
  22. data/lib/intercom/extended_api_operations/reply.rb +16 -0
  23. data/lib/intercom/extended_api_operations/tags.rb +14 -0
  24. data/lib/intercom/extended_api_operations/users.rb +17 -0
  25. data/lib/intercom/generic_handlers/base_handler.rb +22 -0
  26. data/lib/intercom/generic_handlers/count.rb +59 -0
  27. data/lib/intercom/generic_handlers/tag.rb +71 -0
  28. data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
  29. data/lib/intercom/lib/dynamic_accessors.rb +59 -0
  30. data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
  31. data/lib/intercom/lib/flat_store.rb +31 -0
  32. data/lib/intercom/lib/typed_json_deserializer.rb +52 -0
  33. data/lib/intercom/message.rb +9 -0
  34. data/lib/intercom/note.rb +14 -42
  35. data/lib/intercom/request.rb +40 -4
  36. data/lib/intercom/segment.rb +14 -0
  37. data/lib/intercom/tag.rb +19 -78
  38. data/lib/intercom/traits/api_resource.rb +120 -0
  39. data/lib/intercom/traits/dirty_tracking.rb +33 -0
  40. data/lib/intercom/traits/generic_handler_binding.rb +29 -0
  41. data/lib/intercom/traits/incrementable_attributes.rb +23 -0
  42. data/lib/intercom/user.rb +25 -361
  43. data/lib/intercom/utils.rb +50 -0
  44. data/lib/intercom/version.rb +1 -1
  45. data/spec/spec_helper.rb +64 -33
  46. data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
  47. data/spec/unit/intercom/event_spec.rb +25 -0
  48. data/spec/unit/intercom/{flat_store_spec.rb → lib/flat_store_spec.rb} +7 -7
  49. data/spec/unit/intercom/note_spec.rb +5 -4
  50. data/spec/unit/intercom/tag_spec.rb +3 -3
  51. data/spec/unit/intercom/traits/api_resource_spec.rb +79 -0
  52. data/spec/unit/intercom/user_spec.rb +101 -119
  53. data/spec/unit/intercom_spec.rb +7 -7
  54. metadata +50 -26
  55. data/lib/intercom/flat_store.rb +0 -27
  56. data/lib/intercom/hashable_object.rb +0 -22
  57. data/lib/intercom/impression.rb +0 -63
  58. data/lib/intercom/message_thread.rb +0 -189
  59. data/lib/intercom/requires_parameters.rb +0 -10
  60. data/lib/intercom/social_profile.rb +0 -24
  61. data/lib/intercom/unix_timestamp_unwrapper.rb +0 -12
  62. data/lib/intercom/user_collection_proxy.rb +0 -52
  63. data/lib/intercom/user_resource.rb +0 -82
  64. data/spec/integration/fixtures/v1-user.json +0 -45
  65. data/spec/integration/fixtures/v1-users-impression.json +0 -3
  66. data/spec/integration/fixtures/v1-users-message_thread.json +0 -44
  67. data/spec/integration/fixtures/v1-users-message_threads.json +0 -46
  68. data/spec/integration/fixtures/v1-users-note.json +0 -49
  69. data/spec/integration/fixtures/v1-users.json +0 -144
  70. data/spec/integration/intercom_api_integration_spec.rb +0 -134
  71. data/spec/unit/intercom/impression_spec.rb +0 -18
  72. data/spec/unit/intercom/message_thread_spec.rb +0 -74
  73. data/spec/unit/intercom/user_collection_proxy_spec.rb +0 -46
  74. data/spec/unit/intercom/user_event_spec.rb +0 -83
  75. data/spec/unit/intercom/user_resource_spec.rb +0 -13
@@ -1,134 +0,0 @@
1
- require "spec_helper"
2
- require 'fakeweb'
3
-
4
- describe "api.intercom.io dummy data requests" do
5
- before :each do
6
- Intercom.app_id = "some-app-id"
7
- Intercom.api_key = "some-secret-key"
8
- Intercom.endpoint = "https://intercom.example.com"
9
- FakeWeb.clean_registry
10
- end
11
-
12
- def fixture(name)
13
- File.read(File.expand_path("../fixtures/#{name}.json", __FILE__))
14
- end
15
-
16
- it "should get all user" do
17
- FakeWeb.register_uri(:get, %r|v1/users|, :body => fixture('v1-users'))
18
- Intercom::User.all.count.must_be :>, 0
19
- end
20
-
21
- it "should get a user" do
22
- FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
23
- user = Intercom::User.find(:email => "somebody@example.com")
24
- user.name.must_equal "Somebody"
25
- end
26
-
27
- it "not found... " do
28
- FakeWeb.register_uri(:get, %r(v1/users\?email=not-found), :status => [404, "Not Found"])
29
- proc { Intercom::User.find(:email => "not-found@example.com") }.must_raise Intercom::ResourceNotFound
30
- end
31
-
32
- it "server error" do
33
- FakeWeb.register_uri(:get, %r(v1/users\?email=server-error), :status => [500, "Oh Noes"])
34
- proc { Intercom::User.find(:email => "server-error@example.com") }.must_raise Intercom::ServerError
35
- end
36
-
37
- it "authentication failure with bad api key" do
38
- FakeWeb.register_uri(:get, %r(v1/users\?email=authentication-error), :status => [401, "Authentication Error"])
39
- Intercom.app_id = "bad-app-id"
40
- Intercom.api_key = "bad-secret-key"
41
- proc { Intercom::User.find(:email => "authentication-error@example.com") }.must_raise Intercom::AuthenticationError
42
- end
43
-
44
- it "should find_all messages for a user" do
45
- FakeWeb.register_uri(:get, %r(v1/users/message_threads\?email=somebody), :body => fixture('v1-users-message_threads'))
46
- message_thread = Intercom::MessageThread.find_all(:email => "somebody@example.com").first
47
- %w(thread_id read messages created_at updated_at created_by_user).each do |expected|
48
- message_thread.send(expected).wont_be_nil
49
- end
50
- end
51
-
52
- it "handles blank string bodies" do
53
- FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
54
- user = Intercom::User.find(:email => "somebody@example.com")
55
- FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"], :body => ' ')
56
- end
57
-
58
- it "should mark message_thread as read" do
59
- FakeWeb.register_uri(:get, %r(v1/users/message_threads\?email=somebody), :body => fixture('v1-users-message_threads'))
60
- FakeWeb.register_uri(:put, %r(v1/users/message_threads), :body => fixture('v1-users-message_thread'))
61
- message_thread = Intercom::MessageThread.find_all(:email => "somebody@example.com").first
62
- message_thread.mark_as_read!
63
- end
64
-
65
- it "should create some impression" do
66
- FakeWeb.register_uri(:post, %r(v1/users/impressions), :body => fixture('v1-users-impression'))
67
- impression = Intercom::Impression.create(:email => 'somebody@example.com')
68
- impression.unread_messages.must_be :>, 0
69
- impression.email.must_equal 'somebody@example.com'
70
- end
71
-
72
- it "should create some notes" do
73
- FakeWeb.register_uri(:post, %r(v1/users/notes), :body => fixture('v1-users-note'))
74
- note = Intercom::Note.create(:body => "This is a note", :email => "somebody@example.com")
75
- note.html.must_equal "<p>This is a note</p>"
76
- note.user.email.must_equal "somebody@example.com"
77
- end
78
-
79
- it "should create an event" do
80
- FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
81
- user = Intercom::User.find(:email => "somebody@example.com")
82
- FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"])
83
- Intercom::Event.create(:event_name => "signup", :created_at => 1391691571, :user => user).event_name.must_equal "signup"
84
- end
85
-
86
- it "should create batch events" do
87
- FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
88
- user = Intercom::User.find(:email => "somebody@example.com")
89
-
90
- first_event = Intercom::Event.new
91
- first_event.event_name = "first event"
92
- first_event.created_at = Time.now
93
- first_event.user = user
94
-
95
- second_event = Intercom::Event.new
96
- second_event.event_name = "second event"
97
- second_event.created_at = Time.now
98
-
99
- FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"])
100
- Intercom::Event.save_batch_events([first_event, second_event], user)
101
- end
102
-
103
- it "should create an event from a user" do
104
- FakeWeb.register_uri(:get, %r(v1/users\?email=), :body => fixture('v1-user'))
105
- user = Intercom::User.find(:email => "somebody@example.com")
106
- FakeWeb.register_uri(:post, %r(/events), :status => ["202", "Created"])
107
- user.track_event("signup").event_name.must_equal "signup"
108
- end
109
-
110
- it "should failover to good endpoint when first one is un-reachable" do
111
- FakeWeb.allow_net_connect = %r(127.0.0.7)
112
- FakeWeb.register_uri(:get, %r(api.intercom.io/v1/users), :body => fixture('v1-user'))
113
- Intercom.endpoints = unshuffleable_array(["http://127.0.0.7", "https://api.intercom.io"])
114
- user = Intercom::User.find(:email => "somebody@example.com")
115
- user.name.must_equal "Somebody"
116
- end
117
-
118
- it "should raise error when endpoint(s) are un-reachable" do
119
- FakeWeb.register_uri(:get, %r|example\.com/|, :status => ["503", "Service Unavailable"])
120
- Intercom.endpoints = ["http://example.com"]
121
- proc { Intercom::User.find(:email => "somebody@example.com")}.must_raise Intercom::ServiceUnavailableError
122
- Intercom.endpoints = ["http://example.com", "http://api.example.com"]
123
- proc { Intercom::User.find(:email => "somebody@example.com")}.must_raise Intercom::ServiceUnavailableError
124
- end
125
-
126
- it "should raise gateway error when the request returns a 502" do
127
- FakeWeb.register_uri(:get, %r|example\.com/|, :status => ["502", "Bad Gateway"])
128
- Intercom.endpoints = ["http://example.com"]
129
- proc { Intercom::User.find(:email => "somebody@example.com")}.must_raise Intercom::BadGatewayError
130
- Intercom.endpoints = ["http://example.com", "http://api.example.com"]
131
- proc { Intercom::User.find(:email => "somebody@example.com")}.must_raise Intercom::BadGatewayError
132
-
133
- end
134
- end
@@ -1,18 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "/v1/impressions" do
4
- it "creates a good impression" do
5
- Intercom.expects(:post).with("/v1/users/impressions", {"email" => "jo@example.com", "location" => "/some/path/in/my/app"}).returns({"unread_messages" => 10})
6
- impression = Intercom::Impression.create("email" => "jo@example.com", "location" => "/some/path/in/my/app")
7
- impression.unread_messages.must_equal 10
8
- end
9
-
10
- it "sets/gets allowed keys" do
11
- params = {"user_ip" => "1.2.3.4", "user_agent" => "ie6", "location" => "/some/path/in/my/app", "email" => "me@example.com", :user_id => "abc123"}
12
- impression = Intercom::Impression.new(params)
13
- impression.to_hash.keys.sort.must_equal params.keys.map(&:to_s).sort
14
- params.keys.each do | key|
15
- impression.send(key).must_equal params[key]
16
- end
17
- end
18
- end
@@ -1,74 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "/v1/messages_threads" do
4
- it "loads messages for a user" do
5
- Intercom.expects(:get).with("/v1/users/message_threads", {"email" => "bo@example.com"}).returns(test_messages)
6
- message_threads = Intercom::MessageThread.find_all("email" => "bo@example.com")
7
- message_threads.size.must_equal 2
8
- message_threads.first.messages.size.must_equal 3
9
- message_threads.first.messages[0].html.must_equal "<p>Hey Intercom, What is up?</p>\n"
10
- end
11
-
12
- it "loads message for a thread id" do
13
- Intercom.expects(:get).with("/v1/users/message_threads", {"email" => "bo@example.com", "thread_id" => 123}).returns(test_message)
14
- message_thread = Intercom::MessageThread.find("email" => "bo@example.com", "thread_id" => 123)
15
- message_thread.messages.size.must_equal 3
16
- end
17
-
18
- it "creates a new message" do
19
- Intercom.expects(:post).with("/v1/users/message_threads", {"email" => "jo@example.com", "body" => "Hello World"}).returns(test_message)
20
- message_thread = Intercom::MessageThread.create("email" => "jo@example.com", "body" => "Hello World")
21
- message_thread.messages.size.must_equal 3
22
- end
23
-
24
- it "creates a comment on existing thread" do
25
- Intercom.expects(:post).with("/v1/users/message_threads", {"email" => "jo@example.com", "body" => "Hello World", "thread_id" => 123}).returns(test_message)
26
- message_thread = Intercom::MessageThread.create("email" => "jo@example.com", "body" => "Hello World", "thread_id" => 123)
27
- message_thread.messages.size.must_equal 3
28
- end
29
-
30
- it "marks a thread as read... " do
31
- Intercom.expects(:put).with("/v1/users/message_threads", {"read" => true, "email" => "jo@example.com", "thread_id" => 123}).returns(test_message)
32
- message_thread = Intercom::MessageThread.mark_as_read("email" => "jo@example.com", "thread_id" => 123)
33
- message_thread.messages.size.must_equal 3
34
- end
35
-
36
- it "sets/gets allowed keys" do
37
- params = {"email" => "me@example.com", :user_id => "abc123", "thread_id" => "123", "body" => "hello world", "read" => true, "url" => "http://example.com"}
38
- message_thread = Intercom::MessageThread.new(params)
39
- message_thread.to_hash.keys.sort.must_equal params.keys.map(&:to_s).sort
40
- params.keys.each do |key|
41
- message_thread.send(key).must_equal params[key]
42
- end
43
- end
44
-
45
- it "should do automatic unwrapping of the timestamp " do
46
- message_thread = Intercom::MessageThread.from_api(test_message)
47
- message_thread.created_at.to_s.must_equal Time.at(test_message['created_at']).to_s
48
- message_thread.updated_at.to_s.must_equal Time.at(test_message['updated_at']).to_s
49
- end
50
-
51
- describe "messages" do
52
- it "has nice interface onto messages thread." do
53
- message_thread = Intercom::MessageThread.from_api(test_message)
54
- message_thread.messages.size.must_equal 3
55
- message_thread.messages[0].created_at.to_s.must_equal Time.at(test_message['messages'][0]['created_at']).to_s
56
- message_thread.messages[0].html.must_equal test_message['messages'][0]['html']
57
- from_0 = test_message['messages'][0]['from']
58
- message_thread.messages[0].from.email.must_equal from_0['email']
59
- message_thread.messages[0].from.name.must_equal from_0['name']
60
- message_thread.messages[0].from.admin?.must_equal from_0['is_admin']
61
- message_thread.messages[0].from.user_id.must_equal from_0['user_id']
62
- message_thread.messages[0].from.avatar_path_50.must_equal nil
63
-
64
- message_thread.messages[1].created_at.must_equal Time.at(test_message['messages'][1]['created_at'])
65
- message_thread.messages[1].html.must_equal test_message['messages'][1]['html']
66
- from_1 = test_message['messages'][1]['from']
67
- message_thread.messages[1].from.email.must_equal from_1['email']
68
- message_thread.messages[1].from.name.must_equal from_1['name']
69
- message_thread.messages[1].from.admin?.must_equal from_1['is_admin']
70
- message_thread.messages[1].from.user_id.must_equal from_1['user_id']
71
- message_thread.messages[1].from.avatar_path_50.must_equal from_1['avatar']['square_50']
72
- end
73
- end
74
- end
@@ -1,46 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Intercom::UserCollectionProxy do
4
- before :each do
5
- Intercom.expects(:execute_request).never
6
- end
7
-
8
- it "supports each" do
9
- Intercom.expects(:get).with("/v1/users", {:page => 1}).returns(page_of_users)
10
- emails = []
11
- Intercom::User.all.each { |user| emails << user.email }
12
- emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
13
- end
14
-
15
- it "supports querying for tagged users" do
16
- Intercom.expects(:get).with("/v1/users", {:tag_id => "1234", :page => 1}).returns(page_of_users)
17
- emails = []
18
- Intercom::User.where(:tag_id => '1234').each { |user| emails << user.email }
19
- emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
20
- end
21
-
22
- it "should only pass whitelisted attributes to collection query" do
23
- Intercom.expects(:get).with("/v1/users", {:tag_name => '1234', :page => 1}).returns(page_of_users)
24
- emails = []
25
- Intercom::User.where(:danger_zone => 'BOOM', :tag_name => '1234').each { |user| emails << user.email }
26
- emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
27
- end
28
-
29
- it "supports map" do
30
- Intercom.expects(:get).with("/v1/users", {:page => 1}).returns(page_of_users).twice
31
- Intercom::User.all.map { |user| user.email }.must_equal %W(user1@example.com user2@example.com user3@example.com)
32
- Intercom::User.all.collect { |user| user.email }.must_equal %W(user1@example.com user2@example.com user3@example.com)
33
- end
34
-
35
- it "loads multiple pages" do
36
- Intercom.expects(:get).with("/v1/users", {:page => 1}).returns(page_of_users(1, 1))
37
- Intercom.expects(:get).with("/v1/users", {:page => 2}).returns(page_of_users(2, 1))
38
- Intercom.expects(:get).with("/v1/users", {:page => 3}).returns(page_of_users(3, 1))
39
- Intercom::User.all.map { |user| user.email }.must_equal %W(user1@example.com user2@example.com user3@example.com)
40
- end
41
-
42
- it "only loads the first page when counting" do
43
- Intercom.expects(:get).with("/v1/users", {:per_page => 1}).returns(page_of_users(1, 1))
44
- Intercom::User.all.count.must_equal(3)
45
- end
46
- end
@@ -1,83 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Intercom::Event" do
4
-
5
- let (:user) {Intercom::User.new("email" => "jim@example.com", :user_id => "12345", :created_at => Time.now, :name => "Jim Bob")}
6
- let (:created_time) {Time.now - 300}
7
-
8
- it "creates an event" do
9
- Intercom.expects(:post).with("/events",
10
- { :type => 'event.list',
11
- :data => [ {:event_name => "signup", :created => created_time.to_i, :type => 'event',
12
- :user => { :user_id => user.user_id},
13
- }]}).returns(:status => 200)
14
-
15
- Intercom::Event.create({ :event_name => "signup", :user => user, :created_at => created_time })
16
- end
17
-
18
- it 'automatically adds a created time upon creation' do
19
- Intercom.expects(:post).with("/events",
20
- { :type => 'event.list',
21
- :data => [ {:event_name => "sale of item", :created => Time.now.to_i, :type => 'event', :user => { :user_id => user.user_id}
22
- }]}).returns(:status => 200)
23
-
24
- Intercom::Event.create({ :event_name => "sale of item", :user => user })
25
- end
26
-
27
- it "creates an event with metadata" do
28
- Intercom.expects(:post).with("/events",
29
- { :type => 'event.list',
30
- :data => [ {:event_name => "signup", :created => created_time.to_i, :type => 'event', :user => { :user_id => user.user_id}, :metadata => { :something => "here"}
31
- }]}).returns(:status => 200)
32
- Intercom::Event.create({ :event_name => "signup", :user => user, :created_at => created_time, :metadata => { :something => "here"} })
33
- end
34
-
35
- it 'fails when no user supplied' do
36
- event = Intercom::Event.new
37
- event.event_name = "some event"
38
- event.created_at = Time.now
39
- proc { event.save }.must_raise ArgumentError, "Missing User"
40
- end
41
-
42
- it 'uses the user.email if no user.id found' do
43
- user2 = Intercom::User.new("email" => "jim@example.com", :created_at => Time.now, :name => "Jim Bob")
44
- Intercom.expects(:post).with("/events",
45
- { :type => 'event.list',
46
- :data => [ {:event_name => "signup", :created => created_time.to_i, :type => 'event',
47
- :user => { :email => user2.email}
48
- }]}).returns(:status => 200)
49
-
50
- Intercom::Event.create({ :event_name => "signup", :user => user2, :created_at => created_time })
51
- end
52
-
53
- describe 'while batching events' do
54
-
55
- let (:event1) do
56
- event = Intercom::Event.new
57
- event.event_name = "first event"
58
- event.created_at = Time.now
59
- event.user = user
60
- event
61
- end
62
-
63
- let (:event2) do
64
- event = Intercom::Event.new
65
- event.event_name = "second event"
66
- event.created_at = Time.now
67
- event
68
- end
69
-
70
- it 'creates batched events' do
71
- Intercom.expects(:post).with("/events",
72
- { :type => 'event.list',
73
- :data => [
74
- {:event_name => "first event", :created => event1.created_at.to_i,
75
- :type => 'event', :user => {:user_id => user.user_id}},
76
- {:event_name => "second event", :created => event2.created_at.to_i,
77
- :type => 'event'},
78
- ],
79
- :user => { :user_id => user.user_id}}).returns(:status => 200)
80
- Intercom::Event.save_batch_events([event1, event2], user)
81
- end
82
- end
83
- end
@@ -1,13 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Intercom::UserResource do
4
- describe "requires_params" do
5
- it "raises if they are missing" do
6
- params = {"a" => 1, "b" => 2}
7
- Intercom::UserResource.requires_parameters(params, %W(a b))
8
- expected_message = "Missing required parameters (c)."
9
- proc { Intercom::UserResource.requires_parameters(params, %W(a b c)) }.must_raise ArgumentError, expected_message
10
- capture_exception { Intercom::UserResource.requires_parameters(params, %W(a b c)) }.message.must_equal expected_message
11
- end
12
- end
13
- end