capsule_crm 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  class CapsuleCRM::Person
2
2
  include Virtus
3
3
 
4
- include CapsuleCRM::Associations::HasMany
4
+ include CapsuleCRM::Contactable
5
5
 
6
6
  extend ActiveModel::Naming
7
7
  extend ActiveModel::Callbacks
@@ -9,7 +9,7 @@ class CapsuleCRM::Person
9
9
  include ActiveModel::Validations
10
10
  include ActiveModel::Validations::Callbacks
11
11
 
12
- attribute :id
12
+ attribute :id, Integer
13
13
  attribute :title
14
14
  attribute :first_name
15
15
  attribute :last_name
@@ -21,11 +21,6 @@ class CapsuleCRM::Person
21
21
  validates :first_name, presence: { if: :first_name_required? }
22
22
  validates :last_name, presence: { if: :last_name_required? }
23
23
 
24
- has_many :addresses
25
- has_many :emails
26
- has_many :phones
27
- has_many :websites
28
-
29
24
  # Public: Set the attributes of a person
30
25
  #
31
26
  # attributes - The Hash of attributes (default: {}):
@@ -109,7 +104,30 @@ class CapsuleCRM::Person
109
104
  #
110
105
  # Returns a CapsuleCRM::Person
111
106
  def self.create(attributes = {})
112
- new CapsuleCRM::Connection.post('/api/person', attributes)['person']
107
+ new(attributes).tap(&:save)
108
+ end
109
+
110
+ # Public: Create a new person in capsulecrm and raise a
111
+ # CapsuleCRM::Errors::InvalidRecord error if not possible
112
+ #
113
+ # attributes - The Hash of person attributes (default: {}):
114
+ # :first_name - The String first name
115
+ # :last_name - The String last name
116
+ # :job_title - The String job title
117
+ # :about - The String information about the person
118
+ # :organisation_name - The String organisation name. If now
119
+ # :organisation_id is supplied, then a new one will be created
120
+ # with this name
121
+ # :organisation_id - The Integer ID of the organisation this
122
+ # person belongs to
123
+ #
124
+ # Examples
125
+ #
126
+ # CapsuleCRM::Person.create!(first_name: 'Matt', last_name: 'Beedle')
127
+ #
128
+ # Returns a CapsuleCRM
129
+ def self.create!(attributes = {})
130
+ new(attributes).tap(&:save!)
113
131
  end
114
132
 
115
133
  # Public: If the person already exists in capsule then update them,
@@ -126,10 +144,32 @@ class CapsuleCRM::Person
126
144
  #
127
145
  # Returns a CapsuleCRM::Person
128
146
  def save
129
- if new_record?
130
- self.attributes = CapsuleCRM::Person.create(attributes).attributes
147
+ if valid?
148
+ new_record? ? create_record : update_record
131
149
  else
132
- update_attributes attributes
150
+ false
151
+ end
152
+ end
153
+
154
+ # Public: If the person already exists in capsule then update them,
155
+ # otherwise create a new person. If the person is not valid then a
156
+ # CapsuleCRM::Errors::RecordInvalid exception is raised
157
+ #
158
+ # Examples
159
+ #
160
+ # person = CapsuleCRM::Person.new(first_name: 'Matt')
161
+ # person.save
162
+ #
163
+ # person = CapsuleCRM::Person.find(1)
164
+ # person.first_name = 'Matt'
165
+ # person.save
166
+ #
167
+ # Returns a CapsuleCRM::Person
168
+ def save!
169
+ if valid?
170
+ new_record ? create_record : update_record
171
+ else
172
+ raise CapsuleCRM::Errors::RecordInvalid.new(self)
133
173
  end
134
174
  end
135
175
 
@@ -150,8 +190,35 @@ class CapsuleCRM::Person
150
190
  #
151
191
  # Returns a CapsuleCRM::Person
152
192
  def update_attributes(attributes = {})
153
- self.attributes =
154
- CapsuleCRM::Connection.put("/api/person/#{id}", attributes)['person']
193
+ self.attributes = attributes
194
+ save
195
+ end
196
+
197
+ # Public: Update the person in capsule. If the person is not valid then a
198
+ # CapsuleCRM::Errors::RecordInvalid exception will be raised
199
+ #
200
+ # attributes - The Hash of person attributes (default: {}):
201
+ # :first_name - The String first name
202
+ # :last_name - The String last name
203
+ # :job_title - The String job title
204
+ # :about - The String information about the person
205
+ # :organisation_name - The String organisation name
206
+ # :organisation_id - The String organisation id
207
+ #
208
+ # Examples
209
+ #
210
+ # person = CapsuleCRM::Person.find(1)
211
+ # person.update_attributes first_name: 'Matt', last_name: 'Beedle'
212
+ #
213
+ # Returns a CapsuleCRM::Person
214
+ def update_attributes!(attributes = {})
215
+ self.attributes = attributes
216
+ save!
217
+ end
218
+
219
+ def destroy
220
+ self.id = nil if CapsuleCRM::Connection.delete("/api/party/#{id}")
221
+ self
155
222
  end
156
223
 
157
224
  # Public: Determine whether this CapsuleCRM::Person is a new record or not
@@ -161,8 +228,45 @@ class CapsuleCRM::Person
161
228
  !id
162
229
  end
163
230
 
231
+ # Public: Determine whether or not this CapsuleCRM::Person has already been
232
+ # persisted to capsulecrm
233
+ #
234
+ # Returns a Boolean
235
+ def persisted?
236
+ !new_record?
237
+ end
238
+
239
+ # Public: Build a hash of attributes and merge in the attributes for the
240
+ # contact information
241
+ #
242
+ # Examples
243
+ #
244
+ # person.to_capsule_json
245
+ #
246
+ # Returns a Hash
247
+ def to_capsule_json
248
+ {
249
+ person: CapsuleCRM::HashHelper.camelize_keys(
250
+ attributes.dup.delete_if { |key, value| value.blank? }.
251
+ merge(contacts: contacts.to_capsule_json)
252
+ )
253
+ }.stringify_keys
254
+ end
255
+
164
256
  private
165
257
 
258
+ def create_record
259
+ self.attributes = CapsuleCRM::Connection.post(
260
+ '/api/person', to_capsule_json
261
+ )
262
+ self
263
+ end
264
+
265
+ def update_record
266
+ CapsuleCRM::Connection.put("/api/person/#{id}", attributes)
267
+ self
268
+ end
269
+
166
270
  # Private: Build a ResultsProxy from a Array of CapsuleCRM::Person attributes
167
271
  #
168
272
  # collection - The Array of CapsuleCRM::Person attributes hashes
@@ -0,0 +1,13 @@
1
+ module CapsuleCRM
2
+ class Phone
3
+ include Virtus
4
+
5
+ extend ActiveModel::Naming
6
+ include ActiveModel::Serializers::JSON
7
+
8
+ include CapsuleCRM::CapsuleJsonable
9
+
10
+ attribute :type
11
+ attribute :phone_number
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module CapsuleCrm
2
- VERSION = "0.0.1"
2
+ VERSION = '0.0.2'
3
3
  end
@@ -0,0 +1,17 @@
1
+ module CapsuleCRM
2
+ class Website
3
+ include Virtus
4
+
5
+ extend ActiveModel::Naming
6
+ include ActiveModel::Validations
7
+ include ActiveModel::Serializers::JSON
8
+
9
+ include CapsuleCRM::CapsuleJsonable
10
+
11
+ attribute :type
12
+ attribute :web_service
13
+ attribute :web_address
14
+
15
+ validates :web_service, :web_address, presence: true
16
+ end
17
+ end
data/lib/capsule_crm.rb CHANGED
@@ -1,12 +1,18 @@
1
1
  require 'active_model'
2
2
  require 'faraday'
3
+ require 'faraday_middleware'
3
4
  require 'virtus'
5
+ require 'capsule_crm/capsule_jsonable'
6
+ require 'capsule_crm/address'
4
7
  require 'capsule_crm/connection'
8
+ require 'capsule_crm/email'
9
+ require 'capsule_crm/phone'
10
+ require 'capsule_crm/website'
5
11
  require 'capsule_crm/hash_helper'
6
12
  require 'capsule_crm/results_proxy'
7
- require 'capsule_crm/associations/belongs_to'
8
- require 'capsule_crm/associations/has_many'
9
- require 'capsule_crm/associations/has_many_proxy'
13
+ require 'capsule_crm/errors/record_invalid'
14
+ require 'capsule_crm/contacts'
15
+ require 'capsule_crm/contactable'
10
16
  require 'capsule_crm/configuration'
11
17
  require 'capsule_crm/organization'
12
18
  require 'capsule_crm/person'
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::Address do
4
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CapsuleCRM::Contacts do
6
+
7
+ let(:address) do
8
+ CapsuleCRM::Address.new(
9
+ street: 'Oranienburgerstraße', city: 'Berlin', state: 'Berlin',
10
+ zip: '10117', country: 'Germany', type: 'Office'
11
+ )
12
+ end
13
+
14
+ let(:email) do
15
+ CapsuleCRM::Email.new(email_address: 'matt@gmail.com', type: 'Work')
16
+ end
17
+
18
+ let(:phone) do
19
+ CapsuleCRM::Phone.new(phone_number: '1234', type: 'Work')
20
+ end
21
+
22
+ let(:website) do
23
+ CapsuleCRM::Website.new(
24
+ type: 'Work', web_service: 'URL', web_address: 'http://somewhere.com'
25
+ )
26
+ end
27
+
28
+ describe '#initialize' do
29
+ context 'when addresses supplied' do
30
+ subject { CapsuleCRM::Contacts.new(addresses: [address]) }
31
+
32
+ it { subject.addresses.should_not be_blank }
33
+
34
+ it do
35
+ subject.addresses.
36
+ all? { |address| address.is_a?(CapsuleCRM::Address) }.should be_true
37
+ end
38
+ end
39
+
40
+ context 'when emails supplied' do
41
+ subject { CapsuleCRM::Contacts.new(emails: [email]) }
42
+
43
+ it { subject.emails.should_not be_blank }
44
+
45
+ it do
46
+ subject.emails.
47
+ all? { |email| email.is_a?(CapsuleCRM::Email) }.should be_true
48
+ end
49
+ end
50
+
51
+ context 'when phone numbers are supplied' do
52
+ subject { CapsuleCRM::Contacts.new(phones: [phone]) }
53
+
54
+ it { subject.phones.should_not be_blank }
55
+
56
+ it do
57
+ subject.phones.
58
+ all? { |phone| phone.is_a?(CapsuleCRM::Phone) }.should be_true
59
+ end
60
+ end
61
+
62
+ context 'when websites are supplied' do
63
+ subject { CapsuleCRM::Contacts.new(websites: [website]) }
64
+
65
+ it { subject.websites.should_not be_blank }
66
+
67
+ it do
68
+ subject.websites.
69
+ all? { |website| website.is_a?(CapsuleCRM::Website) }.should be_true
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe CapsuleCRM::Email do
4
+ end
@@ -1,3 +1,5 @@
1
+ #encoding: utf-8
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe CapsuleCRM::Person do
@@ -49,33 +51,56 @@ describe CapsuleCRM::Person do
49
51
  end
50
52
 
51
53
  describe '.create' do
52
- context 'when the person saves successfully' do
54
+ context 'when the person is valid' do
53
55
  before do
54
- stub_request(:post, /.*/).
55
- to_return(body: File.read('spec/support/create-person.json'))
56
+ stub_request(:post, /.*/).to_return(headers: {
57
+ 'Location' => 'https://sample.capsulecrm.com/api/party/100'
58
+ })
56
59
  end
57
60
 
58
- subject { CapsuleCRM::Person.create }
61
+ subject { CapsuleCRM::Person.create(first_name: 'Eric') }
59
62
 
60
63
  it { should be_a(CapsuleCRM::Person) }
61
64
 
62
- it { subject.about.should eql('A comment here') }
65
+ it { subject.id.should eql(100) }
66
+ end
67
+
68
+ context 'when the person is not valid' do
69
+ subject { CapsuleCRM::Person.create }
70
+
71
+ it { subject.errors.should_not be_blank }
72
+ end
73
+ end
74
+
75
+ describe '.create!' do
76
+ context 'when the person is valid' do
77
+ before do
78
+ stub_request(:post, /.*/).to_return(headers: {
79
+ 'Location' => 'https://sample.capsulecrm.com/api/party/101'
80
+ })
81
+ end
82
+
83
+ subject { CapsuleCRM::Person.create(first_name: 'Eric') }
63
84
 
64
- it { subject.first_name.should eql('Eric') }
85
+ it { should be_a(CapsuleCRM::Person) }
65
86
 
66
- it { subject.last_name.should eql('Schmidt') }
87
+ it { should be_persisted }
67
88
 
68
- it { subject.organisation_name.should eql('Google Inc') }
89
+ it { subject.id.should eql(101) }
90
+ end
69
91
 
70
- it { subject.job_title.should eql('Chairman') }
92
+ context 'when the person is not valid' do
93
+ it do
94
+ expect { CapsuleCRM::Person.create! }.
95
+ to raise_error(CapsuleCRM::Errors::RecordInvalid)
96
+ end
71
97
  end
72
98
  end
73
99
 
74
100
  describe '#update_attributes' do
75
- context 'when the person saves successfully' do
101
+ context 'when the person is valid' do
76
102
  before do
77
- stub_request(:put, /.*/).
78
- to_return(body: File.read('spec/support/update-person.json'))
103
+ stub_request(:put, /.*/).to_return(status: 200)
79
104
  end
80
105
 
81
106
  let(:person) { CapsuleCRM::Person.new(id: 1) }
@@ -86,43 +111,96 @@ describe CapsuleCRM::Person do
86
111
 
87
112
  it { person.id.should eql(1) }
88
113
  end
114
+
115
+ context 'when the person is not valid' do
116
+ let(:person) { CapsuleCRM::Person.new(id: 1) }
117
+
118
+ before { person.update_attributes }
119
+
120
+ it { person.should_not be_valid }
121
+
122
+ it { person.errors.should_not be_blank }
123
+ end
124
+ end
125
+
126
+ describe '#update_attributes!' do
127
+
128
+ let(:person) { CapsuleCRM::Person.new(id: 1) }
129
+
130
+ context 'when the person is valid' do
131
+ before do
132
+ stub_request(:put, /.*/).to_return(status: 200)
133
+ end
134
+
135
+ before { person.update_attributes first_name: 'James' }
136
+
137
+ it { person.first_name.should eql('James') }
138
+
139
+ it { person.id.should eql(1) }
140
+ end
141
+
142
+ context 'when the person is not valid' do
143
+ it do
144
+ expect { person.update_attributes! }.
145
+ to raise_error(CapsuleCRM::Errors::RecordInvalid)
146
+ end
147
+ end
89
148
  end
90
149
 
91
150
  describe '#save' do
92
151
  context 'when the person is a new record' do
93
152
  before do
94
- stub_request(:post, /.*/).
95
- to_return(body: File.read('spec/support/create-person.json'))
153
+ stub_request(:post, /.*/).to_return(headers: {
154
+ 'Location' => 'https://sample.capsulecrm.com/api/party/100'
155
+ }, status: 200)
96
156
  end
97
157
 
98
- let(:person) { CapsuleCRM::Person.new }
158
+ let(:person) { CapsuleCRM::Person.new(first_name: 'Eric') }
99
159
 
100
160
  before { person.save }
101
161
 
102
- it { person.about.should eql('A comment here') }
103
-
104
162
  it { person.first_name.should eql('Eric') }
105
163
 
106
- it { person.last_name.should eql('Schmidt') }
164
+ it { person.should be_persisted }
165
+ end
166
+ end
107
167
 
108
- it { person.organisation_name.should eql('Google Inc') }
168
+ describe '#save!' do
169
+ context 'when the person is a new record' do
170
+ context 'when the person is valid' do
171
+ before do
172
+ stub_request(:post, /.*/).to_return(headers: {
173
+ 'Location' => 'https://sample.capsulecrm.com/api/party/100',
174
+ }, status: 200)
175
+ end
109
176
 
110
- it { person.job_title.should eql('Chairman') }
111
- end
177
+ let(:person) { CapsuleCRM::Person.new(first_name: 'Eric') }
112
178
 
113
- context 'when the person is not a new record' do
114
- before do
115
- stub_request(:put, /.*/).
116
- to_return(body: File.read('spec/support/update-person.json'))
179
+ before { person.save }
180
+
181
+ it { person.should be_persisted }
117
182
  end
118
183
 
119
- let(:person) { CapsuleCRM::Person.new(id: 1) }
184
+ context 'when the person is not valid' do
185
+ let(:person) { CapsuleCRM::Person.new }
120
186
 
121
- before { person.save }
187
+ it do
188
+ expect { person.save! }.
189
+ to raise_error(CapsuleCRM::Errors::RecordInvalid)
190
+ end
191
+ end
192
+ end
122
193
 
123
- it { person.first_name.should eql('James') }
194
+ context 'when the person is not a new record' do
195
+ context 'when the person is not valid' do
124
196
 
125
- it { person.id.should eql(1) }
197
+ let(:person) { CapsuleCRM::Person.new(id: 1) }
198
+
199
+ it do
200
+ expect { person.save! }.
201
+ to raise_exception(CapsuleCRM::Errors::RecordInvalid)
202
+ end
203
+ end
126
204
  end
127
205
  end
128
206
 
@@ -144,6 +222,24 @@ describe CapsuleCRM::Person do
144
222
  end
145
223
  end
146
224
 
225
+ describe '#persisted?' do
226
+ context 'when the person is persisted' do
227
+ let(:person) { CapsuleCRM::Person.new(id: 1) }
228
+
229
+ subject { person.persisted? }
230
+
231
+ it { should be_true }
232
+ end
233
+
234
+ context 'when the person is not persisted' do
235
+ let(:person) { CapsuleCRM::Person.new }
236
+
237
+ subject { person.persisted? }
238
+
239
+ it { should be_false }
240
+ end
241
+ end
242
+
147
243
  describe '.init_collection' do
148
244
  subject do
149
245
  CapsuleCRM::Person.init_collection(
@@ -193,4 +289,56 @@ describe CapsuleCRM::Person do
193
289
  it { should be_false }
194
290
  end
195
291
  end
292
+
293
+ describe '#to_capsule_json' do
294
+ let(:address) do
295
+ CapsuleCRM::Address.new(
296
+ street: 'Oranienburgerstraße', city: 'Berlin', state: 'Berlin',
297
+ zip: '10117', country: 'de'
298
+ )
299
+ end
300
+
301
+ let(:email) do
302
+ CapsuleCRM::Email.new(type: 'Work', email_address: 'matt@gmail.com')
303
+ end
304
+
305
+ let(:contacts) do
306
+ CapsuleCRM::Contacts.new(addresses: [address], emails: [email])
307
+ end
308
+
309
+ let(:person) do
310
+ CapsuleCRM::Person.new(
311
+ first_name: 'Matt', last_name: 'Beedle',
312
+ organisation_name: "Matt's Company", contacts: contacts
313
+ )
314
+ end
315
+
316
+ let(:email_json) { subject['contacts']['email'].first }
317
+
318
+ let(:address_json) { subject['contacts']['address'].first }
319
+
320
+ subject { person.to_capsule_json['person'] }
321
+
322
+ it { should have_key('firstName') }
323
+
324
+ it { should have_key('lastName') }
325
+
326
+ it { should have_key('organisationName') }
327
+
328
+ it { should have_key('contacts') }
329
+
330
+ it { address_json.should have_key('street') }
331
+
332
+ it { address_json.should have_key('city') }
333
+
334
+ it { address_json.should have_key('state') }
335
+
336
+ it { address_json.should have_key('zip') }
337
+
338
+ it { address_json.should have_key('country') }
339
+
340
+ it { email_json.should have_key('type') }
341
+
342
+ it { email_json.should have_key('emailAddress') }
343
+ end
196
344
  end
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.0.1
4
+ version: 0.0.2
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-04-22 00:00:00.000000000 Z
11
+ date: 2013-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faraday_middleware
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: virtus
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -159,6 +173,7 @@ extra_rdoc_files: []
159
173
  files:
160
174
  - .gitignore
161
175
  - .rspec
176
+ - .travis.yml
162
177
  - Gemfile
163
178
  - Guardfile
164
179
  - LICENSE.txt
@@ -167,26 +182,31 @@ files:
167
182
  - capsule_crm.gemspec
168
183
  - features/organizations.feature
169
184
  - lib/capsule_crm.rb
185
+ - lib/capsule_crm/address.rb
170
186
  - lib/capsule_crm/associations.rb
171
- - lib/capsule_crm/associations/belongs_to.rb
172
- - lib/capsule_crm/associations/has_many.rb
173
- - lib/capsule_crm/associations/has_many_proxy.rb
187
+ - lib/capsule_crm/capsule_jsonable.rb
174
188
  - lib/capsule_crm/configuration.rb
175
189
  - lib/capsule_crm/connection.rb
176
- - lib/capsule_crm/contact.rb
190
+ - lib/capsule_crm/contactable.rb
191
+ - lib/capsule_crm/contacts.rb
192
+ - lib/capsule_crm/email.rb
193
+ - lib/capsule_crm/errors/record_invalid.rb
177
194
  - lib/capsule_crm/hash_helper.rb
178
195
  - lib/capsule_crm/organization.rb
179
196
  - lib/capsule_crm/party.rb
180
197
  - lib/capsule_crm/person.rb
198
+ - lib/capsule_crm/phone.rb
181
199
  - lib/capsule_crm/results_proxy.rb
182
200
  - lib/capsule_crm/version.rb
201
+ - lib/capsule_crm/website.rb
202
+ - spec/lib/capsule_crm/address_spec.rb
203
+ - spec/lib/capsule_crm/contacts_spec.rb
204
+ - spec/lib/capsule_crm/email_spec.rb
183
205
  - spec/lib/capsule_crm/person_spec.rb
184
206
  - spec/spec_helper.rb
185
207
  - spec/support/all_parties.json
186
- - spec/support/create-person.json
187
208
  - spec/support/helpers.rb
188
209
  - spec/support/person.json
189
- - spec/support/update-person.json
190
210
  homepage: ''
191
211
  licenses: []
192
212
  metadata: {}
@@ -212,10 +232,11 @@ specification_version: 4
212
232
  summary: Gem to communicate with CapsuleCRM
213
233
  test_files:
214
234
  - features/organizations.feature
235
+ - spec/lib/capsule_crm/address_spec.rb
236
+ - spec/lib/capsule_crm/contacts_spec.rb
237
+ - spec/lib/capsule_crm/email_spec.rb
215
238
  - spec/lib/capsule_crm/person_spec.rb
216
239
  - spec/spec_helper.rb
217
240
  - spec/support/all_parties.json
218
- - spec/support/create-person.json
219
241
  - spec/support/helpers.rb
220
242
  - spec/support/person.json
221
- - spec/support/update-person.json