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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 895602f68388ac5ca0d367ee33568425ea6b9b94
4
- data.tar.gz: 426048ab8c437b47607fe449af53455ee22a6c14
3
+ metadata.gz: 6cc2774ab10bd28336dd0d4586a9e580339da8fa
4
+ data.tar.gz: 993020dd12dc61dcf601e70b111279f7dbf0dd8b
5
5
  SHA512:
6
- metadata.gz: 2c0c4236c700a3014c6ed84ed1122d4784047016dfc69b2f8431cac9b23bea80832f17858562e1adf86c0eaf8c3367e0fa21d365187197acce034c91c171400f
7
- data.tar.gz: bab4f5d64be4d3bf1f75be0de9d98a1a294307b1fae5af38ee70bee1f26d2ba50c64e70508808d523713c61acb3b94e5e5cdff57c3949a745584aea8c18f4465
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.parent].include?(association.defined_on)
41
+ [self, self.ancestors].flatten.include?(association.defined_on)
35
42
  end
36
43
  end
37
44
  end
@@ -34,8 +34,7 @@ module CapsuleCRM
34
34
  #
35
35
  # Returns an Array of CapsuleCRM::Address objects
36
36
  def addresses=(addresses)
37
- addresses = CapsuleCRM::Address.new(addresses) if addresses.is_a?(Hash)
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
- emails = CapsuleCRM::Email.new(emails) if emails.is_a?(Hash)
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
- phones = CapsuleCRM::Phone.new(phones) if phones.is_a?(Hash)
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
- websites = CapsuleCRM::Website.new(websites) if websites.is_a?(Hash)
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
@@ -3,8 +3,8 @@ module CapsuleCRM
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
- def get(path)
7
- CapsuleCRM::Connection.get(path)
6
+ def get(path, options = {})
7
+ CapsuleCRM::Connection.get(path, options)
8
8
  end
9
9
  end
10
10
  end
@@ -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
- if valid?
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 = {})
@@ -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
@@ -1,3 +1,3 @@
1
1
  module CapsuleCrm
2
- VERSION = '1.3.0'
2
+ VERSION = '1.4.0'
3
3
  end
@@ -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]) }
@@ -50,6 +50,8 @@ describe CapsuleCRM::CustomField do
50
50
  end
51
51
 
52
52
  it 'should have a root element of "customField"' do
53
+ p described_class.serializable_options
54
+ p subject
53
55
  expect(subject.keys.first).to eql('customField')
54
56
  end
55
57
  end
@@ -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
- if described_class.attributes.map(&:name).include?(:track_id)
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.3.0
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-14 00:00:00.000000000 Z
11
+ date: 2014-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel