capsule_crm 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/capsule_crm/address.rb +4 -3
  4. data/lib/capsule_crm/associations/belongs_to.rb +2 -1
  5. data/lib/capsule_crm/associations/belongs_to_association.rb +19 -2
  6. data/lib/capsule_crm/associations/belongs_to_finder.rb +46 -0
  7. data/lib/capsule_crm/associations/has_many_association.rb +23 -9
  8. data/lib/capsule_crm/associations/has_many_proxy.rb +38 -4
  9. data/lib/capsule_crm/case.rb +33 -236
  10. data/lib/capsule_crm/configuration.rb +1 -1
  11. data/lib/capsule_crm/connection.rb +3 -0
  12. data/lib/capsule_crm/contactable.rb +1 -1
  13. data/lib/capsule_crm/country.rb +7 -13
  14. data/lib/capsule_crm/currency.rb +7 -13
  15. data/lib/capsule_crm/custom_field.rb +14 -54
  16. data/lib/capsule_crm/custom_field_definition.rb +36 -0
  17. data/lib/capsule_crm/email.rb +4 -3
  18. data/lib/capsule_crm/gettable.rb +11 -0
  19. data/lib/capsule_crm/hash_helper.rb +5 -0
  20. data/lib/capsule_crm/history.rb +37 -252
  21. data/lib/capsule_crm/milestone.rb +9 -9
  22. data/lib/capsule_crm/normalizer.rb +85 -0
  23. data/lib/capsule_crm/opportunity.rb +30 -271
  24. data/lib/capsule_crm/organization.rb +19 -197
  25. data/lib/capsule_crm/party.rb +13 -26
  26. data/lib/capsule_crm/persistence/configuration.rb +25 -0
  27. data/lib/capsule_crm/persistence/deletable.rb +14 -0
  28. data/lib/capsule_crm/persistence/persistable.rb +76 -0
  29. data/lib/capsule_crm/persistence.rb +3 -0
  30. data/lib/capsule_crm/person.rb +19 -194
  31. data/lib/capsule_crm/phone.rb +4 -3
  32. data/lib/capsule_crm/querying/configuration.rb +21 -0
  33. data/lib/capsule_crm/querying/find_all.rb +16 -0
  34. data/lib/capsule_crm/querying/find_one.rb +14 -0
  35. data/lib/capsule_crm/querying/findable.rb +14 -0
  36. data/lib/capsule_crm/querying.rb +4 -0
  37. data/lib/capsule_crm/serializable.rb +38 -0
  38. data/lib/capsule_crm/serializer.rb +54 -7
  39. data/lib/capsule_crm/task.rb +16 -96
  40. data/lib/capsule_crm/track.rb +5 -10
  41. data/lib/capsule_crm/user.rb +3 -15
  42. data/lib/capsule_crm/version.rb +1 -1
  43. data/lib/capsule_crm/website.rb +4 -2
  44. data/lib/capsule_crm.rb +15 -5
  45. data/spec/fabricators/case_fabricator.rb +1 -0
  46. data/spec/fabricators/history_fabricator.rb +1 -0
  47. data/spec/fabricators/opportunity_fabricator.rb +1 -0
  48. data/spec/lib/capsule_crm/associations/belongs_to_finder_spec.rb +48 -0
  49. data/spec/lib/capsule_crm/associations/belongs_to_spec.rb +34 -0
  50. data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +54 -14
  51. data/spec/lib/capsule_crm/associations/has_many_spec.rb +15 -2
  52. data/spec/lib/capsule_crm/case_spec.rb +20 -330
  53. data/spec/lib/capsule_crm/country_spec.rb +1 -16
  54. data/spec/lib/capsule_crm/currency_spec.rb +1 -18
  55. data/spec/lib/capsule_crm/custom_field_definition_spec.rb +59 -0
  56. data/spec/lib/capsule_crm/custom_field_spec.rb +2 -27
  57. data/spec/lib/capsule_crm/history_spec.rb +14 -389
  58. data/spec/lib/capsule_crm/milestone_spec.rb +1 -23
  59. data/spec/lib/capsule_crm/normalizer_spec.rb +11 -0
  60. data/spec/lib/capsule_crm/opportunity_spec.rb +22 -341
  61. data/spec/lib/capsule_crm/organization_spec.rb +39 -60
  62. data/spec/lib/capsule_crm/party_spec.rb +37 -59
  63. data/spec/lib/capsule_crm/person_spec.rb +49 -247
  64. data/spec/lib/capsule_crm/serializer_spec.rb +25 -4
  65. data/spec/lib/capsule_crm/task_spec.rb +21 -250
  66. data/spec/lib/capsule_crm/track_spec.rb +1 -15
  67. data/spec/lib/capsule_crm/user_spec.rb +1 -14
  68. data/spec/support/{countries.json → all_countries.json} +0 -0
  69. data/spec/support/{currencies.json → all_currencies.json} +0 -0
  70. data/spec/support/{milestones.json → all_milestones.json} +0 -0
  71. data/spec/support/{tracks.json → all_tracks.json} +0 -0
  72. data/spec/support/custom_field_definitions.json +19 -0
  73. data/spec/support/helpers.rb +3 -2
  74. data/spec/support/no_cases.json +5 -0
  75. data/spec/support/no_countries.json +5 -0
  76. data/spec/support/no_currencies.json +5 -0
  77. data/spec/support/no_milestones.json +5 -0
  78. data/spec/support/no_opportunities.json +5 -0
  79. data/spec/support/no_tasks.json +5 -0
  80. data/spec/support/no_tracks.json +5 -0
  81. data/spec/support/no_users.json +5 -0
  82. data/spec/support/shared_examples/deletable.rb +15 -0
  83. data/spec/support/shared_examples/find_all.rb +34 -0
  84. data/spec/support/shared_examples/find_one.rb +23 -0
  85. data/spec/support/shared_examples/persistable.rb +318 -0
  86. data/spec/support/single_person.json +16 -0
  87. metadata +60 -15
  88. data/lib/capsule_crm/attributes.rb +0 -11
  89. data/lib/capsule_crm/capsule_jsonable.rb +0 -13
  90. data/lib/capsule_crm/collection.rb +0 -9
  91. data/spec/support/single_user.json +0 -25
@@ -3,6 +3,21 @@ require 'spec_helper'
3
3
  describe CapsuleCRM::Case do
4
4
  before { configure }
5
5
 
6
+ it_behaves_like 'persistable', 'https://sample.capsulecrm.com/api/kase/1001', 1001 do
7
+ let(:attributes) { Fabricate.attributes_for(:case).merge(party: party) }
8
+ let(:party) { Fabricate.build(:person, id: Random.rand(1..10)) }
9
+ end
10
+
11
+ it_behaves_like 'deletable'
12
+
13
+ it_behaves_like 'listable', '/kase', 'cases', 1
14
+
15
+ it_behaves_like 'findable', '/api/kase/43', 43, 'case' do
16
+ let(:attributes) do
17
+ { name: 'Consulting' }
18
+ end
19
+ end
20
+
6
21
  before do
7
22
  stub_request(:get, /\/api\/users$/).
8
23
  to_return(body: File.read('spec/support/all_users.json'))
@@ -40,337 +55,12 @@ describe CapsuleCRM::Case do
40
55
  it { subject.first.detail.should eql('Go and get drunk') }
41
56
  end
42
57
 
43
- describe '.all' do
44
- before do
45
- stub_request(:get, 'https://1234:@company.capsulecrm.com/api/kase').
46
- to_return(body: File.read('spec/support/all_cases.json'))
47
- end
48
-
49
- subject { CapsuleCRM::Case.all }
50
-
51
- it { should be_a(Array) }
52
-
53
- it { subject.length.should eql(1) }
54
-
55
- it { subject.all? { |item| item.is_a?(CapsuleCRM::Case) }.should be_true }
56
- end
57
-
58
- describe '.find' do
59
- before do
60
- stub_request(:get, 'https://1234:@company.capsulecrm.com/api/kase/43').
61
- to_return(body: File.read('spec/support/case.json'))
62
- end
63
-
64
- subject { CapsuleCRM::Case.find(43) }
65
-
66
- it { should be_a(CapsuleCRM::Case) }
67
-
68
- it { subject.name.should eql('Consulting') }
69
- end
70
-
71
- describe '.create' do
72
- let(:request_uri) do
73
- 'https://1234:@company.capsulecrm.com/api/party/1/kase'
74
- end
75
-
76
- let(:party) { CapsuleCRM::Person.new(id: 1, first_name: 'Matt') }
77
-
78
- context 'when the case is valid' do
79
- before do
80
- stub_request(:post, request_uri).to_return(
81
- headers: { 'Location' => 'https://sample.capsulecrm.com/api/kase/59' }
82
- )
83
- end
84
-
85
- subject { CapsuleCRM::Case.create name: 'Test Case', party: party }
86
-
87
- it { should be_a(CapsuleCRM::Case) }
88
-
89
- it { subject.id.should eql(59) }
90
- end
91
-
92
- context 'when the case is invalid' do
93
- let(:kase) { CapsuleCRM::Case.create name: 'Test Case' }
94
-
95
- it { kase.errors.should_not be_blank }
96
- end
97
-
98
- context 'when the case has a track' do
99
- before do
100
- stub_request(:post, "#{request_uri}?trackId=#{track.id}").to_return(
101
- headers: { 'Location' => 'https://sample.capsulecrm.com/api/kase/59' }
102
- )
103
- end
104
-
105
- let(:track) { CapsuleCRM::Track.new(id: rand(10)) }
106
-
107
- subject do
108
- CapsuleCRM::Case.create(name: 'Test Case', party: party, track: track)
109
- end
110
-
111
- it { expect(subject).to be_a(CapsuleCRM::Case) }
112
-
113
- it { expect(subject).to be_persisted }
114
-
115
- it 'should add the trackId to the URI' do
116
- subject
117
- expect(WebMock).
118
- to have_requested(:post, "#{request_uri}?trackId=#{track.id}")
119
- end
120
- end
121
- end
122
-
123
- describe '.create!' do
124
- context 'when the case is valid' do
125
- before do
126
- stub_request(
127
- :post, 'https://1234:@company.capsulecrm.com/api/party/1/kase'
128
- ).to_return(
129
- headers: { 'Location' => 'https://sample.capsulecrm.com/api/kase/61' }
130
- )
131
- end
132
-
133
- let(:party) { CapsuleCRM::Person.new(id: 1, first_name: 'Matt') }
134
-
135
- subject { CapsuleCRM::Case.create! name: 'Test Case', party: party }
136
-
137
- it { should be_a(CapsuleCRM::Case) }
138
-
139
- it { subject.id.should eql(61) }
140
- end
141
-
142
- context 'when the case is invalid' do
143
- let(:kase) { CapsuleCRM::Case.create! name: 'Test Case' }
144
-
145
- it 'should raise an error' do
146
- expect { kase }.to raise_error(CapsuleCRM::Errors::RecordInvalid)
147
- end
148
- end
149
- end
150
-
151
- describe '#update_attributes' do
152
- context 'when the case is valid' do
153
- let(:party) { CapsuleCRM::Person.new(id: 10) }
154
-
155
- let(:kase) do
156
- CapsuleCRM::Case.new(id: 1, name: 'Test Case', party: party)
157
- end
158
-
159
- before do
160
- stub_request(
161
- :put, 'https://1234:@company.capsulecrm.com/api/kase/1'
162
- ).to_return(status: 200)
163
- kase.update_attributes name: 'changed name'
164
- end
165
-
166
- it { kase.name.should eql('changed name') }
167
-
168
- it { kase.id.should eql(1) }
169
- end
170
-
171
- context 'when the case is not valid' do
172
- let(:kase) { CapsuleCRM::Case.new(id: 2, name: 'Test Case') }
173
-
174
- before do
175
- kase.update_attributes name: 'changed name'
176
- end
177
-
178
- it { kase.errors.should_not be_blank }
179
-
180
- it { kase.name.should eql('changed name') }
181
- end
182
- end
183
-
184
- describe '#update_attributes!' do
185
- context 'when the case is valid' do
186
- let(:party) { CapsuleCRM::Person.new(id: 1, first_name: 'Matt') }
187
-
188
- let(:kase) do
189
- CapsuleCRM::Case.new(id: 1, name: 'Test Case', party: party)
190
- end
191
-
192
- before do
193
- stub_request(
194
- :put, 'https://1234:@company.capsulecrm.com/api/kase/1'
195
- ).to_return(status: 200)
196
- kase.update_attributes! name: 'changed name'
197
- end
198
-
199
- it { kase.name.should eql('changed name') }
200
-
201
- it { kase.id.should eql(1) }
202
- end
203
-
204
- context 'when the case is invalid' do
205
- let(:kase) { CapsuleCRM::Case.new(id: 1, name: 'Test Case') }
206
-
207
- subject { kase.update_attributes! name: 'changed name' }
208
-
209
- it do
210
- expect { subject }.to raise_error(CapsuleCRM::Errors::RecordInvalid)
211
- end
212
- end
213
- end
214
-
215
- describe '#save' do
216
- let(:party) { CapsuleCRM::Person.new(id: 1) }
217
-
218
- context 'when it is a new record' do
219
- context 'when it is valid' do
220
- let(:kase) { CapsuleCRM::Case.new(name: 'Test', party: party) }
221
-
222
- before do
223
- stub_request(
224
- :post, 'https://1234:@company.capsulecrm.com/api/party/1/kase'
225
- ).to_return(
226
- headers: { 'Location' => 'https://sample.capsulecrm.com/api/kase/2' }
227
- )
228
- kase.save
229
- end
230
-
231
- subject { kase }
232
-
233
- it { should be_persisted }
234
-
235
- it { kase.id.should eql(2) }
236
- end
237
-
238
- context 'when it is invalid' do
239
- let(:kase) { CapsuleCRM::Case.new(name: 'Test') }
240
-
241
- before { kase.save }
242
-
243
- it { kase.errors.should_not be_blank }
244
-
245
- it { kase.should_not be_persisted }
246
- end
247
- end
248
-
249
- context 'when it is an existing record' do
250
- let(:party) { CapsuleCRM::Person.new(id: 1) }
251
-
252
- context 'when it is valid' do
253
- let(:kase) { CapsuleCRM::Case.new(id: 2, name: 'Test', party: party) }
254
-
255
- before do
256
- stub_request(
257
- :put, 'https://1234:@company.capsulecrm.com/api/kase/2'
258
- ).to_return(status: 200)
259
- kase.name = 'changed name'
260
- kase.save
261
- end
262
-
263
- it { kase.should be_persisted }
264
-
265
- it { kase.name.should eql('changed name') }
266
- end
267
-
268
- context 'when it is invalid' do
269
- let(:kase) { CapsuleCRM::Case.new(id: 2, name: 'Test') }
270
-
271
- before { kase.save }
272
-
273
- it { kase.should be_persisted }
274
-
275
- it { kase.errors.should_not be_blank }
276
- end
277
- end
278
- end
279
-
280
- describe '#save!' do
281
- let(:party) { CapsuleCRM::Person.new(id: 1) }
282
-
283
- context 'when it is a new record' do
284
- context 'when it is valid' do
285
- let(:kase) { CapsuleCRM::Case.new(name: 'Test Case', party: party) }
286
-
287
- before do
288
- stub_request(:post, /^https.*\/api\/party\/1\/kase$/).
289
- to_return(headers: {
290
- 'Location' => 'https://sample.capsulecrm.com/api/kase/59'
291
- })
292
- kase.save!
293
- end
294
-
295
- it { kase.should be_persisted }
296
- end
297
-
298
- context 'when it is invalid' do
299
- let(:kase) { CapsuleCRM::Case.new(name: 'Test Case') }
300
-
301
- it do
302
- expect { kase.save! }.
303
- to raise_error(CapsuleCRM::Errors::RecordInvalid)
304
- end
305
- end
306
- end
307
-
308
- context 'when it is not a new record' do
309
- context 'when it is valid' do
310
- let(:kase) do
311
- CapsuleCRM::Case.new(id: 1, name: 'Test Case', party: party)
312
- end
313
-
314
- before do
315
- stub_request(:put, /^.*\/api\/kase\/1$/).to_return(status: 200)
316
- kase.save!
317
- end
318
-
319
- it { kase.should be_persisted }
320
- end
321
-
322
- context 'when it is invalid' do
323
- let(:kase) do
324
- CapsuleCRM::Case.new(id: 1, name: 'Test Case')
325
- end
326
-
327
- it do
328
- expect { kase.save! }.
329
- to raise_error(CapsuleCRM::Errors::RecordInvalid)
330
- end
331
- end
332
- end
333
- end
334
-
335
- describe '#destroy' do
336
- let(:party) { CapsuleCRM::Person.new(id: 2) }
337
-
338
- let(:kase) { CapsuleCRM::Case.new(id: 1, party: party, name: 'Test Case') }
339
-
340
- before do
341
- stub_request(:delete, /^.*\/api\/kase\/1$/).to_return(status: 200)
342
- kase.destroy
343
- end
344
-
345
- it { kase.should_not be_persisted }
346
- end
347
-
348
- describe '#new_record?' do
349
- describe 'when it is a new record' do
350
-
351
- subject { CapsuleCRM::Case.new }
352
-
353
- it { should be_new_record }
354
- end
355
-
356
- describe 'when it is not a new record' do
357
- subject { CapsuleCRM::Case.new(id: 1) }
358
-
359
- it { should_not be_new_record }
360
- end
361
- end
362
-
363
- describe '#persisted?' do
364
- context 'when it is persisted' do
365
- subject { CapsuleCRM::Case.new(id: 1) }
366
-
367
- it { should be_persisted }
368
- end
369
-
370
- context 'when it is not persisted' do
371
- subject { CapsuleCRM::Case.new }
58
+ describe '#to_capsule_json' do
59
+ let(:kase) { CapsuleCRM::Case.new }
60
+ subject { kase.to_capsule_json }
372
61
 
373
- it { should_not be_persisted }
62
+ it 'should have a root of "kase"' do
63
+ expect(subject.keys.first).to eql('kase')
374
64
  end
375
65
  end
376
66
  end
@@ -3,20 +3,5 @@ require 'spec_helper'
3
3
  describe CapsuleCRM::Country do
4
4
  before { configure }
5
5
 
6
- describe '.all' do
7
- before do
8
- stub_request(:get, /\/api\/countries$/).
9
- to_return(body: File.read('spec/support/countries.json'))
10
- end
11
-
12
- subject { CapsuleCRM::Country.all }
13
-
14
- it { should be_a(Array) }
15
-
16
- it { subject.count.should eql(2) }
17
-
18
- it do
19
- subject.all? { |item| item.is_a?(CapsuleCRM::Country) }.should be_true
20
- end
21
- end
6
+ it_behaves_like 'listable', '/countries', 'countries', 2
22
7
  end
@@ -3,22 +3,5 @@ require 'spec_helper'
3
3
  describe CapsuleCRM::Currency do
4
4
  before { configure }
5
5
 
6
- describe '.all' do
7
- before do
8
- stub_request(:get, /\/api\/currencies$/).
9
- to_return(body: File.read('spec/support/currencies.json'))
10
- end
11
-
12
- subject { CapsuleCRM::Currency.all }
13
-
14
- it { should be_a(Array) }
15
-
16
- it { subject.length.should eql(3) }
17
-
18
- it do
19
- subject.all? { |item| item.is_a?(CapsuleCRM::Currency) }.should be_true
20
- end
21
-
22
- it { subject.first.code.should eql('AUD') }
23
- end
6
+ it_behaves_like 'listable', '/currencies', 'currencies', 3
24
7
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::CustomFieldDefinition do
4
+ before { configure }
5
+
6
+ describe '.for_parties' do
7
+ context 'when some definitions are returned' do
8
+ before do
9
+ stub_request(:get, /.*/).
10
+ to_return(body: File.read('spec/support/custom_field_definitions.json'))
11
+ end
12
+ subject { described_class.for_parties }
13
+
14
+ it 'should be an array' do
15
+ expect(subject).to be_a(Array)
16
+ end
17
+
18
+ it 'should contain 2 items' do
19
+ expect(subject.length).to eql(2)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe '.for_opportunities' do
25
+ context 'when some definitions are returned' do
26
+ before do
27
+ stub_request(:get, /.*/).
28
+ to_return(body: File.read('spec/support/custom_field_definitions.json'))
29
+ end
30
+ subject { described_class.for_opportunities }
31
+
32
+ it 'should be an array' do
33
+ expect(subject).to be_a(Array)
34
+ end
35
+
36
+ it 'should contain 2 items' do
37
+ expect(subject.length).to eql(2)
38
+ end
39
+ end
40
+ end
41
+
42
+ describe '.for_cases' do
43
+ context 'when some definitions are returned' do
44
+ before do
45
+ stub_request(:get, /.*/).
46
+ to_return(body: File.read('spec/support/custom_field_definitions.json'))
47
+ end
48
+ subject { described_class.for_cases }
49
+
50
+ it 'should be an array' do
51
+ expect(subject).to be_a(Array)
52
+ end
53
+
54
+ it 'should contain 2 items' do
55
+ expect(subject.length).to eql(2)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -7,7 +7,7 @@ describe CapsuleCRM::CustomField do
7
7
  stub_request(:get, /\/api\/users$/).
8
8
  to_return(body: File.read('spec/support/all_users.json'))
9
9
  stub_request(:get, /\/api\/opportunity\/milestones$/).
10
- to_return(body: File.read('spec/support/milestones.json'))
10
+ to_return(body: File.read('spec/support/all_milestones.json'))
11
11
  end
12
12
 
13
13
  describe 'validations' do
@@ -41,27 +41,6 @@ describe CapsuleCRM::CustomField do
41
41
  end
42
42
  end
43
43
 
44
- describe '.create' do
45
- context 'when it belongs to a party' do
46
- let(:organization) { Fabricate.build(:organization, id: 1) }
47
- let(:location) do
48
- 'https://sample.capsulecrm.com/api/party/#{organization.id}/customfields'
49
- end
50
- subject do
51
- CapsuleCRM::CustomField.create(
52
- id: 100, tag: 'The tag', label: 'A field', text: 'Some text',
53
- date: Date.today, boolean: true, party: organization
54
- )
55
- end
56
- before do
57
- stub_request(:post, /\/api\/party\/#{organization.id}\/customfields$/).
58
- to_return(headers: { 'Location' => location})
59
- end
60
-
61
- it { expect(subject.id).to eql(100) }
62
- end
63
- end
64
-
65
44
  describe '#to_capsule_json' do
66
45
  let(:custom_field) { Fabricate.build(:custom_field) }
67
46
  subject { custom_field.to_capsule_json }
@@ -71,11 +50,7 @@ describe CapsuleCRM::CustomField do
71
50
  end
72
51
 
73
52
  it 'should have a root element of "customField"' do
74
- expect(subject.keys.first).to eql('customFields')
75
- end
76
-
77
- it 'should have an element named "customField"' do
78
- expect(subject['customFields'].keys.first).to eql('customField')
53
+ expect(subject.keys.first).to eql('customField')
79
54
  end
80
55
  end
81
56
  end