capsule_crm 1.2.0 → 1.3.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 (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
@@ -7,21 +7,28 @@ describe CapsuleCRM::History 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
+ it_behaves_like 'persistable', 'https://sample.capsulecrm.com/api/history/205', 205 do
14
+ let(:attributes) { Fabricate.attributes_for(:history).merge(party: party) }
15
+ let(:party) { Fabricate.build(:person, id: Random.rand(1..10)) }
16
+ end
17
+
18
+ it_behaves_like 'deletable'
19
+
13
20
  describe 'validations' do
14
21
  subject { described_class.new }
15
22
 
16
23
  it { should validate_numericality_of(:id) }
17
24
  it { should validate_presence_of(:note) }
18
- it { should validate_presence_of(:kase) }
25
+ it { should validate_presence_of(:case) }
19
26
  it { should validate_presence_of(:party) }
20
27
  it { should validate_presence_of(:opportunity) }
21
28
 
22
29
  context 'when it belongs to a case' do
23
30
  before do
24
- subject.kase = double('CapsuleCRM::Case', id: Random.rand(1..10))
31
+ subject.case = double('CapsuleCRM::Case', id: Random.rand(1..10))
25
32
  end
26
33
 
27
34
  it { should_not validate_presence_of(:party) }
@@ -33,7 +40,7 @@ describe CapsuleCRM::History do
33
40
  subject.party = double('CapsuleCRM::Party', id: Random.rand(1..10))
34
41
  end
35
42
 
36
- it { should_not validate_presence_of(:kase) }
43
+ it { should_not validate_presence_of(:case) }
37
44
  it { should_not validate_presence_of(:opportunity) }
38
45
  end
39
46
 
@@ -44,7 +51,7 @@ describe CapsuleCRM::History do
44
51
  end
45
52
 
46
53
  it { should_not validate_presence_of(:party) }
47
- it { should_not validate_presence_of(:kase) }
54
+ it { should_not validate_presence_of(:case) }
48
55
  end
49
56
  end
50
57
 
@@ -132,7 +139,7 @@ describe CapsuleCRM::History do
132
139
  end
133
140
  end
134
141
 
135
- describe 'find' do
142
+ describe '.find' do
136
143
  let(:first_attachment) { subject.attachments.first }
137
144
  let(:first_participant) { subject.participants.first }
138
145
  before do
@@ -171,7 +178,7 @@ describe CapsuleCRM::History do
171
178
  end
172
179
 
173
180
  its(:case_id) { should_not be_blank }
174
- its(:kase) { should_not be_blank }
181
+ its(:case) { should_not be_blank }
175
182
  end
176
183
 
177
184
  context 'when it belongs to an opportunity' do
@@ -216,388 +223,6 @@ describe CapsuleCRM::History do
216
223
  end
217
224
  end
218
225
 
219
- describe '.create' do
220
- context 'when it belongs to a party' do
221
- let(:person) { Fabricate.build(:person, id: 1) }
222
- subject do
223
- CapsuleCRM::History.create(
224
- note: Faker::Lorem.paragraph, party: person
225
- )
226
- end
227
- let(:location) do
228
- "https://sample.capsulecrm.com/api/party/#{person.id}/history/101"
229
- end
230
- before do
231
- stub_request(:post, /\/api\/party\/#{person.id}\/history$/).
232
- to_return(headers: { 'Location' => location})
233
- end
234
-
235
- its(:id) { should eql(101) }
236
- end
237
-
238
- context 'when it belongs to a kase' do
239
- let(:kase) { Fabricate.build(:case, id: 2) }
240
- let(:location) do
241
- "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10"
242
- end
243
- subject do
244
- CapsuleCRM::History.create(note: Faker::Lorem.paragraph, kase: kase)
245
- end
246
- before do
247
- stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
248
- to_return(headers: { 'Location' => location })
249
- end
250
-
251
- its(:id) { should eql(10) }
252
- end
253
-
254
- context 'when it belongs to an opportunity' do
255
- let(:opportunity) { Fabricate.build(:opportunity, id: 1) }
256
- subject do
257
- CapsuleCRM::History.create(
258
- note: Faker::Lorem.paragraph, opportunity: opportunity
259
- )
260
- end
261
- let(:location) do
262
- [
263
- 'https://sample.capsulecrm.com/api/opportunity/',
264
- opportunity.id, '/history/9'
265
- ].join
266
- end
267
- before do
268
- stub_request(:post, /\/api\/opportunity\/#{opportunity.id}\/history$/).
269
- to_return(headers: { 'Location' => location })
270
- end
271
-
272
- its(:id) { should eql(9) }
273
- end
274
-
275
- context 'when it is invalid' do
276
- subject { CapsuleCRM::History.create }
277
-
278
- it { should_not be_valid }
279
- end
280
- end
281
-
282
- describe '.create!' do
283
- context 'when it belongs to a party' do
284
- let(:person) { Fabricate.build(:person, id: 1) }
285
- subject do
286
- CapsuleCRM::History.create!(
287
- note: Faker::Lorem.paragraph, party: person
288
- )
289
- end
290
- let(:location) do
291
- "https://sample.capsulecrm.com/api/party/#{person.id}/history/101"
292
- end
293
- before do
294
- stub_request(:post, /\/api\/party\/#{person.id}\/history$/).
295
- to_return(headers: { 'Location' => location})
296
- end
297
-
298
- its(:id) { should eql(101) }
299
- end
300
-
301
- context 'when it belongs to a kase' do
302
- let(:kase) { Fabricate.build(:case, id: 2) }
303
- let(:location) do
304
- "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10"
305
- end
306
- subject do
307
- CapsuleCRM::History.create!(note: Faker::Lorem.paragraph, kase: kase)
308
- end
309
- before do
310
- stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
311
- to_return(headers: { 'Location' => location })
312
- end
313
-
314
- its(:id) { should eql(10) }
315
- end
316
-
317
- context 'when it belongs to an opportunity' do
318
- let(:opportunity) { Fabricate.build(:opportunity, id: 1) }
319
- subject do
320
- CapsuleCRM::History.create!(
321
- note: Faker::Lorem.paragraph, opportunity: opportunity
322
- )
323
- end
324
- let(:location) do
325
- [
326
- 'https://sample.capsulecrm.com/api/opportunity/',
327
- opportunity.id, '/history/9'
328
- ].join
329
- end
330
- before do
331
- stub_request(:post, /\/api\/opportunity\/#{opportunity.id}\/history$/).
332
- to_return(headers: { 'Location' => location })
333
- end
334
-
335
- its(:id) { should eql(9) }
336
- end
337
-
338
- context 'when it is invalid' do
339
- it do
340
- expect { CapsuleCRM::History.create! }.
341
- to raise_error(CapsuleCRM::Errors::RecordInvalid)
342
- end
343
- end
344
- end
345
-
346
- describe '#update_attributes' do
347
- context 'when the history is valid' do
348
- subject { Fabricate(:history, id: 2, party: Fabricate.build(:person)) }
349
- before do
350
- stub_request(:put, /api\/history\/2$/).to_return(status: 200)
351
- subject.update_attributes note: 'changed note text'
352
- end
353
-
354
- its(:note) { should eql('changed note text') }
355
- it { should be_persisted }
356
- end
357
-
358
- context 'when the history is not valid' do
359
- subject { CapsuleCRM::History.new(id: 2) }
360
- before { subject.update_attributes subject: Faker::Lorem.sentence }
361
-
362
- it { should_not be_valid }
363
- end
364
- end
365
-
366
- describe '#update_attributes!' do
367
- context 'when it is valid' do
368
- subject { Fabricate(:history, id: 3, party: Fabricate.build(:case)) }
369
- before do
370
- stub_request(:put, /api\/history\/3$/).to_return(status: 200)
371
- subject.update_attributes! note: 'some new note'
372
- end
373
-
374
- its(:note) { should eql('some new note') }
375
- it { should be_persisted }
376
- end
377
-
378
- context 'when it is not valid' do
379
- subject { CapsuleCRM::History.new(id: 3) }
380
-
381
- it do
382
- expect { subject.update_attributes! subject: 'test' }.
383
- to raise_error(CapsuleCRM::Errors::RecordInvalid)
384
- end
385
- end
386
- end
387
-
388
- describe '#save' do
389
- context 'when it is a new record' do
390
- let(:history) { Fabricate.build(:history) }
391
-
392
- context 'when it belongs to a party' do
393
- let(:party) { Fabricate.build(:organization, id: 2) }
394
- let(:location) do
395
- "https://sample.capsulecrm.com/api/party/#{party.id}/history/101"
396
- end
397
- before do
398
- history.party = party
399
- stub_request(:post, /\/api\/party\/#{party.id}\/history$/).
400
- to_return(headers: { 'Location' => location })
401
- history.save
402
- end
403
- subject { history }
404
-
405
- its(:id) { should eql(101) }
406
- it { history.should be_persisted }
407
- end
408
-
409
- context 'when it belongs to a kase' do
410
- let(:kase) { Fabricate.build(:case, id: 5) }
411
- let(:location) do
412
- "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10005"
413
- end
414
- before do
415
- history.kase = kase
416
- stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
417
- to_return(headers: { 'Location' => location })
418
- history.save
419
- end
420
- subject { history }
421
-
422
- its(:id) { should eql(10005) }
423
- it { should be_persisted }
424
- end
425
-
426
- context 'when it belongs to an opportunity' do
427
- let(:opportunity) { Fabricate.build(:opportunity, id: 3) }
428
- let(:location) do
429
- [
430
- 'https://sample.capsulecrm.com/api/opportunity/',
431
- opportunity.id, '/history/101'
432
- ].join
433
- end
434
- before do
435
- history.opportunity = opportunity
436
- stub_request(
437
- :post, /\/api\/opportunity\/#{opportunity.id}\/history$/
438
- ).to_return(headers: { 'Location' => location })
439
- history.save
440
- end
441
- subject { history }
442
-
443
- its(:id) { should eql(101) }
444
- it { should be_persisted }
445
- end
446
- end
447
-
448
- context 'when it is an existing record' do
449
- let(:history) do
450
- Fabricate.build(:history, party: Fabricate.build(:person), id: 10)
451
- end
452
- before do
453
- stub_request(:put, /\/api\/history\/#{history.id}$/).
454
- to_return(status: 200)
455
- history.save
456
- end
457
- subject { history }
458
-
459
- it { should be_persisted }
460
- end
461
- end
462
-
463
- describe '#save!' do
464
- context 'when it is a new record' do
465
- context 'when it is invalid' do
466
- let(:history) { CapsuleCRM::History.new(id: 5) }
467
-
468
- it 'should raise an error' do
469
- expect { history.save! }.
470
- to raise_error(CapsuleCRM::Errors::RecordInvalid)
471
- end
472
- end
473
- let(:history) { Fabricate.build(:history) }
474
-
475
- context 'when it belongs to a party' do
476
- let(:party) { Fabricate.build(:organization, id: 2) }
477
- let(:location) do
478
- "https://sample.capsulecrm.com/api/party/#{party.id}/history/101"
479
- end
480
- before do
481
- history.party = party
482
- stub_request(:post, /\/api\/party\/#{party.id}\/history$/).
483
- to_return(headers: { 'Location' => location })
484
- history.save!
485
- end
486
- subject { history }
487
-
488
- its(:id) { should eql(101) }
489
- it { should be_persisted }
490
- end
491
-
492
- context 'when it belongs to a kase' do
493
- let(:kase) { Fabricate.build(:case, id: 5) }
494
- let(:location) do
495
- "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10005"
496
- end
497
- before do
498
- history.kase = kase
499
- stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
500
- to_return(headers: { 'Location' => location })
501
- history.save!
502
- end
503
- subject { history }
504
-
505
- its(:id) { should eql(10005) }
506
- it { should be_persisted }
507
- end
508
-
509
- context 'when it belongs to an opportunity' do
510
- let(:opportunity) { Fabricate.build(:opportunity, id: 3) }
511
- let(:location) do
512
- [
513
- 'https://sample.capsulecrm.com/api/opportunity/',
514
- opportunity.id, '/history/101'
515
- ].join
516
- end
517
- before do
518
- history.opportunity = opportunity
519
- stub_request(
520
- :post, /\/api\/opportunity\/#{opportunity.id}\/history$/
521
- ).to_return(headers: { 'Location' => location })
522
- history.save!
523
- end
524
- subject { history }
525
-
526
- its(:id) { should eql(101) }
527
- it { should be_persisted }
528
- end
529
- end
530
-
531
- context 'when it is an existing record' do
532
- context 'when it is valid' do
533
- let(:history) do
534
- Fabricate.build(:history, party: Fabricate.build(:person), id: 10)
535
- end
536
- before do
537
- stub_request(:put, /\/api\/history\/#{history.id}$/).
538
- to_return(status: 200)
539
- history.save!
540
- end
541
- subject { history }
542
-
543
- it { should be_persisted }
544
- end
545
-
546
- context 'when it is not valid' do
547
- let(:history) { CapsuleCRM::History.new(id: 1) }
548
-
549
- it 'should raise an error' do
550
- expect { history.save! }.
551
- to raise_error(CapsuleCRM::Errors::RecordInvalid)
552
- end
553
- end
554
- end
555
- end
556
-
557
- describe '#destroy' do
558
- let(:history) { Fabricate.build(:history, id: 19) }
559
- before do
560
- stub_request(:delete, /\/api\/history\/#{history.id}$/).
561
- to_return(status: 200)
562
- history.destroy
563
- end
564
- subject { history }
565
-
566
- it { should_not be_persisted }
567
- end
568
-
569
- describe '#new_record?' do
570
- context 'when the history item is a new record' do
571
- let(:history) { CapsuleCRM::History.new }
572
- subject { history.new_record? }
573
-
574
- it { should be_true }
575
- end
576
-
577
- context 'when the history item is not a new record' do
578
- let(:history) { CapsuleCRM::History.new(id: 1) }
579
- subject { history.new_record? }
580
-
581
- it { should be_false }
582
- end
583
- end
584
-
585
- describe '#persisted?' do
586
- context 'when the history item is persisted' do
587
- let(:history) { CapsuleCRM::History.new(id: 1) }
588
- subject { history.persisted? }
589
-
590
- it { should be_true }
591
- end
592
-
593
- context 'when the hitory item is not persisted' do
594
- let(:history) { CapsuleCRM::History.new }
595
- subject { history.persisted? }
596
-
597
- it { should be_false }
598
- end
599
- end
600
-
601
226
  describe '#to_capsule_json' do
602
227
  let(:creator) { CapsuleCRM::User.new(username: Faker::Name.name) }
603
228
  let(:history) do
@@ -7,27 +7,5 @@ describe CapsuleCRM::Milestone do
7
7
  it { should validate_numericality_of(:id) }
8
8
  end
9
9
 
10
- describe '.all' do
11
- before do
12
- stub_request(:get, /\/api\/opportunity\/milestones$/).
13
- to_return(body: File.read('spec/support/milestones.json'))
14
- end
15
-
16
- subject { CapsuleCRM::Milestone.all }
17
-
18
- it { should be_a(Array) }
19
-
20
- it do
21
- subject.all? { |item| item.is_a?(CapsuleCRM::Milestone) }.should be_true
22
- end
23
-
24
- it do
25
- expect(subject.first.description).
26
- to eql('You have a potential buyer for your offering')
27
- end
28
-
29
- it { expect(subject.first.probability).to eql(10.0) }
30
-
31
- it { expect(subject.first.complete).to be_false }
32
- end
10
+ it_behaves_like 'listable', '/opportunity/milestones', 'milestones', 4
33
11
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::Normalizer do
4
+ describe '#normalize' do
5
+ pending
6
+ end
7
+
8
+ describe '#normalize_collection' do
9
+ pending
10
+ end
11
+ end