intercom 3.9.5 → 4.1.3

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +406 -236
  3. data/Rakefile +1 -1
  4. data/changes.txt +32 -0
  5. data/lib/intercom/api_operations/archive.rb +2 -1
  6. data/lib/intercom/api_operations/delete.rb +16 -0
  7. data/lib/intercom/api_operations/find.rb +5 -2
  8. data/lib/intercom/api_operations/find_all.rb +4 -3
  9. data/lib/intercom/api_operations/list.rb +4 -1
  10. data/lib/intercom/api_operations/load.rb +4 -2
  11. data/lib/intercom/api_operations/nested_resource.rb +70 -0
  12. data/lib/intercom/api_operations/save.rb +6 -4
  13. data/lib/intercom/api_operations/scroll.rb +4 -5
  14. data/lib/intercom/api_operations/search.rb +3 -2
  15. data/lib/intercom/article.rb +7 -0
  16. data/lib/intercom/base_collection_proxy.rb +73 -0
  17. data/lib/intercom/client.rb +36 -25
  18. data/lib/intercom/client_collection_proxy.rb +17 -39
  19. data/lib/intercom/collection.rb +7 -0
  20. data/lib/intercom/company.rb +8 -0
  21. data/lib/intercom/contact.rb +22 -3
  22. data/lib/intercom/conversation.rb +5 -0
  23. data/lib/intercom/data_attribute.rb +7 -0
  24. data/lib/intercom/deprecated_leads_collection_proxy.rb +22 -0
  25. data/lib/intercom/deprecated_resources.rb +13 -0
  26. data/lib/intercom/errors.rb +3 -0
  27. data/lib/intercom/extended_api_operations/segments.rb +3 -1
  28. data/lib/intercom/extended_api_operations/tags.rb +3 -1
  29. data/lib/intercom/lead.rb +21 -0
  30. data/lib/intercom/lib/dynamic_accessors.rb +9 -10
  31. data/lib/intercom/lib/typed_json_deserializer.rb +42 -37
  32. data/lib/intercom/note.rb +4 -0
  33. data/lib/intercom/request.rb +37 -33
  34. data/lib/intercom/scroll_collection_proxy.rb +38 -42
  35. data/lib/intercom/search_collection_proxy.rb +30 -65
  36. data/lib/intercom/section.rb +23 -0
  37. data/lib/intercom/segment.rb +4 -0
  38. data/lib/intercom/service/article.rb +20 -0
  39. data/lib/intercom/service/base_service.rb +7 -0
  40. data/lib/intercom/service/collection.rb +24 -0
  41. data/lib/intercom/service/company.rb +2 -12
  42. data/lib/intercom/service/contact.rb +31 -10
  43. data/lib/intercom/service/conversation.rb +12 -3
  44. data/lib/intercom/service/data_attribute.rb +20 -0
  45. data/lib/intercom/service/lead.rb +41 -0
  46. data/lib/intercom/service/note.rb +4 -8
  47. data/lib/intercom/service/section.rb +7 -0
  48. data/lib/intercom/service/subscription.rb +2 -2
  49. data/lib/intercom/service/tag.rb +9 -9
  50. data/lib/intercom/service/visitor.rb +17 -8
  51. data/lib/intercom/tag.rb +4 -0
  52. data/lib/intercom/traits/api_resource.rb +44 -18
  53. data/lib/intercom/traits/dirty_tracking.rb +8 -1
  54. data/lib/intercom/user.rb +12 -3
  55. data/lib/intercom/utils.rb +13 -2
  56. data/lib/intercom/version.rb +1 -1
  57. data/lib/intercom/visitor.rb +0 -2
  58. data/lib/intercom.rb +33 -22
  59. data/spec/spec_helper.rb +843 -520
  60. data/spec/unit/intercom/admin_spec.rb +2 -2
  61. data/spec/unit/intercom/article_spec.rb +40 -0
  62. data/spec/unit/intercom/base_collection_proxy_spec.rb +47 -0
  63. data/spec/unit/intercom/client_collection_proxy_spec.rb +41 -41
  64. data/spec/unit/intercom/client_spec.rb +25 -26
  65. data/spec/unit/intercom/collection_spec.rb +32 -0
  66. data/spec/unit/intercom/company_spec.rb +18 -14
  67. data/spec/unit/intercom/contact_spec.rb +385 -33
  68. data/spec/unit/intercom/conversation_spec.rb +55 -7
  69. data/spec/unit/intercom/count_spec.rb +4 -4
  70. data/spec/unit/intercom/data_attribute_spec.rb +40 -0
  71. data/spec/unit/intercom/deprecated_leads_collection_proxy_spec.rb +17 -0
  72. data/spec/unit/intercom/event_spec.rb +9 -11
  73. data/spec/unit/intercom/job_spec.rb +24 -24
  74. data/spec/unit/intercom/lead_spec.rb +57 -0
  75. data/spec/unit/intercom/lib/flat_store_spec.rb +22 -20
  76. data/spec/unit/intercom/message_spec.rb +1 -1
  77. data/spec/unit/intercom/note_spec.rb +4 -10
  78. data/spec/unit/intercom/request_spec.rb +1 -1
  79. data/spec/unit/intercom/scroll_collection_proxy_spec.rb +40 -39
  80. data/spec/unit/intercom/search_collection_proxy_spec.rb +32 -28
  81. data/spec/unit/intercom/section_spec.rb +32 -0
  82. data/spec/unit/intercom/segment_spec.rb +2 -2
  83. data/spec/unit/intercom/subscription_spec.rb +5 -6
  84. data/spec/unit/intercom/tag_spec.rb +22 -14
  85. data/spec/unit/intercom/team_spec.rb +2 -2
  86. data/spec/unit/intercom/traits/api_resource_spec.rb +107 -52
  87. data/spec/unit/intercom/user_spec.rb +224 -226
  88. data/spec/unit/intercom/visitor_spec.rb +49 -0
  89. data/spec/unit/intercom_spec.rb +5 -3
  90. metadata +34 -8
  91. data/lib/intercom/customer.rb +0 -10
  92. data/lib/intercom/service/customer.rb +0 -14
  93. data/spec/unit/intercom/visitors_spec.rb +0 -61
@@ -1,98 +1,115 @@
1
- require "spec_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
2
4
 
3
5
  describe Intercom::Traits::ApiResource do
4
6
  let(:object_json) do
5
- {"type"=>"company",
6
- "id"=>"aaaaaaaaaaaaaaaaaaaaaaaa",
7
- "app_id"=>"some-app-id",
8
- "name"=>"SuperSuite",
9
- "plan_id"=>1,
10
- "remote_company_id"=>"8",
11
- "remote_created_at"=>103201,
12
- "created_at"=>1374056196,
13
- "user_count"=>1,
14
- "custom_attributes"=>{},
15
- "metadata"=>{
16
- "type"=>"user",
17
- "color"=>"cyan"
18
- }}
7
+ { 'type' => 'company',
8
+ 'id' => 'aaaaaaaaaaaaaaaaaaaaaaaa',
9
+ 'app_id' => 'some-app-id',
10
+ 'name' => 'SuperSuite',
11
+ 'plan_id' => 1,
12
+ 'remote_company_id' => '8',
13
+ 'remote_created_at' => 103_201,
14
+ 'created_at' => 1_374_056_196,
15
+ 'user_count' => 1,
16
+ 'custom_attributes' => {},
17
+ 'metadata' => {
18
+ 'type' => 'user',
19
+ 'color' => 'cyan'
20
+ },
21
+ 'nested_fields' => {
22
+ 'type' => 'nested_fields_content',
23
+ 'field_1' => {
24
+ 'type' => 'field_content',
25
+ 'name' => 'Nested Field'
26
+ }
27
+ }
28
+ }
19
29
  end
20
30
 
21
31
  let(:object_hash) do
22
32
  {
23
- type: "company",
24
- id: "aaaaaaaaaaaaaaaaaaaaaaaa",
25
- app_id: "some-app-id",
26
- name: "SuperSuite",
33
+ type: 'company',
34
+ id: 'aaaaaaaaaaaaaaaaaaaaaaaa',
35
+ app_id: 'some-app-id',
36
+ name: 'SuperSuite',
27
37
  plan_id: 1,
28
- remote_company_id: "8",
29
- remote_created_at: 103201,
30
- created_at: 1374056196,
38
+ remote_company_id: '8',
39
+ remote_created_at: 103_201,
40
+ created_at: 1_374_056_196,
31
41
  user_count: 1,
32
- custom_attributes: { type: "ping" },
42
+ custom_attributes: { type: 'ping' },
33
43
  metadata: {
34
- type: "user",
35
- color: "cyan"
44
+ type: 'user',
45
+ color: 'cyan'
46
+ },
47
+ nested_fields: {
48
+ type: 'nested_fields_content',
49
+ field_1: {
50
+ type: 'field_content',
51
+ name: 'Nested Field'
52
+ }
36
53
  }
37
54
  }
38
55
  end
39
56
 
40
- let(:api_resource) { DummyClass.new.extend(Intercom::Traits::ApiResource)}
57
+ let(:api_resource) { DummyClass.new.extend(Intercom::Traits::ApiResource) }
41
58
 
42
59
  before(:each) { api_resource.from_response(object_json) }
43
60
 
44
- it "coerces time on parsing json" do
45
- assert_equal Time.at(1374056196), api_resource.created_at
61
+ it 'coerces time on parsing json' do
62
+ assert_equal Time.at(1_374_056_196), api_resource.created_at
46
63
  end
47
64
 
48
- it "exposes string" do
49
- assert_equal Time.at(1374056196), api_resource.created_at
65
+ it 'exposes string' do
66
+ assert_equal Time.at(1_374_056_196), api_resource.created_at
50
67
  end
51
68
 
52
69
  it "treats 'metadata' as a plain hash, not a typed object" do
53
70
  assert_equal Hash, api_resource.metadata.class
54
71
  end
55
72
 
56
- it "dynamically defines accessors when a non-existent property is called that looks like a setter" do
57
- api_resource.wont_respond_to :spiders
73
+ it 'dynamically defines accessors when a non-existent property is called that looks like a setter' do
74
+ _(api_resource).wont_respond_to :spiders
58
75
  api_resource.spiders = 4
59
- api_resource.must_respond_to :spiders
76
+ _(api_resource).must_respond_to :spiders
60
77
  end
61
78
 
62
- it "calls dynamically defined getter when asked" do
79
+ it 'calls dynamically defined getter when asked' do
63
80
  api_resource.foo = 4
64
81
  assert_equal 4, api_resource.foo
65
82
  end
66
83
 
67
- it "accepts unix timestamps into dynamically defined date setters" do
68
- api_resource.foo_at = 1401200468
69
- assert_equal 1401200468, api_resource.instance_variable_get(:@foo_at)
84
+ it 'accepts unix timestamps into dynamically defined date setters' do
85
+ api_resource.foo_at = 1_401_200_468
86
+ assert_equal 1_401_200_468, api_resource.instance_variable_get(:@foo_at)
70
87
  end
71
88
 
72
- it "exposes dates correctly for dynamically defined getters" do
73
- api_resource.foo_at = 1401200468
74
- assert_equal Time.at(1401200468), api_resource.foo_at
89
+ it 'exposes dates correctly for dynamically defined getters' do
90
+ api_resource.foo_at = 1_401_200_468
91
+ assert_equal Time.at(1_401_200_468), api_resource.foo_at
75
92
  end
76
93
 
77
- it "throws regular method missing error when non-existent getter is called that is backed by an instance variable" do
94
+ it 'throws regular method missing error when non-existent getter is called that is backed by an instance variable' do
78
95
  api_resource.instance_variable_set(:@bar, 'you cant see me')
79
- proc { api_resource.bar }.must_raise NoMethodError
96
+ _(proc { api_resource.bar }).must_raise NoMethodError
80
97
  end
81
98
 
82
- it "throws attribute not set error when non-existent getter is called that is not backed by an instance variable" do
83
- proc { api_resource.flubber }.must_raise Intercom::AttributeNotSetError
99
+ it 'throws attribute not set error when non-existent getter is called that is not backed by an instance variable' do
100
+ _(proc { api_resource.flubber }).must_raise Intercom::AttributeNotSetError
84
101
  end
85
102
 
86
- it "throws regular method missing error when non-existent method is called that cannot be an accessor" do
87
- proc { api_resource.flubber! }.must_raise NoMethodError
88
- proc { api_resource.flubber? }.must_raise NoMethodError
103
+ it 'throws regular method missing error when non-existent method is called that cannot be an accessor' do
104
+ _(proc { api_resource.flubber! }).must_raise NoMethodError
105
+ _(proc { api_resource.flubber? }).must_raise NoMethodError
89
106
  end
90
107
 
91
- it "throws regular method missing error when non-existent setter is called with multiple arguments" do
92
- proc { api_resource.send(:flubber=, 'a', 'b') }.must_raise NoMethodError
108
+ it 'throws regular method missing error when non-existent setter is called with multiple arguments' do
109
+ _(proc { api_resource.send(:flubber=, 'a', 'b') }).must_raise NoMethodError
93
110
  end
94
111
 
95
- it "an initialized ApiResource is equal to one generated from a response" do
112
+ it 'an initialized ApiResource is equal to one generated from a response' do
96
113
  class ConcreteApiResource; include Intercom::Traits::ApiResource; end
97
114
  initialized_api_resource = ConcreteApiResource.new(object_json)
98
115
  except(object_json, 'type').keys.each do |attribute|
@@ -100,17 +117,55 @@ describe Intercom::Traits::ApiResource do
100
117
  end
101
118
  end
102
119
 
103
- it "initialized ApiResource using hash is equal to one generated from response" do
120
+ it 'initialized ApiResource using hash is equal to one generated from response' do
104
121
  class ConcreteApiResource; include Intercom::Traits::ApiResource; end
105
122
 
106
123
  api_resource.from_hash(object_hash)
107
124
  initialized_api_resource = ConcreteApiResource.new(object_hash)
108
-
109
125
  except(object_json, 'type').keys.each do |attribute|
110
126
  assert_equal initialized_api_resource.send(attribute), api_resource.send(attribute)
111
127
  end
112
128
  end
113
129
 
130
+ describe 'correctly equates two resources' do
131
+ class DummyResource; include Intercom::Traits::ApiResource; end
132
+
133
+ specify 'if each resource has the same class and same value' do
134
+ api_resource1 = DummyResource.new(object_json)
135
+ api_resource2 = DummyResource.new(object_json)
136
+ assert_equal (api_resource1 == api_resource2), true
137
+ end
138
+
139
+ specify 'if each resource has the same class and different value' do
140
+ object2_json = object_json.merge('id' => 'bbbbbb')
141
+ api_resource1 = DummyResource.new(object_json)
142
+ api_resource2 = DummyResource.new(object2_json)
143
+ assert_equal (api_resource1 == api_resource2), false
144
+ end
145
+
146
+ specify 'if each resource has a different class' do
147
+ dummy_resource = DummyResource.new(object_json)
148
+ assert_equal (dummy_resource == api_resource), false
149
+ end
150
+ end
151
+
152
+ it 'correctly generates submittable hash when no updates' do
153
+ assert_equal api_resource.to_submittable_hash, {}
154
+ end
155
+
156
+ it 'correctly generates submittable hash when there are updates' do
157
+ api_resource.name = 'SuperSuite updated'
158
+ api_resource.nested_fields.field_1.name = 'Updated Name'
159
+ assert_equal api_resource.to_submittable_hash, {
160
+ 'name' => 'SuperSuite updated',
161
+ 'nested_fields' => {
162
+ 'field_1' => {
163
+ 'name' => 'Updated Name'
164
+ }
165
+ }
166
+ }
167
+ end
168
+
114
169
  def except(h, *keys)
115
170
  keys.each { |key| h.delete(key) }
116
171
  h