intercom 3.5.10 → 3.9.5

Sign up to get free protection for your applications and to get access to all the features.
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