intercom 3.5.10 → 4.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) 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 +418 -216
  6. data/RELEASING.md +9 -0
  7. data/Rakefile +1 -1
  8. data/changes.txt +141 -0
  9. data/intercom.gemspec +1 -2
  10. data/lib/intercom.rb +34 -19
  11. data/lib/intercom/api_operations/archive.rb +16 -0
  12. data/lib/intercom/api_operations/delete.rb +4 -1
  13. data/lib/intercom/api_operations/find.rb +5 -2
  14. data/lib/intercom/api_operations/find_all.rb +4 -3
  15. data/lib/intercom/api_operations/list.rb +4 -1
  16. data/lib/intercom/api_operations/load.rb +4 -2
  17. data/lib/intercom/api_operations/nested_resource.rb +70 -0
  18. data/lib/intercom/api_operations/request_hard_delete.rb +12 -0
  19. data/lib/intercom/api_operations/save.rb +6 -4
  20. data/lib/intercom/api_operations/scroll.rb +4 -5
  21. data/lib/intercom/api_operations/search.rb +18 -0
  22. data/lib/intercom/article.rb +7 -0
  23. data/lib/intercom/base_collection_proxy.rb +72 -0
  24. data/lib/intercom/client.rb +66 -18
  25. data/lib/intercom/client_collection_proxy.rb +17 -39
  26. data/lib/intercom/collection.rb +7 -0
  27. data/lib/intercom/company.rb +8 -0
  28. data/lib/intercom/contact.rb +22 -3
  29. data/lib/intercom/conversation.rb +5 -0
  30. data/lib/intercom/data_attribute.rb +7 -0
  31. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  32. data/lib/intercom/deprecated_resources.rb +13 -0
  33. data/lib/intercom/errors.rb +44 -4
  34. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  35. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  36. data/lib/intercom/lead.rb +21 -0
  37. data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
  38. data/lib/intercom/note.rb +4 -0
  39. data/lib/intercom/request.rb +162 -95
  40. data/lib/intercom/scroll_collection_proxy.rb +38 -42
  41. data/lib/intercom/search_collection_proxy.rb +47 -0
  42. data/lib/intercom/section.rb +23 -0
  43. data/lib/intercom/segment.rb +4 -0
  44. data/lib/intercom/service/article.rb +20 -0
  45. data/lib/intercom/service/base_service.rb +13 -0
  46. data/lib/intercom/service/collection.rb +24 -0
  47. data/lib/intercom/service/company.rb +4 -2
  48. data/lib/intercom/service/contact.rb +29 -6
  49. data/lib/intercom/service/conversation.rb +23 -2
  50. data/lib/intercom/service/data_attribute.rb +20 -0
  51. data/lib/intercom/service/event.rb +12 -0
  52. data/lib/intercom/service/lead.rb +41 -0
  53. data/lib/intercom/service/note.rb +4 -8
  54. data/lib/intercom/service/section.rb +7 -0
  55. data/lib/intercom/service/tag.rb +8 -8
  56. data/lib/intercom/service/team.rb +17 -0
  57. data/lib/intercom/service/user.rb +4 -2
  58. data/lib/intercom/service/visitor.rb +15 -6
  59. data/lib/intercom/tag.rb +4 -0
  60. data/lib/intercom/team.rb +7 -0
  61. data/lib/intercom/traits/api_resource.rb +48 -27
  62. data/lib/intercom/traits/dirty_tracking.rb +8 -1
  63. data/lib/intercom/user.rb +12 -3
  64. data/lib/intercom/utils.rb +13 -2
  65. data/lib/intercom/version.rb +1 -1
  66. data/lib/intercom/visitor.rb +0 -2
  67. data/spec/spec_helper.rb +881 -436
  68. data/spec/unit/intercom/admin_spec.rb +2 -2
  69. data/spec/unit/intercom/article_spec.rb +40 -0
  70. data/spec/unit/intercom/base_collection_proxy_spec.rb +30 -0
  71. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  72. data/spec/unit/intercom/client_spec.rb +76 -9
  73. data/spec/unit/intercom/collection_spec.rb +32 -0
  74. data/spec/unit/intercom/company_spec.rb +29 -21
  75. data/spec/unit/intercom/contact_spec.rb +365 -29
  76. data/spec/unit/intercom/conversation_spec.rb +70 -7
  77. data/spec/unit/intercom/count_spec.rb +4 -4
  78. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  79. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  80. data/spec/unit/intercom/event_spec.rb +25 -8
  81. data/spec/unit/intercom/job_spec.rb +24 -24
  82. data/spec/unit/intercom/lead_spec.rb +57 -0
  83. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  84. data/spec/unit/intercom/message_spec.rb +1 -1
  85. data/spec/unit/intercom/note_spec.rb +4 -10
  86. data/spec/unit/intercom/request_spec.rb +150 -9
  87. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  88. data/spec/unit/intercom/search_collection_proxy_spec.rb +60 -0
  89. data/spec/unit/intercom/section_spec.rb +32 -0
  90. data/spec/unit/intercom/segment_spec.rb +2 -2
  91. data/spec/unit/intercom/subscription_spec.rb +5 -6
  92. data/spec/unit/intercom/tag_spec.rb +22 -14
  93. data/spec/unit/intercom/team_spec.rb +21 -0
  94. data/spec/unit/intercom/traits/api_resource_spec.rb +129 -47
  95. data/spec/unit/intercom/user_spec.rb +227 -217
  96. data/spec/unit/intercom/visitor_spec.rb +49 -0
  97. data/spec/unit/intercom_spec.rb +5 -3
  98. metadata +63 -26
  99. data/.travis.yml +0 -6
  100. data/lib/intercom/extended_api_operations/users.rb +0 -16
  101. 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,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Intercom::Article" do
4
+ let(:client) { Intercom::Client.new(token: 'token') }
5
+
6
+ describe "Getting an Article" do
7
+ it "successfully finds an article" do
8
+ client.expects(:get).with("/articles/1", {}).returns(test_article)
9
+ client.articles.find(id: "1")
10
+ end
11
+ end
12
+
13
+ describe "Creating an Article" do
14
+ it "successfully creates and article with information passed individually" do
15
+ client.expects(:post).with("/articles", {"title" => "new title", "author_id" => 1, "body" => "<p>thingbop</p>", "state" => "draft"}).returns(test_article)
16
+ client.articles.create(:title => "new title", :author_id => 1, :body => "<p>thingbop</p>", :state => "draft")
17
+ end
18
+
19
+ it "successfully creates and article with information in json" do
20
+ client.expects(:post).with("/articles", {"title" => "new title", "author_id" => 1, "body" => "<p>thingbop</p>", "state" => "draft"}).returns(test_article)
21
+ client.articles.create({title: "new title", author_id: 1, body: "<p>thingbop</p>", state: "draft"})
22
+ end
23
+ end
24
+
25
+ describe "Updating an article" do
26
+ it "successfully updates an article" do
27
+ article = Intercom::Article.new(id: 12345)
28
+ client.expects(:put).with('/articles/12345', {})
29
+ client.articles.save(article)
30
+ end
31
+ end
32
+
33
+ describe "Deleting an article" do
34
+ it "successfully deletes an article" do
35
+ article = Intercom::Article.new(id: 12345)
36
+ client.expects(:delete).with('/articles/12345', {})
37
+ client.articles.delete(article)
38
+ end
39
+ end
40
+ end
@@ -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(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(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(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(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(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,31 +1,98 @@
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(:client) { Client.new(app_id: app_id, api_key: api_key) }
7
+ let(:token) { 'my_access_token' }
8
+ let(:client) do
9
+ Client.new(
10
+ token: token,
11
+ handle_rate_limit: true
12
+ )
13
+ end
8
14
 
9
15
  it 'should set the base url' do
10
- client.base_url.must_equal('https://api.intercom.io')
16
+ _(client.base_url).must_equal('https://api.intercom.io')
17
+ end
18
+
19
+ it 'should have handle_rate_limit set' do
20
+ _(client.handle_rate_limit).must_equal(true)
11
21
  end
12
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
- client.base_url.must_equal('https://mymockintercom.io')
25
+ _(client.base_url).must_equal('https://mymockintercom.io')
16
26
  client.options(prev)
17
- client.base_url.must_equal('https://api.intercom.io')
27
+ _(client.base_url).must_equal('https://api.intercom.io')
28
+ end
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)
18
49
  end
19
50
 
20
51
  it 'should raise on nil credentials' do
21
- proc { Client.new(app_id: nil, api_key: nil) }.must_raise MisconfiguredClientError
52
+ _(proc { Client.new(token: nil) }).must_raise MisconfiguredClientError
53
+ end
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(token: token, api_version: '2.0').api_version).must_equal('2.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(token: token, api_version: nil).api_version)
67
+ end
68
+
69
+ it 'allows api version to be Unstable' do
70
+ _(Client.new(token: token, api_version: 'Unstable').api_version).must_equal('Unstable')
71
+ end
72
+
73
+ it 'raises on invalid api version' do
74
+ _(proc { Client.new(token: token, api_version: '0.2') }).must_raise MisconfiguredClientError
75
+ end
76
+
77
+ it 'raises on empty api version' do
78
+ _(proc { Client.new(token: token, api_version: '') }).must_raise MisconfiguredClientError
79
+ end
80
+
81
+ it 'assigns works' do
82
+ stub_request(:any, 'https://api.intercom.io/contacts?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('/contacts', id: '123')
89
+ end
22
90
  end
23
91
 
24
92
  describe 'OAuth clients' do
25
93
  it 'supports "token"' do
26
94
  client = Client.new(token: 'foo')
27
- client.username_part.must_equal('foo')
28
- client.password_part.must_equal('')
95
+ _(client.token).must_equal('foo')
29
96
  end
30
97
  end
31
98
  end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe Intercom::Collection do
4
+ let(:client) { Intercom::Client.new(token: 'token') }
5
+
6
+ it 'creates a collection' do
7
+ client.expects(:post).with('/help_center/collections', { 'name' => 'Collection 1', 'description' => 'Collection desc' }).returns(test_collection)
8
+ client.collections.create(:name => 'Collection 1', :description => 'Collection desc')
9
+ end
10
+
11
+ it 'lists collections' do
12
+ client.expects(:get).with('/help_center/collections', {}).returns(test_collection_list)
13
+ client.collections.all.each { |t| }
14
+ end
15
+
16
+ it 'finds a collection' do
17
+ client.expects(:get).with('/help_center/collections/1', {}).returns(test_collection)
18
+ client.collections.find(id: '1')
19
+ end
20
+
21
+ it 'updates a collection' do
22
+ collection = Intercom::Collection.new(id: '12345')
23
+ client.expects(:put).with('/help_center/collections/12345', {})
24
+ client.collections.save(collection)
25
+ end
26
+
27
+ it 'deletes a collection' do
28
+ collection = Intercom::Collection.new(id: '12345')
29
+ client.expects(:delete).with('/help_center/collections/12345', {})
30
+ client.collections.delete(collection)
31
+ end
32
+ end
@@ -1,36 +1,44 @@
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(token: 'token') }
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
- 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
- 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
- proc {client.companies.load(company)}.must_raise Intercom::HttpError
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
+ _(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
26
- client.expects(:get).with("/companies/abc123/users", {}).returns(page_of_users(false))
27
- client.companies.users('abc123').each do |u|
28
- end
25
+ it "finds a company" do
26
+ client.expects(:get).with("/companies/531ee472cce572a6ec000006", {}).returns(test_company)
27
+ company = client.companies.find(id: "531ee472cce572a6ec000006")
28
+ _(company.name).must_equal("Blue Sun")
29
29
  end
30
30
 
31
- it 'finds a company' do
32
- client.expects(:get).with("/companies/531ee472cce572a6ec000006", {}).returns(test_company)
33
- company = client.companies.find(id: '531ee472cce572a6ec000006')
34
- company.name.must_equal("Blue Sun")
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
37
+ end
38
+
39
+ it "deletes a company" do
40
+ company = Intercom::Company.new("id" => "1")
41
+ client.expects(:delete).with("/companies/1", {})
42
+ client.companies.delete(company)
35
43
  end
36
44
  end
@@ -1,53 +1,389 @@
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
176
+
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
182
+
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
27
188
 
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)
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
36
194
 
37
- client.contacts.convert(contact, user)
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
229
+ end
230
+
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)
45
243
  end
46
244
 
47
- it "deletes a contact" do
48
- contact = Intercom::Contact.new("id" => "1")
49
- client.expects(:delete).with("/contacts/1", {}).returns(contact)
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
 
251
+ it 'archives a contact' do
252
+ contact = Intercom::Contact.new('id' => '1')
253
+ client.expects(:post).with('/contacts/1/archive', {})
254
+ client.contacts.archive(contact)
255
+ end
256
+
257
+ it 'unarchives a contact' do
258
+ contact = Intercom::Contact.new('id' => '1')
259
+ client.expects(:post).with('/contacts/1/unarchive', {})
260
+ client.contacts.unarchive(contact)
261
+ end
262
+
263
+ describe 'merging' do
264
+ let(:lead) { Intercom::Contact.from_api(external_id: 'contact_id', role: 'lead') }
265
+ let(:user) { Intercom::Contact.from_api(id: 'external_id', role: 'user') }
266
+
267
+ it 'should be successful with a lead and user' do
268
+ client.expects(:post).with('/contacts/merge',
269
+ from: lead.id, into: user.id).returns(test_contact)
270
+
271
+ client.contacts.merge(lead, user)
272
+ end
273
+ end
274
+
275
+ describe 'nested resources' do
276
+ let(:contact) { Intercom::Contact.new(id: '1', client: client) }
277
+ let(:company) { Intercom::Company.new(id: '1') }
278
+ let(:tag) { Intercom::Tag.new(id: '1') }
279
+ let(:note) { Intercom::Note.new(body: "<p>Text for the note</p>") }
280
+
281
+ it 'returns a collection proxy for listing notes' do
282
+ proxy = contact.notes
283
+ _(proxy.resource_name).must_equal 'notes'
284
+ _(proxy.url).must_equal '/contacts/1/notes'
285
+ _(proxy.resource_class).must_equal Intercom::Note
286
+ end
287
+
288
+ it 'returns a collection proxy for listing segments' do
289
+ proxy = contact.segments
290
+ _(proxy.resource_name).must_equal 'segments'
291
+ _(proxy.url).must_equal '/contacts/1/segments'
292
+ _(proxy.resource_class).must_equal Intercom::Segment
293
+ end
294
+
295
+ it 'returns a collection proxy for listing tags' do
296
+ proxy = contact.tags
297
+ _(proxy.resource_name).must_equal 'tags'
298
+ _(proxy.url).must_equal '/contacts/1/tags'
299
+ _(proxy.resource_class).must_equal Intercom::Tag
300
+ end
301
+
302
+ it 'returns a collection proxy for listing companies' do
303
+ proxy = contact.companies
304
+ _(proxy.resource_name).must_equal 'companies'
305
+ _(proxy.url).must_equal '/contacts/1/companies'
306
+ _(proxy.resource_class).must_equal Intercom::Company
307
+ end
308
+
309
+ it 'adds a note to a contact' do
310
+ client.expects(:post).with('/contacts/1/notes', {body: note.body}).returns(note.to_hash)
311
+ contact.create_note({body: note.body})
312
+ end
313
+
314
+ it 'adds a tag to a contact' do
315
+ client.expects(:post).with('/contacts/1/tags', "id": tag.id).returns(tag.to_hash)
316
+ contact.add_tag({ "id": tag.id })
317
+ end
318
+
319
+ it 'removes a tag from a contact' do
320
+ client.expects(:delete).with("/contacts/1/tags/#{tag.id}", "id": tag.id ).returns(tag.to_hash)
321
+ contact.remove_tag({ "id": tag.id })
322
+ end
323
+
324
+ it 'adds a contact to a company' do
325
+ client.expects(:post).with('/contacts/1/companies', "id": company.id).returns(test_company)
326
+ contact.add_company({ "id": tag.id })
327
+ end
328
+
329
+ it 'removes a contact from a company' do
330
+ client.expects(:delete).with("/contacts/1/companies/#{company.id}", "id": tag.id ).returns(test_company)
331
+ contact.remove_company({ "id": tag.id })
332
+ end
333
+
334
+ describe 'just after creating the contact' do
335
+ let(:contact) do
336
+ contact = Intercom::Contact.new('email' => 'jo@example.com', :external_id => 'i-1224242')
337
+ client.expects(:post).with('/contacts', 'email' => 'jo@example.com', 'external_id' => 'i-1224242', 'custom_attributes' => {})
338
+ .returns('id' => 1, 'email' => 'jo@example.com', 'external_id' => 'i-1224242')
339
+ client.contacts.save(contact)
340
+ end
341
+
342
+ it 'returns a collection proxy for listing notes' do
343
+ proxy = contact.notes
344
+ _(proxy.resource_name).must_equal 'notes'
345
+ _(proxy.url).must_equal '/contacts/1/notes'
346
+ _(proxy.resource_class).must_equal Intercom::Note
347
+ end
348
+
349
+ it 'returns a collection proxy for listing tags' do
350
+ proxy = contact.tags
351
+ _(proxy.resource_name).must_equal 'tags'
352
+ _(proxy.url).must_equal '/contacts/1/tags'
353
+ _(proxy.resource_class).must_equal Intercom::Tag
354
+ end
355
+
356
+ it 'returns a collection proxy for listing companies' do
357
+ proxy = contact.companies
358
+ _(proxy.resource_name).must_equal 'companies'
359
+ _(proxy.url).must_equal '/contacts/1/companies'
360
+ _(proxy.resource_class).must_equal Intercom::Company
361
+ end
362
+
363
+ it 'adds a note to a contact' do
364
+ client.expects(:post).with('/contacts/1/notes', {body: note.body}).returns(note.to_hash)
365
+ contact.create_note({body: note.body})
366
+ end
367
+
368
+ it 'adds a tag to a contact' do
369
+ client.expects(:post).with('/contacts/1/tags', "id": tag.id).returns(tag.to_hash)
370
+ contact.add_tag({ "id": tag.id })
371
+ end
372
+
373
+ it 'removes a tag from a contact' do
374
+ client.expects(:delete).with("/contacts/1/tags/#{tag.id}", "id": tag.id ).returns(tag.to_hash)
375
+ contact.remove_tag({ "id": tag.id })
376
+ end
377
+
378
+ it 'adds a contact to a company' do
379
+ client.expects(:post).with('/contacts/1/companies', "id": company.id).returns(test_company)
380
+ contact.add_company({ "id": tag.id })
381
+ end
382
+
383
+ it 'removes a contact from a company' do
384
+ client.expects(:delete).with("/contacts/1/companies/#{company.id}", "id": tag.id ).returns(test_company)
385
+ contact.remove_company({ "id": tag.id })
386
+ end
387
+ end
388
+ end
53
389
  end