acts_as_icontact 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.3.0
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{acts_as_icontact}
5
- s.version = "0.2.4"
5
+ s.version = "0.3.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Stephen Eley"]
9
- s.date = %q{2009-07-29}
9
+ s.date = %q{2009-08-01}
10
10
  s.default_executable = %q{icontact}
11
11
  s.description = %q{ActsAsIcontact connects Ruby applications with the iContact e-mail marketing service using the iContact API v2.0. Building on the RestClient gem, it offers two significant feature sets:
12
12
 
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "lib/acts_as_icontact/exceptions.rb",
35
35
  "lib/acts_as_icontact/rails.rb",
36
36
  "lib/acts_as_icontact/rails/callbacks.rb",
37
+ "lib/acts_as_icontact/rails/lists.rb",
37
38
  "lib/acts_as_icontact/rails/macro.rb",
38
39
  "lib/acts_as_icontact/rails/mappings.rb",
39
40
  "lib/acts_as_icontact/resource.rb",
@@ -16,6 +16,7 @@ end
16
16
  if defined?(::ActiveRecord)
17
17
  module ::ActiveRecord
18
18
  class Base
19
+ extend ActsAsIcontact::Rails::ClassMethods::Lists
19
20
  extend ActsAsIcontact::Rails::ClassMethods::Mappings
20
21
  extend ActsAsIcontact::Rails::ClassMethods::Macro
21
22
  end
@@ -5,15 +5,10 @@ module ActsAsIcontact
5
5
  protected
6
6
  # Called after a new record has been saved. Creates a new contact in iContact.
7
7
  def icontact_after_create
8
+ logger.debug "ActsAsIcontact creating contact for Rails ID: #{id}"
8
9
  c = ActsAsIcontact::Contact.new
9
- self.class.icontact_mappings.each do |rails, iContact|
10
- if (value = self.send(rails))
11
- ic = (iContact.to_s + '=').to_sym # Blah. This feels like it should be easier.
12
- c.send(ic, value)
13
- end
14
- end
15
- if c.save
16
- # Update with iContact fields returned
10
+ update_contact_from_rails_fields(c)
11
+ if attempt_contact_save(c)
17
12
  @icontact_in_progress = true
18
13
  self.class.icontact_mappings.each do |rails, iContact|
19
14
  unless (value = c.send(iContact)).blank?
@@ -22,20 +17,21 @@ module ActsAsIcontact
22
17
  end
23
18
  end
24
19
  self.save
20
+ # Subscribe the contact to any lists
21
+ self.class.icontact_default_lists.each do |list|
22
+ c.subscribe(list)
23
+ end
25
24
  @icontact_in_progress = false # Very primitive loop prevention
26
25
  end
27
26
  end
28
27
 
28
+ # Called after an existing record has been updated. Updates an existing contact in iContact if one
29
+ # can be found; otherwise creates a new one.
29
30
  def icontact_after_update
30
31
  unless @icontact_in_progress # Avoid callback loops
31
- c = find_contact_by_identity
32
- self.class.icontact_mappings.each do |rails, iContact|
33
- if (value = self.send(rails))
34
- ic = (iContact.to_s + '=').to_sym # Blah. This feels like it should be easier.
35
- c.send(ic, value)
36
- end
37
- end
38
- c.save
32
+ c = find_contact_by_identity or ActsAsIcontact::Contact.new
33
+ update_contact_from_rails_fields(c)
34
+ attempt_contact_save(c)
39
35
  # No need to update the record this time; iContact field changes don't have side effects
40
36
  end
41
37
  end
@@ -54,6 +50,31 @@ module ActsAsIcontact
54
50
  nil
55
51
  end
56
52
 
53
+ def update_contact_from_rails_fields(contact)
54
+ self.class.icontact_mappings.each do |rails, iContact|
55
+ if (value = self.send(rails))
56
+ ic = (iContact.to_s + '=').to_sym # Blah. This feels like it should be easier.
57
+ contact.send(ic, value)
58
+ end
59
+ end
60
+ end
61
+
62
+ def attempt_contact_save(contact)
63
+ if self.class.icontact_exception_on_failure
64
+ contact.save!
65
+ logger.info "ActsAsIcontact contact created. Rails ID: #{id}; iContact ID: #{contact.id}"
66
+ true
67
+ else
68
+ if contact.save
69
+ logger.info "ActsAsIcontact contact created. Rails ID: #{id}; iContact ID: #{contact.id}"
70
+ true
71
+ else
72
+ logger.warn "ActsAsIcontact contact creation failed! iContact says: #{contact.error}"
73
+ false
74
+ end
75
+ end
76
+ end
77
+
57
78
  end
58
79
  end
59
80
  end
@@ -0,0 +1,25 @@
1
+ module ActsAsIcontact
2
+ module Rails
3
+ module ClassMethods
4
+ module Lists
5
+
6
+ # The lists that each new contact will be subscribed to upon creation. Set by the :list and :lists
7
+ # options to acts_as_icontact.
8
+ def icontact_default_lists
9
+ @icontact_default_lists
10
+ end
11
+
12
+ protected
13
+
14
+ # Builds an array of any lists in the :list or :lists parameter.
15
+ def set_default_lists(list, lists)
16
+ # Combines :list and :lists parameters into one array
17
+ @icontact_default_lists = []
18
+ @icontact_default_lists << list if list
19
+ @icontact_default_lists += lists if lists
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -6,23 +6,30 @@ module ActsAsIcontact
6
6
  # The core macro for ActsAsIcontact's Rails integration. Establishes callbacks to keep Rails models in
7
7
  # sync with iContact. See the README for more on what it does.
8
8
  def acts_as_icontact(options = {})
9
+ logger.info "Initializing ActsAsIcontact module..."
10
+
9
11
  # Fail on exceptions?
10
12
  @icontact_exception_on_failure = options.delete(:exception_on_failure) || false
13
+ logger.info "ActsAsIcontact #{'NOT ' unless @icontact_exception_on_failure}returning exceptions on failure."
11
14
 
12
- # Combines :list and :lists parameters into one array
13
- @icontact_default_lists = []
14
- @icontact_default_lists << options.delete(:list) if options.has_key?(:list)
15
- @icontact_default_lists += options.delete(:lists) if options.has_key?(:lists)
15
+ # Set up lists for autosubscribe
16
+ set_default_lists(options.delete(:list), options.delete(:lists))
17
+ logger.info "ActsAsIcontact autosubscribe lists: #{icontact_default_lists.join}" unless icontact_default_lists.empty?
16
18
 
17
19
  # Set up field mappings
18
20
  set_mappings(options)
21
+ logger.info "ActsAsIcontact field mappings: #{icontact_mappings}"
19
22
 
20
23
  # If we haven't flaked out so far, we must be doing okay. Make magic happen.
21
24
  include ActsAsIcontact::Rails::Callbacks
22
25
  after_create :icontact_after_create
23
26
  after_update :icontact_after_update
27
+ logger.info "ActsAsIcontact callbacks created. Have Fun."
28
+ end
29
+
30
+ def icontact_exception_on_failure
31
+ @icontact_exception_on_failure
24
32
  end
25
-
26
33
  end
27
34
  end
28
35
  end
@@ -71,7 +71,7 @@ module ActsAsIcontact
71
71
  end
72
72
  parsed = JSON.parse(response)
73
73
  if parsed[result_type].empty?
74
- @errors = parsed["warnings"]
74
+ @errors = parsed["warnings"] || []
75
75
  false
76
76
  else
77
77
  @properties = (new_record? ? parsed[result_type].first : parsed[result_type])
data/spec/rails_spec.rb CHANGED
@@ -11,6 +11,7 @@ describe "Rails integration" do
11
11
  before(:all) do
12
12
  ActiveRecord::Base.establish_connection :adapter => :nulldb,
13
13
  :schema => File.dirname(__FILE__) + '/examples/schema.rb'
14
+
14
15
  end
15
16
 
16
17
  before(:each) do
@@ -40,11 +41,16 @@ describe "Rails integration" do
40
41
  def self.name
41
42
  "Person"
42
43
  end
44
+
43
45
  end
44
46
 
45
47
  end
46
48
 
47
49
  @class = @module.module_eval("Person")
50
+ # Stub out the logger
51
+ @class.stubs(:logger).returns(stub('Logger', :info => true, :warn => true, :error => true, :debug => true))
52
+ @class.any_instance.stubs(:logger).returns(stub('Logger', :info => true, :warn => true, :error => true, :debug => true))
53
+
48
54
  end
49
55
 
50
56
  it "allows the acts_as_icontact macro method" do
@@ -17,6 +17,11 @@ share_as :Callbacks do
17
17
  @person.save
18
18
  @person.icontact_id.should == 333444
19
19
  end
20
+
21
+ it "subscribes the Person to any lists" do
22
+ ActsAsIcontact::Contact.any_instance.expects(:subscribe).with("First Test").returns(true)
23
+ @person.save
24
+ end
20
25
  end
21
26
 
22
27
  context "for update" do
@@ -59,4 +59,4 @@ FakeWeb.register_uri(:get, "#{ic}/subscriptions?limit=500&listId=444444", :body
59
59
  FakeWeb.register_uri(:get, "#{ic}/subscriptions?limit=1&contactId=333444", :body => %q<{"subscriptions":[{"status":"normal","addDate":"2009-07-27T15:36:37-04:00","contactId":333444,"listId":444444, "subscriptionId":"444444_333333","confirmationMessageId":555666}]}>)
60
60
  FakeWeb.register_uri(:get, "#{ic}/subscriptions?limit=500&contactId=333444", :body => %q<{"subscriptions":[{"status":"normal","addDate":"2009-07-27T15:36:37-04:00","contactId":333444,"listId":444444, "subscriptionId":"444444_333444","confirmationMessageId":555666}]}>)
61
61
  FakeWeb.register_uri(:get, "#{ic}/subscriptions?limit=500&contactId=333333", :body => %q<{"subscriptions":[{"status":"normal","addDate":"2009-07-27T15:36:37-04:00","contactId":333333,"listId":444444, "subscriptionId":"444444_333333","confirmationMessageId":555666}]}>)
62
-
62
+ FakeWeb.register_uri(:post, "#{ic}/subscriptions", :body => %q<{"subscriptions":[{"status":"normal","addDate":"2009-07-27T15:36:37-04:00","contactId":333333,"listId":444444, "subscriptionId":"444444_333333","confirmationMessageId":555666}]}>)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_icontact
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Eley
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-29 00:00:00 -04:00
12
+ date: 2009-08-01 00:00:00 -04:00
13
13
  default_executable: icontact
14
14
  dependencies: []
15
15
 
@@ -42,6 +42,7 @@ files:
42
42
  - lib/acts_as_icontact/exceptions.rb
43
43
  - lib/acts_as_icontact/rails.rb
44
44
  - lib/acts_as_icontact/rails/callbacks.rb
45
+ - lib/acts_as_icontact/rails/lists.rb
45
46
  - lib/acts_as_icontact/rails/macro.rb
46
47
  - lib/acts_as_icontact/rails/mappings.rb
47
48
  - lib/acts_as_icontact/resource.rb