cogniteev-intercom 2.5.4

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 (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +13 -0
  5. data/MIT-LICENSE +21 -0
  6. data/README.md +378 -0
  7. data/Rakefile +21 -0
  8. data/changes.txt +168 -0
  9. data/intercom.gemspec +28 -0
  10. data/lib/data/cacert.pem +3965 -0
  11. data/lib/ext/sliceable_hash.rb +16 -0
  12. data/lib/intercom.rb +176 -0
  13. data/lib/intercom/admin.rb +9 -0
  14. data/lib/intercom/api_operations/convert.rb +19 -0
  15. data/lib/intercom/api_operations/count.rb +16 -0
  16. data/lib/intercom/api_operations/delete.rb +15 -0
  17. data/lib/intercom/api_operations/find.rb +23 -0
  18. data/lib/intercom/api_operations/find_all.rb +33 -0
  19. data/lib/intercom/api_operations/list.rb +17 -0
  20. data/lib/intercom/api_operations/load.rb +16 -0
  21. data/lib/intercom/api_operations/save.rb +51 -0
  22. data/lib/intercom/collection_proxy.rb +71 -0
  23. data/lib/intercom/company.rb +29 -0
  24. data/lib/intercom/contact.rb +22 -0
  25. data/lib/intercom/conversation.rb +17 -0
  26. data/lib/intercom/count.rb +21 -0
  27. data/lib/intercom/errors.rb +61 -0
  28. data/lib/intercom/event.rb +11 -0
  29. data/lib/intercom/extended_api_operations/reply.rb +16 -0
  30. data/lib/intercom/extended_api_operations/tags.rb +14 -0
  31. data/lib/intercom/extended_api_operations/users.rb +17 -0
  32. data/lib/intercom/generic_handlers/base_handler.rb +22 -0
  33. data/lib/intercom/generic_handlers/count.rb +59 -0
  34. data/lib/intercom/generic_handlers/tag.rb +71 -0
  35. data/lib/intercom/generic_handlers/tag_find_all.rb +47 -0
  36. data/lib/intercom/lib/dynamic_accessors.rb +59 -0
  37. data/lib/intercom/lib/dynamic_accessors_on_method_missing.rb +53 -0
  38. data/lib/intercom/lib/flat_store.rb +31 -0
  39. data/lib/intercom/lib/typed_json_deserializer.rb +53 -0
  40. data/lib/intercom/message.rb +9 -0
  41. data/lib/intercom/note.rb +17 -0
  42. data/lib/intercom/notification.rb +20 -0
  43. data/lib/intercom/request.rb +166 -0
  44. data/lib/intercom/segment.rb +14 -0
  45. data/lib/intercom/subscription.rb +15 -0
  46. data/lib/intercom/tag.rb +23 -0
  47. data/lib/intercom/traits/api_resource.rb +132 -0
  48. data/lib/intercom/traits/dirty_tracking.rb +33 -0
  49. data/lib/intercom/traits/generic_handler_binding.rb +29 -0
  50. data/lib/intercom/traits/incrementable_attributes.rb +12 -0
  51. data/lib/intercom/user.rb +30 -0
  52. data/lib/intercom/utils.rb +62 -0
  53. data/lib/intercom/version.rb +3 -0
  54. data/spec/spec_helper.rb +308 -0
  55. data/spec/unit/intercom/admin_spec.rb +9 -0
  56. data/spec/unit/intercom/collection_proxy_spec.rb +34 -0
  57. data/spec/unit/intercom/company_spec.rb +23 -0
  58. data/spec/unit/intercom/contact_spec.rb +25 -0
  59. data/spec/unit/intercom/event_spec.rb +25 -0
  60. data/spec/unit/intercom/lib/flat_store_spec.rb +29 -0
  61. data/spec/unit/intercom/message_spec.rb +21 -0
  62. data/spec/unit/intercom/note_spec.rb +19 -0
  63. data/spec/unit/intercom/notification_spec.rb +68 -0
  64. data/spec/unit/intercom/request_spec.rb +16 -0
  65. data/spec/unit/intercom/subscription_spec.rb +18 -0
  66. data/spec/unit/intercom/tag_spec.rb +23 -0
  67. data/spec/unit/intercom/traits/api_resource_spec.rb +85 -0
  68. data/spec/unit/intercom/user_spec.rb +230 -0
  69. data/spec/unit/intercom_spec.rb +90 -0
  70. metadata +214 -0
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe "Intercom::Admin" do
4
+ it "returns a CollectionProxy for all without making any requests" do
5
+ Intercom.expects(:execute_request).never
6
+ all = Intercom::Admin.all
7
+ all.must_be_instance_of(Intercom::CollectionProxy)
8
+ end
9
+ end
@@ -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