intercom 3.9.5 → 4.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 (81) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +235 -222
  3. data/Rakefile +1 -1
  4. data/changes.txt +3 -0
  5. data/lib/intercom.rb +27 -22
  6. data/lib/intercom/api_operations/archive.rb +2 -1
  7. data/lib/intercom/api_operations/delete.rb +16 -0
  8. data/lib/intercom/api_operations/find.rb +5 -2
  9. data/lib/intercom/api_operations/find_all.rb +4 -3
  10. data/lib/intercom/api_operations/list.rb +4 -1
  11. data/lib/intercom/api_operations/load.rb +4 -2
  12. data/lib/intercom/api_operations/nested_resource.rb +70 -0
  13. data/lib/intercom/api_operations/save.rb +5 -4
  14. data/lib/intercom/api_operations/scroll.rb +4 -5
  15. data/lib/intercom/api_operations/search.rb +3 -2
  16. data/lib/intercom/base_collection_proxy.rb +72 -0
  17. data/lib/intercom/client.rb +20 -25
  18. data/lib/intercom/client_collection_proxy.rb +17 -39
  19. data/lib/intercom/company.rb +8 -0
  20. data/lib/intercom/contact.rb +21 -3
  21. data/lib/intercom/conversation.rb +4 -0
  22. data/lib/intercom/data_attribute.rb +7 -0
  23. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  24. data/lib/intercom/deprecated_resources.rb +13 -0
  25. data/lib/intercom/errors.rb +3 -0
  26. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  27. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  28. data/lib/intercom/lead.rb +21 -0
  29. data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
  30. data/lib/intercom/note.rb +4 -0
  31. data/lib/intercom/request.rb +37 -33
  32. data/lib/intercom/scroll_collection_proxy.rb +33 -38
  33. data/lib/intercom/search_collection_proxy.rb +30 -65
  34. data/lib/intercom/service/base_service.rb +7 -0
  35. data/lib/intercom/service/company.rb +0 -12
  36. data/lib/intercom/service/contact.rb +21 -10
  37. data/lib/intercom/service/conversation.rb +12 -3
  38. data/lib/intercom/service/data_attribute.rb +20 -0
  39. data/lib/intercom/service/lead.rb +41 -0
  40. data/lib/intercom/service/note.rb +4 -8
  41. data/lib/intercom/service/subscription.rb +2 -2
  42. data/lib/intercom/service/tag.rb +9 -9
  43. data/lib/intercom/service/visitor.rb +17 -8
  44. data/lib/intercom/tag.rb +4 -0
  45. data/lib/intercom/traits/api_resource.rb +28 -17
  46. data/lib/intercom/user.rb +12 -3
  47. data/lib/intercom/utils.rb +13 -2
  48. data/lib/intercom/version.rb +1 -1
  49. data/lib/intercom/visitor.rb +0 -2
  50. data/spec/spec_helper.rb +738 -513
  51. data/spec/unit/intercom/admin_spec.rb +2 -2
  52. data/spec/unit/intercom/base_collection_proxy_spec.rb +30 -0
  53. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  54. data/spec/unit/intercom/client_spec.rb +25 -26
  55. data/spec/unit/intercom/company_spec.rb +13 -15
  56. data/spec/unit/intercom/contact_spec.rb +289 -33
  57. data/spec/unit/intercom/conversation_spec.rb +29 -7
  58. data/spec/unit/intercom/count_spec.rb +4 -4
  59. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  60. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  61. data/spec/unit/intercom/event_spec.rb +9 -11
  62. data/spec/unit/intercom/job_spec.rb +24 -24
  63. data/spec/unit/intercom/lead_spec.rb +57 -0
  64. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  65. data/spec/unit/intercom/message_spec.rb +1 -1
  66. data/spec/unit/intercom/note_spec.rb +4 -10
  67. data/spec/unit/intercom/request_spec.rb +1 -1
  68. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  69. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  70. data/spec/unit/intercom/segment_spec.rb +2 -2
  71. data/spec/unit/intercom/subscription_spec.rb +5 -6
  72. data/spec/unit/intercom/tag_spec.rb +22 -14
  73. data/spec/unit/intercom/team_spec.rb +2 -2
  74. data/spec/unit/intercom/traits/api_resource_spec.rb +53 -51
  75. data/spec/unit/intercom/user_spec.rb +224 -226
  76. data/spec/unit/intercom/visitor_spec.rb +49 -0
  77. data/spec/unit/intercom_spec.rb +5 -3
  78. metadata +22 -7
  79. data/lib/intercom/customer.rb +0 -10
  80. data/lib/intercom/service/customer.rb +0 -14
  81. data/spec/unit/intercom/visitors_spec.rb +0 -61
@@ -1,12 +1,12 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Intercom::Admin" do
4
- let (:client) { Intercom::Client.new(token: 'token') }
4
+ let(:client) { Intercom::Client.new(token: 'token') }
5
5
 
6
6
  it "returns a CollectionProxy for all without making any requests" do
7
7
  client.expects(:execute_request).never
8
8
  all = client.admins.all
9
- all.must_be_instance_of(Intercom::ClientCollectionProxy)
9
+ _(all).must_be_instance_of(Intercom::ClientCollectionProxy)
10
10
  end
11
11
 
12
12
  it "gets me (access token method only)" do
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ describe Intercom::BaseCollectionProxy do
4
+ let(:client) { Intercom::Client.new(token: 'token') }
5
+
6
+ it "stops iterating if no starting after value" do
7
+ client.expects(:get).with("/contacts", {}). returns(page_of_contacts(false))
8
+ emails = []
9
+ client.contacts.all.each { |contact| emails << contact.email }
10
+ _(emails).must_equal %w[test1@example.com test2@example.com test3@example.com]
11
+ end
12
+
13
+ it "keeps iterating if starting after value" do
14
+ client.expects(:get).with("/contacts", {}).returns(page_of_contacts(true))
15
+ client.expects(:get).with('/contacts', { starting_after: "EnCrYpTeDsTrInG" }).returns(page_of_contacts(false))
16
+ emails = []
17
+ client.contacts.all.each { |contact| emails << contact.email }
18
+ end
19
+
20
+ it "supports indexed array access" do
21
+ client.expects(:get).with("/contacts", {}).returns(page_of_contacts(false))
22
+ _(client.contacts.all[0].email).must_equal "test1@example.com"
23
+ end
24
+
25
+ it "supports map" do
26
+ client.expects(:get).with("/contacts", {}).returns(page_of_contacts(false))
27
+ emails = client.contacts.all.map { |contact| contact.email }
28
+ _(emails).must_equal %w[test1@example.com test2@example.com test3@example.com]
29
+ end
30
+ end
@@ -1,80 +1,80 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Intercom::ClientCollectionProxy do
4
- let (:client) { Intercom::Client.new(app_id: 'app_id', api_key: 'api_key') }
4
+ let(:client) { Intercom::Client.new(token: 'token') }
5
5
 
6
6
  it "stops iterating if no next link" do
7
- client.expects(:get).with("/users", {}).returns(page_of_users(false))
8
- emails = []
9
- client.users.all.each { |user| emails << user.email }
10
- emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
7
+ client.expects(:get).with("/companies", {}).returns(page_of_companies(false))
8
+ names = []
9
+ client.companies.all.each { |company| names << company.name }
10
+ _(names).must_equal %W(company1 company2 company3)
11
11
  end
12
12
 
13
13
  it "keeps iterating if next link" do
14
- client.expects(:get).with("/users", {}).returns(page_of_users(true))
15
- client.expects(:get).with('https://api.intercom.io/users?per_page=50&page=2', {}).returns(page_of_users(false))
16
- emails = []
17
- client.users.all.each { |user| emails << user.email }
14
+ client.expects(:get).with("/companies", {}).returns(page_of_companies(true))
15
+ client.expects(:get).with('https://api.intercom.io/companies?per_page=50&page=2', {}).returns(page_of_companies(false))
16
+ names = []
17
+ client.companies.all.each { |company| names << company.name }
18
18
  end
19
19
 
20
20
  it "supports indexed array access" do
21
- client.expects(:get).with("/users", {}).returns(page_of_users(false))
22
- client.users.all[0].email.must_equal 'user1@example.com'
21
+ client.expects(:get).with("/companies", {}).returns(page_of_companies(false))
22
+ _(client.companies.all[0].name).must_equal 'company1'
23
23
  end
24
24
 
25
25
  it "supports map" do
26
- client.expects(:get).with("/users", {}).returns(page_of_users(false))
27
- emails = client.users.all.map { |user| user.email }
28
- emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
26
+ client.expects(:get).with("/companies", {}).returns(page_of_companies(false))
27
+ names = client.companies.all.map { |company| company.name }
28
+ _(names).must_equal %W(company1 company2 company3)
29
29
  end
30
30
 
31
31
  it "supports querying" do
32
- client.expects(:get).with("/users", {:tag_name => 'Taggart J'}).returns(page_of_users(false))
33
- client.users.find_all(:tag_name => 'Taggart J').map(&:email).must_equal %W(user1@example.com user2@example.com user3@example.com)
32
+ client.expects(:get).with("/companies", {:tag_name => 'Taggart J'}).returns(page_of_companies(false))
33
+ _(client.companies.find_all(:tag_name => 'Taggart J').map(&:name)).must_equal %W(company1 company2 company3)
34
34
  end
35
35
 
36
36
  it "supports single page pagination" do
37
- users = [test_user("user1@example.com"), test_user("user2@example.com"), test_user("user3@example.com"),
38
- test_user("user4@example.com"), test_user("user5@example.com"), test_user("user6@example.com"),
39
- test_user("user7@example.com"), test_user("user8@example.com"), test_user("user9@example.com"),
40
- test_user("user10@example.com")]
41
- client.expects(:get).with("/users", {:type=>'users', :per_page => 10, :page => 1}).returns(users_pagination(include_next_link: false, per_page: 10, page: 1, total_pages: 1, total_count: 10, user_list: users))
42
- result = client.users.find_all(:type=>'users', :per_page => 10, :page => 1).map {|user| user.email }
43
- result.must_equal %W(user1@example.com user2@example.com user3@example.com user4@example.com user5@example.com user6@example.com user7@example.com user8@example.com user9@example.com user10@example.com)
37
+ companies = [test_company("company1"), test_company("company2"), test_company("company3"),
38
+ test_company("company4"), test_company("company5"), test_company("company6"),
39
+ test_company("company7"), test_company("company8"), test_company("company9"),
40
+ test_company("company10")]
41
+ client.expects(:get).with("/companies", {:type=>'companies', :per_page => 10, :page => 1}).returns(companies_pagination(include_next_link: false, per_page: 10, page: 1, total_pages: 1, total_count: 10, company_list: companies))
42
+ result = client.companies.find_all(:type=>'companies', :per_page => 10, :page => 1).map {|company| company.name }
43
+ _(result).must_equal %W(company1 company2 company3 company4 company5 company6 company7 company8 company9 company10)
44
44
  end
45
45
 
46
46
  it "supports multi page pagination" do
47
- users = [test_user("user3@example.com"), test_user("user4@example.com")]
48
- client.expects(:get).with("/users", {:type=>'users', :per_page => 2, :page => 3}).returns(users_pagination(include_next_link: true, per_page: 2, page: 3, total_pages: 5, total_count: 10, user_list: users))
49
- result = client.users.find_all(:type=>'users', :per_page => 2, :page => 3).map {|user| user.email }
50
- result.must_equal %W(user3@example.com user4@example.com)
47
+ companies = [test_company("company3"), test_company("company4")]
48
+ client.expects(:get).with("/companies", {:type=>'companies', :per_page => 2, :page => 3}).returns(companies_pagination(include_next_link: true, per_page: 2, page: 3, total_pages: 5, total_count: 10, company_list: companies))
49
+ result = client.companies.find_all(:type=>'companies', :per_page => 2, :page => 3).map {|company| company.name }
50
+ _(result).must_equal %W(company3 company4)
51
51
  end
52
52
 
53
53
  it "works with page out of range request" do
54
- users = []
55
- client.expects(:get).with("/users", {:type=>'users', :per_page => 2, :page => 30}).returns(users_pagination(include_next_link: true, per_page: 2, page: 30, total_pages: 2, total_count: 3, user_list: users))
56
- result = client.users.find_all(:type=>'users', :per_page => 2, :page => 30).map {|user| user.email }
57
- result.must_equal %W()
54
+ companies = []
55
+ client.expects(:get).with("/companies", {:type=>'companies', :per_page => 2, :page => 30}).returns(companies_pagination(include_next_link: true, per_page: 2, page: 30, total_pages: 2, total_count: 3, company_list: companies))
56
+ result = client.companies.find_all(:type=>'companies', :per_page => 2, :page => 30).map {|company| company.name }
57
+ _(result).must_equal %W()
58
58
  end
59
59
 
60
60
  it "works with asc order" do
61
61
  test_date=1457337600
62
62
  time_increment=1000
63
- users = [test_user_dates(email="user1@example.com", created_at=test_date), test_user_dates(email="user2@example.com", created_at=test_date-time_increment),
64
- test_user_dates(email="user3@example.com", created_at=test_date-2*time_increment), test_user_dates(email="user4@example.com", created_at=test_date-3*time_increment)]
65
- client.expects(:get).with("/users", {:type=>'users', :per_page => 4, :page => 5, :order => "asc", :sort => "created_at"}).returns(users_pagination(include_next_link: true, per_page: 4, page: 5, total_pages: 6, total_count: 30, user_list: users))
66
- result = client.users.find_all(:type=>'users', :per_page => 4, :page => 5, :order => "asc", :sort => "created_at").map(&:email)
67
- result.must_equal %W(user1@example.com user2@example.com user3@example.com user4@example.com)
63
+ companies = [test_company_dates(name="company1", created_at=test_date), test_company_dates(name="company2", created_at=test_date-time_increment),
64
+ test_company_dates(name="company3", created_at=test_date-2*time_increment), test_company_dates(name="company4", created_at=test_date-3*time_increment)]
65
+ client.expects(:get).with("/companies", {:type=>'companies', :per_page => 4, :page => 5, :order => "asc", :sort => "created_at"}).returns(companies_pagination(include_next_link: true, per_page: 4, page: 5, total_pages: 6, total_count: 30, company_list: companies))
66
+ result = client.companies.find_all(:type=>'companies', :per_page => 4, :page => 5, :order => "asc", :sort => "created_at").map(&:name)
67
+ _(result).must_equal %W(company1 company2 company3 company4)
68
68
  end
69
69
 
70
70
  it "works with desc order" do
71
71
  test_date=1457337600
72
72
  time_increment=1000
73
- users = [test_user_dates(email="user4@example.com", created_at=3*test_date), test_user_dates(email="user3@example.com", created_at=test_date-2*time_increment),
74
- test_user_dates(email="user2@example.com", created_at=test_date-time_increment), test_user_dates(email="user1@example.com", created_at=test_date)]
75
- client.expects(:get).with("/users", {:type=>'users', :per_page => 4, :page => 5, :order => "desc", :sort => "created_at"}).returns(users_pagination(include_next_link: true, per_page: 4, page: 5, total_pages: 6, total_count: 30, user_list: users))
76
- result = client.users.find_all(:type=>'users', :per_page => 4, :page => 5, :order => "desc", :sort => "created_at").map {|user| user.email }
77
- result.must_equal %W(user4@example.com user3@example.com user2@example.com user1@example.com)
73
+ companies = [test_company_dates(name="company4", created_at=3*test_date), test_company_dates(name="company3", created_at=test_date-2*time_increment),
74
+ test_company_dates(name="company2", created_at=test_date-time_increment), test_company_dates(name="company1", created_at=test_date)]
75
+ client.expects(:get).with("/companies", {:type=>'companies', :per_page => 4, :page => 5, :order => "desc", :sort => "created_at"}).returns(companies_pagination(include_next_link: true, per_page: 4, page: 5, total_pages: 6, total_count: 30, company_list: companies))
76
+ result = client.companies.find_all(:type=>'companies', :per_page => 4, :page => 5, :order => "desc", :sort => "created_at").map {|company| company.name }
77
+ _(result).must_equal %W(company4 company3 company2 company1)
78
78
  end
79
79
 
80
80
  end
@@ -1,19 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  module Intercom
4
6
  describe Client do
5
- let(:app_id) { 'myappid' }
6
- let(:api_key) { 'myapikey' }
7
+ let(:token) { 'my_access_token' }
7
8
  let(:client) do
8
9
  Client.new(
9
- app_id: app_id,
10
- api_key: api_key,
10
+ token: token,
11
11
  handle_rate_limit: true
12
12
  )
13
13
  end
14
14
 
15
15
  it 'should set the base url' do
16
- client.base_url.must_equal('https://api.intercom.io')
16
+ _(client.base_url).must_equal('https://api.intercom.io')
17
17
  end
18
18
 
19
19
  it 'should have handle_rate_limit set' do
@@ -22,34 +22,34 @@ module Intercom
22
22
 
23
23
  it 'should be able to change the base url' do
24
24
  prev = client.options(Intercom::Client.set_base_url('https://mymockintercom.io'))
25
- client.base_url.must_equal('https://mymockintercom.io')
25
+ _(client.base_url).must_equal('https://mymockintercom.io')
26
26
  client.options(prev)
27
- client.base_url.must_equal('https://api.intercom.io')
27
+ _(client.base_url).must_equal('https://api.intercom.io')
28
28
  end
29
29
 
30
30
  it 'should be able to change the timeouts' do
31
31
  prev = client.options(Intercom::Client.set_timeouts(open_timeout: 10, read_timeout: 15))
32
- client.timeouts.must_equal(open_timeout: 10, read_timeout: 15)
32
+ _(client.timeouts).must_equal(open_timeout: 10, read_timeout: 15)
33
33
  client.options(prev)
34
- client.timeouts.must_equal(open_timeout: 30, read_timeout: 90)
34
+ _(client.timeouts).must_equal(open_timeout: 30, read_timeout: 90)
35
35
  end
36
36
 
37
37
  it 'should be able to change the open timeout individually' do
38
38
  prev = client.options(Intercom::Client.set_timeouts(open_timeout: 50))
39
- client.timeouts.must_equal(open_timeout: 50, read_timeout: 90)
39
+ _(client.timeouts).must_equal(open_timeout: 50, read_timeout: 90)
40
40
  client.options(prev)
41
- client.timeouts.must_equal(open_timeout: 30, read_timeout: 90)
41
+ _(client.timeouts).must_equal(open_timeout: 30, read_timeout: 90)
42
42
  end
43
43
 
44
44
  it 'should be able to change the read timeout individually' do
45
45
  prev = client.options(Intercom::Client.set_timeouts(read_timeout: 50))
46
- client.timeouts.must_equal(open_timeout: 30, read_timeout: 50)
46
+ _(client.timeouts).must_equal(open_timeout: 30, read_timeout: 50)
47
47
  client.options(prev)
48
- client.timeouts.must_equal(open_timeout: 30, read_timeout: 90)
48
+ _(client.timeouts).must_equal(open_timeout: 30, read_timeout: 90)
49
49
  end
50
50
 
51
51
  it 'should raise on nil credentials' do
52
- proc { Client.new(app_id: nil, api_key: nil) }.must_raise MisconfiguredClientError
52
+ _(proc { Client.new(token: nil) }).must_raise MisconfiguredClientError
53
53
  end
54
54
 
55
55
  describe 'API version' do
@@ -58,42 +58,41 @@ module Intercom
58
58
  end
59
59
 
60
60
  it 'allows api version to be provided' do
61
- Client.new(app_id: app_id, api_key: api_key, api_version: '1.0').api_version.must_equal('1.0')
61
+ _(Client.new(token: token, api_version: '2.0').api_version).must_equal('2.0')
62
62
  end
63
63
 
64
64
  it 'allows api version to be nil' do
65
65
  # matches default behavior, and will honor version set in the Developer Hub
66
- assert_nil(Client.new(app_id: app_id, api_key: api_key, api_version: nil).api_version)
66
+ assert_nil(Client.new(token: token, api_version: nil).api_version)
67
67
  end
68
68
 
69
69
  it 'allows api version to be Unstable' do
70
- Client.new(app_id: app_id, api_key: api_key, api_version: 'Unstable').api_version.must_equal('Unstable')
70
+ _(Client.new(token: token, api_version: 'Unstable').api_version).must_equal('Unstable')
71
71
  end
72
72
 
73
73
  it 'raises on invalid api version' do
74
- proc { Client.new(app_id: app_id, api_key: api_key, api_version: '0.2') }.must_raise MisconfiguredClientError
74
+ _(proc { Client.new(token: token, api_version: '0.2') }).must_raise MisconfiguredClientError
75
75
  end
76
76
 
77
77
  it 'raises on empty api version' do
78
- proc { Client.new(app_id: app_id, api_key: api_key, api_version: '') }.must_raise MisconfiguredClientError
78
+ _(proc { Client.new(token: token, api_version: '') }).must_raise MisconfiguredClientError
79
79
  end
80
80
 
81
- it "assigns works" do
82
- stub_request(:any, "https://api.intercom.io/users?id=123").to_return(
83
- status: [200, "OK"],
81
+ it 'assigns works' do
82
+ stub_request(:any, 'https://api.intercom.io/contacts?id=123').to_return(
83
+ status: [200, 'OK'],
84
84
  headers: { 'X-RateLimit-Reset' => Time.now.utc + 10 },
85
- body: { "test": "testing" }.to_json
85
+ body: { "test": 'testing' }.to_json
86
86
  )
87
87
 
88
- client.get("/users", { id: "123" })
88
+ client.get('/contacts', id: '123')
89
89
  end
90
90
  end
91
91
 
92
92
  describe 'OAuth clients' do
93
93
  it 'supports "token"' do
94
94
  client = Client.new(token: 'foo')
95
- client.username_part.must_equal('foo')
96
- client.password_part.must_equal('')
95
+ _(client.token).must_equal('foo')
97
96
  end
98
97
  end
99
98
  end
@@ -1,40 +1,38 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Intercom::Company do
4
- let (:client) { Intercom::Client.new(app_id: "app_id", api_key: "api_key") }
4
+ let(:client) { Intercom::Client.new(token: 'token') }
5
5
 
6
6
  describe "when no response raises error" do
7
7
  it "on find" do
8
8
  client.expects(:get).with("/companies", {:company_id => "4"}).returns(nil)
9
- proc {client.companies.find(:company_id => "4")}.must_raise Intercom::HttpError
9
+ _(proc { client.companies.find(:company_id => "4")}).must_raise Intercom::HttpError
10
10
  end
11
11
 
12
12
  it "on find_all" do
13
13
  client.expects(:get).with("/companies", {}).returns(nil)
14
- proc {client.companies.all.each {|company| }}.must_raise Intercom::HttpError
14
+ _(proc { client.companies.all.each {|company| }}).must_raise Intercom::HttpError
15
15
  end
16
16
 
17
17
  it "on load" do
18
18
  client.expects(:get).with("/companies", {:company_id => "4"}).returns({"type" =>"user", "id" =>"aaaaaaaaaaaaaaaaaaaaaaaa", "company_id" => "4", "name" => "MyCo"})
19
19
  company = client.companies.find(:company_id => "4")
20
20
  client.expects(:get).with("/companies/aaaaaaaaaaaaaaaaaaaaaaaa", {}).returns(nil)
21
- proc {client.companies.load(company)}.must_raise Intercom::HttpError
21
+ _(proc { client.companies.load(company)}).must_raise Intercom::HttpError
22
22
  end
23
23
  end
24
24
 
25
- it "gets users in a company by intercom ID" do
26
- client.expects(:get).with("/companies/abc123/users", {}).returns(page_of_users(false))
27
- client.companies.users_by_intercom_company_id("abc123").each { |u| }
28
- end
29
-
30
- it "gets users in a company by external company ID" do
31
- client.expects(:get).with("/companies", { company_id: "abc123", type: "user" }).returns(page_of_users(false))
32
- client.companies.users_by_company_id("abc123").each { |u| }
33
- end
34
-
35
25
  it "finds a company" do
36
26
  client.expects(:get).with("/companies/531ee472cce572a6ec000006", {}).returns(test_company)
37
27
  company = client.companies.find(id: "531ee472cce572a6ec000006")
38
- company.name.must_equal("Blue Sun")
28
+ _(company.name).must_equal("Blue Sun")
29
+ end
30
+
31
+ it "returns a collection proxy for listing contacts" do
32
+ company = Intercom::Company.new("id" => "1")
33
+ proxy = company.contacts
34
+ _(proxy.resource_name).must_equal 'contacts'
35
+ _(proxy.url).must_equal '/companies/1/contacts'
36
+ _(proxy.resource_class).must_equal Intercom::Contact
39
37
  end
40
38
  end
@@ -1,59 +1,315 @@
1
- require "spec_helper"
1
+ # frozen_string_literal: true
2
2
 
3
- describe "Intercom::Contact" do
4
- let (:client) { Intercom::Client.new(app_id: 'app_id', api_key: 'api_key') }
3
+ require 'spec_helper'
4
+
5
+ describe Intercom::Contact do
6
+ let(:client) { Intercom::Client.new(token: 'token') }
5
7
 
6
8
  it 'should be listable' do
7
9
  proxy = client.contacts.all
8
- proxy.resource_name.must_equal 'contacts'
9
- proxy.finder_url.must_equal '/contacts'
10
- proxy.resource_class.must_equal Intercom::Contact
10
+ _(proxy.resource_name).must_equal 'contacts'
11
+ _(proxy.url).must_equal '/contacts'
12
+ _(proxy.resource_class).must_equal Intercom::Contact
11
13
  end
12
14
 
13
- it 'should not throw ArgumentErrors when there are no parameters' do
14
- client.expects(:post)
15
- client.contacts.create
15
+ it 'should throw an ArgumentError when there are no parameters' do
16
+ _(proc { client.contacts.create }).must_raise(ArgumentError)
16
17
  end
17
18
 
18
- it 'can update a contact with an id' do
19
- contact = Intercom::Contact.new(:id => "de45ae78gae1289cb")
20
- client.expects(:put).with("/contacts/de45ae78gae1289cb", {'custom_attributes' => {}})
19
+ it "to_hash'es itself" do
20
+ created_at = Time.now
21
+ contact = Intercom::Contact.new(email: 'jim@example.com', contact_id: '12345', created_at: created_at, name: 'Jim Bob')
22
+ as_hash = contact.to_hash
23
+ _(as_hash['email']).must_equal 'jim@example.com'
24
+ _(as_hash['contact_id']).must_equal '12345'
25
+ _(as_hash['created_at']).must_equal created_at.to_i
26
+ _(as_hash['name']).must_equal 'Jim Bob'
27
+ end
28
+
29
+ it 'presents created_at and last_impression_at as Date' do
30
+ now = Time.now
31
+ contact = Intercom::Contact.new(created_at: now, last_impression_at: now)
32
+ _(contact.created_at).must_be_kind_of Time
33
+ _(contact.created_at.to_s).must_equal now.to_s
34
+ _(contact.last_impression_at).must_be_kind_of Time
35
+ _(contact.last_impression_at.to_s).must_equal now.to_s
36
+ end
37
+
38
+ it 'is throws a Intercom::AttributeNotSetError on trying to access an attribute that has not been set' do
39
+ contact = Intercom::Contact.new
40
+ _(proc { contact.foo_property }).must_raise Intercom::AttributeNotSetError
41
+ end
42
+
43
+ it 'presents a complete contact record correctly' do
44
+ contact = Intercom::Contact.new(test_contact)
45
+ _(contact.external_id).must_equal 'id-from-customers-app'
46
+ _(contact.email).must_equal 'bob@example.com'
47
+ _(contact.name).must_equal 'Joe Schmoe'
48
+ _(contact.workspace_id).must_equal 'the-workspace-id'
49
+ _(contact.session_count).must_equal 123
50
+ _(contact.created_at.to_i).must_equal 1_401_970_114
51
+ _(contact.remote_created_at.to_i).must_equal 1_393_613_864
52
+ _(contact.updated_at.to_i).must_equal 1_401_970_114
53
+
54
+ _(contact.avatar).must_be_kind_of Intercom::Avatar
55
+ _(contact.avatar.image_url).must_equal 'https://graph.facebook.com/1/picture?width=24&height=24'
56
+
57
+ _(contact.notes).must_be_kind_of Intercom::BaseCollectionProxy
58
+ _(contact.tags).must_be_kind_of Intercom::BaseCollectionProxy
59
+ _(contact.companies).must_be_kind_of Intercom::ClientCollectionProxy
60
+
61
+ _(contact.custom_attributes).must_be_kind_of Intercom::Lib::FlatStore
62
+ _(contact.custom_attributes['a']).must_equal 'b'
63
+ _(contact.custom_attributes['b']).must_equal 2
64
+
65
+ _(contact.social_profiles.size).must_equal 4
66
+ twitter_account = contact.social_profiles.first
67
+ _(twitter_account).must_be_kind_of Intercom::SocialProfile
68
+ _(twitter_account.name).must_equal 'twitter'
69
+ _(twitter_account.username).must_equal 'abc'
70
+ _(twitter_account.url).must_equal 'http://twitter.com/abc'
71
+
72
+ _(contact.location_data).must_be_kind_of Intercom::LocationData
73
+ _(contact.location_data.city_name).must_equal 'Dublin'
74
+ _(contact.location_data.continent_code).must_equal 'EU'
75
+ _(contact.location_data.country_name).must_equal 'Ireland'
76
+ _(contact.location_data.latitude).must_equal '90'
77
+ _(contact.location_data.longitude).must_equal '10'
78
+ _(contact.location_data.country_code).must_equal 'IRL'
79
+
80
+ _(contact.unsubscribed_from_emails).must_equal true
81
+ _(contact.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'
82
+ end
83
+
84
+ it 'allows easy setting of custom data' do
85
+ now = Time.now
86
+ contact = Intercom::Contact.new
87
+ contact.custom_attributes['mad'] = 123
88
+ contact.custom_attributes['other'] = now.to_i
89
+ contact.custom_attributes['thing'] = 'yay'
90
+ _(contact.to_hash['custom_attributes']).must_equal 'mad' => 123, 'other' => now.to_i, 'thing' => 'yay'
91
+ end
92
+
93
+ it 'rejects nested data structures in custom_attributes' do
94
+ contact = Intercom::Contact.new
95
+
96
+ _(proc { contact.custom_attributes['thing'] = [1] }).must_raise(ArgumentError)
97
+ _(proc { contact.custom_attributes['thing'] = { 1 => 2 } }).must_raise(ArgumentError)
98
+ _(proc { contact.custom_attributes['thing'] = { 1 => { 2 => 3 } } }).must_raise(ArgumentError)
99
+
100
+ contact = Intercom::Contact.new(test_contact)
101
+ _(proc { contact.custom_attributes['thing'] = [1] }).must_raise(ArgumentError)
102
+ end
103
+
104
+ describe 'incrementing custom_attributes fields' do
105
+ before :each do
106
+ @now = Time.now
107
+ @contact = Intercom::Contact.new('email' => 'jo@example.com', :external_id => 'i-1224242', :custom_attributes => { 'mad' => 123, 'another' => 432, 'other' => @now.to_i, :thing => 'yay' })
108
+ end
109
+
110
+ it 'increments up by 1 with no args' do
111
+ @contact.increment('mad')
112
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 124
113
+ end
114
+
115
+ it 'increments up by given value' do
116
+ @contact.increment('mad', 4)
117
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 127
118
+ end
119
+
120
+ it 'increments down by given value' do
121
+ @contact.increment('mad', -1)
122
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 122
123
+ end
124
+
125
+ it 'can increment new custom data fields' do
126
+ @contact.increment('new_field', 3)
127
+ _(@contact.to_hash['custom_attributes']['new_field']).must_equal 3
128
+ end
129
+
130
+ it 'can call increment on the same key twice and increment by 2' do
131
+ @contact.increment('mad')
132
+ @contact.increment('mad')
133
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 125
134
+ end
135
+ end
136
+
137
+ describe 'decrementing custom_attributes fields' do
138
+ before :each do
139
+ @now = Time.now
140
+ @contact = Intercom::Contact.new('email' => 'jo@example.com', :external_id => 'i-1224242', :custom_attributes => { 'mad' => 123, 'another' => 432, 'other' => @now.to_i, :thing => 'yay' })
141
+ end
142
+
143
+ it 'decrements down by 1 with no args' do
144
+ @contact.decrement('mad')
145
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 122
146
+ end
147
+
148
+ it 'decrements down by given value' do
149
+ @contact.decrement('mad', 3)
150
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 120
151
+ end
152
+
153
+ it 'can decrement new custom data fields' do
154
+ @contact.decrement('new_field', 5)
155
+ _(@contact.to_hash['custom_attributes']['new_field']).must_equal(-5)
156
+ end
157
+
158
+ it 'can call decrement on the same key twice and decrement by 2' do
159
+ @contact.decrement('mad')
160
+ @contact.decrement('mad')
161
+ _(@contact.to_hash['custom_attributes']['mad']).must_equal 121
162
+ end
163
+ end
164
+
165
+ it 'saves a contact (always sends custom_attributes)' do
166
+ contact = Intercom::Contact.new('email' => 'jo@example.com', :external_id => 'i-1224242')
167
+ client.expects(:post).with('/contacts', 'email' => 'jo@example.com', 'external_id' => 'i-1224242', 'custom_attributes' => {}).returns('email' => 'jo@example.com', 'external_id' => 'i-1224242')
21
168
  client.contacts.save(contact)
22
169
  end
23
170
 
24
- describe 'converting' do
25
- let(:contact) { Intercom::Contact.from_api(user_id: 'contact_id') }
26
- let(:user) { Intercom::User.from_api(id: 'user_id') }
171
+ it 'can save a contact with a nil email' do
172
+ contact = Intercom::Contact.new('email' => nil, :external_id => 'i-1224242')
173
+ client.expects(:post).with('/contacts', 'custom_attributes' => {}, 'email' => nil, 'external_id' => 'i-1224242').returns('email' => nil, 'external_id' => 'i-1224242')
174
+ client.contacts.save(contact)
175
+ end
27
176
 
28
- it do
29
- client.expects(:post).with(
30
- "/contacts/convert",
31
- {
32
- contact: { user_id: contact.user_id },
33
- user: { 'id' => user.id }
34
- }
35
- ).returns(test_user)
177
+ it 'can use client.contacts.create for convenience' do
178
+ client.expects(:post).with('/contacts', 'custom_attributes' => {}, 'email' => 'jo@example.com', 'external_id' => 'i-1224242').returns('email' => 'jo@example.com', 'external_id' => 'i-1224242')
179
+ contact = client.contacts.create('email' => 'jo@example.com', :external_id => 'i-1224242')
180
+ _(contact.email).must_equal 'jo@example.com'
181
+ end
36
182
 
37
- client.contacts.convert(contact, user)
183
+ it 'updates the contact with attributes as set by the server' do
184
+ client.expects(:post).with('/contacts', 'email' => 'jo@example.com', 'external_id' => 'i-1224242', 'custom_attributes' => {}).returns('email' => 'jo@example.com', 'external_id' => 'i-1224242', 'session_count' => 4)
185
+ contact = client.contacts.create('email' => 'jo@example.com', :external_id => 'i-1224242')
186
+ _(contact.session_count).must_equal 4
187
+ end
188
+
189
+ it 'allows setting dates to nil without converting them to 0' do
190
+ client.expects(:post).with('/contacts', 'email' => 'jo@example.com', 'custom_attributes' => {}, 'remote_created_at' => nil).returns('email' => 'jo@example.com')
191
+ contact = client.contacts.create('email' => 'jo@example.com', 'remote_created_at' => nil)
192
+ assert_nil contact.remote_created_at
193
+ end
194
+
195
+ it 'sets/gets rw keys' do
196
+ params = { 'email' => 'me@example.com', :external_id => 'abc123', 'name' => 'Bob Smith', 'last_seen_ip' => '1.2.3.4', 'last_seen_contact_agent' => 'ie6', 'created_at' => Time.now }
197
+ contact = Intercom::Contact.new(params)
198
+ custom_attributes = (params.keys + ['custom_attributes']).map(&:to_s).sort
199
+ _(contact.to_hash.keys.sort).must_equal custom_attributes
200
+ params.keys.each do |key|
201
+ _(contact.send(key).to_s).must_equal params[key].to_s
38
202
  end
39
203
  end
40
204
 
41
- it "returns a ClientCollectionProxy for all without making any requests" do
205
+ it 'will allow extra attributes in response from api' do
206
+ contact = Intercom::Contact.send(:from_api, 'new_param' => 'some value')
207
+ _(contact.new_param).must_equal 'some value'
208
+ end
209
+
210
+ it 'returns a BaseCollectionProxy for all without making any requests' do
42
211
  client.expects(:execute_request).never
43
212
  all = client.contacts.all
44
- all.must_be_instance_of(Intercom::ClientCollectionProxy)
213
+ _(all).must_be_instance_of(Intercom::BaseCollectionProxy)
214
+ end
215
+
216
+ it 'can print contacts without crashing' do
217
+ client.expects(:get).with('/contacts', 'email' => 'bo@example.com').returns(test_contact)
218
+ contact = client.contacts.find('email' => 'bo@example.com')
219
+
220
+ begin
221
+ orignal_stdout = $stdout
222
+ $stdout = StringIO.new
223
+
224
+ puts contact
225
+ p contact
226
+ ensure
227
+ $stdout = orignal_stdout
228
+ end
45
229
  end
46
230
 
47
- it "deletes a contact" do
48
- contact = Intercom::Contact.new("id" => "1")
49
- client.expects(:delete).with("/contacts/1", {}).returns(contact)
231
+ it 'fetches a contact' do
232
+ client.expects(:get).with('/contacts', 'email' => 'bo@example.com').returns(test_contact)
233
+ contact = client.contacts.find('email' => 'bo@example.com')
234
+ _(contact.email).must_equal 'bob@example.com'
235
+ _(contact.name).must_equal 'Joe Schmoe'
236
+ _(contact.session_count).must_equal 123
237
+ end
238
+
239
+ it 'can update a contact with an id' do
240
+ contact = Intercom::Contact.new(id: 'de45ae78gae1289cb')
241
+ client.expects(:put).with('/contacts/de45ae78gae1289cb', 'custom_attributes' => {})
242
+ client.contacts.save(contact)
243
+ end
244
+
245
+ it 'deletes a contact' do
246
+ contact = Intercom::Contact.new('id' => '1')
247
+ client.expects(:delete).with('/contacts/1', {}).returns(contact)
50
248
  client.contacts.delete(contact)
51
249
  end
52
250
 
53
- it "sends a request for a hard deletion" do
54
- contact = Intercom::Contact.new("id" => "1")
55
- client.expects(:post).with("/user_delete_requests", {intercom_user_id: "1"}).returns({id: contact.id})
56
- client.contacts.request_hard_delete(contact)
251
+ describe 'merging' do
252
+ let(:lead) { Intercom::Contact.from_api(external_id: 'contact_id', role: 'lead') }
253
+ let(:user) { Intercom::Contact.from_api(id: 'external_id', role: 'user') }
254
+
255
+ it 'should be successful with a lead and user' do
256
+ client.expects(:post).with('/contacts/merge',
257
+ from: lead.id, into: user.id).returns(test_contact)
258
+
259
+ client.contacts.merge(lead, user)
260
+ end
57
261
  end
58
262
 
263
+ describe 'nested resources' do
264
+ let(:contact) { Intercom::Contact.new(id: '1', client: client) }
265
+ let(:company) { Intercom::Company.new(id: '1') }
266
+ let(:tag) { Intercom::Tag.new(id: '1') }
267
+ let(:note) { Intercom::Note.new(body: "<p>Text for the note</p>") }
268
+
269
+ it 'returns a collection proxy for listing notes' do
270
+ proxy = contact.notes
271
+ _(proxy.resource_name).must_equal 'notes'
272
+ _(proxy.url).must_equal '/contacts/1/notes'
273
+ _(proxy.resource_class).must_equal Intercom::Note
274
+ end
275
+
276
+ it 'returns a collection proxy for listing tags' do
277
+ proxy = contact.tags
278
+ _(proxy.resource_name).must_equal 'tags'
279
+ _(proxy.url).must_equal '/contacts/1/tags'
280
+ _(proxy.resource_class).must_equal Intercom::Tag
281
+ end
282
+
283
+ it 'returns a collection proxy for listing companies' do
284
+ proxy = contact.companies
285
+ _(proxy.resource_name).must_equal 'companies'
286
+ _(proxy.url).must_equal '/contacts/1/companies'
287
+ _(proxy.resource_class).must_equal Intercom::Company
288
+ end
289
+
290
+ it 'adds a note to a contact' do
291
+ client.expects(:post).with('/contacts/1/notes', {body: note.body}).returns(note.to_hash)
292
+ contact.create_note({body: note.body})
293
+ end
294
+
295
+ it 'adds a tag to a contact' do
296
+ client.expects(:post).with('/contacts/1/tags', "id": tag.id).returns(tag.to_hash)
297
+ contact.add_tag({ "id": tag.id })
298
+ end
299
+
300
+ it 'removes a tag from a contact' do
301
+ client.expects(:delete).with("/contacts/1/tags/#{tag.id}", "id": tag.id ).returns(tag.to_hash)
302
+ contact.remove_tag({ "id": tag.id })
303
+ end
304
+
305
+ it 'adds a contact to a company' do
306
+ client.expects(:post).with('/contacts/1/companies', "id": company.id).returns(test_company)
307
+ contact.add_company({ "id": tag.id })
308
+ end
309
+
310
+ it 'removes a contact from a company' do
311
+ client.expects(:delete).with("/contacts/1/companies/#{company.id}", "id": tag.id ).returns(test_company)
312
+ contact.remove_company({ "id": tag.id })
313
+ end
314
+ end
59
315
  end