capsule_crm 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +14 -6
- data/lib/capsule_crm.rb +1 -0
- data/lib/capsule_crm/associations/has_many_proxy.rb +13 -3
- data/lib/capsule_crm/attachment.rb +4 -0
- data/lib/capsule_crm/case.rb +1 -0
- data/lib/capsule_crm/connection.rb +2 -2
- data/lib/capsule_crm/custom_field.rb +1 -0
- data/lib/capsule_crm/errors/record_not_saved.rb +18 -0
- data/lib/capsule_crm/history.rb +1 -0
- data/lib/capsule_crm/milestone.rb +3 -1
- data/lib/capsule_crm/opportunity.rb +2 -1
- data/lib/capsule_crm/organization.rb +2 -2
- data/lib/capsule_crm/person.rb +3 -1
- data/lib/capsule_crm/task.rb +1 -0
- data/lib/capsule_crm/track.rb +2 -0
- data/lib/capsule_crm/version.rb +1 -1
- data/spec/fabricators/opportunity_fabricator.rb +0 -1
- data/spec/lib/capsule_crm/associations/has_many_proxy_spec.rb +19 -3
- data/spec/lib/capsule_crm/attachment_spec.rb +7 -0
- data/spec/lib/capsule_crm/case_spec.rb +5 -3
- data/spec/lib/capsule_crm/connection_spec.rb +89 -3
- data/spec/lib/capsule_crm/custom_field_spec.rb +4 -1
- data/spec/lib/capsule_crm/history_spec.rb +37 -1
- data/spec/lib/capsule_crm/milestone_spec.rb +4 -0
- data/spec/lib/capsule_crm/opportunity_spec.rb +20 -34
- data/spec/lib/capsule_crm/organization_spec.rb +16 -0
- data/spec/lib/capsule_crm/person_spec.rb +36 -0
- data/spec/lib/capsule_crm/task_spec.rb +6 -11
- data/spec/lib/capsule_crm/track_spec.rb +4 -5
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b2ac3b80afb32c0e5e01fb90ed2677ec5bbc633
|
4
|
+
data.tar.gz: 0e12ab771e075cad5a39598da55d81015111620a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 377306fa489bb3aa8e2f1c19a64d233b47763b7d6ca250fa32ac30a5a536173f1c726dc17b8d402dced4578f9694797fd776095ed811c9d8e8bc6e047d9ec2bc
|
7
|
+
data.tar.gz: 6a34894ec8bd04703a4767dbebe8a91c48164f477a079729be646e8d59e21d4f074bcc7d11fc7c8b6b5ae60215ca1f38f7e53107cc439c03bc5dfaafc70aa767
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.0.0
|
4
|
+
|
5
|
+
- Using SemVer and this gem is being used in production, so bumped to version 1
|
6
|
+
- Handle 401 responses by raising a CapsuleCRM::Errors::Unauthorized error
|
7
|
+
|
8
|
+
## 0.10.1
|
9
|
+
|
10
|
+
- Automatically strformat the lastmodified param for GET requests
|
11
|
+
|
3
12
|
## 0.10.0
|
4
13
|
|
5
14
|
- Added Track support
|
data/README.md
CHANGED
@@ -15,12 +15,6 @@ Ready](http://badge.waffle.io/mattbeedle/capsule_crm.png)](http://waffle.io/matt
|
|
15
15
|
|
16
16
|
CapsuleCRM provides an ActiveModel compliant interface to the capsulecrm API
|
17
17
|
|
18
|
-
## Versioning
|
19
|
-
|
20
|
-
This project follows [semver](http://semver.org/spec/v2.0.0.html) so there will
|
21
|
-
be no breaking changes in minor/patch version changes. It is pre 1.0
|
22
|
-
though, so it's not finished and expect to find bugs.
|
23
|
-
|
24
18
|
## Installation
|
25
19
|
|
26
20
|
Add this line to your application's Gemfile:
|
@@ -312,12 +306,18 @@ CapsuleCRM::Currency.all
|
|
312
306
|
|
313
307
|
1.9.3, 2.0, jruby-19mode
|
314
308
|
|
309
|
+
## Versioning
|
310
|
+
|
311
|
+
This project follows [semver](http://semver.org/spec/v2.0.0.html) so there will
|
312
|
+
be no breaking changes in minor/patch version changes.
|
313
|
+
|
315
314
|
## Feedback
|
316
315
|
|
317
316
|
Please use github issues to give feedback. If you have a bug to report then an
|
318
317
|
accompanying failing test would be great. Extra points for a full pull request
|
319
318
|
with fix.
|
320
319
|
|
320
|
+
|
321
321
|
## Contributing
|
322
322
|
|
323
323
|
1. Fork it
|
@@ -325,3 +325,11 @@ with fix.
|
|
325
325
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
326
326
|
4. Push to the branch (`git push origin my-new-feature`)
|
327
327
|
5. Create new Pull Request
|
328
|
+
|
329
|
+
## Contributers
|
330
|
+
|
331
|
+
Many thanks to the following contributers:
|
332
|
+
|
333
|
+
- @srbaker
|
334
|
+
- @clod81
|
335
|
+
- @danthompson
|
data/lib/capsule_crm.rb
CHANGED
@@ -25,6 +25,7 @@ require 'capsule_crm/website'
|
|
25
25
|
require 'capsule_crm/hash_helper'
|
26
26
|
require 'capsule_crm/results_proxy'
|
27
27
|
require 'capsule_crm/errors/record_invalid'
|
28
|
+
require 'capsule_crm/errors/record_not_saved'
|
28
29
|
require 'capsule_crm/errors/unauthorized'
|
29
30
|
require 'capsule_crm/contacts'
|
30
31
|
require 'capsule_crm/contactable'
|
@@ -10,18 +10,20 @@ module CapsuleCRM
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def method_missing(name, *args, &block)
|
13
|
-
|
13
|
+
target.send(name, *args, &block)
|
14
14
|
end
|
15
15
|
|
16
16
|
def build(attributes = {})
|
17
17
|
target_klass.new(attributes).tap do |item|
|
18
18
|
item.send("#{source}=", parent)
|
19
|
-
|
19
|
+
target << item
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def create(attributes = {})
|
24
|
-
build(attributes).
|
24
|
+
build(attributes).tap do |record|
|
25
|
+
record_not_saved(record) unless parent.persisted?
|
26
|
+
end.save
|
25
27
|
end
|
26
28
|
|
27
29
|
def tap
|
@@ -31,6 +33,14 @@ module CapsuleCRM
|
|
31
33
|
|
32
34
|
private
|
33
35
|
|
36
|
+
def record_not_saved(record)
|
37
|
+
raise ::CapsuleCRM::Errors::RecordNotSaved.new(record)
|
38
|
+
end
|
39
|
+
|
40
|
+
def target
|
41
|
+
@target
|
42
|
+
end
|
43
|
+
|
34
44
|
def parent
|
35
45
|
@parent
|
36
46
|
end
|
data/lib/capsule_crm/case.rb
CHANGED
@@ -13,7 +13,7 @@ module CapsuleCRM
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.post(path, params = {})
|
16
|
-
process_post_response request(:post, path, params)
|
16
|
+
process_post_response request(:post, path, params.to_json)
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.put(path, params)
|
@@ -56,7 +56,7 @@ module CapsuleCRM
|
|
56
56
|
def self.process_post_response(response)
|
57
57
|
if response.headers['Location'] &&
|
58
58
|
match = response.headers['Location'].match(/\/(?<id>\d+)$/)
|
59
|
-
{ id: match[:id] }
|
59
|
+
{ id: match[:id].to_i }
|
60
60
|
else
|
61
61
|
true
|
62
62
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CapsuleCRM
|
2
|
+
module Errors
|
3
|
+
class RecordNotSaved < StandardError
|
4
|
+
attr_reader :record
|
5
|
+
|
6
|
+
def initialize(record)
|
7
|
+
@record = record
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
[
|
12
|
+
'CapsuleCRM::Errors::RecordNotSaved',
|
13
|
+
'You cannot call create unless the parent is saved'
|
14
|
+
].join(': ')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/capsule_crm/history.rb
CHANGED
@@ -25,6 +25,7 @@ module CapsuleCRM
|
|
25
25
|
foreign_key: :case_id
|
26
26
|
belongs_to :opportunity, class_name: 'CapsuleCRM::Opportunity'
|
27
27
|
|
28
|
+
validates :id, numericality: { allow_blank: true }
|
28
29
|
validates :note, presence: true
|
29
30
|
validates :party, :kase, :opportunity,
|
30
31
|
presence: { if: :belongs_to_required? }
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module CapsuleCRM
|
2
2
|
class Milestone
|
3
3
|
include Virtus
|
4
|
-
|
5
4
|
include CapsuleCRM::Collection
|
5
|
+
include ActiveModel::Validations
|
6
6
|
|
7
7
|
attribute :id, Integer
|
8
8
|
attribute :name, String
|
@@ -10,6 +10,8 @@ module CapsuleCRM
|
|
10
10
|
attribute :probability, Float
|
11
11
|
attribute :complete, Boolean
|
12
12
|
|
13
|
+
validates :id, numericality: { allow_blank: true }
|
14
|
+
|
13
15
|
def self.all
|
14
16
|
init_collection(
|
15
17
|
CapsuleCRM::Connection.
|
@@ -24,8 +24,9 @@ module CapsuleCRM
|
|
24
24
|
|
25
25
|
attr_accessor :milestone, :owner
|
26
26
|
|
27
|
+
validates :id, numericality: { allow_blank: true }
|
27
28
|
validates :name, presence: true
|
28
|
-
validates :
|
29
|
+
validates :party, presence: true
|
29
30
|
validates :milestone, presence: true
|
30
31
|
|
31
32
|
has_many :tasks, class_name: 'CapsuleCRM::Task', source: :opportunity
|
@@ -21,7 +21,7 @@ module CapsuleCRM
|
|
21
21
|
|
22
22
|
has_many :people, class_name: 'CapsuleCRM::Person', source: :organization
|
23
23
|
has_many :custom_fields, class_name: 'CapsuleCRM::CustomField',
|
24
|
-
source: :
|
24
|
+
source: :party
|
25
25
|
|
26
26
|
# Public: Get all people from Capsule. The list can be restricted
|
27
27
|
# and/or paginated with various query parameters sent through the options
|
@@ -134,7 +134,7 @@ module CapsuleCRM
|
|
134
134
|
# Returns a CapsuleCRM::Organization
|
135
135
|
def save!
|
136
136
|
if valid?
|
137
|
-
new_record ? create_record : update_record
|
137
|
+
new_record? ? create_record : update_record
|
138
138
|
else
|
139
139
|
raise CapsuleCRM::Errors::RecordInvalid.new(self)
|
140
140
|
end
|
data/lib/capsule_crm/person.rb
CHANGED
@@ -19,8 +19,10 @@ module CapsuleCRM
|
|
19
19
|
belongs_to :organization, class_name: 'CapsuleCRM::Organization',
|
20
20
|
foreign_key: :organisation_id
|
21
21
|
|
22
|
-
has_many :custom_fields, class_name: 'CapsuleCRM::CustomField',
|
22
|
+
has_many :custom_fields, class_name: 'CapsuleCRM::CustomField',
|
23
|
+
source: :party
|
23
24
|
|
25
|
+
validates :id, numericality: { allow_blank: true }
|
24
26
|
validates :first_name, presence: { if: :first_name_required? }
|
25
27
|
validates :last_name, presence: { if: :last_name_required? }
|
26
28
|
|
data/lib/capsule_crm/task.rb
CHANGED
@@ -22,6 +22,7 @@ module CapsuleCRM
|
|
22
22
|
belongs_to :case, class_name: 'CapsuleCRM::Case'
|
23
23
|
belongs_to :owner, class_name: 'CapsuleCRM::User'
|
24
24
|
|
25
|
+
validates :id, numericality: { allow_blank: true }
|
25
26
|
validates :description, presence: true
|
26
27
|
validates :due_date, presence: { unless: :due_date_time }
|
27
28
|
validates :due_date_time, presence: { unless: :due_date }
|
data/lib/capsule_crm/track.rb
CHANGED
@@ -17,6 +17,8 @@ module CapsuleCRM
|
|
17
17
|
has_many :opportunities, class_name: 'CapsuleCRM::Opportunity'
|
18
18
|
has_many :cases, class_name: 'CapsuleCRM::Case'
|
19
19
|
|
20
|
+
validates :id, numericality: { allow_blank: true }
|
21
|
+
|
20
22
|
def self.all
|
21
23
|
init_collection(
|
22
24
|
CapsuleCRM::Connection.get('/api/tracks')['tracks']['track']
|
data/lib/capsule_crm/version.rb
CHANGED
@@ -7,6 +7,10 @@ class Parent
|
|
7
7
|
attribute :id, Integer
|
8
8
|
|
9
9
|
has_many :children, class_name: 'Child', source: :parent
|
10
|
+
|
11
|
+
def persisted?
|
12
|
+
!!id
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
class Child
|
@@ -62,10 +66,22 @@ describe CapsuleCRM::Associations::HasManyProxy do
|
|
62
66
|
end
|
63
67
|
|
64
68
|
describe '#create' do
|
65
|
-
|
69
|
+
subject { parent.children.create(name: 'a test name') }
|
70
|
+
context 'when the parent is persisted' do
|
71
|
+
before do
|
72
|
+
parent.id = Random.rand(1..10)
|
73
|
+
subject
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should persist the child' do
|
77
|
+
expect(parent.children.last).to be_persisted
|
78
|
+
end
|
79
|
+
end
|
66
80
|
|
67
|
-
|
68
|
-
|
81
|
+
context 'when the parent is not persisted' do
|
82
|
+
it 'should raise a RecordNotSaved error' do
|
83
|
+
expect { subject }.to raise_error(CapsuleCRM::Errors::RecordNotSaved)
|
84
|
+
end
|
69
85
|
end
|
70
86
|
end
|
71
87
|
end
|
@@ -8,9 +8,11 @@ describe CapsuleCRM::Case do
|
|
8
8
|
to_return(body: File.read('spec/support/all_users.json'))
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
describe 'validations' do
|
12
|
+
it { should validate_numericality_of(:id) }
|
13
|
+
it { should validate_presence_of(:name) }
|
14
|
+
it { should validate_presence_of(:party) }
|
15
|
+
end
|
14
16
|
|
15
17
|
describe '._for_track' do
|
16
18
|
let(:track) { CapsuleCRM::Track.new }
|
@@ -23,11 +23,97 @@ describe CapsuleCRM::Connection do
|
|
23
23
|
stub_request(:get, /\/api\/v1\/foo/).
|
24
24
|
to_return(status: 401, body: '<html></html>')
|
25
25
|
end
|
26
|
-
subject { CapsuleCRM::Connection.get('/api/v1/
|
26
|
+
subject { CapsuleCRM::Connection.get('/api/v1/foo') }
|
27
27
|
|
28
28
|
it 'should raise an Unauthorized error' do
|
29
|
-
expect { CapsuleCRM::
|
30
|
-
|
29
|
+
expect { subject }.to raise_error(CapsuleCRM::Errors::Unauthorized)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.post' do
|
35
|
+
subject { CapsuleCRM::Connection.post('/foo', { bar: :baz }) }
|
36
|
+
|
37
|
+
context 'when it is a success' do
|
38
|
+
context 'when it returns a location header' do
|
39
|
+
before do
|
40
|
+
stub_request(:post, /.*/).to_return(
|
41
|
+
status: 200, headers: { 'Location' => "http://foo.bar/#{id}" }
|
42
|
+
)
|
43
|
+
end
|
44
|
+
let(:id) { Random.rand(1..100) }
|
45
|
+
|
46
|
+
it 'should return the ID' do
|
47
|
+
expect(subject).to eql({ id: id })
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when it does not return a location header' do
|
52
|
+
before do
|
53
|
+
stub_request(:post, /.*/).to_return(status: 200, body: {}.to_json)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should return true' do
|
57
|
+
expect(subject).to eql(true)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when the request is not authorized' do
|
63
|
+
before do
|
64
|
+
stub_request(:post, /.*/).to_return(status: 401, body: '<html></html>')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should raise an Unauthorized error' do
|
68
|
+
expect { subject }.to raise_error(CapsuleCRM::Errors::Unauthorized)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '.put' do
|
74
|
+
subject { CapsuleCRM::Connection.put('/foo', { bar: :baz }) }
|
75
|
+
|
76
|
+
context 'when it is a success' do
|
77
|
+
before do
|
78
|
+
stub_request(:put, /.*/).to_return(status: 200, body: {}.to_json)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should return true' do
|
82
|
+
expect(subject).to eql(true)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when it is not authorized' do
|
87
|
+
before do
|
88
|
+
stub_request(:put, /\.*/).to_return(status: 401)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should raise an Unauthorized error' do
|
92
|
+
expect { subject }.to raise_error(CapsuleCRM::Errors::Unauthorized)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '.delete' do
|
98
|
+
subject { CapsuleCRM::Connection.delete('/foo') }
|
99
|
+
|
100
|
+
context 'when it is a success' do
|
101
|
+
before do
|
102
|
+
stub_request(:delete, /.*/).to_return(status: 200)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should return true' do
|
106
|
+
expect(subject).to eql(true)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'when it is not authorized' do
|
111
|
+
before do
|
112
|
+
stub_request(:delete, /.*/).to_return(status: 401)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should raise an Unauthorized error' do
|
116
|
+
expect { subject }.to raise_error(CapsuleCRM::Errors::Unauthorized)
|
31
117
|
end
|
32
118
|
end
|
33
119
|
end
|
@@ -10,7 +10,10 @@ describe CapsuleCRM::CustomField do
|
|
10
10
|
to_return(body: File.read('spec/support/milestones.json'))
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
describe 'validations' do
|
14
|
+
it { should validate_numericality_of(:id) }
|
15
|
+
it { should validate_presence_of(:label) }
|
16
|
+
end
|
14
17
|
|
15
18
|
describe '._for_party' do
|
16
19
|
let(:party) { Fabricate.build(:organization, id: 1) }
|
@@ -10,7 +10,43 @@ describe CapsuleCRM::History do
|
|
10
10
|
to_return(body: File.read('spec/support/milestones.json'))
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
describe 'validations' do
|
14
|
+
subject { described_class.new }
|
15
|
+
|
16
|
+
it { should validate_numericality_of(:id) }
|
17
|
+
it { should validate_presence_of(:note) }
|
18
|
+
it { should validate_presence_of(:kase) }
|
19
|
+
it { should validate_presence_of(:party) }
|
20
|
+
it { should validate_presence_of(:opportunity) }
|
21
|
+
|
22
|
+
context 'when it belongs to a case' do
|
23
|
+
before do
|
24
|
+
subject.kase = double('CapsuleCRM::Case', id: Random.rand(1..10))
|
25
|
+
end
|
26
|
+
|
27
|
+
it { should_not validate_presence_of(:party) }
|
28
|
+
it { should_not validate_presence_of(:opportunity) }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when it belongs to a party' do
|
32
|
+
before do
|
33
|
+
subject.party = double('CapsuleCRM::Party', id: Random.rand(1..10))
|
34
|
+
end
|
35
|
+
|
36
|
+
it { should_not validate_presence_of(:kase) }
|
37
|
+
it { should_not validate_presence_of(:opportunity) }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when it belongs to an opportunity' do
|
41
|
+
before do
|
42
|
+
subject.opportunity =
|
43
|
+
double('CapsuleCRM::Opportunity', id: Random.rand(1..10))
|
44
|
+
end
|
45
|
+
|
46
|
+
it { should_not validate_presence_of(:party) }
|
47
|
+
it { should_not validate_presence_of(:kase) }
|
48
|
+
end
|
49
|
+
end
|
14
50
|
|
15
51
|
describe '_.for_party' do
|
16
52
|
let(:party) { Fabricate.build(:person, id: 1) }
|
@@ -13,26 +13,13 @@ describe CapsuleCRM::Opportunity do
|
|
13
13
|
to_return(body: File.read('spec/support/all_users.json'))
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
describe 'validations' do
|
17
|
+
subject { described_class.new }
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
before do
|
24
|
-
subject.valid?
|
25
|
-
end
|
26
|
-
|
27
|
-
it { subject.errors[:milestone].should be_blank }
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'when milestone is set' do
|
31
|
-
let(:milestone) { CapsuleCRM::Milestone.new name: 'Bid' }
|
32
|
-
|
33
|
-
subject { CapsuleCRM::Opportunity.new(milestone: milestone) }
|
34
|
-
|
35
|
-
it { should_not validate_presence_of(:milestone_id) }
|
19
|
+
it { should validate_numericality_of(:id) }
|
20
|
+
it { should validate_presence_of(:name) }
|
21
|
+
it { should validate_presence_of(:milestone) }
|
22
|
+
it { should validate_presence_of(:party) }
|
36
23
|
end
|
37
24
|
|
38
25
|
describe '._for_track' do
|
@@ -215,7 +202,6 @@ describe CapsuleCRM::Opportunity do
|
|
215
202
|
end
|
216
203
|
|
217
204
|
it { opportunity.party_id.should eql(1) }
|
218
|
-
|
219
205
|
it { opportunity.milestone_id.should eql(3) }
|
220
206
|
end
|
221
207
|
|
@@ -226,25 +212,23 @@ describe CapsuleCRM::Opportunity do
|
|
226
212
|
'Location' => 'https://sample.capsulecrm.com/api/opportunity/59'
|
227
213
|
})
|
228
214
|
end
|
229
|
-
|
230
215
|
let(:request_path) do
|
231
216
|
[
|
232
217
|
'https://1234:@company.capsulecrm.com/api/party/',
|
233
|
-
opportunity_attributes[:
|
234
|
-
'/opportunity'
|
218
|
+
opportunity_attributes[:party].id, '/opportunity'
|
235
219
|
].join
|
236
220
|
end
|
237
|
-
|
238
|
-
let(:opportunity_attributes)
|
221
|
+
let(:party) { Fabricate.build(:person, id: Random.rand(1..10)) }
|
222
|
+
let(:opportunity_attributes) do
|
223
|
+
Fabricate.attributes_for(:opportunity).merge(party: party)
|
224
|
+
end
|
239
225
|
|
240
226
|
subject do
|
241
227
|
CapsuleCRM::Opportunity.create opportunity_attributes
|
242
228
|
end
|
243
229
|
|
244
230
|
it { should be_a(CapsuleCRM::Opportunity) }
|
245
|
-
|
246
231
|
it { should be_persisted }
|
247
|
-
|
248
232
|
it { subject.id.should eql(59) }
|
249
233
|
|
250
234
|
context 'when the opportunity has a track' do
|
@@ -288,15 +272,17 @@ describe CapsuleCRM::Opportunity do
|
|
288
272
|
'Location' => 'https://sample.capsulecrm.com/api/opportunity/71'
|
289
273
|
})
|
290
274
|
end
|
275
|
+
let(:party) { Fabricate.build(:person, id: Random.rand(1..10)) }
|
276
|
+
let(:opportunity_attributes) do
|
277
|
+
Fabricate.attributes_for(:opportunity).merge(party: party)
|
278
|
+
end
|
291
279
|
|
292
280
|
subject do
|
293
|
-
CapsuleCRM::Opportunity.create
|
281
|
+
CapsuleCRM::Opportunity.create opportunity_attributes
|
294
282
|
end
|
295
283
|
|
296
284
|
it { should be_a(CapsuleCRM::Opportunity) }
|
297
|
-
|
298
285
|
it { should be_persisted }
|
299
|
-
|
300
286
|
it { subject.id.should eql(71) }
|
301
287
|
end
|
302
288
|
|
@@ -365,9 +351,9 @@ describe CapsuleCRM::Opportunity do
|
|
365
351
|
'Location' => 'https://sample.capsulecrm.com/api/party/100'
|
366
352
|
}, status: 200)
|
367
353
|
end
|
368
|
-
|
354
|
+
let(:party) { Fabricate.build(:person) }
|
369
355
|
let(:opportunity) do
|
370
|
-
Fabricate.build(:opportunity)
|
356
|
+
Fabricate.build(:opportunity, party: party)
|
371
357
|
end
|
372
358
|
|
373
359
|
before { opportunity.save }
|
@@ -388,9 +374,9 @@ describe CapsuleCRM::Opportunity do
|
|
388
374
|
'Location' => 'https://sample.capsulecrm.com/api/party/100',
|
389
375
|
}, status: 200)
|
390
376
|
end
|
391
|
-
|
377
|
+
let(:party) { Fabricate.build(:person) }
|
392
378
|
let(:opportunity) do
|
393
|
-
Fabricate.build(:opportunity)
|
379
|
+
Fabricate.build(:opportunity, party: party)
|
394
380
|
end
|
395
381
|
|
396
382
|
before { opportunity.save! }
|
@@ -11,6 +11,22 @@ describe CapsuleCRM::Organization do
|
|
11
11
|
to_return(body: File.read('spec/support/all_users.json'))
|
12
12
|
end
|
13
13
|
|
14
|
+
describe '#custom_fields' do
|
15
|
+
before do
|
16
|
+
stub_request(:get, /\/api\/party\/#{organization.id}\/customfields/).
|
17
|
+
to_return(body: File.read('spec/support/no_customfields.json'))
|
18
|
+
end
|
19
|
+
let(:organization) { Fabricate.build(:organization, id: 1) }
|
20
|
+
|
21
|
+
describe '#build' do
|
22
|
+
before { organization.custom_fields.build(label: 'test', text: 'bidule') }
|
23
|
+
|
24
|
+
it 'should add a new custom field to the organization' do
|
25
|
+
expect(organization.custom_fields.length).to eql(1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
14
30
|
describe '.all' do
|
15
31
|
context 'when some parties exist' do
|
16
32
|
before do
|
@@ -13,6 +13,26 @@ describe CapsuleCRM::Person do
|
|
13
13
|
|
14
14
|
before { configure }
|
15
15
|
|
16
|
+
describe 'validations' do
|
17
|
+
subject { described_class.new }
|
18
|
+
|
19
|
+
it { should validate_numericality_of(:id) }
|
20
|
+
it { should validate_presence_of(:first_name) }
|
21
|
+
it { should validate_presence_of(:last_name) }
|
22
|
+
|
23
|
+
context 'when the first name is set' do
|
24
|
+
before { subject.first_name = Faker::Lorem.word }
|
25
|
+
|
26
|
+
it { should_not validate_presence_of(:last_name) }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the last name is set' do
|
30
|
+
before { subject.last_name = Faker::Lorem.word }
|
31
|
+
|
32
|
+
it { should_not validate_presence_of(:first_name) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
16
36
|
describe '#tasks' do
|
17
37
|
let(:person) { Fabricate.build(:person, id: 1) }
|
18
38
|
|
@@ -26,6 +46,22 @@ describe CapsuleCRM::Person do
|
|
26
46
|
it { should be_a(Array) }
|
27
47
|
end
|
28
48
|
|
49
|
+
describe '#custom_fields' do
|
50
|
+
before do
|
51
|
+
stub_request(:get, /\/api\/party\/#{person.id}\/customfields/).
|
52
|
+
to_return(body: File.read('spec/support/no_customfields.json'))
|
53
|
+
end
|
54
|
+
let(:person) { Fabricate.build(:person, id: 1) }
|
55
|
+
|
56
|
+
describe '#build' do
|
57
|
+
before { person.custom_fields.build(label: 'test', text: 'bidule') }
|
58
|
+
|
59
|
+
it 'should add a custom field' do
|
60
|
+
expect(person.custom_fields.length).to eql(1)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
29
65
|
describe '._for_organization' do
|
30
66
|
context 'when there are many people for the organization' do
|
31
67
|
pending
|
@@ -9,11 +9,12 @@ describe CapsuleCRM::Task do
|
|
9
9
|
to_return(body: File.read('spec/support/person.json'))
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
describe 'validations' do
|
13
|
+
it { should validate_numericality_of(:id) }
|
14
|
+
it { should validate_presence_of(:description) }
|
15
|
+
it { should validate_presence_of(:due_date) }
|
16
|
+
it { should validate_presence_of(:due_date_time) }
|
17
|
+
end
|
17
18
|
|
18
19
|
describe '.find' do
|
19
20
|
before do
|
@@ -24,17 +25,11 @@ describe CapsuleCRM::Task do
|
|
24
25
|
subject { CapsuleCRM::Task.find(2) }
|
25
26
|
|
26
27
|
it { should be_a(CapsuleCRM::Task) }
|
27
|
-
|
28
28
|
it { subject.due_date.should_not be_blank }
|
29
|
-
|
30
29
|
it { subject.category.should eql('Meeting') }
|
31
|
-
|
32
30
|
it { subject.description.should eql('Meet with customer') }
|
33
|
-
|
34
31
|
it { subject.detail.should eql('Meeting at Coffee shop') }
|
35
|
-
|
36
32
|
it { subject.owner.should be_a(CapsuleCRM::User) }
|
37
|
-
|
38
33
|
it { subject.party.should be_a(CapsuleCRM::Person) }
|
39
34
|
end
|
40
35
|
|
@@ -3,6 +3,10 @@ require 'spec_helper'
|
|
3
3
|
describe CapsuleCRM::Track do
|
4
4
|
before { configure }
|
5
5
|
|
6
|
+
describe 'validations' do
|
7
|
+
it { should validate_numericality_of(:id) }
|
8
|
+
end
|
9
|
+
|
6
10
|
describe '.all' do
|
7
11
|
before do
|
8
12
|
stub_request(:get, /\/api\/tracks$/).
|
@@ -12,15 +16,10 @@ describe CapsuleCRM::Track do
|
|
12
16
|
subject { CapsuleCRM::Track.all }
|
13
17
|
|
14
18
|
it { expect(subject).to be_a(Array) }
|
15
|
-
|
16
19
|
it { expect(subject.length).to eql(2) }
|
17
|
-
|
18
20
|
it { expect(subject.first).to be_a(CapsuleCRM::Track) }
|
19
|
-
|
20
21
|
it { expect(subject.first.description).to eql('Sales follow up') }
|
21
|
-
|
22
22
|
it { expect(subject.first.capture_rule).to eql('OPPORTUNITY') }
|
23
|
-
|
24
23
|
it { expect(subject.first.id).to eql(1) }
|
25
24
|
end
|
26
25
|
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: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Beedle
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -272,6 +272,7 @@ files:
|
|
272
272
|
- lib/capsule_crm/custom_field.rb
|
273
273
|
- lib/capsule_crm/email.rb
|
274
274
|
- lib/capsule_crm/errors/record_invalid.rb
|
275
|
+
- lib/capsule_crm/errors/record_not_saved.rb
|
275
276
|
- lib/capsule_crm/errors/unauthorized.rb
|
276
277
|
- lib/capsule_crm/hash_helper.rb
|
277
278
|
- lib/capsule_crm/history.rb
|
@@ -299,6 +300,7 @@ files:
|
|
299
300
|
- spec/lib/capsule_crm/address_spec.rb
|
300
301
|
- spec/lib/capsule_crm/associations/has_many_proxy_spec.rb
|
301
302
|
- spec/lib/capsule_crm/associations/has_many_spec.rb
|
303
|
+
- spec/lib/capsule_crm/attachment_spec.rb
|
302
304
|
- spec/lib/capsule_crm/case_spec.rb
|
303
305
|
- spec/lib/capsule_crm/connection_spec.rb
|
304
306
|
- spec/lib/capsule_crm/contacts_spec.rb
|
@@ -379,6 +381,7 @@ test_files:
|
|
379
381
|
- spec/lib/capsule_crm/address_spec.rb
|
380
382
|
- spec/lib/capsule_crm/associations/has_many_proxy_spec.rb
|
381
383
|
- spec/lib/capsule_crm/associations/has_many_spec.rb
|
384
|
+
- spec/lib/capsule_crm/attachment_spec.rb
|
382
385
|
- spec/lib/capsule_crm/case_spec.rb
|
383
386
|
- spec/lib/capsule_crm/connection_spec.rb
|
384
387
|
- spec/lib/capsule_crm/contacts_spec.rb
|