amorail 0.3.4 → 0.6.0

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 (66) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +19 -1
  3. data/README.md +7 -1
  4. data/Rakefile +7 -3
  5. data/amorail.gemspec +4 -3
  6. data/lib/amorail.rb +3 -0
  7. data/lib/amorail/client.rb +8 -4
  8. data/lib/amorail/config.rb +2 -0
  9. data/lib/amorail/entities/company.rb +2 -0
  10. data/lib/amorail/entities/contact.rb +3 -0
  11. data/lib/amorail/entities/contact_link.rb +2 -0
  12. data/lib/amorail/entities/elementable.rb +39 -0
  13. data/lib/amorail/entities/lead.rb +4 -1
  14. data/lib/amorail/entities/leadable.rb +3 -0
  15. data/lib/amorail/entities/note.rb +19 -0
  16. data/lib/amorail/entities/task.rb +11 -23
  17. data/lib/amorail/entities/webhook.rb +44 -0
  18. data/lib/amorail/entity.rb +17 -9
  19. data/lib/amorail/entity/finders.rb +19 -14
  20. data/lib/amorail/entity/params.rb +2 -0
  21. data/lib/amorail/entity/{persistance.rb → persistence.rb} +24 -0
  22. data/lib/amorail/exceptions.rb +2 -0
  23. data/lib/amorail/property.rb +8 -0
  24. data/lib/amorail/railtie.rb +4 -1
  25. data/lib/amorail/version.rb +3 -1
  26. data/lib/tasks/amorail.rake +2 -0
  27. data/spec/client_spec.rb +2 -0
  28. data/spec/company_spec.rb +2 -0
  29. data/spec/contact_link_spec.rb +2 -0
  30. data/spec/contact_spec.rb +17 -0
  31. data/spec/entity_spec.rb +2 -0
  32. data/spec/fixtures/{account_response.json → accounts/response_1.json} +5 -5
  33. data/spec/fixtures/{account2_response.json → accounts/response_2.json} +1 -1
  34. data/spec/fixtures/{contact_create.json → contacts/create.json} +1 -1
  35. data/spec/fixtures/{contact_find_query.json → contacts/find_many.json} +3 -5
  36. data/spec/fixtures/{contact_find.json → contacts/find_one.json} +5 -6
  37. data/spec/fixtures/contacts/links.json +16 -0
  38. data/spec/fixtures/{my_contact_find.json → contacts/my_contact_find.json} +2 -3
  39. data/spec/fixtures/contacts/update.json +13 -0
  40. data/spec/fixtures/leads/create.json +13 -0
  41. data/spec/fixtures/leads/find_many.json +73 -0
  42. data/spec/fixtures/leads/links.json +16 -0
  43. data/spec/fixtures/leads/update.json +13 -0
  44. data/spec/fixtures/leads/update_errors.json +12 -0
  45. data/spec/fixtures/webhooks/list.json +24 -0
  46. data/spec/fixtures/webhooks/subscribe.json +17 -0
  47. data/spec/fixtures/webhooks/unsubscribe.json +17 -0
  48. data/spec/helpers/webmock_helpers.rb +92 -13
  49. data/spec/lead_spec.rb +30 -0
  50. data/spec/my_contact_spec.rb +2 -0
  51. data/spec/note_spec.rb +28 -0
  52. data/spec/property_spec.rb +2 -0
  53. data/spec/spec_helper.rb +4 -2
  54. data/spec/support/elementable_example.rb +54 -0
  55. data/spec/support/entity_class_example.rb +2 -0
  56. data/spec/support/leadable_example.rb +2 -0
  57. data/spec/support/my_contact.rb +2 -0
  58. data/spec/support/my_entity.rb +2 -0
  59. data/spec/task_spec.rb +8 -28
  60. data/spec/webhook_spec.rb +61 -0
  61. metadata +60 -33
  62. data/.hound.yml +0 -12
  63. data/spec/fixtures/contact_update.json +0 -5
  64. data/spec/fixtures/contacts_links.json +0 -15
  65. data/spec/fixtures/leads.json +0 -69
  66. data/spec/fixtures/leads_links.json +0 -15
@@ -0,0 +1,24 @@
1
+ {
2
+ "response": {
3
+ "webhooks": [
4
+ {
5
+ "id": "1",
6
+ "url": "http://example.org",
7
+ "events": [
8
+ "add_contact"
9
+ ],
10
+ "disabled": false
11
+ },
12
+ {
13
+ "id": "2",
14
+ "url": "http://example.com",
15
+ "events": [
16
+ "add_contact",
17
+ "add_company"
18
+ ],
19
+ "disabled": true
20
+ }
21
+ ],
22
+ "server_time": 1539938502
23
+ }
24
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "response": {
3
+ "webhooks": {
4
+ "subscribe": [
5
+ {
6
+ "url": "http://example.org",
7
+ "result": true
8
+ },
9
+ {
10
+ "url": "http://example.com",
11
+ "result": true
12
+ }
13
+ ]
14
+ },
15
+ "server_time": 1539941636
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "response": {
3
+ "webhooks": {
4
+ "unsubscribe": [
5
+ {
6
+ "url": "http://example.org",
7
+ "result": true
8
+ },
9
+ {
10
+ "url": "http://example.com",
11
+ "result": true
12
+ }
13
+ ]
14
+ },
15
+ "server_time": 1539941911
16
+ }
17
+ }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # rubocop: disable Metrics/ModuleLength
2
4
  module AmoWebMock
3
5
  def mock_api
@@ -9,7 +11,7 @@ module AmoWebMock
9
11
  account_info_stub(Amorail.config.api_endpoint)
10
12
  end
11
13
 
12
- def mock_custom_api(endpoint, usermail, api_key, properties = 'account2_response.json')
14
+ def mock_custom_api(endpoint, usermail, api_key, properties = 'response_2.json')
13
15
  authorize_stub(
14
16
  endpoint,
15
17
  usermail,
@@ -33,10 +35,10 @@ module AmoWebMock
33
35
  })
34
36
  end
35
37
 
36
- def account_info_stub(endpoint, properties = 'account_response.json')
38
+ def account_info_stub(endpoint, properties = 'response_1.json')
37
39
  stub_request(:get, endpoint + '/private/api/v2/json/accounts/current')
38
40
  .to_return(
39
- body: File.read("./spec/fixtures/#{properties}"),
41
+ body: File.read("./spec/fixtures/accounts/#{properties}"),
40
42
  headers: { 'Content-Type' => 'application/json' },
41
43
  status: 200
42
44
  )
@@ -61,7 +63,7 @@ module AmoWebMock
61
63
  def contact_create_stub(endpoint)
62
64
  stub_request(:post, endpoint + '/private/api/v2/json/contacts/set')
63
65
  .to_return(
64
- body: File.read('./spec/fixtures/contact_create.json'),
66
+ body: File.read('./spec/fixtures/contacts/create.json'),
65
67
  headers: { 'Content-Type' => 'application/json' },
66
68
  status: 200
67
69
  )
@@ -70,7 +72,7 @@ module AmoWebMock
70
72
  def contact_update_stub(endpoint)
71
73
  stub_request(:post, endpoint + '/private/api/v2/json/contacts/set')
72
74
  .to_return(
73
- body: File.read('./spec/fixtures/contact_update.json'),
75
+ body: File.read('./spec/fixtures/contacts/update.json'),
74
76
  headers: {
75
77
  'Content-Type' => 'application/json'
76
78
  },
@@ -84,7 +86,7 @@ module AmoWebMock
84
86
  :get,
85
87
  "#{endpoint}/private/api/v2/json/contacts/list?id=#{id}")
86
88
  .to_return(
87
- body: File.read('./spec/fixtures/contact_find.json'),
89
+ body: File.read('./spec/fixtures/contacts/find_one.json'),
88
90
  headers: { 'Content-Type' => 'application/json' },
89
91
  status: 200
90
92
  )
@@ -102,7 +104,7 @@ module AmoWebMock
102
104
  :get,
103
105
  "#{endpoint}/private/api/v2/json/contacts/list?id=#{id}")
104
106
  .to_return(
105
- body: File.read('./spec/fixtures/my_contact_find.json'),
107
+ body: File.read('./spec/fixtures/contacts/my_contact_find.json'),
106
108
  headers: { 'Content-Type' => 'application/json' },
107
109
  status: 200
108
110
  )
@@ -120,7 +122,7 @@ module AmoWebMock
120
122
  :get,
121
123
  "#{endpoint}/private/api/v2/json/contacts/list?query=#{query}")
122
124
  .to_return(
123
- body: File.read('./spec/fixtures/contact_find_query.json'),
125
+ body: File.read('./spec/fixtures/contacts/find_many.json'),
124
126
  headers: { 'Content-Type' => 'application/json' },
125
127
  status: 200
126
128
  )
@@ -138,7 +140,7 @@ module AmoWebMock
138
140
  :get,
139
141
  "#{endpoint}/private/api/v2/json/contacts/list?#{ids.to_query('id')}")
140
142
  .to_return(
141
- body: File.read('./spec/fixtures/contact_find_query.json'),
143
+ body: File.read('./spec/fixtures/contacts/find_many.json'),
142
144
  headers: { 'Content-Type' => 'application/json' },
143
145
  status: 200
144
146
  )
@@ -150,10 +152,30 @@ module AmoWebMock
150
152
  end
151
153
  end
152
154
 
155
+ def contacts_where_stub(endpoint, success = true, **params)
156
+ if success
157
+ stub_request(
158
+ :get,
159
+ "#{endpoint}/private/api/v2/json/contacts/list"
160
+ ).with(
161
+ query: params
162
+ ).to_return(
163
+ body: File.read('./spec/fixtures/contacts/find_many.json'),
164
+ headers: { 'Content-Type' => 'application/json' },
165
+ status: 200
166
+ )
167
+ else
168
+ stub_request(
169
+ :get,
170
+ "#{endpoint}/private/api/v2/json/contacts/list?query=#{query}")
171
+ .to_return(status: 204)
172
+ end
173
+ end
174
+
153
175
  def company_create_stub(endpoint)
154
176
  stub_request(:post, endpoint + '/private/api/v2/json/company/set')
155
177
  .to_return(
156
- body: File.read('./spec/fixtures/contact_create.json'),
178
+ body: File.read('./spec/fixtures/contacts/create.json'),
157
179
  headers: { 'Content-Type' => 'application/json' },
158
180
  status: 200
159
181
  )
@@ -165,7 +187,7 @@ module AmoWebMock
165
187
  :get,
166
188
  "#{endpoint}/private/api/v2/json/leads/list?#{ids.to_query('id')}")
167
189
  .to_return(
168
- body: File.read('./spec/fixtures/leads.json'),
190
+ body: File.read('./spec/fixtures/leads/find_many.json'),
169
191
  headers: { 'Content-Type' => 'application/json' },
170
192
  status: 200
171
193
  )
@@ -177,10 +199,37 @@ module AmoWebMock
177
199
  end
178
200
  end
179
201
 
202
+ def lead_create_stub(endpoint)
203
+ stub_request(:post, endpoint + '/private/api/v2/json/leads/set')
204
+ .to_return(
205
+ body: File.read('./spec/fixtures/leads/create.json'),
206
+ headers: { 'Content-Type' => 'application/json' },
207
+ status: 200
208
+ )
209
+ end
210
+
211
+ def lead_update_stub(endpoint, success = true)
212
+ fixture_file =
213
+ if success
214
+ './spec/fixtures/leads/update.json'
215
+ else
216
+ './spec/fixtures/leads/update_errors.json'
217
+ end
218
+
219
+ stub_request(:post, endpoint + '/private/api/v2/json/leads/set')
220
+ .to_return(
221
+ body: File.read(fixture_file),
222
+ headers: {
223
+ 'Content-Type' => 'application/json'
224
+ },
225
+ status: 200
226
+ )
227
+ end
228
+
180
229
  def contacts_links_stub(endpoint, ids)
181
230
  stub_request(:get, endpoint + "/private/api/v2/json/contacts/links?#{ids.to_query('contacts_link')}")
182
231
  .to_return(
183
- body: File.read('./spec/fixtures/contacts_links.json'),
232
+ body: File.read('./spec/fixtures/contacts/links.json'),
184
233
  headers: { 'Content-Type' => 'application/json' },
185
234
  status: 200
186
235
  )
@@ -190,7 +239,7 @@ module AmoWebMock
190
239
  if success
191
240
  stub_request(:get, endpoint + "/private/api/v2/json/contacts/links?#{ids.to_query('deals_link')}")
192
241
  .to_return(
193
- body: File.read('./spec/fixtures/leads_links.json'),
242
+ body: File.read('./spec/fixtures/leads/links.json'),
194
243
  headers: { 'Content-Type' => 'application/json' },
195
244
  status: 200
196
245
  )
@@ -199,4 +248,34 @@ module AmoWebMock
199
248
  .to_return(status: 204)
200
249
  end
201
250
  end
251
+
252
+ def webhooks_list_stub(endpoint, empty: false)
253
+ body = empty ? '' : File.read('./spec/fixtures/webhooks/list.json')
254
+ stub_request(:get, "#{endpoint}/private/api/v2/json/webhooks/list")
255
+ .to_return(
256
+ body: body,
257
+ headers: { 'Content-Type' => 'application/json' },
258
+ status: 200
259
+ )
260
+ end
261
+
262
+ def webhooks_subscribe_stub(endpoint, webhooks)
263
+ stub_request(:post, "#{endpoint}/private/api/v2/json/webhooks/subscribe")
264
+ .with(body: { request: { webhooks: { subscribe: webhooks } } }.to_json)
265
+ .to_return(
266
+ body: File.read('./spec/fixtures/webhooks/subscribe.json'),
267
+ headers: { 'Content-Type' => 'application/json' },
268
+ status: 200
269
+ )
270
+ end
271
+
272
+ def webhooks_unsubscribe_stub(endpoint, webhooks)
273
+ stub_request(:post, "#{endpoint}/private/api/v2/json/webhooks/unsubscribe")
274
+ .with(body: { request: { webhooks: { unsubscribe: webhooks } } }.to_json)
275
+ .to_return(
276
+ body: File.read('./spec/fixtures/webhooks/unsubscribe.json'),
277
+ headers: { 'Content-Type' => 'application/json' },
278
+ status: 200
279
+ )
280
+ end
202
281
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  describe Amorail::Lead do
@@ -18,6 +20,7 @@ describe Amorail::Lead do
18
20
  :name,
19
21
  :price,
20
22
  :status_id,
23
+ :pipeline_id,
21
24
  :tags
22
25
  )
23
26
  end
@@ -29,6 +32,7 @@ describe Amorail::Lead do
29
32
  name: 'Test',
30
33
  price: 100,
31
34
  status_id: 2,
35
+ pipeline_id: 17,
32
36
  tags: 'test lead'
33
37
  )
34
38
  end
@@ -39,6 +43,7 @@ describe Amorail::Lead do
39
43
  specify { is_expected.to include(name: 'Test') }
40
44
  specify { is_expected.to include(price: 100) }
41
45
  specify { is_expected.to include(status_id: 2) }
46
+ specify { is_expected.to include(pipeline_id: 17) }
42
47
  specify { is_expected.to include(tags: 'test lead') }
43
48
  end
44
49
 
@@ -70,4 +75,29 @@ describe Amorail::Lead do
70
75
  end
71
76
  end
72
77
  end
78
+
79
+ describe "#update" do
80
+ subject { lead.update }
81
+
82
+ let(:lead) { described_class.new(name: 'RSpec lead', status_id: 142) }
83
+
84
+ before do
85
+ lead_create_stub(Amorail.config.api_endpoint)
86
+ lead.save!
87
+ end
88
+
89
+ context 'with errors in response' do
90
+ before do
91
+ lead_update_stub(Amorail.config.api_endpoint, false)
92
+ lead.name = 'Updated name'
93
+ end
94
+
95
+ it { is_expected.to be_falsey }
96
+
97
+ specify do
98
+ subject
99
+ expect(lead.errors[:base]).to include('Last modified date is older than in database')
100
+ end
101
+ end
102
+ end
73
103
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  describe MyContact do
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Amorail::Note do
6
+ before { mock_api }
7
+
8
+ it_behaves_like 'elementable'
9
+
10
+ describe 'validations' do
11
+ it { is_expected.to validate_presence_of(:text) }
12
+ it { is_expected.to validate_presence_of(:note_type) }
13
+ it { is_expected.to validate_inclusion_of(:element_type).in_range(1..4) }
14
+ end
15
+
16
+ describe '.attributes' do
17
+ subject { described_class.attributes }
18
+
19
+ it_behaves_like 'entity_class'
20
+
21
+ specify do
22
+ is_expected.to include(
23
+ :text,
24
+ :note_type
25
+ )
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
  require "webmock/rspec"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
5
 
@@ -10,9 +12,9 @@ require 'helpers/webmock_helpers'
10
12
 
11
13
  # Cleanup Amorail env
12
14
  ENV.delete_if { |k, _| k =~ /amorail/i }
13
- ENV["AMORAIL_CONF"] = File.expand_path("../fixtures/amorail_test.yml", __FILE__)
15
+ ENV["AMORAIL_CONF"] = File.expand_path("fixtures/amorail_test.yml", __dir__)
14
16
 
15
- Dir[File.expand_path("../support/**/*.rb", __FILE__)].each { |f| require f }
17
+ Dir[File.expand_path("support/**/*.rb", __dir__)].each { |f| require f }
16
18
 
17
19
  RSpec.configure do |config|
18
20
  config.mock_with :rspec
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples 'elementable' do
4
+ describe 'validations' do
5
+ it { is_expected.to validate_presence_of(:element_id) }
6
+ it { is_expected.to validate_presence_of(:element_type) }
7
+ end
8
+
9
+ describe '.attributes' do
10
+ subject { described_class.attributes }
11
+
12
+ specify do
13
+ is_expected.to include(
14
+ :element_type,
15
+ :element_id
16
+ )
17
+ end
18
+ end
19
+
20
+ describe '#params' do
21
+ subject { elementable.params }
22
+
23
+ let(:elementable) do
24
+ described_class.new(
25
+ element_id: 1,
26
+ element_type: 2
27
+ )
28
+ end
29
+
30
+ it { is_expected.to include(element_id: 1) }
31
+ it { is_expected.to include(element_type: 2) }
32
+ end
33
+
34
+ describe 'element type behaviour' do
35
+ let(:elementable) { described_class.new }
36
+
37
+ it 'set element_type on initialize' do
38
+ expect(described_class.new(lead: true).element_type).to eq 2
39
+ expect(described_class.new(lead: false).element_type).to be_nil
40
+ expect(described_class.new(contact: true).contact?).to be_truthy
41
+ end
42
+
43
+ it 'set element_type with bang method' do
44
+ elementable.contact!
45
+ expect(elementable.element_type).to eq 1
46
+
47
+ elementable.lead!
48
+ expect(elementable.element_type).to eq 2
49
+
50
+ elementable.company!
51
+ expect(elementable.element_type).to eq 3
52
+ end
53
+ end
54
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  shared_examples 'entity_class' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  shared_examples 'leadable' do