intercom 3.5.10 → 3.9.5

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 (47) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +35 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +5 -0
  4. data/Gemfile +1 -4
  5. data/README.md +152 -83
  6. data/RELEASING.md +9 -0
  7. data/changes.txt +116 -0
  8. data/intercom.gemspec +1 -2
  9. data/lib/intercom.rb +4 -0
  10. data/lib/intercom/api_operations/{delete.rb → archive.rb} +4 -2
  11. data/lib/intercom/api_operations/find_all.rb +1 -1
  12. data/lib/intercom/api_operations/request_hard_delete.rb +12 -0
  13. data/lib/intercom/api_operations/search.rb +17 -0
  14. data/lib/intercom/client.rb +42 -5
  15. data/lib/intercom/customer.rb +10 -0
  16. data/lib/intercom/errors.rb +41 -4
  17. data/lib/intercom/request.rb +144 -81
  18. data/lib/intercom/search_collection_proxy.rb +82 -0
  19. data/lib/intercom/service/base_service.rb +6 -0
  20. data/lib/intercom/service/company.rb +14 -2
  21. data/lib/intercom/service/contact.rb +4 -2
  22. data/lib/intercom/service/conversation.rb +12 -0
  23. data/lib/intercom/service/customer.rb +14 -0
  24. data/lib/intercom/service/event.rb +12 -0
  25. data/lib/intercom/service/subscription.rb +2 -2
  26. data/lib/intercom/service/tag.rb +1 -1
  27. data/lib/intercom/service/team.rb +17 -0
  28. data/lib/intercom/service/user.rb +4 -2
  29. data/lib/intercom/service/visitor.rb +2 -2
  30. data/lib/intercom/team.rb +7 -0
  31. data/lib/intercom/traits/api_resource.rb +4 -9
  32. data/lib/intercom/version.rb +1 -1
  33. data/spec/spec_helper.rb +124 -2
  34. data/spec/unit/intercom/client_collection_proxy_spec.rb +5 -5
  35. data/spec/unit/intercom/client_spec.rb +69 -1
  36. data/spec/unit/intercom/company_spec.rb +20 -16
  37. data/spec/unit/intercom/contact_spec.rb +6 -0
  38. data/spec/unit/intercom/conversation_spec.rb +15 -0
  39. data/spec/unit/intercom/event_spec.rb +19 -0
  40. data/spec/unit/intercom/request_spec.rb +150 -9
  41. data/spec/unit/intercom/search_collection_proxy_spec.rb +56 -0
  42. data/spec/unit/intercom/team_spec.rb +21 -0
  43. data/spec/unit/intercom/traits/api_resource_spec.rb +34 -7
  44. data/spec/unit/intercom/user_spec.rb +15 -3
  45. metadata +33 -22
  46. data/.travis.yml +0 -6
  47. data/lib/intercom/extended_api_operations/users.rb +0 -16
@@ -38,21 +38,21 @@ describe Intercom::ClientCollectionProxy do
38
38
  test_user("user4@example.com"), test_user("user5@example.com"), test_user("user6@example.com"),
39
39
  test_user("user7@example.com"), test_user("user8@example.com"), test_user("user9@example.com"),
40
40
  test_user("user10@example.com")]
41
- client.expects(:get).with("/users", {:type=>'users', :per_page => 10, :page => 1}).returns(users_pagination(false, per_page=10, page=1, total_pages=1, total_count=10, user_list=users))
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
42
  result = client.users.find_all(:type=>'users', :per_page => 10, :page => 1).map {|user| user.email }
43
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)
44
44
  end
45
45
 
46
46
  it "supports multi page pagination" do
47
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(true, per_page=2, page=3, total_pages=5, total_count=10, user_list=users))
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
49
  result = client.users.find_all(:type=>'users', :per_page => 2, :page => 3).map {|user| user.email }
50
50
  result.must_equal %W(user3@example.com user4@example.com)
51
51
  end
52
52
 
53
53
  it "works with page out of range request" do
54
54
  users = []
55
- client.expects(:get).with("/users", {:type=>'users', :per_page => 2, :page => 30}).returns(users_pagination(true, per_page=2, page=30, total_pages=2, total_count=3, user_list=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
56
  result = client.users.find_all(:type=>'users', :per_page => 2, :page => 30).map {|user| user.email }
57
57
  result.must_equal %W()
58
58
  end
@@ -62,7 +62,7 @@ describe Intercom::ClientCollectionProxy do
62
62
  time_increment=1000
63
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
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(true, per_page=4, page=5, total_pages=6, total_count=30, user_list=users))
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
66
  result = client.users.find_all(:type=>'users', :per_page => 4, :page => 5, :order => "asc", :sort => "created_at").map(&:email)
67
67
  result.must_equal %W(user1@example.com user2@example.com user3@example.com user4@example.com)
68
68
  end
@@ -72,7 +72,7 @@ describe Intercom::ClientCollectionProxy do
72
72
  time_increment=1000
73
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
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(true, per_page=4, page=5, total_pages=6, total_count=30, user_list=users))
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
76
  result = client.users.find_all(:type=>'users', :per_page => 4, :page => 5, :order => "desc", :sort => "created_at").map {|user| user.email }
77
77
  result.must_equal %W(user4@example.com user3@example.com user2@example.com user1@example.com)
78
78
  end
@@ -4,12 +4,22 @@ module Intercom
4
4
  describe Client do
5
5
  let(:app_id) { 'myappid' }
6
6
  let(:api_key) { 'myapikey' }
7
- let(:client) { Client.new(app_id: app_id, api_key: api_key) }
7
+ let(:client) do
8
+ Client.new(
9
+ app_id: app_id,
10
+ api_key: api_key,
11
+ handle_rate_limit: true
12
+ )
13
+ end
8
14
 
9
15
  it 'should set the base url' do
10
16
  client.base_url.must_equal('https://api.intercom.io')
11
17
  end
12
18
 
19
+ it 'should have handle_rate_limit set' do
20
+ _(client.handle_rate_limit).must_equal(true)
21
+ end
22
+
13
23
  it 'should be able to change the base url' do
14
24
  prev = client.options(Intercom::Client.set_base_url('https://mymockintercom.io'))
15
25
  client.base_url.must_equal('https://mymockintercom.io')
@@ -17,10 +27,68 @@ module Intercom
17
27
  client.base_url.must_equal('https://api.intercom.io')
18
28
  end
19
29
 
30
+ it 'should be able to change the timeouts' do
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)
33
+ client.options(prev)
34
+ client.timeouts.must_equal(open_timeout: 30, read_timeout: 90)
35
+ end
36
+
37
+ it 'should be able to change the open timeout individually' do
38
+ prev = client.options(Intercom::Client.set_timeouts(open_timeout: 50))
39
+ client.timeouts.must_equal(open_timeout: 50, read_timeout: 90)
40
+ client.options(prev)
41
+ client.timeouts.must_equal(open_timeout: 30, read_timeout: 90)
42
+ end
43
+
44
+ it 'should be able to change the read timeout individually' do
45
+ prev = client.options(Intercom::Client.set_timeouts(read_timeout: 50))
46
+ client.timeouts.must_equal(open_timeout: 30, read_timeout: 50)
47
+ client.options(prev)
48
+ client.timeouts.must_equal(open_timeout: 30, read_timeout: 90)
49
+ end
50
+
20
51
  it 'should raise on nil credentials' do
21
52
  proc { Client.new(app_id: nil, api_key: nil) }.must_raise MisconfiguredClientError
22
53
  end
23
54
 
55
+ describe 'API version' do
56
+ it 'does not set the api version by default' do
57
+ assert_nil(client.api_version)
58
+ end
59
+
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')
62
+ end
63
+
64
+ it 'allows api version to be nil' do
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)
67
+ end
68
+
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')
71
+ end
72
+
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
75
+ end
76
+
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
79
+ end
80
+
81
+ it "assigns works" do
82
+ stub_request(:any, "https://api.intercom.io/users?id=123").to_return(
83
+ status: [200, "OK"],
84
+ headers: { 'X-RateLimit-Reset' => Time.now.utc + 10 },
85
+ body: { "test": "testing" }.to_json
86
+ )
87
+
88
+ client.get("/users", { id: "123" })
89
+ end
90
+ end
91
+
24
92
  describe 'OAuth clients' do
25
93
  it 'supports "token"' do
26
94
  client = Client.new(token: 'foo')
@@ -1,36 +1,40 @@
1
- require 'spec_helper'
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(app_id: "app_id", api_key: "api_key") }
5
5
 
6
- describe 'when no response raises error' do
7
- it 'on find' do
8
- client.expects(:get).with("/companies", {:company_id => '4'}).returns(nil)
9
- proc {client.companies.find(:company_id => '4')}.must_raise Intercom::HttpError
6
+ describe "when no response raises error" do
7
+ it "on find" do
8
+ client.expects(:get).with("/companies", {:company_id => "4"}).returns(nil)
9
+ proc {client.companies.find(:company_id => "4")}.must_raise Intercom::HttpError
10
10
  end
11
11
 
12
- it 'on find_all' do
12
+ it "on find_all" do
13
13
  client.expects(:get).with("/companies", {}).returns(nil)
14
14
  proc {client.companies.all.each {|company| }}.must_raise Intercom::HttpError
15
15
  end
16
16
 
17
- it 'on load' do
18
- client.expects(:get).with("/companies", {:company_id => '4'}).returns({'type' =>'user', 'id' =>'aaaaaaaaaaaaaaaaaaaaaaaa', 'company_id' => '4', 'name' => 'MyCo'})
19
- company = client.companies.find(:company_id => '4')
20
- client.expects(:get).with('/companies/aaaaaaaaaaaaaaaaaaaaaaaa', {}).returns(nil)
17
+ it "on load" do
18
+ client.expects(:get).with("/companies", {:company_id => "4"}).returns({"type" =>"user", "id" =>"aaaaaaaaaaaaaaaaaaaaaaaa", "company_id" => "4", "name" => "MyCo"})
19
+ company = client.companies.find(:company_id => "4")
20
+ client.expects(:get).with("/companies/aaaaaaaaaaaaaaaaaaaaaaaa", {}).returns(nil)
21
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' do
25
+ it "gets users in a company by intercom ID" do
26
26
  client.expects(:get).with("/companies/abc123/users", {}).returns(page_of_users(false))
27
- client.companies.users('abc123').each do |u|
28
- end
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| }
29
33
  end
30
34
 
31
- it 'finds a company' do
35
+ it "finds a company" do
32
36
  client.expects(:get).with("/companies/531ee472cce572a6ec000006", {}).returns(test_company)
33
- company = client.companies.find(id: '531ee472cce572a6ec000006')
37
+ company = client.companies.find(id: "531ee472cce572a6ec000006")
34
38
  company.name.must_equal("Blue Sun")
35
39
  end
36
40
  end
@@ -50,4 +50,10 @@ describe "Intercom::Contact" do
50
50
  client.contacts.delete(contact)
51
51
  end
52
52
 
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)
57
+ end
58
+
53
59
  end
@@ -8,6 +8,11 @@ describe "Intercom::Conversation" do
8
8
  client.conversations.find(:id => "147")
9
9
  end
10
10
 
11
+ it "gets all conversations" do
12
+ client.expects(:get).with("/conversations", {}).returns(test_conversation_list)
13
+ client.conversations.all.each { |c| }
14
+ end
15
+
11
16
  it 'marks a conversation as read' do
12
17
  client.expects(:put).with('/conversations/147', { read: true })
13
18
  client.conversations.mark_read('147')
@@ -23,6 +28,11 @@ describe "Intercom::Conversation" do
23
28
  client.conversations.reply(id: '147', type: 'user', body: 'Thanks again', message_type: 'comment', user_id: 'ac4', attachment_urls: ["http://www.example.com/attachment.jpg"])
24
29
  end
25
30
 
31
+ it 'sends a reply to a users last conversation from an admin' do
32
+ client.expects(:post).with('/conversations/last/reply', { type: 'admin', body: 'Thanks again', message_type: 'comment', user_id: 'ac4', admin_id: '123' }).returns(test_conversation)
33
+ client.conversations.reply_to_last(type: 'admin', body: 'Thanks again', message_type: 'comment', user_id: 'ac4', admin_id: '123')
34
+ end
35
+
26
36
  it 'opens a conversation' do
27
37
  client.expects(:post).with('/conversations/147/reply', { type: 'admin', message_type: 'open', conversation_id: '147', admin_id: '123'}).returns(test_conversation)
28
38
  client.conversations.open(id: '147', admin_id: '123')
@@ -38,6 +48,11 @@ describe "Intercom::Conversation" do
38
48
  client.conversations.assign(id: '147', admin_id: '123', assignee_id: '124')
39
49
  end
40
50
 
51
+ it 'snoozes a conversation' do
52
+ client.expects(:post).with('/conversations/147/reply', { type: 'admin', message_type: 'snoozed', conversation_id: '147', admin_id: '123', snoozed_until: tomorrow}).returns(test_conversation)
53
+ client.conversations.snooze(id: '147', admin_id: '123', snoozed_until: tomorrow)
54
+ end
55
+
41
56
  # it "creates a subscription" do
42
57
  # client.expects(:post).with("/subscriptions", {'url' => "http://example.com", 'topics' => ["user.created"]}).returns(test_subscription)
43
58
  # subscription = client.subscriptions.create(:url => "http://example.com", :topics => ["user.created"])
@@ -11,6 +11,25 @@ describe "Intercom::Event" do
11
11
  client.events.find_all(type: 'user', email: 'joe@example.com').first
12
12
  end
13
13
 
14
+ it "has the correct collection proxy class" do
15
+ client.events.collection_proxy_class.must_equal Intercom::EventCollectionProxy
16
+ end
17
+
18
+ it "stops iterating if no next link" do
19
+ client.expects(:get).with("/events", type: 'user', email: 'joe@example.com').returns(page_of_events(false))
20
+ event_names = []
21
+ client.events.find_all(type: 'user', email: 'joe@example.com').each { |event| event_names << event.event_name }
22
+ event_names.must_equal %W(invited-friend)
23
+ end
24
+
25
+ it "keeps iterating if next link" do
26
+ client.expects(:get).with("/events", type: 'user', email: 'joe@example.com').returns(page_of_events(true))
27
+ client.expects(:get).with("https://api.intercom.io/events?type=user&intercom_user_id=55a3b&before=144474756550", {}).returns(page_of_events(false))
28
+ event_names = []
29
+ client.events.find_all(type: 'user', email: 'joe@example.com').each { |event| event_names << event.event_name }
30
+ event_names.must_equal %W(invited-friend invited-friend)
31
+ end
32
+
14
33
  it "creates an event with metadata" do
15
34
  client.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)
16
35
 
@@ -1,16 +1,157 @@
1
1
  require 'spec_helper'
2
2
  require 'ostruct'
3
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)
4
+ WebMock.enable!
5
+
6
+ describe 'Intercom::Request', '#execute' do
7
+ let(:uri) {"https://api.intercom.io/users"}
8
+ let(:req) { Intercom::Request.get(uri, {}) }
9
+ let(:default_body) { { data: "test" }.to_json }
10
+
11
+ def execute!
12
+ req.execute(uri, username: 'ted', secret: '')
13
+ end
14
+
15
+ it 'should call sleep for rate limit error three times and raise a rate limit error otherwise' do
16
+ stub_request(:any, uri).to_return(
17
+ status: [429, "Too Many Requests"],
18
+ headers: { 'X-RateLimit-Reset' => (Time.now.utc + 10).to_i.to_s },
19
+ body: default_body
20
+ )
21
+
22
+ req.handle_rate_limit=true
23
+
24
+ req.expects(:sleep).times(3).with(any_parameters)
25
+
26
+ expect { execute! }.must_raise(Intercom::RateLimitExceeded)
27
+ end
28
+
29
+ it 'should not call sleep for rate limit error' do
30
+ stub_request(:any, uri).to_return(
31
+ status: [200, "OK"],
32
+ headers: { 'X-RateLimit-Reset' => Time.now.utc + 10 },
33
+ body: default_body
34
+ )
35
+
36
+ req.handle_rate_limit=true
37
+ req.expects(:sleep).never.with(any_parameters)
38
+
39
+ execute!
40
+ end
41
+
42
+ it 'should call sleep for rate limit error just once' do
43
+ stub_request(:any, uri).to_return(
44
+ status: [429, "Too Many Requests"],
45
+ headers: { 'X-RateLimit-Reset' => (Time.now.utc + 10).to_i.to_s },
46
+ ).then.to_return(status: [200, "OK"], body: default_body)
47
+
48
+ req.handle_rate_limit=true
49
+ req.expects(:sleep).with(any_parameters)
50
+
51
+ execute!
9
52
  end
10
53
 
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)
54
+ it 'should not sleep if rate limit reset time has passed' do
55
+ stub_request(:any, uri).to_return(
56
+ status: [429, "Too Many Requests"],
57
+ headers: { 'X-RateLimit-Reset' => Time.parse("February 25 2010").utc.to_i.to_s },
58
+ body: default_body
59
+ ).then.to_return(status: [200, "OK"], body: default_body)
60
+
61
+ req.handle_rate_limit=true
62
+ req.expects(:sleep).never.with(any_parameters)
63
+
64
+ execute!
65
+ end
66
+
67
+ it 'handles an empty body gracefully' do
68
+ stub_request(:any, uri).to_return(
69
+ status: 200,
70
+ body: nil
71
+ )
72
+
73
+ assert_nil(execute!)
74
+ end
75
+
76
+ describe 'HTTP error handling' do
77
+ it 'raises an error when the response is successful but the body is not JSON' do
78
+ stub_request(:any, uri).to_return(
79
+ status: 200,
80
+ body: '<html>something</html>'
81
+ )
82
+
83
+ expect { execute! }.must_raise(Intercom::UnexpectedResponseError)
84
+ end
85
+
86
+ it 'raises an error when an html error page rendered' do
87
+ stub_request(:any, uri).to_return(
88
+ status: 500,
89
+ body: '<html>something</html>'
90
+ )
91
+
92
+ expect { execute! }.must_raise(Intercom::ServerError)
93
+ end
94
+
95
+ it 'raises an error if the decoded_body is "null"' do
96
+ stub_request(:any, uri).to_return(
97
+ status: 500,
98
+ body: 'null'
99
+ )
100
+
101
+ expect { execute! }.must_raise(Intercom::ServerError)
102
+ end
103
+
104
+ it 'raises a RateLimitExceeded error when the response code is 429' do
105
+ stub_request(:any, uri).to_return(
106
+ status: 429,
107
+ body: 'null'
108
+ )
109
+
110
+ expect { execute! }.must_raise(Intercom::RateLimitExceeded)
111
+ end
112
+
113
+ it 'raises a GatewayTimeoutError error when the response code is 504' do
114
+ stub_request(:any, uri).to_return(
115
+ status: 504,
116
+ body: '<html> <head><title>504 Gateway Time-out</title></head> <body bgcolor="white"> <center><h1>504 Gateway Time-out</h1></center> </body> </html>'
117
+ )
118
+
119
+ expect { execute! }.must_raise(Intercom::GatewayTimeoutError)
120
+ end
121
+ end
122
+
123
+ describe "application error handling" do
124
+ let(:uri) {"https://api.intercom.io/conversations/reply"}
125
+ let(:req) { Intercom::Request.put(uri, {}) }
126
+
127
+ it 'should raise ResourceNotUniqueError error on resource_conflict code' do
128
+ stub_request(:put, uri).to_return(
129
+ status: [409, "Resource Already Exists"],
130
+ headers: { 'X-RateLimit-Reset' => (Time.now.utc + 10).to_i.to_s },
131
+ body: { type: "error.list", errors: [ code: "resource_conflict" ] }.to_json
132
+ )
133
+
134
+ expect { execute! }.must_raise(Intercom::ResourceNotUniqueError)
135
+ end
136
+
137
+ it 'should raise ApiVersionInvalid error on intercom_version_invalid code' do
138
+ stub_request(:put, uri).to_return(
139
+ status: [400, "Bad Request"],
140
+ headers: { 'X-RateLimit-Reset' => (Time.now.utc + 10).to_i.to_s },
141
+ body: { type: "error.list", errors: [ code: "intercom_version_invalid" ] }.to_json
142
+ )
143
+
144
+ expect { execute! }.must_raise(Intercom::ApiVersionInvalid)
145
+ end
146
+
147
+ it 'should raise ResourceNotFound error on company_not_found code' do
148
+ stub_request(:put, uri).to_return(
149
+ status: [404, "Not Found"],
150
+ headers: { 'X-RateLimit-Reset' => (Time.now.utc + 10).to_i.to_s },
151
+ body: { type: "error.list", errors: [ code: "company_not_found" ] }.to_json
152
+ )
153
+
154
+ expect { execute! }.must_raise(Intercom::ResourceNotFound)
155
+ end
15
156
  end
16
157
  end
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+
3
+ describe Intercom::SearchCollectionProxy do
4
+ let (:client) { Intercom::Client.new(app_id: 'app_id', api_key: 'api_key') }
5
+
6
+ it "send query to the customer search endpoint" do
7
+ client.expects(:post).with("/customers/search", { query: {} }). returns(page_of_customers(false))
8
+ client.customers.search(query: {}).first
9
+ end
10
+
11
+ it "send query to the customer search endpoint with sort_field" do
12
+ client.expects(:post).with("/customers/search", { query: {}, sort: { field: "name" } }). returns(page_of_customers(false))
13
+ client.customers.search(query: {}, sort_field: "name").first
14
+ end
15
+
16
+ it "send query to the customer search endpoint with sort_field and sort_order" do
17
+ client.expects(:post).with("/customers/search", { query: {}, sort: { field: "name", order: "ascending" } }). returns(page_of_customers(false))
18
+ client.customers.search(query: {}, sort_field: "name", sort_order: "ascending").first
19
+ end
20
+
21
+ it "send query to the customer search endpoint with per_page" do
22
+ client.expects(:post).with("/customers/search", { query: {}, pagination: { per_page: 10 }}). returns(page_of_customers(false))
23
+ client.customers.search(query: {}, per_page: 10).first
24
+ end
25
+
26
+ it "send query to the customer search endpoint with starting_after" do
27
+ client.expects(:post).with("/customers/search", { query: {}, pagination: { starting_after: "EnCrYpTeDsTrInG" }}). returns(page_of_customers(false))
28
+ client.customers.search(query: {}, starting_after: "EnCrYpTeDsTrInG").first
29
+ end
30
+
31
+ it "stops iterating if no starting_after value" do
32
+ client.expects(:post).with("/customers/search", { query: {} }). returns(page_of_customers(false))
33
+ emails = []
34
+ client.customers.search(query: {}).each { |user| emails << user.email }
35
+ emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
36
+ end
37
+
38
+ it "keeps iterating if starting_after value" do
39
+ client.expects(:post).with("/customers/search", { query: {} }).returns(page_of_customers(true))
40
+ client.expects(:post).with("/customers/search", { query: {}, pagination: { starting_after: "EnCrYpTeDsTrInG" }}).returns(page_of_customers(false))
41
+ emails = []
42
+ client.customers.search(query: {}).each { |user| emails << user.email }
43
+ end
44
+
45
+ it "supports indexed array access" do
46
+ client.expects(:post).with("/customers/search", { query: {} }).returns(page_of_customers(false))
47
+ client.customers.search(query: {})[0].email.must_equal 'user1@example.com'
48
+ end
49
+
50
+ it "supports map" do
51
+ client.expects(:post).with("/customers/search", { query: {} }).returns(page_of_customers(false))
52
+ emails = client.customers.search(query: {}).map { |user| user.email }
53
+ emails.must_equal %W(user1@example.com user2@example.com user3@example.com)
54
+ end
55
+
56
+ end