cogniteev-intercom 2.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +6 -0
- data/Gemfile +13 -0
- data/MIT-LICENSE +21 -0
- data/README.md +378 -0
- data/Rakefile +21 -0
- data/changes.txt +168 -0
- data/intercom.gemspec +28 -0
- data/lib/data/cacert.pem +3965 -0
- data/lib/ext/sliceable_hash.rb +16 -0
- data/lib/intercom.rb +176 -0
- data/lib/intercom/admin.rb +9 -0
- data/lib/intercom/api_operations/convert.rb +19 -0
- data/lib/intercom/api_operations/count.rb +16 -0
- data/lib/intercom/api_operations/delete.rb +15 -0
- data/lib/intercom/api_operations/find.rb +23 -0
- data/lib/intercom/api_operations/find_all.rb +33 -0
- data/lib/intercom/api_operations/list.rb +17 -0
- data/lib/intercom/api_operations/load.rb +16 -0
- data/lib/intercom/api_operations/save.rb +51 -0
- data/lib/intercom/collection_proxy.rb +71 -0
- data/lib/intercom/company.rb +29 -0
- data/lib/intercom/contact.rb +22 -0
- data/lib/intercom/conversation.rb +17 -0
- data/lib/intercom/count.rb +21 -0
- data/lib/intercom/errors.rb +61 -0
- data/lib/intercom/event.rb +11 -0
- data/lib/intercom/extended_api_operations/reply.rb +16 -0
- data/lib/intercom/extended_api_operations/tags.rb +14 -0
- data/lib/intercom/extended_api_operations/users.rb +17 -0
- data/lib/intercom/generic_handlers/base_handler.rb +22 -0
- data/lib/intercom/generic_handlers/count.rb +59 -0
- data/lib/intercom/generic_handlers/tag.rb +71 -0
- data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
- data/lib/intercom/lib/dynamic_accessors.rb +59 -0
- data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
- data/lib/intercom/lib/flat_store.rb +31 -0
- data/lib/intercom/lib/typed_json_deserializer.rb +53 -0
- data/lib/intercom/message.rb +9 -0
- data/lib/intercom/note.rb +17 -0
- data/lib/intercom/notification.rb +20 -0
- data/lib/intercom/request.rb +166 -0
- data/lib/intercom/segment.rb +14 -0
- data/lib/intercom/subscription.rb +15 -0
- data/lib/intercom/tag.rb +23 -0
- data/lib/intercom/traits/api_resource.rb +132 -0
- data/lib/intercom/traits/dirty_tracking.rb +33 -0
- data/lib/intercom/traits/generic_handler_binding.rb +29 -0
- data/lib/intercom/traits/incrementable_attributes.rb +12 -0
- data/lib/intercom/user.rb +30 -0
- data/lib/intercom/utils.rb +62 -0
- data/lib/intercom/version.rb +3 -0
- data/spec/spec_helper.rb +308 -0
- data/spec/unit/intercom/admin_spec.rb +9 -0
- data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
- data/spec/unit/intercom/company_spec.rb +23 -0
- data/spec/unit/intercom/contact_spec.rb +25 -0
- data/spec/unit/intercom/event_spec.rb +25 -0
- data/spec/unit/intercom/lib/flat_store_spec.rb +29 -0
- data/spec/unit/intercom/message_spec.rb +21 -0
- data/spec/unit/intercom/note_spec.rb +19 -0
- data/spec/unit/intercom/notification_spec.rb +68 -0
- data/spec/unit/intercom/request_spec.rb +16 -0
- data/spec/unit/intercom/subscription_spec.rb +18 -0
- data/spec/unit/intercom/tag_spec.rb +23 -0
- data/spec/unit/intercom/traits/api_resource_spec.rb +85 -0
- data/spec/unit/intercom/user_spec.rb +230 -0
- data/spec/unit/intercom_spec.rb +90 -0
- metadata +214 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Intercom::CollectionProxy do
|
4
|
+
|
5
|
+
it "stops iterating if no next link" do
|
6
|
+
Intercom.expects(:get).with("/users", {}).returns(page_of_users(false))
|
7
|
+
emails = []
|
8
|
+
Intercom::User.all.each { |user| emails << user.email }
|
9
|
+
emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "keeps iterating if next link" do
|
13
|
+
Intercom.expects(:get).with("/users", {}).returns(page_of_users(true))
|
14
|
+
Intercom.expects(:get).with('https://api.intercom.io/users?per_page=50&page=2', {}).returns(page_of_users(false))
|
15
|
+
emails = []
|
16
|
+
Intercom::User.all.each { |user| emails << user.email }
|
17
|
+
end
|
18
|
+
|
19
|
+
it "supports indexed array access" do
|
20
|
+
Intercom.expects(:get).with("/users", {}).returns(page_of_users(false))
|
21
|
+
Intercom::User.all[0].email.must_equal 'user1@example.com'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "supports map" do
|
25
|
+
Intercom.expects(:get).with("/users", {}).returns(page_of_users(false))
|
26
|
+
emails = Intercom::User.all.map { |user| user.email }
|
27
|
+
emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "supports querying" do
|
31
|
+
Intercom.expects(:get).with("/users", {:tag_name => 'Taggart J'}).returns(page_of_users(false))
|
32
|
+
Intercom::User.find_all(:tag_name => 'Taggart J').map(&:email).must_equal %W(user1@example.com user2@example.com user3@example.com)
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Intercom::Company do
|
4
|
+
|
5
|
+
describe 'when no response raises error' do
|
6
|
+
it 'on find' do
|
7
|
+
Intercom.expects(:get).with("/companies", {:company_id => '4'}).returns(nil)
|
8
|
+
proc {Intercom::Company.find(:company_id => '4')}.must_raise Intercom::HttpError
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'on find_all' do
|
12
|
+
Intercom.expects(:get).with("/companies", {}).returns(nil)
|
13
|
+
proc {Intercom::Company.all.each {|company| }}.must_raise Intercom::HttpError
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'on load' do
|
17
|
+
Intercom.expects(:get).with("/companies", {:company_id => '4'}).returns({'type' =>'user', 'id' =>'aaaaaaaaaaaaaaaaaaaaaaaa', 'company_id' => '4', 'name' => 'MyCo'})
|
18
|
+
company = Intercom::Company.find(:company_id => '4')
|
19
|
+
Intercom.expects(:get).with('/companies/aaaaaaaaaaaaaaaaaaaaaaaa', {}).returns(nil)
|
20
|
+
proc {company.load}.must_raise Intercom::HttpError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Intercom::Contact" do
|
4
|
+
it 'should not throw ArgumentErrors when there are no parameters' do
|
5
|
+
Intercom.expects(:post)
|
6
|
+
Intercom::Contact.create
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'converting' do
|
10
|
+
let(:contact) { Intercom::Contact.from_api(user_id: 'contact_id') }
|
11
|
+
let(:user) { Intercom::User.from_api(id: 'user_id') }
|
12
|
+
|
13
|
+
it do
|
14
|
+
Intercom.expects(:post).with(
|
15
|
+
"/contacts/convert",
|
16
|
+
{
|
17
|
+
contact: { user_id: contact.user_id },
|
18
|
+
user: user.identity_hash
|
19
|
+
}
|
20
|
+
).returns(test_user)
|
21
|
+
|
22
|
+
contact.convert(user)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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 with metadata" do
|
9
|
+
Intercom.expects(:post).with('/events', {'event_name' => 'Eventful 1', 'created_at' => created_time.to_i, 'email' => 'joe@example.com', 'metadata' => {'invitee_email' => 'pi@example.org', :invite_code => 'ADDAFRIEND', 'found_date' => 12909364407}}).returns(:status => 202)
|
10
|
+
|
11
|
+
Intercom::Event.create(:event_name => "Eventful 1", :created_at => created_time,
|
12
|
+
:email => 'joe@example.com',
|
13
|
+
:metadata => {
|
14
|
+
"invitee_email" => "pi@example.org",
|
15
|
+
:invite_code => "ADDAFRIEND",
|
16
|
+
"found_date" => 12909364407
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
it "creates an event without metadata" do
|
21
|
+
Intercom.expects(:post).with('/events', {'event_name' => 'sale of item', 'email' => 'joe@example.com'})
|
22
|
+
Intercom::Event.create(:event_name => "sale of item", :email => 'joe@example.com')
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Intercom::Lib::FlatStore do
|
4
|
+
it "raises if you try to set or merge in nested hash structures" do
|
5
|
+
data = Intercom::Lib::FlatStore.new()
|
6
|
+
proc { data["thing"] = [1] }.must_raise ArgumentError
|
7
|
+
proc { data["thing"] = {1 => 2} }.must_raise ArgumentError
|
8
|
+
proc { Intercom::Lib::FlatStore.new({1 => {2 => 3}}) }.must_raise ArgumentError
|
9
|
+
end
|
10
|
+
|
11
|
+
it "raises if you try to use a non string key" do
|
12
|
+
data =Intercom::Lib::FlatStore.new()
|
13
|
+
proc { data[1] = "something" }.must_raise ArgumentError
|
14
|
+
end
|
15
|
+
|
16
|
+
it "sets and merges valid entries" do
|
17
|
+
data = Intercom::Lib::FlatStore.new()
|
18
|
+
data["a"] = 1
|
19
|
+
data[:b] = 2
|
20
|
+
data[:a].must_equal 1
|
21
|
+
data["b"].must_equal 2
|
22
|
+
data[:b].must_equal 2
|
23
|
+
data = Intercom::Lib::FlatStore.new({"a" => 1, :b => 2})
|
24
|
+
data["a"].must_equal 1
|
25
|
+
data[:a].must_equal 1
|
26
|
+
data["b"].must_equal 2
|
27
|
+
data[:b].must_equal 2
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Intercom::Message" do
|
4
|
+
|
5
|
+
let (:user) {Intercom::User.new("email" => "jim@example.com", :user_id => "12345", :created_at => Time.now, :name => "Jim Bob")}
|
6
|
+
|
7
|
+
it 'creates an user message with symbol keys' do
|
8
|
+
Intercom.expects(:post).with('/messages', {'from' => { :type => 'user', :email => 'jim@example.com'}, 'body' => 'halp'}).returns(:status => 200)
|
9
|
+
Intercom::Message.create(:from => { :type => "user", :email => "jim@example.com" }, :body => "halp")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "creates an user message with string keys" do
|
13
|
+
Intercom.expects(:post).with('/messages', {'from' => { 'type' => 'user', 'email' => 'jim@example.com'}, 'body' => 'halp'}).returns(:status => 200)
|
14
|
+
Intercom::Message.create('from' => { 'type' => "user", 'email' => "jim@example.com" }, 'body' => "halp")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "creates a admin message" do
|
18
|
+
Intercom.expects(:post).with('/messages', {'from' => { 'type' => "admin", 'id' => "1234" }, 'to' => { 'type' => 'user', 'id' => '5678' }, 'body' => 'halp', 'message_type' => 'inapp'}).returns(:status => 200)
|
19
|
+
Intercom::Message.create('from' => { 'type' => "admin", 'id' => "1234" }, :to => { 'type' => 'user', 'id' => '5678' }, 'body' => "halp", 'message_type' => 'inapp')
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "notes" do
|
4
|
+
it "creates a note" do
|
5
|
+
Intercom.expects(:post).with("/notes", {"body" => "Note to leave on user"}).returns({"body" => "<p>Note to leave on user</p>", "created_at" => 1234567890})
|
6
|
+
note = Intercom::Note.create("body" => "Note to leave on user")
|
7
|
+
note.body.must_equal "<p>Note to leave on user</p>"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "sets/gets allowed keys" do
|
11
|
+
params = {"body" => "Note body", "email" => "me@example.com", :user_id => "abc123"}
|
12
|
+
note = Intercom::Note.new(params)
|
13
|
+
|
14
|
+
note.to_hash.keys.sort.must_equal params.keys.map(&:to_s).sort
|
15
|
+
params.keys.each do | key|
|
16
|
+
note.send(key).must_equal params[key]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Intercom::Notification" do
|
4
|
+
|
5
|
+
it "converts notification hash to object" do
|
6
|
+
payload = Intercom::Notification.new(test_user_notification)
|
7
|
+
payload.must_be_instance_of Intercom::Notification
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns correct model type for User" do
|
11
|
+
payload = Intercom::Notification.new(test_user_notification)
|
12
|
+
payload.model_type.must_equal Intercom::User
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns correct User notification topic" do
|
16
|
+
payload = Intercom::Notification.new(test_user_notification)
|
17
|
+
payload.topic.must_equal "user.created"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns instance of User" do
|
21
|
+
payload = Intercom::Notification.new(test_user_notification)
|
22
|
+
payload.model.must_be_instance_of Intercom::User
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns instance of Conversation" do
|
26
|
+
payload = Intercom::Notification.new(test_conversation_notification)
|
27
|
+
payload.model.must_be_instance_of Intercom::Conversation
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns correct model type for Conversation" do
|
31
|
+
payload = Intercom::Notification.new(test_conversation_notification)
|
32
|
+
payload.model_type.must_equal Intercom::Conversation
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns correct Conversation notification topic" do
|
36
|
+
payload = Intercom::Notification.new(test_conversation_notification)
|
37
|
+
payload.topic.must_equal "conversation.user.created"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns inner User object for Conversation" do
|
41
|
+
payload = Intercom::Notification.new(test_conversation_notification)
|
42
|
+
payload.model.user.must_be_instance_of Intercom::User
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns inner User object with nil tags" do
|
46
|
+
user_notification = {
|
47
|
+
"type" => "notification_event",
|
48
|
+
"app_id" => "aa11aa",
|
49
|
+
"data" => {
|
50
|
+
"type" => "notification_event_data",
|
51
|
+
"item" => {
|
52
|
+
"type" => "user",
|
53
|
+
"id" => "abc123def",
|
54
|
+
"user_id" => "666",
|
55
|
+
"email" => "joe@example.com",
|
56
|
+
"name" => "Joe",
|
57
|
+
"tags" => {
|
58
|
+
"type" => "tag.list",
|
59
|
+
"tags" => nil
|
60
|
+
}
|
61
|
+
}
|
62
|
+
},
|
63
|
+
}
|
64
|
+
payload = Intercom::Notification.new(user_notification)
|
65
|
+
payload.model.tags.must_equal([])
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe 'Intercom::Request' do
|
5
|
+
it 'raises an error when a html error page rendered' do
|
6
|
+
response = OpenStruct.new(:code => 500)
|
7
|
+
req = Intercom::Request.new('path/', 'GET')
|
8
|
+
proc {req.parse_body('<html>somethjing</html>', response)}.must_raise(Intercom::ServerError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'parse_body returns nil if decoded_body is nil' do
|
12
|
+
response = OpenStruct.new(:code => 500)
|
13
|
+
req = Intercom::Request.new('path/', 'GET')
|
14
|
+
req.parse_body(nil, response).must_equal(nil)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Intercom::Subscription" do
|
4
|
+
it "gets a subscription" do
|
5
|
+
Intercom.expects(:get).with("/subscriptions/nsub_123456789", {}).returns(test_subscription)
|
6
|
+
subscription = Intercom::Subscription.find(:id => "nsub_123456789")
|
7
|
+
subscription.request.topics[0].must_equal "user.created"
|
8
|
+
subscription.request.topics[1].must_equal "conversation.user.replied"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "creates a subscription" do
|
12
|
+
Intercom.expects(:post).with("/subscriptions", {'url' => "http://example.com", 'topics' => ["user.created"]}).returns(test_subscription)
|
13
|
+
subscription = Intercom::Subscription.create(:url => "http://example.com", :topics => ["user.created"])
|
14
|
+
subscription.request.topics[0].must_equal "user.created"
|
15
|
+
subscription.request.url.must_equal "http://example.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Intercom::Tag" do
|
4
|
+
it "gets a tag" do
|
5
|
+
Intercom.expects(:get).with("/tags", {:name => "Test Tag"}).returns(test_tag)
|
6
|
+
tag = Intercom::Tag.find(:name => "Test Tag")
|
7
|
+
tag.name.must_equal "Test Tag"
|
8
|
+
end
|
9
|
+
|
10
|
+
it "creates a tag" do
|
11
|
+
Intercom.expects(:post).with("/tags", {'name' => "Test Tag"}).returns(test_tag)
|
12
|
+
tag = Intercom::Tag.create(:name => "Test Tag")
|
13
|
+
tag.name.must_equal "Test Tag"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "tags users" do
|
17
|
+
Intercom.expects(:post).with("/tags", {'name' => "Test Tag", 'user_ids' => ["abc123", "def456"], 'tag_or_untag' => "tag"}).returns(test_tag)
|
18
|
+
tag = Intercom::Tag.create(:name => "Test Tag", :user_ids => ["abc123", "def456"], :tag_or_untag => "tag")
|
19
|
+
tag.name.must_equal "Test Tag"
|
20
|
+
tag.tagged_user_count.must_equal 2
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Intercom::Traits::ApiResource do
|
4
|
+
let(:object_json) do
|
5
|
+
{"type"=>"company",
|
6
|
+
"id"=>"aaaaaaaaaaaaaaaaaaaaaaaa",
|
7
|
+
"app_id"=>"some-app-id",
|
8
|
+
"name"=>"SuperSuite",
|
9
|
+
"plan_id"=>1,
|
10
|
+
"remote_company_id"=>"8",
|
11
|
+
"remote_created_at"=>103201,
|
12
|
+
"created_at"=>1374056196,
|
13
|
+
"user_count"=>1,
|
14
|
+
"custom_attributes"=>{}}
|
15
|
+
end
|
16
|
+
let(:api_resource) { DummyClass.new.extend(Intercom::Traits::ApiResource)}
|
17
|
+
|
18
|
+
before(:each) { api_resource.from_response(object_json) }
|
19
|
+
|
20
|
+
it "does not set type on parsing json" do
|
21
|
+
api_resource.wont_respond_to :type
|
22
|
+
end
|
23
|
+
|
24
|
+
it "coerces time on parsing json" do
|
25
|
+
assert_equal Time.at(1374056196), api_resource.created_at
|
26
|
+
end
|
27
|
+
|
28
|
+
it "exposes string" do
|
29
|
+
assert_equal Time.at(1374056196), api_resource.created_at
|
30
|
+
end
|
31
|
+
|
32
|
+
it "dynamically defines accessors when a non-existent property is called that looks like a setter" do
|
33
|
+
api_resource.wont_respond_to :spiders
|
34
|
+
api_resource.spiders = 4
|
35
|
+
api_resource.must_respond_to :spiders
|
36
|
+
end
|
37
|
+
|
38
|
+
it "calls dynamically defined getter when asked" do
|
39
|
+
api_resource.foo = 4
|
40
|
+
assert_equal 4, api_resource.foo
|
41
|
+
end
|
42
|
+
|
43
|
+
it "accepts unix timestamps into dynamically defined date setters" do
|
44
|
+
api_resource.foo_at = 1401200468
|
45
|
+
assert_equal 1401200468, api_resource.instance_variable_get(:@foo_at)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "exposes dates correctly for dynamically defined getters" do
|
49
|
+
api_resource.foo_at = 1401200468
|
50
|
+
assert_equal Time.at(1401200468), api_resource.foo_at
|
51
|
+
end
|
52
|
+
|
53
|
+
it "throws regular method missing error when non-existent getter is called that is backed by an instance variable" do
|
54
|
+
api_resource.instance_variable_set(:@bar, 'you cant see me')
|
55
|
+
proc { api_resource.bar }.must_raise NoMethodError
|
56
|
+
end
|
57
|
+
|
58
|
+
it "throws attribute not set error when non-existent getter is called that is not backed by an instance variable" do
|
59
|
+
proc { api_resource.flubber }.must_raise Intercom::AttributeNotSetError
|
60
|
+
end
|
61
|
+
|
62
|
+
it "throws regular method missing error when non-existent method is called that cannot be an accessor" do
|
63
|
+
proc { api_resource.flubber! }.must_raise NoMethodError
|
64
|
+
proc { api_resource.flubber? }.must_raise NoMethodError
|
65
|
+
end
|
66
|
+
|
67
|
+
it "throws regular method missing error when non-existent setter is called with multiple arguments" do
|
68
|
+
proc { api_resource.send(:flubber=, 'a', 'b') }.must_raise NoMethodError
|
69
|
+
end
|
70
|
+
|
71
|
+
it "an initialized ApiResource is equal to on generated from a response" do
|
72
|
+
class ConcreteApiResource; include Intercom::Traits::ApiResource; end
|
73
|
+
initialized_api_resource = ConcreteApiResource.new(object_json)
|
74
|
+
except(object_json, 'type').keys.each do |attribute|
|
75
|
+
assert_equal initialized_api_resource.send(attribute), api_resource.send(attribute)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def except(h, *keys)
|
80
|
+
keys.each { |key| h.delete(key) }
|
81
|
+
h
|
82
|
+
end
|
83
|
+
|
84
|
+
class DummyClass; end
|
85
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Intercom::User" do
|
4
|
+
it "to_hash'es itself" do
|
5
|
+
created_at = Time.now
|
6
|
+
user = Intercom::User.new(:email => "jim@example.com", :user_id => "12345", :created_at => created_at, :name => "Jim Bob")
|
7
|
+
as_hash = user.to_hash
|
8
|
+
as_hash["email"].must_equal "jim@example.com"
|
9
|
+
as_hash["user_id"].must_equal "12345"
|
10
|
+
as_hash["created_at"].must_equal created_at.to_i
|
11
|
+
as_hash["name"].must_equal "Jim Bob"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "presents created_at and last_impression_at as Date" do
|
15
|
+
now = Time.now
|
16
|
+
user = Intercom::User.from_api(:created_at => now, :last_impression_at => now)
|
17
|
+
user.created_at.must_be_kind_of Time
|
18
|
+
user.created_at.to_s.must_equal now.to_s
|
19
|
+
user.last_impression_at.must_be_kind_of Time
|
20
|
+
user.last_impression_at.to_s.must_equal now.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is throws a Intercom::AttributeNotSetError on trying to access an attribute that has not been set" do
|
24
|
+
user = Intercom::User.new
|
25
|
+
proc { user.foo_property }.must_raise Intercom::AttributeNotSetError
|
26
|
+
end
|
27
|
+
|
28
|
+
it "presents a complete user record correctly" do
|
29
|
+
user = Intercom::User.from_api(test_user)
|
30
|
+
user.user_id.must_equal 'id-from-customers-app'
|
31
|
+
user.email.must_equal 'bob@example.com'
|
32
|
+
user.name.must_equal 'Joe Schmoe'
|
33
|
+
user.app_id.must_equal 'the-app-id'
|
34
|
+
user.session_count.must_equal 123
|
35
|
+
user.created_at.to_i.must_equal 1401970114
|
36
|
+
user.remote_created_at.to_i.must_equal 1393613864
|
37
|
+
user.updated_at.to_i.must_equal 1401970114
|
38
|
+
|
39
|
+
user.avatar.must_be_kind_of Intercom::Avatar
|
40
|
+
user.avatar.image_url.must_equal 'https://graph.facebook.com/1/picture?width=24&height=24'
|
41
|
+
|
42
|
+
user.companies.must_be_kind_of Array
|
43
|
+
user.companies.size.must_equal 1
|
44
|
+
user.companies[0].must_be_kind_of Intercom::Company
|
45
|
+
user.companies[0].company_id.must_equal "123"
|
46
|
+
user.companies[0].id.must_equal "bbbbbbbbbbbbbbbbbbbbbbbb"
|
47
|
+
user.companies[0].app_id.must_equal "the-app-id"
|
48
|
+
user.companies[0].name.must_equal "Company 1"
|
49
|
+
user.companies[0].remote_created_at.to_i.must_equal 1390936440
|
50
|
+
user.companies[0].created_at.to_i.must_equal 1401970114
|
51
|
+
user.companies[0].updated_at.to_i.must_equal 1401970114
|
52
|
+
user.companies[0].last_request_at.to_i.must_equal 1401970113
|
53
|
+
user.companies[0].monthly_spend.must_equal 0
|
54
|
+
user.companies[0].session_count.must_equal 0
|
55
|
+
user.companies[0].user_count.must_equal 1
|
56
|
+
user.companies[0].tag_ids.must_equal []
|
57
|
+
|
58
|
+
user.custom_attributes.must_be_kind_of Intercom::Lib::FlatStore
|
59
|
+
user.custom_attributes["a"].must_equal "b"
|
60
|
+
user.custom_attributes["b"].must_equal 2
|
61
|
+
|
62
|
+
user.social_profiles.size.must_equal 4
|
63
|
+
twitter_account = user.social_profiles.first
|
64
|
+
twitter_account.must_be_kind_of Intercom::SocialProfile
|
65
|
+
twitter_account.name.must_equal "twitter"
|
66
|
+
twitter_account.username.must_equal "abc"
|
67
|
+
twitter_account.url.must_equal "http://twitter.com/abc"
|
68
|
+
|
69
|
+
user.location_data.must_be_kind_of Intercom::LocationData
|
70
|
+
user.location_data.city_name.must_equal "Dublin"
|
71
|
+
user.location_data.continent_code.must_equal "EU"
|
72
|
+
user.location_data.country_name.must_equal "Ireland"
|
73
|
+
user.location_data.latitude.must_equal "90"
|
74
|
+
user.location_data.longitude.must_equal "10"
|
75
|
+
user.location_data.country_code.must_equal "IRL"
|
76
|
+
|
77
|
+
user.unsubscribed_from_emails.must_equal true
|
78
|
+
user.user_agent_data.must_equal "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'allows update_last_request_at' do
|
82
|
+
Intercom.expects(:post).with("/users", {"user_id" => "1224242", 'update_last_request_at' => true, "custom_attributes" => {}}).returns({"user_id" => "i-1224242", "last_request_at" => 1414509439})
|
83
|
+
Intercom::User.create(user_id:'1224242', update_last_request_at:true)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "allows easy setting of custom data" do
|
87
|
+
now = Time.now
|
88
|
+
user = Intercom::User.new
|
89
|
+
user.custom_attributes["mad"] = 123
|
90
|
+
user.custom_attributes["other"] = now.to_i
|
91
|
+
user.custom_attributes["thing"] = "yay"
|
92
|
+
user.to_hash["custom_attributes"].must_equal "mad" => 123, "other" => now.to_i, "thing" => "yay"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "allows easy setting of multiple companies" do
|
96
|
+
user = Intercom::User.new()
|
97
|
+
companies = [
|
98
|
+
{"name" => "Intercom", "company_id" => "6"},
|
99
|
+
{"name" => "Test", "company_id" => "9"}
|
100
|
+
]
|
101
|
+
user.companies = companies
|
102
|
+
user.to_hash["companies"].must_equal companies
|
103
|
+
end
|
104
|
+
|
105
|
+
it "rejects nested data structures in custom_attributes" do
|
106
|
+
user = Intercom::User.new()
|
107
|
+
|
108
|
+
proc { user.custom_attributes["thing"] = [1] }.must_raise(ArgumentError)
|
109
|
+
proc { user.custom_attributes["thing"] = {1 => 2} }.must_raise(ArgumentError)
|
110
|
+
proc { user.custom_attributes["thing"] = {1 => {2 => 3}} }.must_raise(ArgumentError)
|
111
|
+
|
112
|
+
user = Intercom::User.from_api(test_user)
|
113
|
+
proc { user.custom_attributes["thing"] = [1] }.must_raise(ArgumentError)
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "incrementing custom_attributes fields" do
|
117
|
+
before :each do
|
118
|
+
@now = Time.now
|
119
|
+
@user = Intercom::User.new("email" => "jo@example.com", :user_id => "i-1224242", :custom_attributes => {"mad" => 123, "another" => 432, "other" => @now.to_i, :thing => "yay"})
|
120
|
+
end
|
121
|
+
|
122
|
+
it "increments up by 1 with no args" do
|
123
|
+
@user.increment("mad")
|
124
|
+
@user.to_hash["custom_attributes"]["mad"].must_equal 124
|
125
|
+
end
|
126
|
+
|
127
|
+
it "increments up by given value" do
|
128
|
+
@user.increment("mad", 4)
|
129
|
+
@user.to_hash["custom_attributes"]["mad"].must_equal 127
|
130
|
+
end
|
131
|
+
|
132
|
+
it "increments down by given value" do
|
133
|
+
@user.increment("mad", -1)
|
134
|
+
@user.to_hash["custom_attributes"]["mad"].must_equal 122
|
135
|
+
end
|
136
|
+
|
137
|
+
it "can increment new custom data fields" do
|
138
|
+
@user.increment("new_field", 3)
|
139
|
+
@user.to_hash["custom_attributes"]["new_field"].must_equal 3
|
140
|
+
end
|
141
|
+
|
142
|
+
it "can call increment on the same key twice and increment by 2" do
|
143
|
+
@user.increment("mad")
|
144
|
+
@user.increment("mad")
|
145
|
+
@user.to_hash["custom_attributes"]["mad"].must_equal 125
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
it "fetches a user" do
|
150
|
+
Intercom.expects(:get).with("/users", {"email" => "bo@example.com"}).returns(test_user)
|
151
|
+
user = Intercom::User.find("email" => "bo@example.com")
|
152
|
+
user.email.must_equal "bob@example.com"
|
153
|
+
user.name.must_equal "Joe Schmoe"
|
154
|
+
user.session_count.must_equal 123
|
155
|
+
end
|
156
|
+
|
157
|
+
it "saves a user (always sends custom_attributes)" do
|
158
|
+
user = Intercom::User.new("email" => "jo@example.com", :user_id => "i-1224242")
|
159
|
+
Intercom.expects(:post).with("/users", {"email" => "jo@example.com", "user_id" => "i-1224242", "custom_attributes" => {}}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
|
160
|
+
user.save
|
161
|
+
end
|
162
|
+
|
163
|
+
it "saves a user with a company" do
|
164
|
+
user = Intercom::User.new("email" => "jo@example.com", :user_id => "i-1224242", :company => {'company_id' => 6, 'name' => "Intercom"})
|
165
|
+
Intercom.expects(:post).with("/users", {'custom_attributes' => {}, "user_id" => "i-1224242", "email" => "jo@example.com", "company" => {"company_id" => 6, "name" => "Intercom"}}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
|
166
|
+
user.save
|
167
|
+
end
|
168
|
+
|
169
|
+
it "saves a user with a companies" do
|
170
|
+
user = Intercom::User.new("email" => "jo@example.com", :user_id => "i-1224242", :companies => [{'company_id' => 6, 'name' => "Intercom"}])
|
171
|
+
Intercom.expects(:post).with("/users", {'custom_attributes' => {}, "email" => "jo@example.com", "user_id" => "i-1224242", "companies" => [{"company_id" => 6, "name" => "Intercom"}]}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
|
172
|
+
user.save
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'can save a user with a nil email' do
|
176
|
+
user = Intercom::User.new("email" => nil, :user_id => "i-1224242", :companies => [{'company_id' => 6, 'name' => "Intercom"}])
|
177
|
+
Intercom.expects(:post).with("/users", {'custom_attributes' => {}, "email" => nil, "user_id" => "i-1224242", "companies" => [{"company_id" => 6, "name" => "Intercom"}]}).returns({"email" => nil, "user_id" => "i-1224242"})
|
178
|
+
user.save
|
179
|
+
end
|
180
|
+
|
181
|
+
it "deletes a user" do
|
182
|
+
user = Intercom::User.new("id" => "1")
|
183
|
+
Intercom.expects(:delete).with("/users/1", {}).returns(user)
|
184
|
+
user.delete
|
185
|
+
end
|
186
|
+
|
187
|
+
it "can use User.create for convenience" do
|
188
|
+
Intercom.expects(:post).with("/users", {'custom_attributes' => {}, "email" => "jo@example.com", "user_id" => "i-1224242"}).returns({"email" => "jo@example.com", "user_id" => "i-1224242"})
|
189
|
+
user = Intercom::User.create("email" => "jo@example.com", :user_id => "i-1224242")
|
190
|
+
user.email.must_equal "jo@example.com"
|
191
|
+
end
|
192
|
+
|
193
|
+
it "updates the @user with attributes as set by the server" do
|
194
|
+
Intercom.expects(:post).with("/users", {"email" => "jo@example.com", "user_id" => "i-1224242", 'custom_attributes' => {}}).returns({"email" => "jo@example.com", "user_id" => "i-1224242", "session_count" => 4})
|
195
|
+
user = Intercom::User.create("email" => "jo@example.com", :user_id => "i-1224242")
|
196
|
+
user.session_count.must_equal 4
|
197
|
+
end
|
198
|
+
|
199
|
+
it "allows setting dates to nil without converting them to 0" do
|
200
|
+
Intercom.expects(:post).with("/users", {"email" => "jo@example.com", 'custom_attributes' => {}, "remote_created_at" => nil}).returns({"email" => "jo@example.com"})
|
201
|
+
user = Intercom::User.create("email" => "jo@example.com", "remote_created_at" => nil)
|
202
|
+
user.remote_created_at.must_equal nil
|
203
|
+
end
|
204
|
+
|
205
|
+
it "sets/gets rw keys" do
|
206
|
+
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}
|
207
|
+
user = Intercom::User.new(params)
|
208
|
+
custom_attributes = (params.keys + ['custom_attributes']).map(&:to_s).sort
|
209
|
+
user.to_hash.keys.sort.must_equal custom_attributes
|
210
|
+
params.keys.each do |key|
|
211
|
+
user.send(key).to_s.must_equal params[key].to_s
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
it "will allow extra attributes in response from api" do
|
216
|
+
user = Intercom::User.send(:from_api, {"new_param" => "some value"})
|
217
|
+
user.new_param.must_equal "some value"
|
218
|
+
end
|
219
|
+
|
220
|
+
it "returns a CollectionProxy for all without making any requests" do
|
221
|
+
Intercom.expects(:execute_request).never
|
222
|
+
all = Intercom::User.all
|
223
|
+
all.must_be_instance_of(Intercom::CollectionProxy)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "returns the total number of users" do
|
227
|
+
Intercom::Count.expects(:user_count).returns('count_info')
|
228
|
+
Intercom::User.count
|
229
|
+
end
|
230
|
+
end
|