SFEley-acts_as_icontact 0.4.0 → 0.4.2

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.4.0
1
+ 0.4.2
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{acts_as_icontact}
8
- s.version = "0.4.0"
8
+ s.version = "0.4.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Stephen Eley"]
12
- s.date = %q{2009-08-10}
12
+ s.date = %q{2009-08-11}
13
13
  s.default_executable = %q{icontact}
14
14
  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:
15
15
 
@@ -42,6 +42,7 @@ Gem::Specification.new do |s|
42
42
  "lib/acts_as_icontact/rails/lists.rb",
43
43
  "lib/acts_as_icontact/rails/macro.rb",
44
44
  "lib/acts_as_icontact/rails/mappings.rb",
45
+ "lib/acts_as_icontact/readonly.rb",
45
46
  "lib/acts_as_icontact/resource.rb",
46
47
  "lib/acts_as_icontact/resource_collection.rb",
47
48
  "lib/acts_as_icontact/resources/account.rb",
@@ -52,7 +53,14 @@ Gem::Specification.new do |s|
52
53
  "lib/acts_as_icontact/resources/custom_field.rb",
53
54
  "lib/acts_as_icontact/resources/list.rb",
54
55
  "lib/acts_as_icontact/resources/message.rb",
56
+ "lib/acts_as_icontact/resources/message_bounces.rb",
57
+ "lib/acts_as_icontact/resources/message_clicks.rb",
58
+ "lib/acts_as_icontact/resources/message_opens.rb",
59
+ "lib/acts_as_icontact/resources/message_statistics.rb",
60
+ "lib/acts_as_icontact/resources/segment.rb",
61
+ "lib/acts_as_icontact/resources/segment_criteria.rb",
55
62
  "lib/acts_as_icontact/resources/subscription.rb",
63
+ "lib/acts_as_icontact/subresource.rb",
56
64
  "rails/init.rb",
57
65
  "spec/config_spec.rb",
58
66
  "spec/connection_spec.rb",
@@ -70,6 +78,7 @@ Gem::Specification.new do |s|
70
78
  "spec/resources/custom_field_spec.rb",
71
79
  "spec/resources/list_spec.rb",
72
80
  "spec/resources/message_spec.rb",
81
+ "spec/resources/segment_spec.rb",
73
82
  "spec/resources/subscription_spec.rb",
74
83
  "spec/spec.opts",
75
84
  "spec/spec_helper.rb",
@@ -100,6 +109,7 @@ Gem::Specification.new do |s|
100
109
  "spec/resources/custom_field_spec.rb",
101
110
  "spec/resources/list_spec.rb",
102
111
  "spec/resources/message_spec.rb",
112
+ "spec/resources/segment_spec.rb",
103
113
  "spec/resources/subscription_spec.rb",
104
114
  "spec/spec_helper.rb",
105
115
  "spec/support/active_record/connection_adapters/nulldb_adapter.rb",
@@ -7,6 +7,8 @@ require 'acts_as_icontact/config'
7
7
  require 'acts_as_icontact/connection'
8
8
  require 'acts_as_icontact/resource'
9
9
  require 'acts_as_icontact/resource_collection'
10
+ require 'acts_as_icontact/subresource'
11
+ require 'acts_as_icontact/readonly'
10
12
 
11
13
  # Load all of our resource files
12
14
  Dir[File.join(File.dirname(__FILE__), 'acts_as_icontact', 'resources', '*.rb')].sort.each do |path|
@@ -0,0 +1,21 @@
1
+ module ActsAsIcontact
2
+
3
+ # Overrides methods to make a resource class read-only. Replaces property assignments and save methods with exceptions.
4
+ module ReadOnly
5
+
6
+ # Properties of this class are read-only.
7
+ def method_missing(method, *params)
8
+ raise ActsAsIcontact::ReadOnlyError, "#{self.class.readable_name} is read-only!" if method.to_s =~ /(.*)=$/
9
+ super
10
+ end
11
+
12
+ # Replace save methods with an exception
13
+ def cannot_save(*arguments)
14
+ raise ActsAsIcontact::ReadOnlyError, "Contact History is read-only!"
15
+ end
16
+ alias_method :save, :cannot_save
17
+ alias_method :save!, :cannot_save
18
+
19
+ end
20
+
21
+ end
@@ -25,7 +25,7 @@ module ActsAsIcontact
25
25
 
26
26
  # Returns a collection of ContactHistory resources for this contact. The usual iContact search options (limit, offset, search terms, etc.) can be passed.
27
27
  def history(options={})
28
- ActsAsIcontact::ContactHistory.scoped_find(self, options)
28
+ @history ||= ActsAsIcontact::ContactHistory.scoped_find(self, options)
29
29
  end
30
30
  end
31
31
  end
@@ -2,51 +2,11 @@ module ActsAsIcontact
2
2
  # The read-only list of actions attached to every Contact. Because of this intrinsic association, the usual #find methods don't
3
3
  # work; contact history _must_ be obtained using the individual contact's #history method.
4
4
  # Property updates and saving are also prohibited (returning a ReadOnlyError exception.)
5
- class ContactHistory < Resource
6
- attr_reader :parent
7
- alias_method :contact, :parent
8
-
9
- # Should only be called by ResourceCollection. Raises an exception if a parent object is not passed.
10
- def initialize(properties={})
11
- @parent = properties.delete(:parent) or raise ActsAsIcontact::ValidationError, "Contact History requires a Contact"
12
- super
13
- end
14
-
15
- # Properties of this class are read-only.
16
- def method_missing(method, *params)
17
- raise ActsAsIcontact::ReadOnlyError, "Contact History is read-only!" if method.to_s =~ /(.*)=$/
18
- super
19
- end
20
-
21
-
22
- # Returns the ContactHistory collection for the passed contact. Takes the usual iContact search parameters.
23
- def self.scoped_find(parent, options = {})
24
- query_options = default_options.merge(options)
25
- validate_options(query_options)
26
- uri_extension = uri_component + build_query(query_options)
27
- response = parent.connection[uri_extension].get
28
- parsed = JSON.parse(response)
29
- ResourceCollection.new(self, parsed, :parent => parent)
30
- end
31
-
32
-
33
- class <<self
34
- # Replace all search methods with an exception
35
- def cannot_query(*arguments)
36
- raise ActsAsIcontact::QueryError, "Contact History must be obtained using the contact.history method."
37
- end
38
- alias_method :all, :cannot_query
39
- alias_method :first, :cannot_query
40
- alias_method :find, :cannot_query
41
- end
42
-
43
- # Replace save methods with an exception
44
- def cannot_save(*arguments)
45
- raise ActsAsIcontact::ReadOnlyError, "Contact History is read-only!"
46
- end
47
- alias_method :save, :cannot_save
48
- alias_method :save!, :cannot_save
5
+ class ContactHistory < Subresource
6
+ include ReadOnly
49
7
 
8
+ alias_method :contact, :parent
9
+
50
10
  protected
51
11
  # An oddball resource class; iContact's URL for it is 'actions', not 'contact_histories'.
52
12
  def self.resource_name
@@ -24,5 +24,27 @@ module ActsAsIcontact
24
24
  nil
25
25
  end
26
26
  end
27
+
28
+ # Returns a collection of MessageBounces resources for this message. The usual iContact search options (limit, offset, search terms, etc.) can be passed.
29
+ def bounces(options={})
30
+ @bounces ||= ActsAsIcontact::MessageBounces.scoped_find(self, options)
31
+ end
32
+
33
+ # Returns a collection of MessageClicks resources for this message. The usual iContact search options (limit, offset, search terms, etc.) can be passed.
34
+ def clicks(options={})
35
+ @clicks ||= ActsAsIcontact::MessageClicks.scoped_find(self, options)
36
+ end
37
+
38
+ # Returns a collection of MessageOpens resources for this message. The usual iContact search options (limit, offset, search terms, etc.) can be passed.
39
+ def opens(options={})
40
+ @opens ||= ActsAsIcontact::MessageOpens.scoped_find(self, options)
41
+ end
42
+
43
+ # Returns the Statistics record for this contact. This is a singleton resource and does not accept find, etc.
44
+ def statistics(options={})
45
+ @statistics ||= ActsAsIcontact::MessageStatistics.scoped_first(self)
46
+ end
47
+
48
+
27
49
  end
28
50
  end
@@ -0,0 +1,16 @@
1
+ module ActsAsIcontact
2
+ # The read-only list of bounces attached to every Message. Because of this intrinsic association, the usual #find methods don't
3
+ # work; this collectin _must_ be obtained using the individual message's #bounces method.
4
+ # Property updates and saving are also prohibited (returning a ReadOnlyError exception.)
5
+ class MessageBounces < Subresource
6
+ include ReadOnly
7
+
8
+ alias_method :message, :parent
9
+
10
+ # Retrieves the contact pointed to by this message record's contactId.
11
+ def contact
12
+ @contact ||= ActsAsIcontact::Contact.find(contactId.to_i) if contactId.to_i > 0
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module ActsAsIcontact
2
+ # The read-only list of clicks attached to every Message. Because of this intrinsic association, the usual #find methods don't
3
+ # work; this collection _must_ be obtained using the individual message's #clicks method.
4
+ # Property updates and saving are also prohibited (returning a ReadOnlyError exception.)
5
+ class MessageClicks < Subresource
6
+ include ReadOnly
7
+
8
+ alias_method :message, :parent
9
+
10
+ # Retrieves the contact pointed to by this message record's contactId.
11
+ def contact
12
+ @contact ||= ActsAsIcontact::Contact.find(contactId.to_i) if contactId.to_i > 0
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module ActsAsIcontact
2
+ # The read-only list of opens attached to every Message. Because of this intrinsic association, the usual #find methods don't
3
+ # work; this collection _must_ be obtained using the individual message's #opens method.
4
+ # Property updates and saving are also prohibited (returning a ReadOnlyError exception.)
5
+ class MessageOpens < Subresource
6
+ include ReadOnly
7
+
8
+ alias_method :message, :parent
9
+
10
+ # Retrieves the contact pointed to by this message record's contactId.
11
+ def contact
12
+ @contact ||= ActsAsIcontact::Contact.find(contactId.to_i) if contactId.to_i > 0
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module ActsAsIcontact
2
+ # The read-only set of statistics attached to every Message. Because of this intrinsic association, the usual #find methods don't
3
+ # work; this resource _must_ be obtained using the individual message's #statistics method. Note also that
4
+ # this is a singleton resource, _not_ a collection.
5
+ # Property updates and saving are also prohibited (returning a ReadOnlyError exception.)
6
+ class MessageStatistics < Subresource
7
+ include ReadOnly
8
+
9
+ alias_method :message, :parent
10
+
11
+ # This one's a little weird; remove scoped_find, and add scoped_first to retrieve just one record
12
+ class <<self
13
+ alias_method :scoped_find, :cannot_query
14
+ end
15
+
16
+ # Returns just one resource corresponding to the parent Message
17
+ def self.scoped_first(parent)
18
+ response = parent.connection[collection_name].get
19
+ parsed = JSON.parse(response)
20
+ self.new(parsed[collection_name].merge(:parent => parent))
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ module ActsAsIcontact
2
+ class Segment < Resource
3
+
4
+ # Name and listId are required
5
+ def self.required_on_create
6
+ super << 'listId' << 'name'
7
+ end
8
+
9
+ # Name and listId are required
10
+ def self.required_on_update
11
+ super << 'name'
12
+ end
13
+
14
+ # Cannot pass listId when updating
15
+ def self.never_on_update
16
+ ['listId']
17
+ end
18
+
19
+ # Searches on segment name.
20
+ def self.find_by_string(value)
21
+ first(:name => value)
22
+ end
23
+
24
+
25
+ # Returns the list to which this segment is bound.
26
+ def list
27
+ @list ||= ActsAsIcontact::List.find(listId.to_i) if (listId.to_i) > 0
28
+ end
29
+
30
+ # Returns a collection of SegmentCriteria resources for this segment. The usual iContact search options (limit, offset, search terms, etc.) can be passed.
31
+ def criteria(options={})
32
+ @criteria ||= ActsAsIcontact::SegmentCriteria.scoped_find(self, options)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ module ActsAsIcontact
2
+ # The list of criteria attached to every Segment. Because of this intrinsic association, the usual #find methods don't
3
+ # work; this collection _must_ be obtained using the individual segment's #criteria method.
4
+ # Unlike other subresources, SegmentCriteria can be created, modified, and saved.
5
+ class SegmentCriteria < Subresource
6
+
7
+ alias_method :segment, :parent
8
+
9
+ # fieldName, operator, and values are required
10
+ def self.required_on_create
11
+ super + %w(fieldName operator values)
12
+ end
13
+
14
+ # Looks like 'criteria' is just a bit too strange for ActiveSupport to know singulars and plurals...
15
+ def self.resource_name # :nodoc:
16
+ "criterion"
17
+ end
18
+
19
+ def self.collection_name # :nodoc:
20
+ "criteria"
21
+ end
22
+
23
+ # Uses criterionId as its ID.
24
+ def id
25
+ properties["criterionId"]
26
+ end
27
+
28
+
29
+ # operator must be one: eq, lt, lte, gt, gte, bet, notcontains, contains
30
+ def validate_on_save(fields)
31
+ operators = %w(eq lt lte gt gte bet notcontains contains)
32
+ raise ActsAsIcontact::ValidationError, "operator must be one of: " + operators.join(', ') unless operators.include?(fields["operator"])
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,54 @@
1
+ module ActsAsIcontact
2
+ # A read-only resource placed beneath the URL of another resource and containing secondary information.
3
+ # Because of this intrinsic association, the usual #find methods don't
4
+ # work; subresources _must_ be obtained using an association method from the parent resource.
5
+ # Property updates and saving are also prohibited (returning a ReadOnlyError exception.)
6
+ class Subresource < Resource
7
+ attr_reader :parent
8
+
9
+ # Should only be called by ResourceCollection. Raises an exception if a parent object is not passed.
10
+ def initialize(properties={})
11
+ @parent = properties.delete(:parent) or raise ActsAsIcontact::ValidationError, "#{self.class.readable_name} requires a #{self.class.readable_parent}"
12
+ super
13
+ end
14
+
15
+
16
+ # Returns the ContactHistory collection for the passed contact. Takes the usual iContact search parameters.
17
+ def self.scoped_find(parent, options = {})
18
+ query_options = default_options.merge(options)
19
+ validate_options(query_options)
20
+ uri_extension = uri_component + build_query(query_options)
21
+ response = parent.connection[uri_extension].get
22
+ parsed = JSON.parse(response)
23
+ ResourceCollection.new(self, parsed, :parent => parent)
24
+ end
25
+
26
+
27
+ class <<self
28
+ # Replace all search methods with an exception
29
+ def cannot_query(*arguments)
30
+ raise ActsAsIcontact::QueryError, "#{readable_name} must be obtained using the #{readable_parent}\##{parent_method} method."
31
+ end
32
+ alias_method :all, :cannot_query
33
+ alias_method :first, :cannot_query
34
+ alias_method :find, :cannot_query
35
+ end
36
+
37
+ protected
38
+ def self.resource_name
39
+ parent_method.singularize
40
+ end
41
+
42
+ def self.readable_name
43
+ name.demodulize.titleize
44
+ end
45
+
46
+ def self.readable_parent
47
+ readable_name.split[0]
48
+ end
49
+
50
+ def self.parent_method
51
+ readable_name.split[1].downcase
52
+ end
53
+ end
54
+ end
@@ -21,11 +21,6 @@ describe ActsAsIcontact, "account method" do
21
21
  ActsAsIcontact.account.should be_a_kind_of(RestClient::Resource)
22
22
  end
23
23
 
24
- it "builds upon the 'connection' object" do
25
- ActsAsIcontact.expects(:connection).returns(ActsAsIcontact.instance_variable_get(:@connection))
26
- ActsAsIcontact.account.should_not be_nil
27
- end
28
-
29
24
  it "can be cleared with the reset_account! method" do
30
25
  ActsAsIcontact.reset_account!
31
26
  ActsAsIcontact.instance_variable_get(:@account).should be_nil
@@ -20,12 +20,7 @@ describe ActsAsIcontact, "clientfolder method" do
20
20
  it "returns a RestClient resource" do
21
21
  ActsAsIcontact.clientfolder.should be_a_kind_of(RestClient::Resource)
22
22
  end
23
-
24
- it "builds upon the 'account' object" do
25
- ActsAsIcontact.expects(:account).returns(ActsAsIcontact.instance_variable_get(:@account))
26
- ActsAsIcontact.clientfolder.should_not be_nil
27
- end
28
-
23
+
29
24
  it "can be cleared with the reset_account! method" do
30
25
  ActsAsIcontact.reset_clientfolder!
31
26
  ActsAsIcontact.instance_variable_get(:@clientfolder).should be_nil
@@ -19,15 +19,15 @@ describe ActsAsIcontact::ContactHistory do
19
19
  end
20
20
 
21
21
  it "does not allow .find" do
22
- lambda{ActsAsIcontact::ContactHistory.find(:all)}.should raise_error(ActsAsIcontact::QueryError, "Contact History must be obtained using the contact.history method.")
22
+ lambda{ActsAsIcontact::ContactHistory.find(:all)}.should raise_error(ActsAsIcontact::QueryError, "Contact History must be obtained using the Contact#history method.")
23
23
  end
24
24
 
25
25
  it "does not allow .first" do
26
- lambda{ActsAsIcontact::ContactHistory.first}.should raise_error(ActsAsIcontact::QueryError, "Contact History must be obtained using the contact.history method.")
26
+ lambda{ActsAsIcontact::ContactHistory.first}.should raise_error(ActsAsIcontact::QueryError, "Contact History must be obtained using the Contact#history method.")
27
27
  end
28
28
 
29
29
  it "does not allow .all" do
30
- lambda{ActsAsIcontact::ContactHistory.all}.should raise_error(ActsAsIcontact::QueryError, "Contact History must be obtained using the contact.history method.")
30
+ lambda{ActsAsIcontact::ContactHistory.all}.should raise_error(ActsAsIcontact::QueryError, "Contact History must be obtained using the Contact#history method.")
31
31
  end
32
32
 
33
33
  it "requires a contactId" do
@@ -25,6 +25,23 @@ describe ActsAsIcontact::Message do
25
25
  it "knows which campaign it has (if any)" do
26
26
  @message.campaign.name.should == "Test Campaign"
27
27
  end
28
+
29
+ it "knows its bounces" do
30
+ @message.bounces.first.contact.email.should == "john@example.org"
31
+ end
32
+
33
+ it "knows its clicks" do
34
+ @message.clicks.first.clickLink.should == "http://www.yahoo.com"
35
+ end
36
+
37
+ it "knows its opens" do
38
+ @message.opens.first.contact.email.should == "john@example.org"
39
+ end
40
+
41
+ it "knows its statistics" do
42
+ @message.statistics.delivered.should == 3
43
+ end
44
+
28
45
  end
29
46
 
30
47
  end
@@ -0,0 +1,31 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe ActsAsIcontact::Segment do
4
+
5
+
6
+ it "requires a listId" do
7
+ s = ActsAsIcontact::Segment.new
8
+ lambda{s.save}.should raise_error(ActsAsIcontact::ValidationError, /listId/)
9
+ end
10
+
11
+ it "requires a name" do
12
+ s = ActsAsIcontact::Segment.new
13
+ lambda{s.save}.should raise_error(ActsAsIcontact::ValidationError, /name/)
14
+ end
15
+
16
+ context "associations" do
17
+ # We have _one_ really good segment set up here
18
+ before(:each) do
19
+ @segment = ActsAsIcontact::Segment.find("People Named John")
20
+ end
21
+
22
+ it "knows its list" do
23
+ @segment.list.name.should == "First Test"
24
+ end
25
+
26
+ it "knows its criteria" do
27
+ @segment.criteria.first.fieldName.should == "firstName"
28
+ end
29
+ end
30
+
31
+ end
@@ -53,6 +53,19 @@ FakeWeb.register_uri(:get, "#{ic}/messages?limit=500&campaignId=777777&messageTy
53
53
  #### Test message for associations originating from Message spec
54
54
  FakeWeb.register_uri(:get, "#{ic}/messages?limit=1&subject=Test%20Message", :body => %q<{"messages":[{"messageId":"666666","subject":"Test Message","messageType":"normal","textBody":"Hi there!\nThis is just a test.","htmlBody":"<p><b>Hi there!</b></p><p>This is just a <i>test.</i></p>","createDate":"20090725 14:53:33","campaignId":"777777"}]}>)
55
55
 
56
+ # Message Bounces
57
+ FakeWeb.register_uri(:get, "#{ic}/messages/666666/bounces?limit=500", :body => %q<{"bounces":[{"contactId":"333333","bounceTime":"2008-04-15T12:05:00-04:00"},{"contactId":"333333","bounceTime":"2008-04-16T12:05:00-04:00"}],"total":2,"limit":500,"offset":0}>)
58
+
59
+ # Message Clicks
60
+ FakeWeb.register_uri(:get, "#{ic}/messages/666666/clicks?limit=500", :body => %q<{"clicks":[{"contactId":"333333","clickTime":"2008-04-17T12:07:00-04:00","clickLink":"http://www.yahoo.com"},{"contactId":"333333","clickTime":"2008-04-17T12:07:30-04:00","clickLink":"http://google.com"}],"total":2,"limit":500,"offset":0}>)
61
+
62
+ # Message Opens
63
+ FakeWeb.register_uri(:get, "#{ic}/messages/666666/opens?limit=500", :body => %q<{"opens":[{"contactId":"333333","openTime":"2008-04-17T12:06:00-04:00"},{"contactId":"333444","bounceTime":"2008-04-17T12:06:15-04:00"}],"total":2,"limit":500,"offset":0}>)
64
+
65
+ # Message Statistics
66
+ FakeWeb.register_uri(:get, "#{ic}/messages/666666/statistics", :body => %q<{"statistics":{"bounces":2,"delivered":3,"unsubscribes":0,"opens":{"unique":2,"total":2},"clicks":{"unique":2,"total":2},"forwards":0,"comments":0,"complaints":0}}>)
67
+
68
+
56
69
  # CustomField
57
70
  FakeWeb.register_uri(:get, "#{ic}/customfields?limit=500", :body => %q<{"customfields":[{"privateName":"test_field","publicName":"Test Field","displayToUser":"0","fieldType":"text"},{"privateName":"custom_field","publicName":"This is for the Rails integration specs","displayToUser":1,"fieldType":"text"}],"total":2}>)
58
71
  FakeWeb.register_uri(:get, "#{ic}/customfields/test_field", :body => %q<{"customfield":{"privateName":"test_field","publicName":"Test Field","displayToUser":"0","fieldType":"text"}}>)
@@ -69,4 +82,10 @@ FakeWeb.register_uri(:post, "#{ic}/subscriptions", :body => %q<{"subscriptions":
69
82
 
70
83
  # Campaign
71
84
  FakeWeb.register_uri(:get, "#{ic}/campaigns?limit=1", :body => %q<{"campaigns":[{"campaignId":"777777","name":"Test Campaign","fromName":"Bob Smith","fromEmail":"bob@example.org","forwardToFriend":0,"subscriptionManagement":1,"clickTrackMode":1,"useAccountAddress":0,"archiveByDefault":0,"description":""}],"count":1}>)
72
- FakeWeb.register_uri(:get, "#{ic}/campaigns/777777", :body => %q<{"campaign":{"campaignId":"777777","name":"Test Campaign","fromName":"Bob Smith","fromEmail":"bob@example.org","forwardToFriend":0,"subscriptionManagement":1,"clickTrackMode":1,"useAccountAddress":0,"archiveByDefault":0,"description":""}}>)
85
+ FakeWeb.register_uri(:get, "#{ic}/campaigns/777777", :body => %q<{"campaign":{"campaignId":"777777","name":"Test Campaign","fromName":"Bob Smith","fromEmail":"bob@example.org","forwardToFriend":0,"subscriptionManagement":1,"clickTrackMode":1,"useAccountAddress":0,"archiveByDefault":0,"description":""}}>)
86
+
87
+ # Segment
88
+ FakeWeb.register_uri(:get, "#{ic}/segments?limit=1&name=People%20Named%20John", :body => %q<{"segments":[{"segmentId":"888888","listId":"444444","name":"People Named John","description":"All the people named John"}],"total":1,"limit":1,"offset":1}>)
89
+
90
+ # Segment Criteria
91
+ FakeWeb.register_uri(:get, "#{ic}/segments/888888/criteria?limit=500", :body => %q<{"criteria":[{"criterionId":0,"fieldName":"firstName","operator":"eq","values":["John"]}]}>)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: SFEley-acts_as_icontact
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
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-08-10 00:00:00 -07:00
12
+ date: 2009-08-11 00:00:00 -07:00
13
13
  default_executable: icontact
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -101,6 +101,7 @@ files:
101
101
  - lib/acts_as_icontact/rails/lists.rb
102
102
  - lib/acts_as_icontact/rails/macro.rb
103
103
  - lib/acts_as_icontact/rails/mappings.rb
104
+ - lib/acts_as_icontact/readonly.rb
104
105
  - lib/acts_as_icontact/resource.rb
105
106
  - lib/acts_as_icontact/resource_collection.rb
106
107
  - lib/acts_as_icontact/resources/account.rb
@@ -111,7 +112,14 @@ files:
111
112
  - lib/acts_as_icontact/resources/custom_field.rb
112
113
  - lib/acts_as_icontact/resources/list.rb
113
114
  - lib/acts_as_icontact/resources/message.rb
115
+ - lib/acts_as_icontact/resources/message_bounces.rb
116
+ - lib/acts_as_icontact/resources/message_clicks.rb
117
+ - lib/acts_as_icontact/resources/message_opens.rb
118
+ - lib/acts_as_icontact/resources/message_statistics.rb
119
+ - lib/acts_as_icontact/resources/segment.rb
120
+ - lib/acts_as_icontact/resources/segment_criteria.rb
114
121
  - lib/acts_as_icontact/resources/subscription.rb
122
+ - lib/acts_as_icontact/subresource.rb
115
123
  - rails/init.rb
116
124
  - spec/config_spec.rb
117
125
  - spec/connection_spec.rb
@@ -129,6 +137,7 @@ files:
129
137
  - spec/resources/custom_field_spec.rb
130
138
  - spec/resources/list_spec.rb
131
139
  - spec/resources/message_spec.rb
140
+ - spec/resources/segment_spec.rb
132
141
  - spec/resources/subscription_spec.rb
133
142
  - spec/spec.opts
134
143
  - spec/spec_helper.rb
@@ -180,6 +189,7 @@ test_files:
180
189
  - spec/resources/custom_field_spec.rb
181
190
  - spec/resources/list_spec.rb
182
191
  - spec/resources/message_spec.rb
192
+ - spec/resources/segment_spec.rb
183
193
  - spec/resources/subscription_spec.rb
184
194
  - spec/spec_helper.rb
185
195
  - spec/support/active_record/connection_adapters/nulldb_adapter.rb