capsule_crm 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 970a6f5219598a75460554b8447b1feb07714674
4
- data.tar.gz: 483c4c0ec0f5fa7639f3c8788d91ce195c51bce5
3
+ metadata.gz: 9c9c330d4eeb07e7c78b092407c54bde1d851b7d
4
+ data.tar.gz: 745c544f60e55e8d7ce5aa9e8e3abdb79c80c0e2
5
5
  SHA512:
6
- metadata.gz: 540692d5ab936b2e828feae94611b02875aee983d2d1e70ccc807ea679ccb9a544e85ab0ddea973fce8f48f2541790f7fc701943eb5f9d33c8e4d91c615df074
7
- data.tar.gz: f7ef2803939afa2b25c5c43176c073cfc3c4412a16ef1347cb428ba15b88a67510bfbc142e85749a59edeab2ef700b138b15e564f45b145e20c692b50e235272
6
+ metadata.gz: c8643c862014d2c0fa7980d6f9c6cdc82279a4fa9e513b556012e1bb902f325a1b61fbeb107d1f92dd5b781c0ce7ab4d5592f55921337c1dd85b90676d78d3f0
7
+ data.tar.gz: ff1850b21048a9994f05b1678895b522089c24240329d436da85e852874986049b8d53217b7122612c14488a8c0105092d59e036c288e61b4f339fc1b6d17a79
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --color
2
- --format progress
2
+ --format documentation
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 0.9.0
4
+
5
+ ### New Features
6
+
7
+ - Custom field support (@srbaker, @clod81)
8
+ - Add Organization#destroy (@danthompson)
9
+
10
+ ### Bug fixes
11
+
12
+ - Fixed init_collection method for when a single (#27) (@clod81)
data/README.md CHANGED
@@ -8,6 +8,8 @@ Version](https://badge.fury.io/rb/capsule_crm.png)](http://badge.fury.io/rb/caps
8
8
  Status](https://coveralls.io/repos/mattbeedle/capsule_crm/badge.png?branch=master)](https://coveralls.io/r/mattbeedle/capsule_crm)
9
9
  [![Dependency
10
10
  Status](https://gemnasium.com/mattbeedle/capsule_crm.png)](https://gemnasium.com/mattbeedle/capsule_crm)
11
+ [![Stories in
12
+ Ready](http://badge.waffle.io/mattbeedle/capsule_crm.png)](http://waffle.io/mattbeedle/capsule_crm)
11
13
 
12
14
  # CapsuleCRM
13
15
 
@@ -6,6 +6,7 @@ module CapsuleCRM
6
6
  include ActiveModel::Conversion
7
7
  include ActiveModel::Validations
8
8
 
9
+ include CapsuleCRM::Collection
9
10
  include CapsuleCRM::Associations::HasMany
10
11
  include CapsuleCRM::Associations::BelongsTo
11
12
  include CapsuleCRM::Taggable
@@ -254,9 +255,5 @@ module CapsuleCRM
254
255
  def update_record
255
256
  CapsuleCRM::Connection.put("/api/kase/#{id}", to_capsule_json)
256
257
  end
257
-
258
- def self.init_collection(results)
259
- CapsuleCRM::ResultsProxy.new(results.map { |item| new item })
260
- end
261
258
  end
262
- end
259
+ end
@@ -0,0 +1,9 @@
1
+ module CapsuleCRM::Collection
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def init_collection(*collection)
6
+ collection.flatten.compact.map { |item| new item }
7
+ end
8
+ end
9
+ end
@@ -22,7 +22,7 @@ module CapsuleCRM
22
22
  end
23
23
 
24
24
  def self.put(path, params)
25
- faraday.put(path, params) do |request|
25
+ faraday.put(path, params.to_json) do |request|
26
26
  request.headers.update default_request_headers
27
27
  end.success?
28
28
  end
@@ -6,34 +6,89 @@ module CapsuleCRM
6
6
  include ActiveModel::Conversion
7
7
  include ActiveModel::Validations
8
8
 
9
+ include CapsuleCRM::Associations
10
+ include CapsuleCRM::Collection
11
+
9
12
  attribute :id, Integer
13
+ attribute :label, String
10
14
  attribute :date, DateTime
11
15
  attribute :tag, String
12
16
  attribute :boolean, Boolean
13
17
  attribute :text, String
14
- attribute :data_tag, String
18
+
19
+ validates :label, presence: true
20
+
21
+ belongs_to :party, class_name: 'CapsuleCRM::Party'
22
+
23
+ def self._for_party(party_id)
24
+ init_collection(
25
+ CapsuleCRM::Connection.
26
+ get("/api/party/#{party_id}/customfields")['customFields'].
27
+ fetch('customField', nil)
28
+ )
29
+ end
30
+
31
+ class << self
32
+ alias :_for_organization :_for_party
33
+ alias :_for_person :_for_party
34
+ end
35
+
36
+ def attributes=(attributes)
37
+ CapsuleCRM::HashHelper.underscore_keys!(attributes)
38
+ super(attributes)
39
+ self
40
+ end
15
41
 
16
42
  def self.create(attributes = {})
43
+ new(attributes).tap(&:save)
17
44
  end
18
45
 
19
46
  def self.create!(attribute = {})
47
+ new(attributes).tap(&:save)
20
48
  end
21
49
 
22
50
  def save
51
+ if valid?
52
+ update_record
53
+ else
54
+ false
55
+ end
23
56
  end
24
57
 
25
58
  def save!
59
+ if valid?
60
+ update_record
61
+ else
62
+ raise CapsuleCRM::Errors::RecordInvalid.new(self)
63
+ end
26
64
  end
27
65
 
28
66
  def destroy
29
67
  end
30
68
 
31
- private
32
-
33
- def create_record
69
+ def to_capsule_json
70
+ {
71
+ customFields: {
72
+ customField: [CapsuleCRM::HashHelper.camelize_keys(
73
+ {
74
+ id: id,
75
+ label: label,
76
+ date: date,
77
+ tag: tag,
78
+ boolean: boolean,
79
+ text: text,
80
+ }.delete_if { |key, value| value.blank? }
81
+ )]
82
+ }
83
+ }
34
84
  end
35
85
 
86
+ private
87
+
36
88
  def update_record
89
+ CapsuleCRM::Connection.post(
90
+ "/api/party/#{party.id}/customfields", to_capsule_json
91
+ )
37
92
  end
38
93
  end
39
- end
94
+ end
@@ -7,6 +7,7 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations
10
+ include CapsuleCRM::Collection
10
11
 
11
12
  attribute :id, Integer
12
13
  attribute :type, String
@@ -55,12 +56,6 @@ module CapsuleCRM
55
56
  )
56
57
  end
57
58
 
58
- def self.init_collection(collection)
59
- CapsuleCRM::ResultsProxy.new(
60
- [collection].flatten.delete_if(&:blank?).map { |item| new(item) }
61
- )
62
- end
63
-
64
59
  # Public: Underscore all of the attributes keys and set the attributes of
65
60
  # this history item
66
61
  #
@@ -355,4 +350,4 @@ module CapsuleCRM
355
350
  CapsuleCRM::Connection.put("/api/history/#{id}", to_capsule_json)
356
351
  end
357
352
  end
358
- end
353
+ end
@@ -2,6 +2,8 @@ module CapsuleCRM
2
2
  class Milestone
3
3
  include Virtus
4
4
 
5
+ include CapsuleCRM::Collection
6
+
5
7
  attribute :id, Integer
6
8
  attribute :name, String
7
9
  attribute :description, String
@@ -22,13 +24,5 @@ module CapsuleCRM
22
24
  def self.find_by_name(name)
23
25
  all.select { |item| item.name == name }.first
24
26
  end
25
-
26
- private
27
-
28
- def self.init_collection(collection)
29
- CapsuleCRM::ResultsProxy.new(
30
- collection.map { |attributes| new attributes }
31
- )
32
- end
33
27
  end
34
- end
28
+ end
@@ -6,8 +6,8 @@ module CapsuleCRM
6
6
  include ActiveModel::Conversion
7
7
  include ActiveModel::Validations
8
8
 
9
- include CapsuleCRM::Associations::HasMany
10
- include CapsuleCRM::Associations::BelongsTo
9
+ include CapsuleCRM::Associations
10
+ include CapsuleCRM::Collection
11
11
 
12
12
  attribute :id, Integer
13
13
  attribute :name, String
@@ -348,9 +348,5 @@ module CapsuleCRM
348
348
  CapsuleCRM::Connection.put("/api/opportunity/#{id}", attributes)
349
349
  self
350
350
  end
351
-
352
- def self.init_collection(collection)
353
- CapsuleCRM::ResultsProxy.new(collection.map { |item| new item })
354
- end
355
351
  end
356
- end
352
+ end
@@ -11,8 +11,9 @@ module CapsuleCRM
11
11
  include ActiveModel::Validations::Callbacks
12
12
 
13
13
  include CapsuleCRM::Associations::HasMany
14
- include CapsuleCRM::Taggable
14
+ include CapsuleCRM::Collection
15
15
  include CapsuleCRM::Contactable
16
+ include CapsuleCRM::Taggable
16
17
 
17
18
  attribute :id, Integer
18
19
  attribute :name, String
@@ -21,6 +22,7 @@ module CapsuleCRM
21
22
  validates :name, presence: true
22
23
 
23
24
  has_many :people, class_name: 'CapsuleCRM::Person', source: :organization
25
+ has_many :custom_fields, class_name: 'CapsuleCRM::CustomField', source: :organization
24
26
 
25
27
  # Public: Set the attributes of an organization
26
28
  #
@@ -227,12 +229,25 @@ module CapsuleCRM
227
229
  #
228
230
  # Returns a Hash
229
231
  def to_capsule_json
232
+ self.contacts = nil if self.contacts.blank?
230
233
  {
231
- organisation: attributes.merge(contacts: contacts.to_capsule_json).
234
+ organisation: attributes.merge(self.contacts ? {contacts: (self.contacts.is_a?(Hash) ? self.contacts : self.contacts.to_capsule_json)} : {}).
232
235
  stringify_keys
233
236
  }.stringify_keys
234
237
  end
235
238
 
239
+ # Public: Delete the organization in capsule
240
+ #
241
+ # Examples
242
+ #
243
+ # organization.destroy
244
+ #
245
+ # Return the CapsuleCRM::Organization
246
+ def destroy
247
+ self.id = nil if CapsuleCRM::Connection.delete("/api/party/#{id}")
248
+ self
249
+ end
250
+
236
251
  private
237
252
 
238
253
  def create_record
@@ -242,17 +257,8 @@ module CapsuleCRM
242
257
  end
243
258
 
244
259
  def update_record
245
- CapsuleCRM::Connection.put("/api/organisation/#{id}", attributes)
246
- end
247
-
248
- # Private: Build a ResultsProxy from a Array of CapsuleCRM::Organization
249
- # attributes
250
- #
251
- # collection - The Array of CapsuleCRM::Organization attributes hashes
252
- #
253
- # Returns a CapsuleCRM::ResultsProxy
254
- def self.init_collection(collection)
255
- CapsuleCRM::ResultsProxy.new(collection.map { |item| new item })
260
+ CapsuleCRM::Connection.put("/api/organisation/#{id}", to_capsule_json)
261
+ self
256
262
  end
257
263
  end
258
264
  end
@@ -2,6 +2,7 @@ module CapsuleCRM
2
2
  class Person < CapsuleCRM::Party
3
3
  include Virtus
4
4
 
5
+ include CapsuleCRM::Collection
5
6
  include CapsuleCRM::Contactable
6
7
  include CapsuleCRM::Associations::BelongsTo
7
8
 
@@ -20,6 +21,8 @@ module CapsuleCRM
20
21
  belongs_to :organization, class_name: 'CapsuleCRM::Organization',
21
22
  foreign_key: :organisation_id
22
23
 
24
+ has_many :custom_fields, class_name: 'CapsuleCRM::CustomField', source: :person
25
+
23
26
  validates :first_name, presence: { if: :first_name_required? }
24
27
  validates :last_name, presence: { if: :last_name_required? }
25
28
 
@@ -243,10 +246,11 @@ module CapsuleCRM
243
246
  #
244
247
  # Returns a Hash
245
248
  def to_capsule_json
249
+ self.contacts = nil if self.contacts.blank?
246
250
  {
247
251
  person: CapsuleCRM::HashHelper.camelize_keys(
248
252
  attributes.dup.delete_if { |key, value| value.blank? }.
249
- merge(contacts: contacts.to_capsule_json)
253
+ merge(self.contacts ? {contacts: (self.contacts.is_a?(Hash) ? self.contacts : self.contacts.to_capsule_json)} : {})
250
254
  )
251
255
  }.stringify_keys
252
256
  end
@@ -265,15 +269,6 @@ module CapsuleCRM
265
269
  self
266
270
  end
267
271
 
268
- # Private: Build a ResultsProxy from a Array of CapsuleCRM::Person attributes
269
- #
270
- # collection - The Array of CapsuleCRM::Person attributes hashes
271
- #
272
- # Returns a CapsuleCRM::ResultsProxy
273
- def self.init_collection(collection)
274
- CapsuleCRM::ResultsProxy.new(collection.map { |item| new item })
275
- end
276
-
277
272
  # Private: Determines whether the person first name is required. Either the
278
273
  # first or the last name is always required
279
274
  #
@@ -11,7 +11,7 @@ module CapsuleCRM
11
11
  def add_tag(tag_name)
12
12
  if id
13
13
  CapsuleCRM::Connection.post(
14
- "/api/#{api_singular_name}/#{id}/#{URI.encode(tag_name)}"
14
+ "/api/#{api_singular_name}/#{id}/tag/#{URI.encode(tag_name)}"
15
15
  )
16
16
  end
17
17
  end
@@ -19,13 +19,15 @@ module CapsuleCRM
19
19
  def remove_tag(tag_name)
20
20
  if id
21
21
  CapsuleCRM::Connection.delete(
22
- "/api/#{api_singular_name}/#{id}/#{URI.encode(tag_name)}"
22
+ "/api/#{api_singular_name}/#{id}/tag/#{URI.encode(tag_name)}"
23
23
  )
24
24
  end
25
25
  end
26
26
 
27
27
  def api_singular_name
28
- self.class.to_s.demodulize.downcase.singularize
28
+ class_name = self.class.superclass.to_s unless self.class.superclass == Object
29
+ class_name ||= self.class.to_s
30
+ class_name.demodulize.downcase.singularize
29
31
  end
30
32
  end
31
33
  end
@@ -7,6 +7,7 @@ module CapsuleCRM
7
7
  include ActiveModel::Validations
8
8
 
9
9
  include CapsuleCRM::Associations::BelongsTo
10
+ include CapsuleCRM::Collection
10
11
 
11
12
  attribute :id, Integer
12
13
  attribute :due_date, Date
@@ -147,10 +148,6 @@ module CapsuleCRM
147
148
  end
148
149
  end
149
150
 
150
- def self.init_collection(collection)
151
- CapsuleCRM::ResultsProxy.new(collection.map { |item| new item })
152
- end
153
-
154
151
  def create_record
155
152
  self.attributes = CapsuleCRM::Connection.post(
156
153
  create_url, to_capsule_json
@@ -175,4 +172,4 @@ module CapsuleCRM
175
172
  self
176
173
  end
177
174
  end
178
- end
175
+ end
@@ -1,3 +1,3 @@
1
1
  module CapsuleCrm
2
- VERSION = '0.8.0'
2
+ VERSION = '0.9.0'
3
3
  end
data/lib/capsule_crm.rb CHANGED
@@ -4,6 +4,7 @@ require 'faraday_middleware'
4
4
  require 'virtus'
5
5
  require 'capsule_crm/capsule_jsonable'
6
6
  require 'capsule_crm/taggable'
7
+ require 'capsule_crm/collection'
7
8
  require 'capsule_crm/associations'
8
9
  require 'capsule_crm/address'
9
10
  require 'capsule_crm/case'
@@ -26,6 +27,7 @@ require 'capsule_crm/errors/record_invalid'
26
27
  require 'capsule_crm/contacts'
27
28
  require 'capsule_crm/contactable'
28
29
  require 'capsule_crm/configuration'
30
+ require 'capsule_crm/custom_field'
29
31
  require 'capsule_crm/opportunity'
30
32
  require 'capsule_crm/organization'
31
33
  require 'capsule_crm/participant'
@@ -0,0 +1,655 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::CustomField do
4
+ before { configure }
5
+
6
+ before do
7
+ stub_request(:get, /\/api\/users$/).
8
+ to_return(body: File.read('spec/support/all_users.json'))
9
+ stub_request(:get, /\/api\/opportunity\/milestones$/).
10
+ to_return(body: File.read('spec/support/milestones.json'))
11
+ end
12
+
13
+ it { should validate_presence_of(:label) }
14
+
15
+ describe '._for_party' do
16
+ let(:party) { Fabricate.build(:organization, id: 1) }
17
+
18
+ subject { CapsuleCRM::CustomField._for_party(party.id) }
19
+
20
+ context 'when there are some custom fields' do
21
+ before do
22
+ stub_request(:get, /\/api\/party\/#{party.id}\/customfields$/).
23
+ to_return(body: File.read('spec/support/all_customfields.json'))
24
+ end
25
+
26
+ it { should be_an(Array) }
27
+
28
+ it do
29
+ subject.all? { |item| item.is_a?(CapsuleCRM::CustomField) }.should be_true
30
+ end
31
+ end
32
+
33
+ context 'when there are no custom fields' do
34
+ before do
35
+ stub_request(:get, /\/api\/party\/#{party.id}\/customfields$/).
36
+ to_return(body: File.read('spec/support/no_customfields.json'))
37
+ end
38
+
39
+ it { should be_blank }
40
+ end
41
+ end
42
+
43
+ describe '.create' do
44
+ context 'when it belongs to a party' do
45
+ let(:organization) { Fabricate.build(:organization, id: 1) }
46
+ let(:location) { "https://sample.capsulecrm.com/api/party/#{organization.id}/customfields" }
47
+
48
+ subject do
49
+ CapsuleCRM::CustomField.create(
50
+ id: 100,
51
+ tag: 'The tag',
52
+ label: 'A field',
53
+ text: 'Some text',
54
+ date: Date.today,
55
+ boolean: true,
56
+ party: organization
57
+ )
58
+ end
59
+
60
+ before do
61
+ stub_request(:post, /\/api\/party\/#{organization.id}\/customfields$/).
62
+ to_return(headers: { 'Location' => location})
63
+ end
64
+
65
+ it { subject.id.should eql(100) }
66
+ end
67
+ end
68
+ end
69
+
70
+
71
+
72
+
73
+ # describe '.create' do
74
+ # context 'when it belongs to a party' do
75
+ # let(:person) { Fabricate.build(:person, id: 1) }
76
+
77
+ # subject do
78
+ # CapsuleCRM::History.create(
79
+ # note: Faker::Lorem.paragraph, party: person
80
+ # )
81
+ # end
82
+
83
+ # let(:location) do
84
+ # "https://sample.capsulecrm.com/api/party/#{person.id}/history/101"
85
+ # end
86
+
87
+ # before do
88
+ # stub_request(:post, /\/api\/party\/#{person.id}\/history$/).
89
+ # to_return(headers: { 'Location' => location})
90
+ # end
91
+
92
+ # it { subject.id.should eql(101) }
93
+ # end
94
+
95
+
96
+
97
+ ####
98
+
99
+
100
+ # describe 'find' do
101
+ # before do
102
+ # stub_request(:get, /\/api\/history\/100$/).
103
+ # to_return(body: File.read('spec/support/history.json'))
104
+ # stub_request(:get, /\/api\/users$/).
105
+ # to_return(body: File.read('spec/support/all_users.json'))
106
+ # end
107
+
108
+ # subject { CapsuleCRM::History.find(100) }
109
+
110
+ # it { subject.type.should eql('Note') }
111
+
112
+ # it { subject.creator.should be_a(CapsuleCRM::User) }
113
+
114
+ # it { subject.entry_date.should_not be_blank }
115
+
116
+ # it { subject.subject.should_not be_blank }
117
+
118
+ # it { subject.note.should_not be_blank }
119
+
120
+ # it { subject.attachments.should be_a(Array) }
121
+
122
+ # it { subject.attachments.first.should be_a(CapsuleCRM::Attachment) }
123
+
124
+ # it { subject.attachments.first.filename.should eql('latin.doc') }
125
+
126
+ # it { subject.participants.should be_a(Array) }
127
+
128
+ # it { subject.participants.first.should be_a(CapsuleCRM::Participant) }
129
+
130
+ # it { subject.participants.first.name.should eql('Matt Beedle') }
131
+
132
+ # context 'when it belongs to a party' do
133
+ # before do
134
+ # stub_request(:get, /\/api\/party\/1$/).
135
+ # to_return(body: File.read('spec/support/person.json'))
136
+ # end
137
+
138
+ # it { subject.party_id.should_not be_blank }
139
+
140
+ # it { subject.party.should_not be_blank }
141
+ # end
142
+
143
+ # context 'when it belongs to a case' do
144
+ # before do
145
+ # stub_request(:get, /\/api\/kase\/5$/).
146
+ # to_return(body: File.read('spec/support/case.json'))
147
+ # end
148
+
149
+ # it { subject.case_id.should_not be_blank }
150
+
151
+ # it { subject.kase.should_not be_blank }
152
+ # end
153
+
154
+ # context 'when it belongs to an opportunity' do
155
+ # before do
156
+ # stub_request(:get, /\/api\/opportunity\/2$/).
157
+ # to_return(body: File.read('spec/support/opportunity.json'))
158
+ # end
159
+
160
+ # it { subject.opportunity_id.should_not be_blank }
161
+
162
+ # it { subject.opportunity.should_not be_blank }
163
+ # end
164
+ # end
165
+
166
+ # describe '#creator=' do
167
+ # let(:history) { CapsuleCRM::History.new }
168
+
169
+ # context 'when a String is supplied' do
170
+ # before do
171
+ # stub_request(:get, /\/api\/users$/).
172
+ # to_return(body: File.read('spec/support/all_users.json'))
173
+ # end
174
+
175
+ # context 'when the user exists' do
176
+ # before { history.creator = 'a.user' }
177
+
178
+ # it { history.creator.should be_a(CapsuleCRM::User) }
179
+ # end
180
+
181
+ # context 'when the user does not exist' do
182
+ # before { history.creator = 'asdfadsfdsaf' }
183
+
184
+ # it { history.creator.should be_blank }
185
+ # end
186
+ # end
187
+
188
+ # context 'when a CapsuleCRM::Person is supplied' do
189
+ # let(:user) { CapsuleCRM::User.new }
190
+
191
+ # before { history.creator = user }
192
+
193
+ # it { history.creator.should eql(user) }
194
+ # end
195
+ # end
196
+
197
+ # describe '.create' do
198
+ # context 'when it belongs to a party' do
199
+ # let(:person) { Fabricate.build(:person, id: 1) }
200
+
201
+ # subject do
202
+ # CapsuleCRM::History.create(
203
+ # note: Faker::Lorem.paragraph, party: person
204
+ # )
205
+ # end
206
+
207
+ # let(:location) do
208
+ # "https://sample.capsulecrm.com/api/party/#{person.id}/history/101"
209
+ # end
210
+
211
+ # before do
212
+ # stub_request(:post, /\/api\/party\/#{person.id}\/history$/).
213
+ # to_return(headers: { 'Location' => location})
214
+ # end
215
+
216
+ # it { subject.id.should eql(101) }
217
+ # end
218
+
219
+ # context 'when it belongs to a kase' do
220
+ # let(:kase) { Fabricate.build(:case, id: 2) }
221
+
222
+ # let(:location) do
223
+ # "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10"
224
+ # end
225
+
226
+ # subject do
227
+ # CapsuleCRM::History.create(note: Faker::Lorem.paragraph, kase: kase)
228
+ # end
229
+
230
+ # before do
231
+ # stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
232
+ # to_return(headers: { 'Location' => location })
233
+ # end
234
+
235
+ # it { subject.id.should eql(10) }
236
+ # end
237
+
238
+ # context 'when it belongs to an opportunity' do
239
+ # let(:opportunity) { Fabricate.build(:opportunity, id: 1) }
240
+
241
+ # subject do
242
+ # CapsuleCRM::History.create(
243
+ # note: Faker::Lorem.paragraph, opportunity: opportunity
244
+ # )
245
+ # end
246
+
247
+ # let(:location) do
248
+ # [
249
+ # 'https://sample.capsulecrm.com/api/opportunity/',
250
+ # opportunity.id, '/history/9'
251
+ # ].join
252
+ # end
253
+
254
+ # before do
255
+ # stub_request(:post, /\/api\/opportunity\/#{opportunity.id}\/history$/).
256
+ # to_return(headers: { 'Location' => location })
257
+ # end
258
+
259
+ # it { subject.id.should eql(9) }
260
+ # end
261
+
262
+ # context 'when it is invalid' do
263
+ # subject { CapsuleCRM::History.create }
264
+
265
+ # it { should_not be_valid }
266
+ # end
267
+ # end
268
+
269
+ # describe '.create!' do
270
+ # context 'when it belongs to a party' do
271
+ # let(:person) { Fabricate.build(:person, id: 1) }
272
+
273
+ # subject do
274
+ # CapsuleCRM::History.create!(
275
+ # note: Faker::Lorem.paragraph, party: person
276
+ # )
277
+ # end
278
+
279
+ # let(:location) do
280
+ # "https://sample.capsulecrm.com/api/party/#{person.id}/history/101"
281
+ # end
282
+
283
+ # before do
284
+ # stub_request(:post, /\/api\/party\/#{person.id}\/history$/).
285
+ # to_return(headers: { 'Location' => location})
286
+ # end
287
+
288
+ # it { subject.id.should eql(101) }
289
+ # end
290
+
291
+ # context 'when it belongs to a kase' do
292
+ # let(:kase) { Fabricate.build(:case, id: 2) }
293
+
294
+ # let(:location) do
295
+ # "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10"
296
+ # end
297
+
298
+ # subject do
299
+ # CapsuleCRM::History.create!(note: Faker::Lorem.paragraph, kase: kase)
300
+ # end
301
+
302
+ # before do
303
+ # stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
304
+ # to_return(headers: { 'Location' => location })
305
+ # end
306
+
307
+ # it { subject.id.should eql(10) }
308
+ # end
309
+
310
+ # context 'when it belongs to an opportunity' do
311
+ # let(:opportunity) { Fabricate.build(:opportunity, id: 1) }
312
+
313
+ # subject do
314
+ # CapsuleCRM::History.create!(
315
+ # note: Faker::Lorem.paragraph, opportunity: opportunity
316
+ # )
317
+ # end
318
+
319
+ # let(:location) do
320
+ # [
321
+ # 'https://sample.capsulecrm.com/api/opportunity/',
322
+ # opportunity.id, '/history/9'
323
+ # ].join
324
+ # end
325
+
326
+ # before do
327
+ # stub_request(:post, /\/api\/opportunity\/#{opportunity.id}\/history$/).
328
+ # to_return(headers: { 'Location' => location })
329
+ # end
330
+
331
+ # it { subject.id.should eql(9) }
332
+ # end
333
+
334
+ # context 'when it is invalid' do
335
+ # it do
336
+ # expect { CapsuleCRM::History.create! }.
337
+ # to raise_error(CapsuleCRM::Errors::RecordInvalid)
338
+ # end
339
+ # end
340
+ # end
341
+
342
+ # describe '#update_attributes' do
343
+ # context 'when the history is valid' do
344
+ # subject { Fabricate(:history, id: 2, party: Fabricate.build(:person)) }
345
+
346
+ # before do
347
+ # stub_request(:put, /api\/history\/2$/).to_return(status: 200)
348
+ # subject.update_attributes note: 'changed note text'
349
+ # end
350
+
351
+ # it { subject.note.should eql('changed note text') }
352
+
353
+ # it { should be_persisted }
354
+ # end
355
+
356
+ # context 'when the history is not valid' do
357
+ # subject do
358
+ # CapsuleCRM::History.new(id: 2)
359
+ # end
360
+
361
+ # before { subject.update_attributes subject: Faker::Lorem.sentence }
362
+
363
+ # it { subject.should_not be_valid }
364
+ # end
365
+ # end
366
+
367
+ # describe '#update_attributes!' do
368
+ # context 'when it is valid' do
369
+ # subject { Fabricate(:history, id: 3, party: Fabricate.build(:case)) }
370
+
371
+ # before do
372
+ # stub_request(:put, /api\/history\/3$/).to_return(status: 200)
373
+ # subject.update_attributes! note: 'some new note'
374
+ # end
375
+
376
+ # it { subject.note.should eql('some new note') }
377
+
378
+ # it { should be_persisted }
379
+ # end
380
+
381
+ # context 'when it is not valid' do
382
+ # subject { CapsuleCRM::History.new(id: 3) }
383
+
384
+ # it do
385
+ # expect { subject.update_attributes! subject: 'test' }.
386
+ # to raise_error(CapsuleCRM::Errors::RecordInvalid)
387
+ # end
388
+ # end
389
+ # end
390
+
391
+ # describe '#save' do
392
+ # context 'when it is a new record' do
393
+ # let(:history) { Fabricate.build(:history) }
394
+
395
+ # context 'when it belongs to a party' do
396
+ # let(:party) { Fabricate.build(:organization, id: 2) }
397
+
398
+ # let(:location) do
399
+ # "https://sample.capsulecrm.com/api/party/#{party.id}/history/101"
400
+ # end
401
+
402
+ # before do
403
+ # history.party = party
404
+ # stub_request(:post, /\/api\/party\/#{party.id}\/history$/).
405
+ # to_return(headers: { 'Location' => location })
406
+ # history.save
407
+ # end
408
+
409
+ # it { history.id.should eql(101) }
410
+
411
+ # it { history.should be_persisted }
412
+ # end
413
+
414
+ # context 'when it belongs to a kase' do
415
+ # let(:kase) { Fabricate.build(:case, id: 5) }
416
+
417
+ # let(:location) do
418
+ # "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10005"
419
+ # end
420
+
421
+ # before do
422
+ # history.kase = kase
423
+ # stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
424
+ # to_return(headers: { 'Location' => location })
425
+ # history.save
426
+ # end
427
+
428
+ # it { history.id.should eql(10005) }
429
+
430
+ # it { history.should be_persisted }
431
+ # end
432
+
433
+ # context 'when it belongs to an opportunity' do
434
+ # let(:opportunity) { Fabricate.build(:opportunity, id: 3) }
435
+
436
+ # let(:location) do
437
+ # [
438
+ # 'https://sample.capsulecrm.com/api/opportunity/',
439
+ # opportunity.id, '/history/101'
440
+ # ].join
441
+ # end
442
+
443
+ # before do
444
+ # history.opportunity = opportunity
445
+ # stub_request(
446
+ # :post, /\/api\/opportunity\/#{opportunity.id}\/history$/
447
+ # ).to_return(headers: { 'Location' => location })
448
+ # history.save
449
+ # end
450
+
451
+ # it { history.id.should eql(101) }
452
+
453
+ # it { history.should be_persisted }
454
+ # end
455
+ # end
456
+
457
+ # context 'when it is an existing record' do
458
+ # let(:history) do
459
+ # Fabricate.build(:history, party: Fabricate.build(:person), id: 10)
460
+ # end
461
+
462
+ # before do
463
+ # stub_request(:put, /\/api\/history\/#{history.id}$/).
464
+ # to_return(status: 200)
465
+ # history.save
466
+ # end
467
+
468
+ # it { history.should be_persisted }
469
+ # end
470
+ # end
471
+
472
+ # describe '#save!' do
473
+ # context 'when it is a new record' do
474
+ # context 'when it is invalid' do
475
+ # let(:history) { CapsuleCRM::History.new(id: 5) }
476
+
477
+ # it 'should raise an error' do
478
+ # expect { history.save! }.
479
+ # to raise_error(CapsuleCRM::Errors::RecordInvalid)
480
+ # end
481
+ # end
482
+
483
+ # let(:history) { Fabricate.build(:history) }
484
+
485
+ # context 'when it belongs to a party' do
486
+ # let(:party) { Fabricate.build(:organization, id: 2) }
487
+
488
+ # let(:location) do
489
+ # "https://sample.capsulecrm.com/api/party/#{party.id}/history/101"
490
+ # end
491
+
492
+ # before do
493
+ # history.party = party
494
+ # stub_request(:post, /\/api\/party\/#{party.id}\/history$/).
495
+ # to_return(headers: { 'Location' => location })
496
+ # history.save!
497
+ # end
498
+
499
+ # it { history.id.should eql(101) }
500
+
501
+ # it { history.should be_persisted }
502
+ # end
503
+
504
+ # context 'when it belongs to a kase' do
505
+ # let(:kase) { Fabricate.build(:case, id: 5) }
506
+
507
+ # let(:location) do
508
+ # "https://sample.capsulecrm.com/api/kase/#{kase.id}/history/10005"
509
+ # end
510
+
511
+ # before do
512
+ # history.kase = kase
513
+ # stub_request(:post, /\/api\/kase\/#{kase.id}\/history$/).
514
+ # to_return(headers: { 'Location' => location })
515
+ # history.save!
516
+ # end
517
+
518
+ # it { history.id.should eql(10005) }
519
+
520
+ # it { history.should be_persisted }
521
+ # end
522
+
523
+ # context 'when it belongs to an opportunity' do
524
+ # let(:opportunity) { Fabricate.build(:opportunity, id: 3) }
525
+
526
+ # let(:location) do
527
+ # [
528
+ # 'https://sample.capsulecrm.com/api/opportunity/',
529
+ # opportunity.id, '/history/101'
530
+ # ].join
531
+ # end
532
+
533
+ # before do
534
+ # history.opportunity = opportunity
535
+ # stub_request(
536
+ # :post, /\/api\/opportunity\/#{opportunity.id}\/history$/
537
+ # ).to_return(headers: { 'Location' => location })
538
+ # history.save!
539
+ # end
540
+
541
+ # it { history.id.should eql(101) }
542
+
543
+ # it { history.should be_persisted }
544
+ # end
545
+ # end
546
+
547
+ # context 'when it is an existing record' do
548
+ # context 'when it is valid' do
549
+ # let(:history) do
550
+ # Fabricate.build(:history, party: Fabricate.build(:person), id: 10)
551
+ # end
552
+
553
+ # before do
554
+ # stub_request(:put, /\/api\/history\/#{history.id}$/).
555
+ # to_return(status: 200)
556
+ # history.save!
557
+ # end
558
+
559
+ # it { history.should be_persisted }
560
+ # end
561
+
562
+ # context 'when it is not valid' do
563
+ # let(:history) { CapsuleCRM::History.new(id: 1) }
564
+
565
+ # it 'should raise an error' do
566
+ # expect { history.save! }.
567
+ # to raise_error(CapsuleCRM::Errors::RecordInvalid)
568
+ # end
569
+ # end
570
+ # end
571
+ # end
572
+
573
+ # describe '#destroy' do
574
+ # let(:history) { Fabricate.build(:history, id: 19) }
575
+
576
+ # before do
577
+ # stub_request(:delete, /\/api\/history\/#{history.id}$/).
578
+ # to_return(status: 200)
579
+ # history.destroy
580
+ # end
581
+
582
+ # subject { history }
583
+
584
+ # it { should_not be_persisted }
585
+ # end
586
+
587
+ # describe '#new_record?' do
588
+ # context 'when the history item is a new record' do
589
+ # let(:history) { CapsuleCRM::History.new }
590
+
591
+ # subject { history.new_record? }
592
+
593
+ # it { should be_true }
594
+ # end
595
+
596
+ # context 'when the history item is not a new record' do
597
+ # let(:history) { CapsuleCRM::History.new(id: 1) }
598
+
599
+ # subject { history.new_record? }
600
+
601
+ # it { should be_false }
602
+ # end
603
+ # end
604
+
605
+ # describe '#persisted?' do
606
+ # context 'when the history item is persisted' do
607
+ # let(:history) { CapsuleCRM::History.new(id: 1) }
608
+
609
+ # subject { history.persisted? }
610
+
611
+ # it { should be_true }
612
+ # end
613
+
614
+ # context 'when the hitory item is not persisted' do
615
+ # let(:history) { CapsuleCRM::History.new }
616
+
617
+ # subject { history.persisted? }
618
+
619
+ # it { should be_false }
620
+ # end
621
+ # end
622
+
623
+ # describe '#to_capsule_json' do
624
+ # let(:creator) { CapsuleCRM::User.new(username: Faker::Name.name) }
625
+
626
+ # let(:history) do
627
+ # CapsuleCRM::History.new(
628
+ # type: 'Note', entry_date: Time.now, creator: creator,
629
+ # subject: Faker::Lorem.sentence, note: Faker::Lorem.paragraph,
630
+ # participants: [participant]
631
+ # )
632
+ # end
633
+
634
+ # let(:participant) do
635
+ # CapsuleCRM::Participant.new(
636
+ # name: Faker::Name.name, email_address: Faker::Internet.email,
637
+ # role: 'TO'
638
+ # )
639
+ # end
640
+
641
+ # subject { history.to_capsule_json }
642
+
643
+ # let(:participants_json) { subject[:historyItem]['participants'] }
644
+
645
+ # it { subject.keys.first.should eql(:historyItem) }
646
+
647
+ # it { subject[:historyItem]['entryDate'].should eql(history.entry_date) }
648
+
649
+ # it { subject[:historyItem]['creator'].should eql(creator.username) }
650
+
651
+ # it { subject[:historyItem]['note'].should eql(history.note) }
652
+
653
+ # it { subject[:historyItem].should have_key('note') }
654
+ # end
655
+ # end
@@ -91,4 +91,18 @@ describe CapsuleCRM::Organization do
91
91
 
92
92
  it { email_json.should have_key('emailAddress') }
93
93
  end
94
+
95
+ describe '#destroy' do
96
+ let(:organization) { CapsuleCRM::Organization.new(id: 1) }
97
+
98
+ before do
99
+ stub_request(:delete, /\/api\/party\/#{organization.id}/).
100
+ to_return(status: 200)
101
+ organization.destroy
102
+ end
103
+
104
+ it { expect(organization.id).to be_blank }
105
+
106
+ it { expect(organization).to_not be_persisted }
107
+ end
94
108
  end
@@ -32,7 +32,13 @@ describe CapsuleCRM::Person do
32
32
  end
33
33
 
34
34
  context 'when there is 1 person for the organization' do
35
- pending
35
+ before do
36
+ stub_request(:get, /\/api\/party\/1\/people$/).
37
+ to_return(body: File.read('spec/support/single_user.json'))
38
+ end
39
+ subject { CapsuleCRM::Person._for_organization(1) }
40
+
41
+ it { should be_a(Array) }
36
42
  end
37
43
 
38
44
  context 'when there are no people for the organization' do
@@ -7,6 +7,9 @@ class TaggableItem
7
7
  attribute :id
8
8
  end
9
9
 
10
+ class SubclassedTaggableItem < TaggableItem
11
+ end
12
+
10
13
  describe CapsuleCRM::Taggable do
11
14
  before { configure }
12
15
 
@@ -39,7 +42,7 @@ describe CapsuleCRM::Taggable do
39
42
 
40
43
  before do
41
44
  loc = 'https://sample.capsulecrm.com/api/party/1000/tag/A%20Test%20Tag'
42
- stub_request(:post, /\/api\/taggableitem\/1\/A%20Test%20Tag$/).
45
+ stub_request(:post, /\/api\/taggableitem\/1\/tag\/A%20Test%20Tag$/).
43
46
  to_return(headers: { 'Location' => loc })
44
47
  end
45
48
 
@@ -66,7 +69,7 @@ describe CapsuleCRM::Taggable do
66
69
 
67
70
  before do
68
71
  loc = 'https://sample.capsulecrm.com/api/party/1000/tag/A%20Test%20Tag'
69
- stub_request(:delete, /\/api\/taggableitem\/1\/A%20Test%20Tag$/).
72
+ stub_request(:delete, /\/api\/taggableitem\/1\/tag\/A%20Test%20Tag$/).
70
73
  to_return(headers: { 'Location' => loc })
71
74
  end
72
75
 
@@ -81,4 +84,14 @@ describe CapsuleCRM::Taggable do
81
84
  it { subject.should be_nil }
82
85
  end
83
86
  end
87
+
88
+ describe '#api_singular_name' do
89
+ it 'turns the class name into appropriate api name' do
90
+ TaggableItem.new.api_singular_name.should == 'taggableitem'
91
+ end
92
+
93
+ it 'gives the superclass unless Object to work with Organization/Person subclassing of Party' do
94
+ SubclassedTaggableItem.new.api_singular_name.should == 'taggableitem'
95
+ end
96
+ end
84
97
  end
@@ -0,0 +1,23 @@
1
+ {
2
+ "customFields": {
3
+ "customField": [
4
+ {
5
+ "id": "1",
6
+ "tag": "Staff",
7
+ "label": "NI Number",
8
+ "text": "12345678"
9
+ },
10
+ {
11
+ "id": "1",
12
+ "tag": "Staff",
13
+ "label": "Start Date",
14
+ "date": "2011-03-13T00:00:00Z"
15
+ },
16
+ {
17
+ "id": "1",
18
+ "label": "Send newsletter",
19
+ "boolean": "true"
20
+ }
21
+ ]
22
+ }
23
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "customFields": {
3
+ "@size": "0"
4
+ }
5
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "parties":
3
+ {
4
+ "@size":"1",
5
+ "person":
6
+ {
7
+ "id":"100",
8
+ "contacts":
9
+ {
10
+ "email":
11
+ {
12
+ "id":"25101754",
13
+ "emailAddress":"aa@aa.com"
14
+ }
15
+ },
16
+ "pictureURL": "",
17
+ "createdOn":"2011-08-10T01:58:49Z",
18
+ "updatedOn":"2011-08-10T03:20:43Z",
19
+ "firstName":"aaa",
20
+ "lastName":"bbb",
21
+ "organisationId":"1",
22
+ "organisationName":"test"
23
+ }
24
+ }
25
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capsule_crm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Beedle
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-10 00:00:00.000000000 Z
11
+ date: 2013-08-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -244,6 +244,7 @@ files:
244
244
  - .gitignore
245
245
  - .rspec
246
246
  - .travis.yml
247
+ - CHANGELOG.md
247
248
  - Gemfile
248
249
  - Guardfile
249
250
  - LICENSE.txt
@@ -260,6 +261,7 @@ files:
260
261
  - lib/capsule_crm/attachment.rb
261
262
  - lib/capsule_crm/capsule_jsonable.rb
262
263
  - lib/capsule_crm/case.rb
264
+ - lib/capsule_crm/collection.rb
263
265
  - lib/capsule_crm/configuration.rb
264
266
  - lib/capsule_crm/connection.rb
265
267
  - lib/capsule_crm/contactable.rb
@@ -298,6 +300,7 @@ files:
298
300
  - spec/lib/capsule_crm/contacts_spec.rb
299
301
  - spec/lib/capsule_crm/country_spec.rb
300
302
  - spec/lib/capsule_crm/currency_spec.rb
303
+ - spec/lib/capsule_crm/custom_field_spec.rb
301
304
  - spec/lib/capsule_crm/email_spec.rb
302
305
  - spec/lib/capsule_crm/history_spec.rb
303
306
  - spec/lib/capsule_crm/milestone_spec.rb
@@ -311,6 +314,7 @@ files:
311
314
  - spec/lib/capsule_crm/user_spec.rb
312
315
  - spec/spec_helper.rb
313
316
  - spec/support/all_cases.json
317
+ - spec/support/all_customfields.json
314
318
  - spec/support/all_history.json
315
319
  - spec/support/all_opportunities.json
316
320
  - spec/support/all_parties.json
@@ -325,11 +329,13 @@ files:
325
329
  - spec/support/helpers.rb
326
330
  - spec/support/history.json
327
331
  - spec/support/milestones.json
332
+ - spec/support/no_customfields.json
328
333
  - spec/support/no_history.json
329
334
  - spec/support/opportunity.json
330
335
  - spec/support/organisation.json
331
336
  - spec/support/person.json
332
337
  - spec/support/shared_examples/contactable.rb
338
+ - spec/support/single_user.json
333
339
  - spec/support/task.json
334
340
  - spec/support/task_categories.json
335
341
  homepage: ''
@@ -370,6 +376,7 @@ test_files:
370
376
  - spec/lib/capsule_crm/contacts_spec.rb
371
377
  - spec/lib/capsule_crm/country_spec.rb
372
378
  - spec/lib/capsule_crm/currency_spec.rb
379
+ - spec/lib/capsule_crm/custom_field_spec.rb
373
380
  - spec/lib/capsule_crm/email_spec.rb
374
381
  - spec/lib/capsule_crm/history_spec.rb
375
382
  - spec/lib/capsule_crm/milestone_spec.rb
@@ -383,6 +390,7 @@ test_files:
383
390
  - spec/lib/capsule_crm/user_spec.rb
384
391
  - spec/spec_helper.rb
385
392
  - spec/support/all_cases.json
393
+ - spec/support/all_customfields.json
386
394
  - spec/support/all_history.json
387
395
  - spec/support/all_opportunities.json
388
396
  - spec/support/all_parties.json
@@ -397,10 +405,12 @@ test_files:
397
405
  - spec/support/helpers.rb
398
406
  - spec/support/history.json
399
407
  - spec/support/milestones.json
408
+ - spec/support/no_customfields.json
400
409
  - spec/support/no_history.json
401
410
  - spec/support/opportunity.json
402
411
  - spec/support/organisation.json
403
412
  - spec/support/person.json
404
413
  - spec/support/shared_examples/contactable.rb
414
+ - spec/support/single_user.json
405
415
  - spec/support/task.json
406
416
  - spec/support/task_categories.json