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.
- checksums.yaml +5 -5
- data/README.md +235 -222
- data/Rakefile +1 -1
- data/changes.txt +3 -0
- data/lib/intercom.rb +27 -22
- data/lib/intercom/api_operations/archive.rb +2 -1
- data/lib/intercom/api_operations/delete.rb +16 -0
- data/lib/intercom/api_operations/find.rb +5 -2
- data/lib/intercom/api_operations/find_all.rb +4 -3
- data/lib/intercom/api_operations/list.rb +4 -1
- data/lib/intercom/api_operations/load.rb +4 -2
- data/lib/intercom/api_operations/nested_resource.rb +70 -0
- data/lib/intercom/api_operations/save.rb +5 -4
- data/lib/intercom/api_operations/scroll.rb +4 -5
- data/lib/intercom/api_operations/search.rb +3 -2
- data/lib/intercom/base_collection_proxy.rb +72 -0
- data/lib/intercom/client.rb +20 -25
- data/lib/intercom/client_collection_proxy.rb +17 -39
- data/lib/intercom/company.rb +8 -0
- data/lib/intercom/contact.rb +21 -3
- data/lib/intercom/conversation.rb +4 -0
- data/lib/intercom/data_attribute.rb +7 -0
- data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
- data/lib/intercom/deprecated_resources.rb +13 -0
- data/lib/intercom/errors.rb +3 -0
- data/lib/intercom/extended_api_operations/segments.rb +3 -1
- data/lib/intercom/extended_api_operations/tags.rb +3 -1
- data/lib/intercom/lead.rb +21 -0
- data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
- data/lib/intercom/note.rb +4 -0
- data/lib/intercom/request.rb +37 -33
- data/lib/intercom/scroll_collection_proxy.rb +33 -38
- data/lib/intercom/search_collection_proxy.rb +30 -65
- data/lib/intercom/service/base_service.rb +7 -0
- data/lib/intercom/service/company.rb +0 -12
- data/lib/intercom/service/contact.rb +21 -10
- data/lib/intercom/service/conversation.rb +12 -3
- data/lib/intercom/service/data_attribute.rb +20 -0
- data/lib/intercom/service/lead.rb +41 -0
- data/lib/intercom/service/note.rb +4 -8
- data/lib/intercom/service/subscription.rb +2 -2
- data/lib/intercom/service/tag.rb +9 -9
- data/lib/intercom/service/visitor.rb +17 -8
- data/lib/intercom/tag.rb +4 -0
- data/lib/intercom/traits/api_resource.rb +28 -17
- data/lib/intercom/user.rb +12 -3
- data/lib/intercom/utils.rb +13 -2
- data/lib/intercom/version.rb +1 -1
- data/lib/intercom/visitor.rb +0 -2
- data/spec/spec_helper.rb +738 -513
- data/spec/unit/intercom/admin_spec.rb +2 -2
- data/spec/unit/intercom/base_collection_proxy_spec.rb +30 -0
- data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
- data/spec/unit/intercom/client_spec.rb +25 -26
- data/spec/unit/intercom/company_spec.rb +13 -15
- data/spec/unit/intercom/contact_spec.rb +289 -33
- data/spec/unit/intercom/conversation_spec.rb +29 -7
- data/spec/unit/intercom/count_spec.rb +4 -4
- data/spec/unit/intercom/data_attribute_spec.rb +40 -0
- data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
- data/spec/unit/intercom/event_spec.rb +9 -11
- data/spec/unit/intercom/job_spec.rb +24 -24
- data/spec/unit/intercom/lead_spec.rb +57 -0
- data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
- data/spec/unit/intercom/message_spec.rb +1 -1
- data/spec/unit/intercom/note_spec.rb +4 -10
- data/spec/unit/intercom/request_spec.rb +1 -1
- data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
- data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
- data/spec/unit/intercom/segment_spec.rb +2 -2
- data/spec/unit/intercom/subscription_spec.rb +5 -6
- data/spec/unit/intercom/tag_spec.rb +22 -14
- data/spec/unit/intercom/team_spec.rb +2 -2
- data/spec/unit/intercom/traits/api_resource_spec.rb +53 -51
- data/spec/unit/intercom/user_spec.rb +224 -226
- data/spec/unit/intercom/visitor_spec.rb +49 -0
- data/spec/unit/intercom_spec.rb +5 -3
- metadata +22 -7
- data/lib/intercom/customer.rb +0 -10
- data/lib/intercom/service/customer.rb +0 -14
- 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
|
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
|
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("/
|
8
|
-
|
9
|
-
client.
|
10
|
-
|
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("/
|
15
|
-
client.expects(:get).with('https://api.intercom.io/
|
16
|
-
|
17
|
-
client.
|
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("/
|
22
|
-
client.
|
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("/
|
27
|
-
|
28
|
-
|
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("/
|
33
|
-
client.
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
client.expects(:get).with("/
|
42
|
-
result = client.
|
43
|
-
result.must_equal %W(
|
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
|
-
|
48
|
-
client.expects(:get).with("/
|
49
|
-
result = client.
|
50
|
-
result.must_equal %W(
|
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
|
-
|
55
|
-
client.expects(:get).with("/
|
56
|
-
result = client.
|
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
|
-
|
64
|
-
|
65
|
-
client.expects(:get).with("/
|
66
|
-
result = client.
|
67
|
-
result.must_equal %W(
|
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
|
-
|
74
|
-
|
75
|
-
client.expects(:get).with("/
|
76
|
-
result = client.
|
77
|
-
result.must_equal %W(
|
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(:
|
6
|
-
let(:api_key) { 'myapikey' }
|
7
|
+
let(:token) { 'my_access_token' }
|
7
8
|
let(:client) do
|
8
9
|
Client.new(
|
9
|
-
|
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(
|
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(
|
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(
|
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(
|
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(
|
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(
|
78
|
+
_(proc { Client.new(token: token, api_version: '') }).must_raise MisconfiguredClientError
|
79
79
|
end
|
80
80
|
|
81
|
-
it
|
82
|
-
stub_request(:any,
|
83
|
-
status: [200,
|
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":
|
85
|
+
body: { "test": 'testing' }.to_json
|
86
86
|
)
|
87
87
|
|
88
|
-
client.get(
|
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.
|
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
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
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.
|
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
|
14
|
-
client.
|
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 '
|
19
|
-
|
20
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
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
|
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::
|
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
|
48
|
-
|
49
|
-
client.
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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
|