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,22 +7,17 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
- include CapsuleCRM::Attributes
11
- include CapsuleCRM::Collection
10
+ include CapsuleCRM::Querying::Configuration
11
+ include CapsuleCRM::Querying::FindAll
12
+ include CapsuleCRM::Serializable
12
13
 
13
14
  attribute :id, Integer
14
15
  attribute :description, String
15
16
  attribute :capture_rule, String
16
17
 
17
- has_many :opportunities, class_name: 'CapsuleCRM::Opportunity'
18
- has_many :cases, class_name: 'CapsuleCRM::Case'
18
+ has_many :opportunities
19
+ has_many :cases
19
20
 
20
21
  validates :id, numericality: { allow_blank: true }
21
-
22
- def self.all
23
- init_collection(
24
- CapsuleCRM::Connection.get('/api/tracks')['tracks']['track']
25
- )
26
- end
27
22
  end
28
23
  end
@@ -7,6 +7,9 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
+ include CapsuleCRM::Querying::Configuration
11
+ include CapsuleCRM::Querying::FindAll
12
+ include CapsuleCRM::Serializable
10
13
 
11
14
  attribute :username, String
12
15
  attribute :name, String
@@ -16,21 +19,6 @@ module CapsuleCRM
16
19
 
17
20
  belongs_to :party, class_name: 'CapsuleCRM::Party'
18
21
 
19
- # Public: Retrieve all users from CapsuleCRM
20
- #
21
- # Examples:
22
- #
23
- # CapsuleCRM::User.all
24
- #
25
- # Returns a CapsuleCRM::ResultsProxy of CapsuleCRM::User objects
26
- def self.all
27
- CapsuleCRM::ResultsProxy.new(
28
- CapsuleCRM::Connection.get('/api/users')['users']['user'].map do |item|
29
- new item
30
- end
31
- )
32
- end
33
-
34
22
  def id
35
23
  username
36
24
  end
@@ -1,3 +1,3 @@
1
1
  module CapsuleCrm
2
- VERSION = '1.2.0'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -1,12 +1,14 @@
1
1
  module CapsuleCRM
2
2
  class Website
3
3
  include Virtus
4
+ include CapsuleCRM::Serializable
4
5
 
5
6
  extend ActiveModel::Naming
6
7
  include ActiveModel::Validations
7
- include ActiveModel::Serializers::JSON
8
8
 
9
- include CapsuleCRM::CapsuleJsonable
9
+ serializable_config do |config|
10
+ config.include_root = false
11
+ end
10
12
 
11
13
  attribute :type
12
14
  attribute :web_service
data/lib/capsule_crm.rb CHANGED
@@ -1,18 +1,21 @@
1
1
  require 'active_model'
2
+ require 'active_support/core_ext/string/inflections'
2
3
  require 'faraday'
3
4
  require 'faraday_middleware'
4
5
  require 'virtus'
5
- require 'capsule_crm/attributes'
6
- require 'capsule_crm/capsule_jsonable'
6
+ require 'capsule_crm/gettable'
7
7
  require 'capsule_crm/taggable'
8
- require 'capsule_crm/collection'
9
8
  require 'capsule_crm/associations'
10
- require 'capsule_crm/address'
11
- require 'capsule_crm/case'
12
9
  require 'capsule_crm/connection'
10
+ require 'capsule_crm/normalizer'
11
+ require 'capsule_crm/persistence'
12
+ require 'capsule_crm/querying'
13
13
  require 'capsule_crm/serializer'
14
+ require 'capsule_crm/serializable'
14
15
 
16
+ require 'capsule_crm/address'
15
17
  require 'capsule_crm/attachment'
18
+ require 'capsule_crm/case'
16
19
  require 'capsule_crm/country'
17
20
  require 'capsule_crm/currency'
18
21
  require 'capsule_crm/email'
@@ -33,6 +36,7 @@ require 'capsule_crm/contacts'
33
36
  require 'capsule_crm/contactable'
34
37
  require 'capsule_crm/configuration'
35
38
  require 'capsule_crm/custom_field'
39
+ require 'capsule_crm/custom_field_definition'
36
40
  require 'capsule_crm/opportunity'
37
41
  require 'capsule_crm/organization'
38
42
  require 'capsule_crm/participant'
@@ -53,4 +57,10 @@ module CapsuleCRM
53
57
  yield(self.configuration)
54
58
  self.configuration
55
59
  end
60
+
61
+ def self.log(message, level = :debug)
62
+ if self.configuration.perform_logging
63
+ self.configuration.logger.send(level, message)
64
+ end
65
+ end
56
66
  end
@@ -1,3 +1,4 @@
1
1
  Fabricator(:case, class_name: :'CapsuleCRM::Case') do
2
2
  name { Faker::Lorem.sentence }
3
+ party { Fabricate.build(:person, id: Random.rand(1..10)) }
3
4
  end
@@ -1,3 +1,4 @@
1
1
  Fabricator(:history, class_name: :'CapsuleCRM::History') do
2
2
  note { Faker::Lorem.paragraph }
3
+ party { Fabricate.build(:person, id: Random.rand(1..10)) }
3
4
  end
@@ -1,4 +1,5 @@
1
1
  Fabricator(:opportunity, class_name: :'CapsuleCRM::Opportunity') do
2
2
  name 'Test'
3
3
  milestone_id 1
4
+ party { Fabricate.build(:person, id: Random.rand(1..10)) }
4
5
  end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::Associations::BelongsToFinder do
4
+ before { configure }
5
+
6
+ describe '#call' do
7
+ let(:association) do
8
+ double(
9
+ 'CapsuleCRM::Associations::BelongsToAssociation', inverse: inverse
10
+ )
11
+ end
12
+ let(:inverse) do
13
+ double('CapsuleCRM::Associations::HasManyAssociation')
14
+ end
15
+ let(:normalizer) do
16
+ double('CapsuleCRM::Normalizer', normalize_collection: [])
17
+ end
18
+ let(:finder) { described_class.new(association) }
19
+ before do
20
+ finder.singular = 'person'
21
+ finder.plural = 'customfields'
22
+ finder.normalizer = normalizer
23
+ end
24
+
25
+ context 'when an ID is supplied' do
26
+ before do
27
+ stub_request(:get, /.*/).
28
+ to_return(body: File.read('spec/support/all_customfields.json'))
29
+ end
30
+ subject { finder.call(1) }
31
+
32
+ it 'should send a request' do
33
+ subject
34
+ expect(WebMock).to have_requested(
35
+ :get, "https://1234:@company.capsulecrm.com/api/person/1/customfields"
36
+ )
37
+ end
38
+ end
39
+
40
+ context 'when a nil ID is supplied' do
41
+ subject { finder.call(nil) }
42
+
43
+ it 'should return an array' do
44
+ expect(subject).to be_a(Array)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ class BelongsToTest
4
+ include Virtus
5
+ include CapsuleCRM::Associations
6
+
7
+ belongs_to :person
8
+ end
9
+
10
+ describe CapsuleCRM::Associations::BelongsTo do
11
+ describe '.belongs_to' do
12
+ subject { BelongsToTest.new }
13
+
14
+ it 'should create a foreign key getter' do
15
+ expect(subject).to respond_to(:person_id)
16
+ end
17
+
18
+ it 'should create a foreign key setter' do
19
+ expect(subject).to respond_to(:person_id=)
20
+ end
21
+
22
+ it 'should create a class level finder method' do
23
+ expect(subject.class).to respond_to(:_for_person)
24
+ end
25
+
26
+ it 'should create an association setter method' do
27
+ expect(subject).to respond_to(:person=)
28
+ end
29
+
30
+ it 'should create an association getter method' do
31
+ expect(subject).to respond_to(:person)
32
+ end
33
+ end
34
+ end
@@ -3,10 +3,18 @@ require 'spec_helper'
3
3
  class Parent
4
4
  include Virtus
5
5
  include CapsuleCRM::Associations
6
+ include CapsuleCRM::Querying::Configuration
7
+
8
+ queryable_config do |config|
9
+ config.plural = :people
10
+ config.singular = :person
11
+ end
6
12
 
7
13
  attribute :id, Integer
8
14
 
9
15
  has_many :children, class_name: 'Child', source: :parent
16
+ has_many :embedded_children, class_name: 'Child', source: :parent_as_embedded,
17
+ embedded: true
10
18
 
11
19
  def persisted?
12
20
  !!id
@@ -16,10 +24,21 @@ end
16
24
  class Child
17
25
  include Virtus
18
26
  include CapsuleCRM::Associations
27
+ include CapsuleCRM::Querying::Configuration
28
+ include CapsuleCRM::Serializable
29
+
30
+ queryable_config do |config|
31
+ config.plural = :children
32
+ end
33
+
34
+ serializable_config do |config|
35
+ config.collection_root = :childs
36
+ end
19
37
 
20
38
  attribute :name
21
39
 
22
- belongs_to :parent
40
+ belongs_to :parent, class_name: 'Parent'
41
+ belongs_to :parent_as_embedded, class_name: 'Parent'
23
42
 
24
43
  def self._for_parent(parent_id)
25
44
  []
@@ -40,10 +59,9 @@ describe CapsuleCRM::Associations::HasManyProxy do
40
59
  parent, Child, target, :parent
41
60
  )
42
61
  end
43
-
44
62
  let(:parent) { Parent.new }
45
-
46
63
  let(:target) { [] }
64
+ before { configure }
47
65
 
48
66
  describe '#build' do
49
67
  before { parent.children.build(name: 'a test name') }
@@ -66,21 +84,43 @@ describe CapsuleCRM::Associations::HasManyProxy do
66
84
  end
67
85
 
68
86
  describe '#create' do
69
- subject { parent.children.create(name: 'a test name') }
70
- context 'when the parent is persisted' do
71
- before do
72
- parent.id = Random.rand(1..10)
73
- subject
87
+ context 'when the child is embedded' do
88
+ let(:name) { Faker::Lorem.word }
89
+ subject { parent.embedded_children.create(name: name) }
90
+
91
+ context 'when the parent is persisted' do
92
+ before do
93
+ stub_request(:put, /.*/).to_return(status: 200)
94
+ parent.id = Random.rand(1..10)
95
+ subject
96
+ end
97
+
98
+ it 'should send a put request to capsule' do
99
+ expect(WebMock).to have_requested(
100
+ :put, "https://1234:@company.capsulecrm.com/api/person/#{parent.id}/children"
101
+ ).with(body: { childs: { child: [{ name: name }] } })
102
+ end
74
103
  end
104
+ end
75
105
 
76
- it 'should persist the child' do
77
- expect(parent.children.last).to be_persisted
106
+ context 'when the child is not embedded' do
107
+ subject { parent.children.create(name: 'a test name') }
108
+
109
+ context 'when the parent is persisted' do
110
+ before do
111
+ parent.id = Random.rand(1..10)
112
+ subject
113
+ end
114
+
115
+ it 'should persist the child' do
116
+ expect(parent.children.last).to be_persisted
117
+ end
78
118
  end
79
- end
80
119
 
81
- context 'when the parent is not persisted' do
82
- it 'should raise a RecordNotSaved error' do
83
- expect { subject }.to raise_error(CapsuleCRM::Errors::RecordNotSaved)
120
+ context 'when the parent is not persisted' do
121
+ it 'should raise a RecordNotSaved error' do
122
+ expect { subject }.to raise_error(CapsuleCRM::Errors::RecordNotSaved)
123
+ end
84
124
  end
85
125
  end
86
126
  end
@@ -1,8 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe CapsuleCRM::Associations::HasMany do
3
+ class HasManyTest
4
+ include CapsuleCRM::Associations
5
+
6
+ has_many :people
7
+ end
4
8
 
9
+ describe CapsuleCRM::Associations::HasMany do
5
10
  describe '#has_many' do
6
- pending
11
+ subject { HasManyTest.new }
12
+
13
+ it 'should create an accessor method' do
14
+ expect(subject).to respond_to(:people)
15
+ end
16
+
17
+ it 'should create a setter method' do
18
+ expect(subject).to respond_to(:people=)
19
+ end
7
20
  end
8
21
  end