aweber 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -3
- data/README.textile +67 -20
- data/aweber.gemspec +1 -1
- data/lib/aweber.rb +1 -0
- data/lib/aweber/base.rb +19 -3
- data/lib/aweber/collection.rb +33 -9
- data/lib/aweber/resource.rb +20 -1
- data/lib/aweber/resources.rb +1 -0
- data/lib/aweber/resources/account.rb +2 -0
- data/lib/aweber/resources/broadcast.rb +2 -0
- data/lib/aweber/resources/click.rb +2 -0
- data/lib/aweber/resources/followup.rb +2 -0
- data/lib/aweber/resources/integration.rb +2 -0
- data/lib/aweber/resources/link.rb +2 -0
- data/lib/aweber/resources/list.rb +11 -53
- data/lib/aweber/resources/message.rb +2 -0
- data/lib/aweber/resources/open.rb +2 -0
- data/lib/aweber/resources/subscriber.rb +21 -3
- data/lib/aweber/resources/tracked_event.rb +2 -0
- data/lib/aweber/resources/web_form.rb +2 -0
- data/lib/aweber/resources/web_form_split_test.rb +2 -0
- data/lib/aweber/resources/web_form_split_test_component.rb +2 -0
- data/spec/collection_spec.rb +40 -1
- data/spec/fixtures/subscribers.json +2 -2
- data/spec/resource_spec.rb +10 -9
- data/spec/resources/account_spec.rb +2 -0
- data/spec/resources/campaign_spec.rb +2 -0
- data/spec/resources/click_spec.rb +2 -0
- data/spec/resources/integration_spec.rb +2 -0
- data/spec/resources/link_spec.rb +2 -0
- data/spec/resources/list_spec.rb +7 -3
- data/spec/resources/message_spec.rb +2 -0
- data/spec/resources/open_spec.rb +2 -0
- data/spec/resources/subscriber_spec.rb +18 -1
- data/spec/resources/tracked_event_spec.rb +2 -0
- data/spec/resources/web_form_spec.rb +2 -0
- data/spec/resources/web_form_split_test_component_spec.rb +2 -0
- data/spec/resources/web_form_split_test_spec.rb +2 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/support/fake_classes.rb +15 -0
- metadata +5 -5
- data/spec/fixtures/lists_page_2.json +0 -38
data/Gemfile.lock
CHANGED
data/README.textile
CHANGED
@@ -4,46 +4,93 @@ Official AWeber API gem.
|
|
4
4
|
|
5
5
|
h2. Installation
|
6
6
|
|
7
|
-
|
7
|
+
@gem install aweber@
|
8
8
|
|
9
|
-
h2.
|
9
|
+
h2. Getting Started
|
10
10
|
|
11
|
-
|
11
|
+
This guide assumes you have nothing previously setup to work with the AWeber API. It will walk through registering an account, creating an app and everything up to the point where you'll actually start working with data.
|
12
12
|
|
13
|
-
|
14
|
-
oauth = AWeber::OAuth.new("consumer_key", "consumer_secret")
|
13
|
+
If you don't want to bother with all the account setup stuff, you can look in the "examples":http://github.com/aweber/aweber-ruby/tree/master/examples/ directory for just example code.
|
15
14
|
|
16
|
-
|
17
|
-
oauth.request_token.authorize_url
|
15
|
+
*Requires a normal AWeber account (not a Labs account)*
|
18
16
|
|
19
|
-
|
20
|
-
oauth.authorize_with_verifier("verification_code")
|
17
|
+
h3. 1. Register an AWeber Labs Account
|
21
18
|
|
22
|
-
|
23
|
-
aweber = AWeber::Base.new(oauth)
|
24
|
-
aweber.account.lists[123456].name
|
19
|
+
Head to "http://labs.aweber.com":http://labs.aweber.com and sign up for a free AWeber Labs account. This is how you register apps and get OAuth keys.
|
25
20
|
|
26
|
-
|
21
|
+
h3. 2. Create an App
|
27
22
|
|
28
|
-
|
23
|
+
Once logged in, _Create a New App_. Once created, it will show you the Consumer Key and Secret for that app.
|
29
24
|
|
30
|
-
|
25
|
+
h3. 3. Write Some Code
|
31
26
|
|
32
|
-
|
33
|
-
account.lists[1] #=> #<AWeber::Resource::List>
|
27
|
+
h4. The OAuth Handler
|
34
28
|
|
35
|
-
|
29
|
+
bc. oauth = AWeber::OAuth.new('consumer_key', 'consumer_secret')
|
36
30
|
|
37
|
-
|
31
|
+
h4. Authorize an Account
|
32
|
+
|
33
|
+
Open, what the following outputs, in a browser and use your AWeber account credentials. This will give your app permission to work with your account's data:
|
34
|
+
|
35
|
+
bc. oauth.request_token.verification_url
|
36
|
+
|
37
|
+
h4. Verification Code
|
38
|
+
|
39
|
+
After you do the above step, it will output a "Verification Code". Copy this and verify your @oauth@ object:
|
40
|
+
|
41
|
+
bc. oauth.authorize_with_verifier('verification_code')
|
42
|
+
|
43
|
+
h4. Grab an AWeber::Base
|
44
|
+
|
45
|
+
bc. aweber = AWeber::Base.new(oauth)
|
46
|
+
|
47
|
+
This object is how you access data from your account. @aweber.account@ is your account object which is the stem for all other resources. Take a look at the next section, "Usage", to find out how to work with different resources.
|
48
|
+
|
49
|
+
h2. Usage
|
50
|
+
|
51
|
+
h3. Resource Traversal
|
52
|
+
|
53
|
+
Getting resource data is much like traversing associations in ActiveRecord. Everything starts with the @account@ object and goes from there:
|
54
|
+
|
55
|
+
bc.. aweber.account.lists #=> #<AWeber::Collection>
|
56
|
+
aweber.account.lists[123] #=> #<AWeber::Resource::List>
|
57
|
+
aweber.account.lists[123].name #=> "WhateverList"
|
58
|
+
|
59
|
+
h3. Collections
|
60
|
+
|
61
|
+
@aweber.account.lists@ in the example above would be a Collection. Collections act like a normal Hash. Resources of a collection are accessed normally, using @[]@ with the key being the ID of the resource.
|
62
|
+
|
63
|
+
h4. find_by_*
|
64
|
+
|
65
|
+
Collections also support ActiveRecord style @find_by_*@ methods:
|
66
|
+
|
67
|
+
bc. aweber.account.lists.find_by_name("testlist")
|
68
|
+
|
69
|
+
h3. Resources
|
70
|
+
|
71
|
+
Resources are elements of a Collection. A single list resource would be retrieved with:
|
72
|
+
|
73
|
+
bc. aweber.account.lists[1234]
|
74
|
+
|
75
|
+
h2. Updating Resources
|
76
|
+
|
77
|
+
Currently, subscribers are the only resource you can update via the API. Everything else is read only for the time being.
|
78
|
+
|
79
|
+
h3. Updateable Subscribers
|
38
80
|
|
39
81
|
* name
|
40
82
|
* misc_notes
|
41
|
-
* email
|
83
|
+
* email
|
42
84
|
* status
|
43
85
|
* last_followup_message_number_sent
|
44
86
|
* custom_fields (Hash of key/value pairs)
|
45
87
|
* ad_tracking
|
46
88
|
|
89
|
+
h3. Moving Subscriber From List to List
|
90
|
+
|
91
|
+
bc. new_list = aweber.account.lists[1234]
|
92
|
+
subscriber.list = new_list
|
93
|
+
|
47
94
|
h3. Example
|
48
95
|
|
49
96
|
bc. subscriber = account.lists[654321].subscribers[123456]
|
data/aweber.gemspec
CHANGED
data/lib/aweber.rb
CHANGED
data/lib/aweber/base.rb
CHANGED
@@ -19,9 +19,21 @@ module AWeber
|
|
19
19
|
oauth.delete(expand(uri))
|
20
20
|
end
|
21
21
|
|
22
|
+
def post(uri, body={})
|
23
|
+
oauth.post(uri, body)
|
24
|
+
end
|
25
|
+
|
22
26
|
def put(uri, body={})
|
23
27
|
oauth.put(uri, body.to_json, {"Content-Type" => "application/json"})
|
24
28
|
end
|
29
|
+
|
30
|
+
def path
|
31
|
+
""
|
32
|
+
end
|
33
|
+
|
34
|
+
def inspect
|
35
|
+
"#<AWeber::Base />"
|
36
|
+
end
|
25
37
|
|
26
38
|
private
|
27
39
|
|
@@ -34,7 +46,10 @@ module AWeber
|
|
34
46
|
end
|
35
47
|
|
36
48
|
def accounts
|
37
|
-
@accounts
|
49
|
+
return @accounts if @accounts
|
50
|
+
|
51
|
+
response = get("/accounts").merge(:parent => self)
|
52
|
+
@accounts = Collection.new(self, Resources::Account, response)
|
38
53
|
end
|
39
54
|
|
40
55
|
def expand(uri)
|
@@ -42,8 +57,9 @@ module AWeber
|
|
42
57
|
url = []
|
43
58
|
url << AWeber.api_endpoint
|
44
59
|
url << API_VERSION unless parsed.path.include? API_VERSION
|
45
|
-
url
|
46
|
-
|
60
|
+
url = [url.join("/"), parsed.path].join
|
61
|
+
url = [url, parsed.query].join("?") if parsed.query
|
62
|
+
url
|
47
63
|
end
|
48
64
|
|
49
65
|
def parse(response)
|
data/lib/aweber/collection.rb
CHANGED
@@ -27,11 +27,12 @@ module AWeber
|
|
27
27
|
class Collection < Resource
|
28
28
|
include Enumerable
|
29
29
|
|
30
|
-
|
31
|
-
attr_reader
|
32
|
-
attr_reader
|
33
|
-
attr_reader
|
34
|
-
attr_reader
|
30
|
+
attr_accessor :entries
|
31
|
+
attr_reader :next_collection_link
|
32
|
+
attr_reader :prev_collection_link
|
33
|
+
attr_reader :resource_type_link
|
34
|
+
attr_reader :total_size
|
35
|
+
attr_reader :parent
|
35
36
|
|
36
37
|
alias_method :size, :total_size
|
37
38
|
alias_method :length, :total_size
|
@@ -45,13 +46,26 @@ module AWeber
|
|
45
46
|
@client = client
|
46
47
|
@klass = klass
|
47
48
|
@entries = {}
|
48
|
-
create_entries(data["entries"])
|
49
|
+
create_entries(data["entries"]) if data.include?("entries")
|
49
50
|
@_entries = @entries.to_a
|
50
51
|
end
|
51
52
|
|
53
|
+
def search(params={})
|
54
|
+
params = params.map { |k,v| "#{h(k)}=#{h(v)}" }.join("&")
|
55
|
+
uri = "#{path}?ws.op=find&#{params}"
|
56
|
+
response = client.get(uri).merge(:parent => parent)
|
57
|
+
response["total_size"] ||= response["entries"].size
|
58
|
+
|
59
|
+
self.class.new(client, @klass, response)
|
60
|
+
end
|
61
|
+
|
52
62
|
def [](id)
|
53
63
|
@entries[id] ||= fetch_entry(id)
|
54
64
|
end
|
65
|
+
|
66
|
+
def []=(key, resource)
|
67
|
+
@entries[key] = resource
|
68
|
+
end
|
55
69
|
|
56
70
|
def each
|
57
71
|
(1..@total_size).each { |n| yield get_entry(n) }
|
@@ -60,11 +74,17 @@ module AWeber
|
|
60
74
|
def inspect
|
61
75
|
"#<AW::Collection(#{@klass.to_s}) size=\"#{size}\">"
|
62
76
|
end
|
77
|
+
|
78
|
+
def path
|
79
|
+
parent and parent.path.to_s + @klass.path.to_s or @klass.path.to_s
|
80
|
+
end
|
63
81
|
|
64
82
|
private
|
65
83
|
|
66
84
|
def create_entries(entries)
|
67
|
-
entries.each
|
85
|
+
entries.each do |entry|
|
86
|
+
@entries[entry["id"]] = @klass.new(client, entry.merge(:parent => self))
|
87
|
+
end
|
68
88
|
end
|
69
89
|
|
70
90
|
def get_entry(n)
|
@@ -73,7 +93,7 @@ module AWeber
|
|
73
93
|
end
|
74
94
|
|
75
95
|
def fetch_entry(id)
|
76
|
-
@klass.new(client, get(
|
96
|
+
@klass.new(client, get(path).merge(:parent => self))
|
77
97
|
end
|
78
98
|
|
79
99
|
def fetch_next_group(amount=20)
|
@@ -86,7 +106,7 @@ module AWeber
|
|
86
106
|
end
|
87
107
|
|
88
108
|
def base_path
|
89
|
-
URI.parse(@next_collection_link).path
|
109
|
+
URI.parse(@next_collection_link).path if @next_collection_link
|
90
110
|
end
|
91
111
|
|
92
112
|
def find_by(_attr, *args)
|
@@ -101,6 +121,10 @@ module AWeber
|
|
101
121
|
end
|
102
122
|
super
|
103
123
|
end
|
124
|
+
|
125
|
+
def h(str)
|
126
|
+
CGI.escape(str.to_s)
|
127
|
+
end
|
104
128
|
|
105
129
|
def client
|
106
130
|
@client
|
data/lib/aweber/resource.rb
CHANGED
@@ -16,6 +16,12 @@ module AWeber
|
|
16
16
|
|
17
17
|
class << self
|
18
18
|
attr_accessor :writable_attrs
|
19
|
+
attr_accessor :path
|
20
|
+
|
21
|
+
def basepath(path)
|
22
|
+
@path = path
|
23
|
+
end
|
24
|
+
|
19
25
|
# Works the same as +alias_method+, but for attributes created via
|
20
26
|
# +attr*+ methods.
|
21
27
|
#
|
@@ -79,7 +85,8 @@ module AWeber
|
|
79
85
|
|
80
86
|
resource_link = instance_variable_get("@#{name}_collection_link")
|
81
87
|
klass = AWeber.get_class(name)
|
82
|
-
|
88
|
+
response = client.get(resource_link).merge(:parent => self)
|
89
|
+
collection = Collection.new(client, klass, response)
|
83
90
|
instance_variable_set("@#{name}", collection)
|
84
91
|
end
|
85
92
|
end
|
@@ -93,6 +100,10 @@ module AWeber
|
|
93
100
|
alias_attribute :etag, :http_etag
|
94
101
|
alias_attribute :link, :self_link
|
95
102
|
alias_attribute :resource_type, :resource_type_link
|
103
|
+
|
104
|
+
def_delegators :client, :get, :post, :put
|
105
|
+
|
106
|
+
attr_reader :parent
|
96
107
|
|
97
108
|
def initialize(client, data={})
|
98
109
|
@client = client
|
@@ -120,6 +131,14 @@ module AWeber
|
|
120
131
|
def <=>(other)
|
121
132
|
@id <=> other.id
|
122
133
|
end
|
134
|
+
|
135
|
+
def path
|
136
|
+
parent and "#{parent.path}/#{id}" or id.to_s
|
137
|
+
end
|
138
|
+
|
139
|
+
def inspect
|
140
|
+
%(#<AWeber::Resources::#{self.class} id="#{id}" />)
|
141
|
+
end
|
123
142
|
|
124
143
|
private
|
125
144
|
|
data/lib/aweber/resources.rb
CHANGED
@@ -4,6 +4,7 @@ require "aweber/resources/click"
|
|
4
4
|
require "aweber/resources/followup"
|
5
5
|
require "aweber/resources/link"
|
6
6
|
require "aweber/resources/list"
|
7
|
+
require "aweber/resources/campaign"
|
7
8
|
require "aweber/resources/message"
|
8
9
|
require "aweber/resources/open"
|
9
10
|
require "aweber/resources/subscriber"
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module AWeber
|
2
2
|
module Resources
|
3
3
|
class List < Resource
|
4
|
+
basepath "/lists"
|
5
|
+
|
4
6
|
FOLLOWUP_TYPE_LINK = File.join(AWeber.api_url, "#followup_campaign")
|
5
7
|
BROADCAST_TYPE_LINK = File.join(AWeber.api_url, "#broadcast_campaign")
|
6
8
|
|
@@ -11,76 +13,32 @@ module AWeber
|
|
11
13
|
api_attr :web_forms_collection_link
|
12
14
|
api_attr :web_form_split_tests_collection_link
|
13
15
|
|
16
|
+
has_many :campaigns
|
14
17
|
has_many :subscribers
|
15
18
|
has_many :web_forms
|
16
19
|
has_many :web_form_split_tests
|
17
20
|
|
18
21
|
def initialize(*args)
|
19
22
|
super(*args)
|
20
|
-
@campaigns = {}
|
21
23
|
@followups = nil
|
22
24
|
@broadcasts = nil
|
23
25
|
end
|
24
26
|
|
25
|
-
def campaigns
|
26
|
-
return @campaigns unless @campaigns == {}
|
27
|
-
create_followups
|
28
|
-
create_broadcasts
|
29
|
-
populate_campaigns
|
30
|
-
@campaigns
|
31
|
-
end
|
32
|
-
|
33
27
|
def broadcasts
|
34
|
-
|
28
|
+
return @broadcasts if @broadcasts
|
29
|
+
|
30
|
+
@broadcasts = AWeber::Collection.new(client, Campaign, :parent => self)
|
31
|
+
@broadcasts.entries = Hash[campaigns.select { |id, c| c.is_broadcast? }]
|
35
32
|
@broadcasts
|
36
33
|
end
|
37
34
|
|
38
35
|
def followups
|
39
|
-
|
36
|
+
return @followups if @followups
|
37
|
+
|
38
|
+
@followups = AWeber::Collection.new(client, Campaign, :parent => self)
|
39
|
+
@followups.entries = Hash[campaigns.select { |id, c| c.is_followup? }]
|
40
40
|
@followups
|
41
41
|
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def create_followups
|
46
|
-
followups = _entries.select { |entry| is_followup? entry }
|
47
|
-
@followups = Collection.new(client, Followup, {
|
48
|
-
"entries" => followups,
|
49
|
-
"total_size" => followups.length,
|
50
|
-
"resource_type_link" => FOLLOWUP_TYPE_LINK
|
51
|
-
})
|
52
|
-
end
|
53
|
-
|
54
|
-
def create_broadcasts
|
55
|
-
broadcasts = _entries.select { |entry| is_broadcast? entry }
|
56
|
-
@broadcasts = Collection.new(client, Broadcast, {
|
57
|
-
"entries" => broadcasts,
|
58
|
-
"total_size" => broadcasts.length,
|
59
|
-
"resource_type_link" => BROADCAST_TYPE_LINK
|
60
|
-
})
|
61
|
-
end
|
62
|
-
|
63
|
-
def populate_campaigns
|
64
|
-
@followups.each { |id, followup| @campaigns[id] = followup }
|
65
|
-
@broadcasts.each { |id, broadcast| @campaigns[id] = broadcast }
|
66
|
-
end
|
67
|
-
|
68
|
-
def is_followup?(entry)
|
69
|
-
entry["resource_type_link"].split("#").last =~ /^followup/
|
70
|
-
end
|
71
|
-
|
72
|
-
def is_broadcast?(entry)
|
73
|
-
entry["resource_type_link"].split("#").last =~ /^broadcast/
|
74
|
-
end
|
75
|
-
|
76
|
-
def _campaigns
|
77
|
-
@_campaigns ||= client.get(@campaigns_collection_link)
|
78
|
-
end
|
79
|
-
|
80
|
-
def _entries
|
81
|
-
_campaigns["entries"]
|
82
|
-
end
|
83
|
-
|
84
42
|
end
|
85
43
|
end
|
86
44
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module AWeber
|
2
2
|
module Resources
|
3
3
|
class Subscriber < Resource
|
4
|
+
basepath "/subscribers"
|
5
|
+
|
4
6
|
api_attr :name, :writable => true
|
5
7
|
api_attr :misc_notes, :writable => true
|
6
8
|
api_attr :email, :writable => true
|
@@ -8,7 +10,7 @@ module AWeber
|
|
8
10
|
api_attr :custom_fields, :writable => true
|
9
11
|
api_attr :ad_tracking, :writable => true
|
10
12
|
api_attr :last_followup_message_number_sent, :writable => true
|
11
|
-
|
13
|
+
|
12
14
|
api_attr :ip_address
|
13
15
|
api_attr :is_verified
|
14
16
|
api_attr :last_followup_sent_at
|
@@ -18,11 +20,27 @@ module AWeber
|
|
18
20
|
api_attr :unsubscribed_at
|
19
21
|
api_attr :verified_at
|
20
22
|
api_attr :last_followup_sent_link
|
21
|
-
|
23
|
+
|
22
24
|
has_one :last_followup_sent
|
23
|
-
|
25
|
+
|
24
26
|
alias_attribute :is_verified?, :is_verified
|
25
27
|
alias_attribute :notes, :misc_notes
|
28
|
+
|
29
|
+
def list=(list)
|
30
|
+
client.post(self_link, {
|
31
|
+
"ws.op" => "move",
|
32
|
+
"list_link" => list.self_link
|
33
|
+
})
|
34
|
+
move_to(list)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def move_to(list)
|
40
|
+
old_list = self_link.match(%r[lists/(\d+)/])[1]
|
41
|
+
client.account.lists[old_list.to_i].subscribers[id] = nil
|
42
|
+
list.subscribers[id] = self
|
43
|
+
end
|
26
44
|
end
|
27
45
|
end
|
28
46
|
end
|
data/spec/collection_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe AWeber::Collection do
|
4
|
-
|
5
4
|
before :each do
|
6
5
|
@oauth = AWeber::OAuth.new("token", "secret")
|
7
6
|
@aweber = AWeber::Base.new(@oauth)
|
@@ -37,4 +36,44 @@ describe AWeber::Collection do
|
|
37
36
|
lists = @lists.find_by_resource_type_link("https://api.aweber.com/1.0/#list")
|
38
37
|
lists.length.should == 3
|
39
38
|
end
|
39
|
+
|
40
|
+
it "should have a path to its collection alone" do
|
41
|
+
@lists.path.should == "/lists"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should create resource with itself as a parent" do
|
45
|
+
collection = AWeber::Collection.new(@aweber, FakeParent)
|
46
|
+
@aweber.stub(:get).and_return({ :name => "Bob" })
|
47
|
+
collection[1].parent.should == collection
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should pass path request through its parent" do
|
51
|
+
root = AWeber::Collection.new(@aweber, FakeParent)
|
52
|
+
leaf = AWeber::Resource.new(@aweber, :id => 1, :parent => root)
|
53
|
+
branch = AWeber::Collection.new(@aweber, FakeChild, :parent => leaf)
|
54
|
+
leafy = AWeber::Resource.new(@aweber, :id => 2, :parent => branch)
|
55
|
+
leafy.path.should == "/parents/1/children/2"
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when searching" do
|
59
|
+
before do
|
60
|
+
@root = AWeber::Collection.new(@aweber, FakeParent)
|
61
|
+
@parent = AWeber::Resource.new(@aweber, :id => 1, :parent => @root)
|
62
|
+
@collection = AWeber::Collection.new(@aweber, FakeChild, :parent => @parent)
|
63
|
+
path = "/parents/1/children?ws.op=find&name=default123456"
|
64
|
+
@aweber.should_receive(:get).with(path).and_return({ "entries" => [] })
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should search the API" do
|
68
|
+
@collection.search(:name => "default123456")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should return a new collection" do
|
72
|
+
@collection.search(:name => "default123456").should be_an AWeber::Collection
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should return a new collection with the same parent" do
|
76
|
+
@collection.search(:name => "default123456").parent.should be @collection.parent
|
77
|
+
end
|
78
|
+
end
|
40
79
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"total_size":
|
2
|
+
"total_size": 4,
|
3
3
|
"start": 0,
|
4
4
|
"resource_type_link": "https://api.aweber.com/1.0/#subscriber-page-resource",
|
5
5
|
"entries": [{
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"verified_at": "2010-11-22 09:24:54",
|
14
14
|
"last_followup_sent_at": "2010-11-23 12:31:58.159050-05:00",
|
15
15
|
"subscription_url": "https://www.aweber.com/users/leads/add",
|
16
|
-
"self_link": "https://api.aweber.com/1.0/accounts/1/lists/
|
16
|
+
"self_link": "https://api.aweber.com/1.0/accounts/1/lists/1/subscribers/50723026",
|
17
17
|
"is_verified": true,
|
18
18
|
"resource_type_link": "https://api.aweber.com/1.0/#subscriber",
|
19
19
|
"id": 50723026
|
data/spec/resource_spec.rb
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
class FakeResource < AWeber::Resource
|
4
|
-
attr_accessor :foo
|
5
|
-
api_attr :name, :writable => true
|
6
|
-
alias_attribute :bar, :foo
|
7
|
-
has_many :lists
|
8
|
-
end
|
9
|
-
|
10
3
|
describe AWeber::Resource do
|
11
|
-
|
12
4
|
before :each do
|
13
5
|
@oauth = AWeber::OAuth.new("token", "secret")
|
14
6
|
@aweber = AWeber::Base.new(@oauth)
|
@@ -72,9 +64,18 @@ describe AWeber::Resource do
|
|
72
64
|
|
73
65
|
it "should send a JSON respresentation of the object on save" do
|
74
66
|
resource = FakeResource.new(@aweber)
|
75
|
-
@oauth.should_receive(:put).with(resource.link, "{\"name\":\"Bob\"}")
|
67
|
+
@oauth.should_receive(:put).with(resource.link, "{\"name\":\"Bob\"}", anything)
|
76
68
|
resource.name = "Bob"
|
77
69
|
resource.save
|
78
70
|
end
|
79
71
|
|
72
|
+
it "should return the id as path when no parent is supplied" do
|
73
|
+
FakeResource.new(@aweber, :id => 1).path.should == "1"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should have a parent" do
|
77
|
+
parent = AWeber::Collection.new(@aweber, FakeParent)
|
78
|
+
child = AWeber::Resource.new(@aweber, :id => 2, :parent => parent)
|
79
|
+
child.path.should == "/parents/2"
|
80
|
+
end
|
80
81
|
end
|
@@ -4,6 +4,8 @@ describe "AWeber::Resources::Campaign" do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].campaigns[50000047] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/campaigns/50000047" }
|
8
|
+
|
7
9
|
it { should respond_to :click_tracking_enabled }
|
8
10
|
it { should respond_to :content_type }
|
9
11
|
it { should respond_to :spam_assassin_score }
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::Click do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].campaigns[50000047].links[136340].clicks[129530] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/campaigns/50000047/links/136340/clicks/129530" }
|
8
|
+
|
7
9
|
it { should respond_to :event_time }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::Integration do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.integrations[8076] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/integrations/8076" }
|
8
|
+
|
7
9
|
it { should respond_to :http_etag }
|
8
10
|
it { should respond_to :id }
|
9
11
|
it { should respond_to :login }
|
data/spec/resources/link_spec.rb
CHANGED
@@ -4,6 +4,8 @@ describe AWeber::Resources::Link do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].campaigns[50000047].links[136340] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/campaigns/50000047/links/136340" }
|
8
|
+
|
7
9
|
it { should respond_to :clicks_collection_link }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
data/spec/resources/list_spec.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
2
|
|
3
|
-
describe AWeber::Resources::
|
3
|
+
describe AWeber::Resources::List do
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1" }
|
8
|
+
|
7
9
|
it { should respond_to :campaigns_collection_link }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
@@ -17,10 +19,12 @@ describe AWeber::Resources::Message do
|
|
17
19
|
it { should respond_to :followups }
|
18
20
|
|
19
21
|
it "should should have a collection of broadcasts" do
|
20
|
-
subject.broadcasts.
|
22
|
+
subject.broadcasts.should be_an AWeber::Collection
|
23
|
+
subject.broadcasts[1].should be_an AWeber::Resources::Campaign
|
21
24
|
end
|
22
25
|
|
23
26
|
it "should should have a collection of followups" do
|
24
|
-
subject.followups.
|
27
|
+
subject.followups.should be_an AWeber::Collection
|
28
|
+
subject.followups[1].should be_an AWeber::Resources::Campaign
|
25
29
|
end
|
26
30
|
end
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::Message do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].campaigns[50000047].messages[11839] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/campaigns/50000047/messages/11839" }
|
8
|
+
|
7
9
|
it { should respond_to :event_time }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
data/spec/resources/open_spec.rb
CHANGED
@@ -4,6 +4,8 @@ describe AWeber::Resources::Open do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].campaigns[50000047].messages[11839].opens[11721] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/campaigns/50000047/messages/11839/opens/11721" }
|
8
|
+
|
7
9
|
it { should respond_to :event_time }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
@@ -22,7 +22,9 @@ describe AWeber::Resources::Subscriber do
|
|
22
22
|
it { should respond_to :subscription_url }
|
23
23
|
it { should respond_to :unsubscribed_at }
|
24
24
|
it { should respond_to :verified_at }
|
25
|
-
|
25
|
+
|
26
|
+
its(:path) { should == "/accounts/1/lists/1/subscribers/50723026" }
|
27
|
+
|
26
28
|
its(:writable_attrs) { should include :name }
|
27
29
|
its(:writable_attrs) { should include :misc_notes }
|
28
30
|
its(:writable_attrs) { should include :email }
|
@@ -30,4 +32,19 @@ describe AWeber::Resources::Subscriber do
|
|
30
32
|
its(:writable_attrs) { should include :custom_fields }
|
31
33
|
its(:writable_attrs) { should include :ad_tracking }
|
32
34
|
its(:writable_attrs) { should include :last_followup_message_number_sent }
|
35
|
+
|
36
|
+
it "should move lists" do
|
37
|
+
list = "http://api.aweber.com/1.0/accounts/1/lists/987654"
|
38
|
+
json = { "ws.op" => "move", "list_link" => list }
|
39
|
+
|
40
|
+
aweber.account.lists[1550685].stub(:self_link).and_return(list)
|
41
|
+
oauth.should_receive(:post).with(subject.self_link, json)
|
42
|
+
subject.list = aweber.account.lists[1550685]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should update list when moving" do
|
46
|
+
new_list = aweber.account.lists[1550685]
|
47
|
+
subject.list = new_list
|
48
|
+
new_list.subscribers[subject.id].should == subject
|
49
|
+
end
|
33
50
|
end
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::TrackedEvent do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].campaigns[50000047].messages[11839].tracked_events[11839] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/campaigns/50000047/messages/11839/tracked_events/11839" }
|
8
|
+
|
7
9
|
it { should respond_to :event_time }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::WebForm do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].web_forms[1911952229] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/web_forms/1911952229" }
|
8
|
+
|
7
9
|
it { should respond_to :conversion_percentage }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::WebFormSplitTestComponent do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].web_form_split_tests[1242668124].components["612763163-513600765"] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/web_form_split_tests/1242668124/components/612763163-513600765" }
|
8
|
+
|
7
9
|
it { should respond_to :conversion_percentage }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
@@ -4,6 +4,8 @@ describe AWeber::Resources::WebFormSplitTest do
|
|
4
4
|
include BaseObjects
|
5
5
|
subject { aweber.account.lists[1].web_form_split_tests[1242668124] }
|
6
6
|
|
7
|
+
its(:path) { should == "/accounts/1/lists/1/web_form_split_tests/1242668124" }
|
8
|
+
|
7
9
|
it { should respond_to :components_collection_link }
|
8
10
|
it { should respond_to :http_etag }
|
9
11
|
it { should respond_to :id }
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
3
3
|
require "aweber"
|
4
|
+
require "support/fake_classes"
|
4
5
|
require "fakeweb"
|
5
6
|
require 'rspec'
|
6
7
|
|
@@ -49,4 +50,6 @@ route :get, %r[/accounts/\d+/lists/\d+/campaigns/[\d\w]+/links\?], fixture("link
|
|
49
50
|
route :get, %r[/accounts/\d+/lists/\d+/campaigns/[\d\w]+/links/\d+/clicks\?], fixture("clicks.json")
|
50
51
|
route :get, %r[/accounts/\d+/lists/\d+/campaigns/[\d\w]+/messages\?], fixture("messages.json")
|
51
52
|
route :get, %r[/accounts/\d+/lists/\d+/campaigns/[\d\w]+/messages/\d+/opens\?], fixture("opens.json")
|
52
|
-
route :get, %r[/accounts/\d+/lists/\d+/campaigns/[\d\w]+/messages/\d+/tracked_events\?], fixture("tracked_events.json")
|
53
|
+
route :get, %r[/accounts/\d+/lists/\d+/campaigns/[\d\w]+/messages/\d+/tracked_events\?], fixture("tracked_events.json")
|
54
|
+
|
55
|
+
route :post, %r[/accounts/\d+/lists/\d+/subscribers/\d+], "201 Created"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class FakeResource < AWeber::Resource
|
2
|
+
attr_accessor :foo
|
3
|
+
basepath "/fakes"
|
4
|
+
api_attr :name, :writable => true
|
5
|
+
alias_attribute :bar, :foo
|
6
|
+
has_many :lists
|
7
|
+
end
|
8
|
+
|
9
|
+
class FakeParent < AWeber::Resource
|
10
|
+
basepath "/parents"
|
11
|
+
end
|
12
|
+
|
13
|
+
class FakeChild < AWeber::Resource
|
14
|
+
basepath "/children"
|
15
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 1.
|
9
|
+
version: 1.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- AWeber Communications, Inc.
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-03-16 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -138,7 +138,6 @@ files:
|
|
138
138
|
- spec/fixtures/links.json
|
139
139
|
- spec/fixtures/list.json
|
140
140
|
- spec/fixtures/lists.json
|
141
|
-
- spec/fixtures/lists_page_2.json
|
142
141
|
- spec/fixtures/message.json
|
143
142
|
- spec/fixtures/messages.json
|
144
143
|
- spec/fixtures/open.json
|
@@ -169,6 +168,7 @@ files:
|
|
169
168
|
- spec/resources/web_form_split_test_component_spec.rb
|
170
169
|
- spec/resources/web_form_split_test_spec.rb
|
171
170
|
- spec/spec_helper.rb
|
171
|
+
- spec/support/fake_classes.rb
|
172
172
|
has_rdoc: true
|
173
173
|
homepage: http://github.com/aweber/AWeber-API-Ruby-Library
|
174
174
|
licenses: []
|
@@ -216,7 +216,6 @@ test_files:
|
|
216
216
|
- spec/fixtures/links.json
|
217
217
|
- spec/fixtures/list.json
|
218
218
|
- spec/fixtures/lists.json
|
219
|
-
- spec/fixtures/lists_page_2.json
|
220
219
|
- spec/fixtures/message.json
|
221
220
|
- spec/fixtures/messages.json
|
222
221
|
- spec/fixtures/open.json
|
@@ -247,3 +246,4 @@ test_files:
|
|
247
246
|
- spec/resources/web_form_split_test_component_spec.rb
|
248
247
|
- spec/resources/web_form_split_test_spec.rb
|
249
248
|
- spec/spec_helper.rb
|
249
|
+
- spec/support/fake_classes.rb
|
@@ -1,38 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"total_size": 6,
|
3
|
-
"start": 4,
|
4
|
-
"resource_type_link": "https://api.aweber.com/1.0/#list-page-resource",
|
5
|
-
"entries": [{
|
6
|
-
"campaigns_collection_link": "/accounts/1/lists/4565456/campaigns",
|
7
|
-
"name": "asdsa456464",
|
8
|
-
"web_form_split_tests_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/4565456/web_form_split_tests",
|
9
|
-
"subscribers_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/4565456/subscribers",
|
10
|
-
"id": 4565456,
|
11
|
-
"http_etag": "\"4ab41e60d14ea138a4522b3d2896942b7335c13c - ca5feee2b7fbb6febfca8af5541541ea960aaedb\"",
|
12
|
-
"self_link": "https://api.aweber.com/1.0/accounts/1/lists/4565456",
|
13
|
-
"resource_type_link": "https://api.aweber.com/1.0/#list",
|
14
|
-
"web_forms_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/4565456/web_forms"
|
15
|
-
},
|
16
|
-
{
|
17
|
-
"campaigns_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/8975612/campaigns",
|
18
|
-
"name": "default8975612",
|
19
|
-
"web_form_split_tests_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/8975612/web_form_split_tests",
|
20
|
-
"subscribers_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/8975612/subscribers",
|
21
|
-
"id": 8975612,
|
22
|
-
"http_etag": "\"685c00e3983add5e4efb5ca3bc7294e247f6e9fe - ca5feee2b7fbb6febfca8af5541541ea960aaedb\"",
|
23
|
-
"self_link": "https://api.aweber.com/1.0/accounts/1/lists/8975612",
|
24
|
-
"resource_type_link": "https://api.aweber.com/1.0/#list",
|
25
|
-
"web_forms_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/8975612/web_forms"
|
26
|
-
},
|
27
|
-
{
|
28
|
-
"campaigns_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/12357254/campaigns",
|
29
|
-
"name": "default123572549",
|
30
|
-
"web_form_split_tests_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/12357254/web_form_split_tests",
|
31
|
-
"subscribers_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/12357254/subscribers",
|
32
|
-
"id": 12357254,
|
33
|
-
"http_etag": "\"0aaa38a50287df08ccb74c7f13fca8679aab688a - ca5feee2b7fbb6febfca8af5541541ea960aaedb\"",
|
34
|
-
"self_link": "https://api.aweber.com/1.0/accounts/1/lists/12357254",
|
35
|
-
"resource_type_link": "https://api.aweber.com/1.0/#list",
|
36
|
-
"web_forms_collection_link": "https://api.aweber.com/1.0/accounts/1/lists/12357254/web_forms"
|
37
|
-
}]
|
38
|
-
}
|