intercom 3.5.10 → 4.1.2

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 (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