capsule_crm 0.4.6 → 0.5.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48c3f7884a088c4d42cee4aa450fc594c3f9fa96
4
- data.tar.gz: 35822071aafa5ea3b7def6616e3e30003fb150ea
3
+ metadata.gz: ddd7d3301e019fef3e849184c72984525d7fba2b
4
+ data.tar.gz: c7d33116a1689a4bc34ec6855e6bc3818ae0c588
5
5
  SHA512:
6
- metadata.gz: 968f3d57a5f7228200488c74021a8c27d05269213094797fdd8124cb843f149cdfc9d1d1b9ffd2a3996fa44cc54b691f9f238bb8b84bf7fbc0a11d4e38376a3f
7
- data.tar.gz: 782f7e740f951e5c7ca5114a1ea6f481b5638657f64c39f8210ff6da890a6342d03dedec30df05120d05f8d0c92d36ee0312289f619fa6749e90daec7ef42fee
6
+ metadata.gz: 92966063166982596f7927c7fbbe3a3d9d12e135914493453e817bb500ca55e41c6fc5dbe693e8cb26d2b496eb16c7b779a6869200f45a0ece520211d2999a52
7
+ data.tar.gz: 8b64c89681e60317a997c961c30e2e28db74b64244be466db1c902445ee160ad4ad8e295c58526fe772b87c9c35749b59e457866e6cd28b79b9d903f69bcf9ac
data/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  [![Build
2
2
  Status](https://travis-ci.org/mattbeedle/capsule_crm.png)](https://travis-ci.org/mattbeedle/capsule_crm)
3
3
 
4
+ [![Code
5
+ Climate](https://codeclimate.com/github/mattbeedle/capsule_crm.png)](https://codeclimate.com/github/mattbeedle/capsule_crm)
6
+
4
7
  [![Gem
5
8
  Version](https://badge.fury.io/rb/capsule_crm.png)](http://badge.fury.io/rb/capsule_crm)
6
9
 
@@ -18,15 +18,7 @@ module CapsuleCRM
18
18
  response = faraday.post(path, params.to_json) do |request|
19
19
  request.headers.update default_request_headers
20
20
  end
21
- if response.success?
22
- if match = response.headers['Location'].match(/\/(?<id>\d+)$/)
23
- { id: match[:id] }
24
- else
25
- true
26
- end
27
- else
28
- false
29
- end
21
+ process_post_response(response)
30
22
  end
31
23
 
32
24
  def self.put(path, params)
@@ -43,6 +35,20 @@ module CapsuleCRM
43
35
 
44
36
  private
45
37
 
38
+ # TODO clean this shit up
39
+ def self.process_post_response(response)
40
+ if response.success?
41
+ if response.headers['Location'] &&
42
+ match = response.headers['Location'].match(/\/(?<id>\d+)$/)
43
+ { id: match[:id] }
44
+ else
45
+ true
46
+ end
47
+ else
48
+ false
49
+ end
50
+ end
51
+
46
52
  def self.default_request_headers
47
53
  { accept: 'application/json', content_type: 'application/json' }
48
54
  end
@@ -233,7 +233,7 @@ module CapsuleCRM
233
233
  end
234
234
 
235
235
  def update_record
236
- CapsuleCRM::Connection.put("/api/person/#{id}", attributes)
236
+ CapsuleCRM::Connection.put("/api/person/#{id}", to_capsule_json)
237
237
  self
238
238
  end
239
239
 
@@ -0,0 +1,142 @@
1
+ module CapsuleCRM
2
+ class Task
3
+ include Virtus
4
+
5
+ extend ActiveModel::Naming
6
+ include ActiveModel::Conversion
7
+ include ActiveModel::Validations
8
+
9
+ include CapsuleCRM::Associations::BelongsTo
10
+
11
+ attribute :id, Integer
12
+ attribute :due_date, Date
13
+ attribute :due_date_time, DateTime
14
+ attribute :category, String
15
+ attribute :description, String
16
+ attribute :detail, String
17
+
18
+ belongs_to :party, class_name: 'CapsuleCRM::Party'
19
+ belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity'
20
+ belongs_to :case, class_name: 'CapsuleCRM::Case'
21
+ belongs_to :owner, class_name: 'CapsuleCRM::User'
22
+
23
+ validates :description, presence: true
24
+ validates :due_date, presence: { unless: :due_date_time }
25
+ validates :due_date_time, presence: { unless: :due_date }
26
+
27
+ def attributes=(attributes)
28
+ CapsuleCRM::HashHelper.underscore_keys!(attributes)
29
+ super(attributes)
30
+ end
31
+
32
+ def owner=(user)
33
+ user = CapsuleCRM::User.find_by_username(user) if user.is_a?(String)
34
+ @owner = user
35
+ self
36
+ end
37
+
38
+ def self.all(options = {})
39
+ init_collection(
40
+ CapsuleCRM::Connection.get('/api/tasks', options)['tasks']['task']
41
+ )
42
+ end
43
+
44
+ def self.find(id)
45
+ new CapsuleCRM::Connection.get("/api/task/#{id}")['task']
46
+ end
47
+
48
+ def self.create(attributes = {})
49
+ new(attributes).tap(&:save)
50
+ end
51
+
52
+ def self.create!(attributes = {})
53
+ new(attributes).tap(&:save!)
54
+ end
55
+
56
+ def update_attributes(attributes = {})
57
+ self.attributes = attributes
58
+ save
59
+ end
60
+
61
+ def update_attributes!(attributes = {})
62
+ self.attributes = attributes
63
+ save!
64
+ end
65
+
66
+ def save
67
+ if valid?
68
+ new_record? ? create_record : update_record
69
+ else
70
+ false
71
+ end
72
+ end
73
+
74
+ def save!
75
+ if valid?
76
+ save
77
+ else
78
+ raise CapsuleCRM::Errors::RecordInvalid.new(self)
79
+ end
80
+ end
81
+
82
+ def destroy
83
+ self.id = nil if CapsuleCRM::Connection.delete("/api/task/#{id}")
84
+ self
85
+ end
86
+
87
+ def complete
88
+ CapsuleCRM::Connection.post("/api/task/#{id}/complete")
89
+ self
90
+ end
91
+
92
+ def reopen
93
+ CapsuleCRM::Connection.post("/api/task/#{id}/reopen")
94
+ self
95
+ end
96
+
97
+ def self.categories
98
+ CapsuleCRM::Connection.
99
+ get('/api/task/categories')['taskCategories']['taskCategory']
100
+ end
101
+
102
+ def new_record?
103
+ !id
104
+ end
105
+
106
+ def persisted?
107
+ !new_record?
108
+ end
109
+
110
+ def to_capsule_json
111
+ {
112
+ task: CapsuleCRM::HashHelper.camelize_keys(capsule_attributes)
113
+ }.stringify_keys
114
+ end
115
+
116
+ private
117
+
118
+ def capsule_attributes
119
+ { description: description, category: category }.tap do |attrs|
120
+ attrs.merge!(owner: owner.username) if owner
121
+ attrs.merge!(due_date: due_date.to_s(:db)) if due_date
122
+ attrs.merge!(due_date_time: due_date_time.to_s(:db)) if due_date_time
123
+ end
124
+ end
125
+
126
+ def self.init_collection(collection)
127
+ CapsuleCRM::ResultsProxy.new(collection.map { |item| new item })
128
+ end
129
+
130
+ def create_record
131
+ self.attributes = CapsuleCRM::Connection.post(
132
+ '/api/task', to_capsule_json
133
+ )
134
+ self
135
+ end
136
+
137
+ def update_record
138
+ CapsuleCRM::Connection.put("/api/task/#{id}", to_capsule_json)
139
+ self
140
+ end
141
+ end
142
+ end
@@ -1,3 +1,3 @@
1
1
  module CapsuleCrm
2
- VERSION = '0.4.6'
2
+ VERSION = '0.5.6'
3
3
  end
data/lib/capsule_crm.rb CHANGED
@@ -17,6 +17,7 @@ require 'capsule_crm/history'
17
17
  require 'capsule_crm/party'
18
18
  require 'capsule_crm/phone'
19
19
  require 'capsule_crm/tag'
20
+ require 'capsule_crm/task'
20
21
  require 'capsule_crm/user'
21
22
  require 'capsule_crm/website'
22
23
  require 'capsule_crm/hash_helper'
@@ -0,0 +1,4 @@
1
+ Fabricator(:task, class_name: :'CapsuleCRM::Task') do
2
+ description { Faker::Lorem.paragraph }
3
+ due_date { Date.tomorrow }
4
+ end
@@ -0,0 +1,289 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::Task do
4
+ before do
5
+ configure
6
+ stub_request(:get, /\/api\/users$/).
7
+ to_return(body: File.read('spec/support/all_users.json'))
8
+ stub_request(:get, /\/api\/party\/1$/).
9
+ to_return(body: File.read('spec/support/person.json'))
10
+ end
11
+
12
+ it { should validate_presence_of(:description) }
13
+
14
+ it { should validate_presence_of(:due_date) }
15
+
16
+ it { should validate_presence_of(:due_date_time) }
17
+
18
+ describe '.find' do
19
+ before do
20
+ stub_request(:get, /\/api\/task\/2$/).
21
+ to_return(body: File.read('spec/support/task.json'))
22
+ end
23
+
24
+ subject { CapsuleCRM::Task.find(2) }
25
+
26
+ it { should be_a(CapsuleCRM::Task) }
27
+
28
+ it { subject.due_date.should_not be_blank }
29
+
30
+ it { subject.category.should eql('Meeting') }
31
+
32
+ it { subject.description.should eql('Meet with customer') }
33
+
34
+ it { subject.detail.should eql('Meeting at Coffee shop') }
35
+
36
+ it { subject.owner.should be_a(CapsuleCRM::User) }
37
+
38
+ it { subject.party.should be_a(CapsuleCRM::Person) }
39
+ end
40
+
41
+ describe '.all' do
42
+ before do
43
+ stub_request(:get, /\/api\/tasks$/).
44
+ to_return(body: File.read('spec/support/all_tasks.json'))
45
+ end
46
+
47
+ subject { CapsuleCRM::Task.all }
48
+
49
+ it { should be_a(Array) }
50
+
51
+ it do
52
+ subject.all? { |item| item.is_a?(CapsuleCRM::Task) }.should be_true
53
+ end
54
+
55
+ it { subject.length.should eql(1) }
56
+
57
+ it { subject.first.description.should eql('Meet with customer') }
58
+ end
59
+
60
+ describe '.create' do
61
+ context 'when it is valid' do
62
+ before do
63
+ location = 'https://sample.capsulecrm.com/api/task/59'
64
+ stub_request(:post, /\/api\/task$/).
65
+ to_return(headers: { 'Location' => location })
66
+ end
67
+
68
+ subject { CapsuleCRM::Task.create Fabricate.attributes_for(:task) }
69
+
70
+ it { should be_a(CapsuleCRM::Task) }
71
+
72
+ it { should be_persisted }
73
+ end
74
+
75
+ context 'when it is not valid' do
76
+ subject { CapsuleCRM::Task.create }
77
+
78
+ it { should_not be_persisted }
79
+ end
80
+ end
81
+
82
+ describe '.create!' do
83
+ context 'when it is valid' do
84
+ before do
85
+ location = 'https://sample.capsulecrm.com/api/task/59'
86
+ stub_request(:post, /\/api\/task$/).
87
+ to_return(headers: { 'Location' => location })
88
+ end
89
+
90
+ subject { CapsuleCRM::Task.create! Fabricate.attributes_for(:task) }
91
+
92
+ it { should be_a(CapsuleCRM::Task) }
93
+
94
+ it { should be_persisted }
95
+ end
96
+
97
+ context 'when it is not valid' do
98
+ subject { CapsuleCRM::Task.create! }
99
+
100
+ it do
101
+ expect { subject }.to raise_error(CapsuleCRM::Errors::RecordInvalid)
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#save' do
107
+ let(:task) { Fabricate.build(:task) }
108
+
109
+ context 'when it is a new record' do
110
+ before do
111
+ location = 'https://sample.capsulecrm.com/api/task/59'
112
+ stub_request(:post, /\/api\/task$/).
113
+ to_return(headers: { 'Location' => location })
114
+ end
115
+
116
+ subject { task.save }
117
+
118
+ it { subject.id.should eql(59) }
119
+
120
+ it { should be_persisted }
121
+ end
122
+
123
+ context 'when it is an existing record' do
124
+ before do
125
+ task.id = 12
126
+ stub_request(:put, /\/api\/task\/12$/).to_return(status: 200)
127
+ end
128
+
129
+ subject { task.save }
130
+
131
+ it { should be_persisted }
132
+ end
133
+
134
+ context 'when it is invalid' do
135
+ it { subject.save.should be_false }
136
+ end
137
+ end
138
+
139
+ describe '#save!' do
140
+ let(:task) { Fabricate.build(:task) }
141
+
142
+ context 'when it is a new record' do
143
+ before do
144
+ location = 'https://sample.capsulecrm.com/api/task/59'
145
+ stub_request(:post, /\/api\/task$/).
146
+ to_return(headers: { 'Location' => location })
147
+ end
148
+
149
+ subject { task.save! }
150
+
151
+ it { subject.id.should eql(59) }
152
+
153
+ it { should be_persisted }
154
+ end
155
+
156
+ context 'when it is an existing record' do
157
+ before do
158
+ task.id = 12
159
+ stub_request(:put, /\/api\/task\/12$/).to_return(status: 200)
160
+ end
161
+
162
+ subject { task.save! }
163
+
164
+ it { should be_persisted }
165
+ end
166
+
167
+ context 'when it is invalid' do
168
+ it do
169
+ expect { subject.save! }.
170
+ to raise_error(CapsuleCRM::Errors::RecordInvalid)
171
+ end
172
+ end
173
+ end
174
+
175
+ describe '#update_attributes' do
176
+ context 'when it is valid' do
177
+ let(:task) { Fabricate.build(:task, id: 1) }
178
+
179
+ subject { task.update_attributes description: Faker::Lorem.sentence }
180
+
181
+ before { stub_request(:put, /\/api\/task\/1$/).to_return(status: 200) }
182
+
183
+ it { should be_persisted }
184
+ end
185
+
186
+ context 'when it is not valid' do
187
+ let(:task) { CapsuleCRM::Task.new(id: 1) }
188
+
189
+ subject { task.update_attributes }
190
+
191
+ it { should be_false }
192
+ end
193
+ end
194
+
195
+ describe '#update_attributes!' do
196
+ context 'when it is valid' do
197
+ let(:task) { Fabricate.build(:task, id: 1) }
198
+
199
+ subject { task.update_attributes! description: Faker::Lorem.sentence }
200
+
201
+ before { stub_request(:put, /\/api\/task\/1$/).to_return(status: 200) }
202
+
203
+ it { should be_persisted }
204
+ end
205
+
206
+ context 'when it is not valid' do
207
+ let(:task) { CapsuleCRM::Task.new(id: 1) }
208
+
209
+ subject { task.update_attributes! }
210
+
211
+ it do
212
+ expect { subject }.to raise_error(CapsuleCRM::Errors::RecordInvalid)
213
+ end
214
+ end
215
+ end
216
+
217
+ describe '#destroy' do
218
+ subject { Fabricate.build(:task, id: 1) }
219
+
220
+ before do
221
+ stub_request(:delete, /\/api\/task\/1$/).to_return(status: 200)
222
+ subject.destroy
223
+ end
224
+
225
+ it { should_not be_persisted }
226
+ end
227
+
228
+ # Not really sure what to test here. CapsuleCRM API doesn't actually tell you
229
+ # anything about a tasks state
230
+ describe '#complete' do
231
+ let(:task) { Fabricate.build(:task, id: 2) }
232
+
233
+ subject { task.complete }
234
+
235
+ before do
236
+ stub_request(:post, /\/api\/task\/#{task.id}\/complete$/).
237
+ to_return(status: 200)
238
+ task.complete
239
+ end
240
+
241
+ it { should be_persisted }
242
+ end
243
+
244
+ describe '#reopen' do
245
+ let(:task) { Fabricate.build(:task, id: 3) }
246
+
247
+ subject { task.reopen }
248
+
249
+ before do
250
+ stub_request(:post, /\/api\/task\/#{task.id}\/reopen$/).
251
+ to_return(status: 200)
252
+ end
253
+
254
+ it { should be_persisted }
255
+ end
256
+
257
+ describe '.categories' do
258
+ subject { CapsuleCRM::Task.categories }
259
+
260
+ before do
261
+ stub_request(:get, /\/api\/task\/categories$/).
262
+ to_return(body: File.read('spec/support/task_categories.json'))
263
+ end
264
+
265
+ it do
266
+ expect(subject).to eql(%w(Call Email Follow-up Meeting Milestone Send))
267
+ end
268
+ end
269
+
270
+ describe '#to_capsule_json' do
271
+ let(:task) { Fabricate.build(:task) }
272
+
273
+ subject { task.to_capsule_json }
274
+
275
+ it { expect(subject.keys).to include('task') }
276
+
277
+ it { expect(subject['task']['description']).to eql(task.description) }
278
+
279
+ it { expect(subject['task']['dueDate']).to eql(task.due_date.to_s) }
280
+
281
+ context 'when it has an owner' do
282
+ let(:owner) { CapsuleCRM::User.new(username: 'matt.beedle') }
283
+
284
+ before { task.owner = owner }
285
+
286
+ it { expect(subject['task']['owner']).to eql(task.owner.username) }
287
+ end
288
+ end
289
+ end
@@ -0,0 +1,16 @@
1
+ {
2
+ "tasks": {
3
+ "task": [
4
+ {
5
+ "id": "100",
6
+ "dueDate": "2012-02-24T00:00:00Z",
7
+ "category": "Meeting",
8
+ "partyName": "Eric Jones",
9
+ "description": "Meet with customer",
10
+ "owner": "a.user",
11
+ "detail": "Meeting at Coffee shop",
12
+ "partyId": "1"
13
+ }
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "task": {
3
+ "id": "100",
4
+ "dueDate": "2012-02-24T00:00:00Z",
5
+ "category": "Meeting",
6
+ "partyName": "Eric Jones",
7
+ "description": "Meet with customer",
8
+ "owner": "a.user",
9
+ "detail": "Meeting at Coffee shop",
10
+ "partyId": "1"
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "taskCategories": {
3
+ "taskCategory": [
4
+ "Call",
5
+ "Email",
6
+ "Follow-up",
7
+ "Meeting",
8
+ "Milestone",
9
+ "Send"
10
+ ]
11
+ }
12
+ }
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.4.6
4
+ version: 0.5.6
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-05-21 00:00:00.000000000 Z
11
+ date: 2013-05-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -266,6 +266,7 @@ files:
266
266
  - lib/capsule_crm/results_proxy.rb
267
267
  - lib/capsule_crm/tag.rb
268
268
  - lib/capsule_crm/taggable.rb
269
+ - lib/capsule_crm/task.rb
269
270
  - lib/capsule_crm/user.rb
270
271
  - lib/capsule_crm/version.rb
271
272
  - lib/capsule_crm/website.rb
@@ -274,6 +275,7 @@ files:
274
275
  - spec/fabricators/opportunity_fabricator.rb
275
276
  - spec/fabricators/organization_fabricator.rb
276
277
  - spec/fabricators/person_fabricator.rb
278
+ - spec/fabricators/task_fabricator.rb
277
279
  - spec/lib/capsule_crm/address_spec.rb
278
280
  - spec/lib/capsule_crm/associations/has_many_proxy_spec.rb
279
281
  - spec/lib/capsule_crm/associations/has_many_spec.rb
@@ -288,6 +290,7 @@ files:
288
290
  - spec/lib/capsule_crm/person_spec.rb
289
291
  - spec/lib/capsule_crm/tag_spec.rb
290
292
  - spec/lib/capsule_crm/taggable_spec.rb
293
+ - spec/lib/capsule_crm/task_spec.rb
291
294
  - spec/lib/capsule_crm/user_spec.rb
292
295
  - spec/spec_helper.rb
293
296
  - spec/support/all_cases.json
@@ -296,6 +299,7 @@ files:
296
299
  - spec/support/all_parties.json
297
300
  - spec/support/all_people.json
298
301
  - spec/support/all_tags.json
302
+ - spec/support/all_tasks.json
299
303
  - spec/support/all_users.json
300
304
  - spec/support/case.json
301
305
  - spec/support/countries.json
@@ -306,6 +310,8 @@ files:
306
310
  - spec/support/opportunity.json
307
311
  - spec/support/organisation.json
308
312
  - spec/support/person.json
313
+ - spec/support/task.json
314
+ - spec/support/task_categories.json
309
315
  homepage: ''
310
316
  licenses: []
311
317
  metadata: {}
@@ -336,6 +342,7 @@ test_files:
336
342
  - spec/fabricators/opportunity_fabricator.rb
337
343
  - spec/fabricators/organization_fabricator.rb
338
344
  - spec/fabricators/person_fabricator.rb
345
+ - spec/fabricators/task_fabricator.rb
339
346
  - spec/lib/capsule_crm/address_spec.rb
340
347
  - spec/lib/capsule_crm/associations/has_many_proxy_spec.rb
341
348
  - spec/lib/capsule_crm/associations/has_many_spec.rb
@@ -350,6 +357,7 @@ test_files:
350
357
  - spec/lib/capsule_crm/person_spec.rb
351
358
  - spec/lib/capsule_crm/tag_spec.rb
352
359
  - spec/lib/capsule_crm/taggable_spec.rb
360
+ - spec/lib/capsule_crm/task_spec.rb
353
361
  - spec/lib/capsule_crm/user_spec.rb
354
362
  - spec/spec_helper.rb
355
363
  - spec/support/all_cases.json
@@ -358,6 +366,7 @@ test_files:
358
366
  - spec/support/all_parties.json
359
367
  - spec/support/all_people.json
360
368
  - spec/support/all_tags.json
369
+ - spec/support/all_tasks.json
361
370
  - spec/support/all_users.json
362
371
  - spec/support/case.json
363
372
  - spec/support/countries.json
@@ -368,3 +377,5 @@ test_files:
368
377
  - spec/support/opportunity.json
369
378
  - spec/support/organisation.json
370
379
  - spec/support/person.json
380
+ - spec/support/task.json
381
+ - spec/support/task_categories.json