capsule_crm 0.4.6 → 0.5.6

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: 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