capsule_crm 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/capsule_crm/associations/has_many.rb +16 -0
- data/lib/capsule_crm/associations/has_many_proxy.rb +6 -6
- data/lib/capsule_crm/associations.rb +8 -1
- data/lib/capsule_crm/contacts.rb +16 -8
- data/lib/capsule_crm/gettable.rb +2 -2
- data/lib/capsule_crm/organization.rb +3 -0
- data/lib/capsule_crm/persistence/persistable.rb +4 -6
- data/lib/capsule_crm/person.rb +2 -0
- data/lib/capsule_crm/serializer.rb +1 -1
- data/lib/capsule_crm/version.rb +1 -1
- data/spec/lib/capsule_crm/contacts_spec.rb +48 -0
- data/spec/lib/capsule_crm/custom_field_spec.rb +2 -0
- data/spec/lib/capsule_crm/person_spec.rb +5 -0
- data/spec/support/shared_examples/persistable.rb +33 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cc2774ab10bd28336dd0d4586a9e580339da8fa
|
4
|
+
data.tar.gz: 993020dd12dc61dcf601e70b111279f7dbf0dd8b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8ff0fcca56968b5f6bcf914c2041e758c2f28c3d16107b2a36f61be649ba35c9741c171619f2197d7ca229b746131a68d6e556e8b440b311413c8611c41b646
|
7
|
+
data.tar.gz: 002ed9d4cb89290cf6151e72439c84912f2752e7b6b4a455d4165aa024b01d4d75c0efbf2b08c5ca65bef995ae9e6bdca176a84bfb17fe8c237c8c1e05bc55fb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.4.0
|
4
|
+
|
5
|
+
- Fix bug with contacts, where contact details were being attached to parties as
|
6
|
+
an array of hashes
|
7
|
+
- Added ActiveModel::Callbacks to persistence module so after_save methods may
|
8
|
+
be added
|
9
|
+
- Used after_save method to save all embedded associations (custom fields)
|
10
|
+
|
3
11
|
## 1.3.0
|
4
12
|
|
5
13
|
- Refactored associations to allow classes to reflect on themselves in order to
|
@@ -39,6 +39,22 @@ module CapsuleCRM
|
|
39
39
|
new(association_name, self, options)
|
40
40
|
self.associations[association_name] = association
|
41
41
|
|
42
|
+
if options[:embedded]
|
43
|
+
define_method "save_#{association_name}" do
|
44
|
+
unless self.send(association_name).blank?
|
45
|
+
# TODO why can't I chain this?
|
46
|
+
a = self.send(association_name)
|
47
|
+
a.save
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class_eval do
|
52
|
+
after_save :"save_#{association_name}" if respond_to?(:after_save)
|
53
|
+
private :"save_#{association_name}"
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
42
58
|
define_method association_name do
|
43
59
|
instance_variable_get(:"@#{association_name}") ||
|
44
60
|
instance_variable_set(:"@#{association_name}", association.proxy(self))
|
@@ -44,12 +44,6 @@ module CapsuleCRM
|
|
44
44
|
{ root => serializer.serialize_collection(target_klass, target) }
|
45
45
|
end
|
46
46
|
|
47
|
-
private
|
48
|
-
|
49
|
-
def serializer
|
50
|
-
@serializer ||= ::CapsuleCRM::Serializer
|
51
|
-
end
|
52
|
-
|
53
47
|
def save
|
54
48
|
json = to_capsule_json(target_klass.serializable_options.collection_root)
|
55
49
|
path = [
|
@@ -59,6 +53,12 @@ module CapsuleCRM
|
|
59
53
|
::CapsuleCRM::Connection.put(path, json)
|
60
54
|
end
|
61
55
|
|
56
|
+
private
|
57
|
+
|
58
|
+
def serializer
|
59
|
+
@serializer ||= ::CapsuleCRM::Serializer
|
60
|
+
end
|
61
|
+
|
62
62
|
def save!
|
63
63
|
save
|
64
64
|
end
|
@@ -28,10 +28,17 @@ module CapsuleCRM
|
|
28
28
|
select_associations(:belongs_to)
|
29
29
|
end
|
30
30
|
|
31
|
+
# Public: Get all the embedded has many associations defined on the class
|
32
|
+
def embedded_associations
|
33
|
+
has_many_associations.select do |name, association|
|
34
|
+
association.embedded
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
31
38
|
def select_associations(macro)
|
32
39
|
associations.select do |name, association|
|
33
40
|
association.macro == macro &&
|
34
|
-
[self, self.
|
41
|
+
[self, self.ancestors].flatten.include?(association.defined_on)
|
35
42
|
end
|
36
43
|
end
|
37
44
|
end
|
data/lib/capsule_crm/contacts.rb
CHANGED
@@ -34,8 +34,7 @@ module CapsuleCRM
|
|
34
34
|
#
|
35
35
|
# Returns an Array of CapsuleCRM::Address objects
|
36
36
|
def addresses=(addresses)
|
37
|
-
|
38
|
-
@addresses = Array(addresses)
|
37
|
+
set_collection(CapsuleCRM::Address, addresses)
|
39
38
|
end
|
40
39
|
|
41
40
|
# Public: Gets the addresses for this contacts container
|
@@ -62,10 +61,10 @@ module CapsuleCRM
|
|
62
61
|
#
|
63
62
|
# Returns an Array of CapsuleCRM::Email objects
|
64
63
|
def emails=(emails)
|
65
|
-
|
66
|
-
@emails = Array(emails)
|
64
|
+
set_collection(CapsuleCRM::Email, emails)
|
67
65
|
end
|
68
66
|
|
67
|
+
|
69
68
|
# Public: Gets the emails for this contacts container
|
70
69
|
#
|
71
70
|
# Examples
|
@@ -89,8 +88,7 @@ module CapsuleCRM
|
|
89
88
|
#
|
90
89
|
# Returns an Array of CapsuleCRM::Phone objects
|
91
90
|
def phones=(phones)
|
92
|
-
|
93
|
-
@phones = Array(phones)
|
91
|
+
set_collection(CapsuleCRM::Phone, phones)
|
94
92
|
end
|
95
93
|
|
96
94
|
# Public: Gets the phones for this contacts container
|
@@ -118,8 +116,7 @@ module CapsuleCRM
|
|
118
116
|
#
|
119
117
|
# Returns an Array of CapsuleCRM::Website objects
|
120
118
|
def websites=(websites)
|
121
|
-
|
122
|
-
@websites = Array(websites)
|
119
|
+
set_collection(CapsuleCRM::Website, websites)
|
123
120
|
end
|
124
121
|
|
125
122
|
# Public: Gets the websites for this contacts container
|
@@ -148,5 +145,16 @@ module CapsuleCRM
|
|
148
145
|
website: websites.map(&:to_capsule_json)
|
149
146
|
}.delete_if { |key, value| value.blank? }.stringify_keys
|
150
147
|
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def set_collection(klass, collection)
|
152
|
+
objects = [collection].compact.flatten.map do |item|
|
153
|
+
item.is_a?(Hash) ? klass.new(item) : item
|
154
|
+
end
|
155
|
+
instance_variable_set(
|
156
|
+
:"@#{klass.to_s.downcase.demodulize.pluralize}", objects
|
157
|
+
)
|
158
|
+
end
|
151
159
|
end
|
152
160
|
end
|
data/lib/capsule_crm/gettable.rb
CHANGED
@@ -24,6 +24,7 @@ module CapsuleCRM
|
|
24
24
|
|
25
25
|
persistable_config do |config|
|
26
26
|
config.create = lambda { |org| "organisation" }
|
27
|
+
config.update = lambda { |org| "organisation" }
|
27
28
|
config.destroy = lambda { |org| "party/#{org.id}" }
|
28
29
|
end
|
29
30
|
|
@@ -33,6 +34,8 @@ module CapsuleCRM
|
|
33
34
|
|
34
35
|
validates :name, presence: true
|
35
36
|
|
37
|
+
after_save :save_custom_fields
|
38
|
+
|
36
39
|
has_many :people
|
37
40
|
|
38
41
|
# Public: Get all people from Capsule. The list can be restricted
|
@@ -6,6 +6,8 @@ module CapsuleCRM
|
|
6
6
|
def self.included(base)
|
7
7
|
base.send :include, CapsuleCRM::Persistence::Configuration
|
8
8
|
base.extend CapsuleCRM::Persistence::Persistable::ClassMethods
|
9
|
+
base.extend ActiveModel::Callbacks
|
10
|
+
base.send :define_model_callbacks, :save
|
9
11
|
end
|
10
12
|
|
11
13
|
module ClassMethods
|
@@ -20,18 +22,14 @@ module CapsuleCRM
|
|
20
22
|
|
21
23
|
def save
|
22
24
|
if valid?
|
23
|
-
new_record? ? create_record : update_record
|
25
|
+
run_callbacks(:save) { new_record? ? create_record : update_record }
|
24
26
|
else
|
25
27
|
false
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
def save!
|
30
|
-
|
31
|
-
new_record? ? create_record : update_record
|
32
|
-
else
|
33
|
-
raise CapsuleCRM::Errors::RecordInvalid.new(self)
|
34
|
-
end
|
32
|
+
save || raise(CapsuleCRM::Errors::RecordInvalid.new(self))
|
35
33
|
end
|
36
34
|
|
37
35
|
def update_attributes(attributes = {})
|
data/lib/capsule_crm/person.rb
CHANGED
@@ -34,6 +34,8 @@ module CapsuleCRM
|
|
34
34
|
|
35
35
|
belongs_to :organization, foreign_key: :organisation_id
|
36
36
|
|
37
|
+
after_save :save_custom_fields
|
38
|
+
|
37
39
|
validates :id, numericality: { allow_blank: true }
|
38
40
|
validates :first_name, presence: { if: :first_name_required? }
|
39
41
|
validates :last_name, presence: { if: :last_name_required? }
|
@@ -18,7 +18,7 @@ module CapsuleCRM
|
|
18
18
|
|
19
19
|
def self.serialize_collection(klass, collection)
|
20
20
|
collection = collection.map do |item|
|
21
|
-
options = klass.serializable_options
|
21
|
+
options = klass.serializable_options.dup
|
22
22
|
options.include_root = false
|
23
23
|
::CapsuleCRM::Serializer.new(options).serialize(item)
|
24
24
|
end
|
data/lib/capsule_crm/version.rb
CHANGED
@@ -25,6 +25,54 @@ describe CapsuleCRM::Contacts do
|
|
25
25
|
)
|
26
26
|
end
|
27
27
|
|
28
|
+
describe '#emails=' do
|
29
|
+
let(:contacts) { CapsuleCRM::Contacts.new }
|
30
|
+
before { contacts.emails = email_attributes }
|
31
|
+
subject { contacts.emails }
|
32
|
+
|
33
|
+
context 'when a hash is supplied' do
|
34
|
+
let(:email_attributes) do
|
35
|
+
{ email_address: 'matt@gmail.com', type: 'Work' }
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should create an email from the attributes' do
|
39
|
+
expect(subject.first).to be_a(CapsuleCRM::Email)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should be an array' do
|
43
|
+
expect(subject).to be_a(Array)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when an array is supplied' do
|
48
|
+
context 'when the array contains hashes' do
|
49
|
+
let(:email_attributes) do
|
50
|
+
[{ email_address: Faker::Internet.email, type: 'Work' }]
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should create an email from the attributes' do
|
54
|
+
expect(subject.first).to be_a(CapsuleCRM::Email)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should be an array' do
|
58
|
+
expect(subject).to be_a(Array)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when the array contains emails' do
|
63
|
+
let(:email) do
|
64
|
+
CapsuleCRM::Email.
|
65
|
+
new(email_address: Faker::Internet.email, type: 'Work')
|
66
|
+
end
|
67
|
+
let(:email_attributes) { [email] }
|
68
|
+
|
69
|
+
it 'should set the emails from the supplied array' do
|
70
|
+
expect(subject).to eql(email_attributes)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
28
76
|
describe '#initialize' do
|
29
77
|
context 'when addresses supplied' do
|
30
78
|
subject { CapsuleCRM::Contacts.new(addresses: [address]) }
|
@@ -36,6 +36,11 @@ describe CapsuleCRM::Person do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
it 'should have embedded custom fields association' do
|
40
|
+
expect(described_class.embedded_associations.keys).
|
41
|
+
to include(:custom_fields)
|
42
|
+
end
|
43
|
+
|
39
44
|
before do
|
40
45
|
stub_request(:get, /\/api\/users$/).
|
41
46
|
to_return(body: File.read('spec/support/all_users.json'))
|
@@ -1,4 +1,13 @@
|
|
1
1
|
shared_examples 'persistable' do |location, id|
|
2
|
+
before do
|
3
|
+
stub_request(:get, /[0-9]*\/customfields/).
|
4
|
+
to_return(body: File.read('spec/support/no_customfields.json'))
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'should add an after_save class method' do
|
8
|
+
expect(described_class).to respond_to(:after_save)
|
9
|
+
end
|
10
|
+
|
2
11
|
describe '.create' do
|
3
12
|
subject { described_class.create attributes }
|
4
13
|
before do
|
@@ -17,7 +26,30 @@ shared_examples 'persistable' do |location, id|
|
|
17
26
|
expect(subject.id).to eql(id)
|
18
27
|
end
|
19
28
|
|
20
|
-
|
29
|
+
described_class.embedded_associations.each do |name, association|
|
30
|
+
context "when the #{described_class} has embedded #{name}" do
|
31
|
+
let(:collection_root) do
|
32
|
+
association.target_klass.serializable_options.collection_root
|
33
|
+
end
|
34
|
+
let(:plural) { association.target_klass.queryable_options.plural }
|
35
|
+
let(:singular) { described_class.queryable_options.singular }
|
36
|
+
before do
|
37
|
+
stub_request(:get, /[0-9]*\/#{plural}/).
|
38
|
+
to_return(body: File.read("spec/support/all_#{plural}.json"))
|
39
|
+
stub_request(:put, /[0-9]*\/#{plural}/).
|
40
|
+
to_return(body: File.read("spec/support/all_#{plural}.json"))
|
41
|
+
end
|
42
|
+
subject { described_class.create attributes }
|
43
|
+
|
44
|
+
it "should save the embedded #{name}" do
|
45
|
+
expect(WebMock).to have_requested(
|
46
|
+
:put, "https://1234:@company.capsulecrm.com/api/#{singular}/#{subject.id}/#{plural}"
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if described_class.attribute_set.map(&:name).include?(:track_id)
|
21
53
|
context "when the #{described_class} has a track" do
|
22
54
|
let(:track) { CapsuleCRM::Track.new(id: Random.rand(1..10)) }
|
23
55
|
subject do
|
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.
|
4
|
+
version: 1.4.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: 2014-01-
|
11
|
+
date: 2014-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|