monkey_wrench 0.1.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.
Files changed (39) hide show
  1. data/README.mdown +18 -0
  2. data/Rakefile +11 -0
  3. data/lib/monkey_wrench.rb +10 -0
  4. data/lib/monkey_wrench/array.rb +9 -0
  5. data/lib/monkey_wrench/base.rb +67 -0
  6. data/lib/monkey_wrench/campaign.rb +0 -0
  7. data/lib/monkey_wrench/campaign_aim.rb +0 -0
  8. data/lib/monkey_wrench/campaign_stats.rb +0 -0
  9. data/lib/monkey_wrench/config.rb +34 -0
  10. data/lib/monkey_wrench/error.rb +104 -0
  11. data/lib/monkey_wrench/hash.rb +69 -0
  12. data/lib/monkey_wrench/helper.rb +0 -0
  13. data/lib/monkey_wrench/list.rb +309 -0
  14. data/lib/monkey_wrench/member.rb +33 -0
  15. data/lib/monkey_wrench/security.rb +0 -0
  16. data/test/fixtures/api_fail.json +1 -0
  17. data/test/fixtures/campaigns_success.json +24 -0
  18. data/test/fixtures/listBatchSubscribe10_success.json +1 -0
  19. data/test/fixtures/listBatchSubscribe5_success.json +1 -0
  20. data/test/fixtures/listBatchSubscribe_success.json +1 -0
  21. data/test/fixtures/listBatchSubscribe_with_error_success.json +1 -0
  22. data/test/fixtures/listBatchUnsubscribe_success.json +1 -0
  23. data/test/fixtures/listMemberInfo_fail.json +1 -0
  24. data/test/fixtures/listMemberInfo_success.json +1 -0
  25. data/test/fixtures/listMembers_none_success.json +1 -0
  26. data/test/fixtures/listMembers_success.json +8 -0
  27. data/test/fixtures/listSubscribe_success.json +1 -0
  28. data/test/fixtures/listUnsubscribe_success.json +0 -0
  29. data/test/fixtures/listUpdateMember_success.json +1 -0
  30. data/test/fixtures/lists_success.json +14 -0
  31. data/test/monkey_wrench/campaign_aim_test.rb +0 -0
  32. data/test/monkey_wrench/campaign_stats_test.rb +0 -0
  33. data/test/monkey_wrench/campaign_test.rb +0 -0
  34. data/test/monkey_wrench/hash_test.rb +47 -0
  35. data/test/monkey_wrench/helper_test.rb +0 -0
  36. data/test/monkey_wrench/list_test.rb +310 -0
  37. data/test/monkey_wrench/security_test.rb +0 -0
  38. data/test/test_helper.rb +67 -0
  39. metadata +134 -0
@@ -0,0 +1,33 @@
1
+ module MonkeyWrench
2
+ class Member
3
+ def initialize(list_member_info)
4
+ @list_member_info = list_member_info
5
+ end
6
+
7
+ def interests
8
+ if @list_member_info['merges']['INTERESTS']
9
+ @list_member_info['merges']['INTERESTS'].split(', ')
10
+ end
11
+ end
12
+
13
+ def method_missing(method, *args)
14
+ if responds_to?(method)
15
+ key_name = method.to_s
16
+ @list_member_info[key_name] || @list_member_info['merges'][key_name] || @list_member_info['merges'][key_name.upcase]
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def responds_to?(method)
23
+ key_name = method.to_s
24
+ @list_member_info.has_key?(key_name) ||
25
+ @list_member_info['merges'].has_key?(key_name) ||
26
+ @list_member_info['merges'].has_key?(key_name.upcase)
27
+ end
28
+
29
+ def ==(other_member)
30
+ !@list_member_info.keys.detect{|key| send(key) != other_member.send(key)}
31
+ end
32
+ end
33
+ end
File without changes
@@ -0,0 +1 @@
1
+ {"error":"Invalid Mailchimp API Key: foada . You are accessing the wrong datacenter - your client library may not properly support our datacenter mapping scheme.","code":104}
@@ -0,0 +1,24 @@
1
+ [{
2
+ "id":"ed7838c182",
3
+ "web_id":534402,
4
+ "list_id":null,
5
+ "folder_id":0,
6
+ "title":"Untitled",
7
+ "type":"regular",
8
+ "create_time":"2009-10-06 16:18:52",
9
+ "send_time":null,
10
+ "status":"save","from_name":null,
11
+ "from_email":null,
12
+ "subject":null,
13
+ "to_email":null,
14
+ "archive_url":"http:\/\/eepurl.com\/d2JN",
15
+ "emails_sent":0,
16
+ "inline_css":"N",
17
+ "analytics":"N",
18
+ "analytics_tag":"",
19
+ "track_clicks_text":false,
20
+ "track_clicks_html":true,
21
+ "track_opens":true,
22
+ "segment_opts":[]
23
+ }
24
+ ]
@@ -0,0 +1 @@
1
+ {"success_count":10,"error_count":0,"errors":[]}
@@ -0,0 +1 @@
1
+ {"success_count":5,"error_count":0,"errors":[]}
@@ -0,0 +1 @@
1
+ {"success_count":1,"error_count":0,"errors":[]}
@@ -0,0 +1 @@
1
+ {"success_count":1,"error_count":1,"errors":[{"code":502,"message":"Invalid Email Address: bademail@badmail","row":{"EMAIL_TYPE":"html","EMAIL":"bademail@badmail"}}]}
@@ -0,0 +1 @@
1
+ {"success_count":1,"error_count":0,"errors":[]}
@@ -0,0 +1 @@
1
+ {"error":"There is no record of \"asdiojasdojas@foo.com\" in the database","code":232}
@@ -0,0 +1 @@
1
+ {"id":"a58cbece83","email":"david@email.com","email_type":"html","ip_opt":"66.132.220.59","ip_signup":null,"member_rating":4,"merges":{"EMAIL":"david@email.com","MERGE0":"david@email.com","FNAME":"David","MERGE1":"David","LNAME":"Heath","MERGE2":"Heath","EXPIRYDATE":"2008-02-04","MERGE5":"2008-02-04","USERNAME":"Test1","MERGE6":"Test1","DURATION":"1","MERGE3":"1","PRODUCT":"One week subscription","MERGE4":"One week subscription","CURRENCY":"GBP","MERGE7":"GBP","ROLLING":"false","MERGE8":"false","EXPIRED":"true","MERGE9":"true","TRIAL":"","MERGE10":"","MMERGE11":"","MERGE11":"","MMERGE12":"","MERGE12":"","MMERGE13":"","MERGE13":"","MMERGE14":"","MERGE14":"","TRACKER":"","MERGE15":"","SUBSTYPE":"","MERGE16":"","FIRSTEBOOK":"","MERGE17":"","MMERGE18":"","MERGE18":"","INTERESTS":"freetrial, tutorials"},"status":"subscribed","timestamp":"2009-11-16 14:11:57","lists":{"699791bff9":"unsubscribed"}}
@@ -0,0 +1,8 @@
1
+ [{
2
+ "timestamp":"2009-11-12 15:46:20",
3
+ "email":"david@email.com"
4
+ },
5
+ {"timestamp":"2009-11-12 15:52:52",
6
+ "email":"julie@email.com"
7
+ }
8
+ ]
@@ -0,0 +1 @@
1
+ true
File without changes
@@ -0,0 +1 @@
1
+ [1]
@@ -0,0 +1,14 @@
1
+ [
2
+ {"id":"my-list-id",
3
+ "web_id":12345 ,
4
+ "name":"A test list",
5
+ "date_created":"2009-09-10 14:14:06",
6
+ "member_count":5,
7
+ "unsubscribe_count":0,
8
+ "cleaned_count":0,
9
+ "email_type_option":false,
10
+ "default_from_name":"John Smith",
11
+ "default_from_email":"johnsmith@acmecorp.com",
12
+ "default_subject":"",
13
+ "default_language":"eng"}
14
+ ]
File without changes
File without changes
File without changes
@@ -0,0 +1,47 @@
1
+ $:.unshift File.expand_path("..", File.dirname(__FILE__))
2
+ require "test_helper"
3
+
4
+ class MonkeyWrench::ListTest < Test::Unit::TestCase
5
+ context "converting a flat hash to a Mailchimp structured array" do
6
+ setup do
7
+ @example_hash = { :email_address => "mail@chimp.com", :type => :html }
8
+ end
9
+
10
+ should "include index keys" do
11
+ assert @example_hash.to_mailchimp(0).keys.include?("%5B0%5D%5BEMAIL_ADDRESS%5D")
12
+ end
13
+
14
+ should "include parent parameter name in keys" do
15
+ assert @example_hash.to_mailchimp(0, "batch").keys.include?("batch%5B0%5D%5BEMAIL_ADDRESS%5D")
16
+ end
17
+ end
18
+
19
+ context "converting a hash with array values to a Mailchimp structured array" do
20
+ setup do
21
+ @example_hash = { :batch => [{ :email_address => "mail@chimp.com", :type => :html },
22
+ { :email_address => "foo@bar.com", :type => :text }]}
23
+ end
24
+
25
+ should "flatten all nested values" do
26
+ chimped = @example_hash.to_mailchimp
27
+ assert chimped.keys.include?("batch%5B0%5D%5BEMAIL_ADDRESS%5D")
28
+ assert chimped.keys.include?("batch%5B1%5D%5BEMAIL_ADDRESS%5D")
29
+
30
+ chimp = chimped["batch%5B0%5D%5BEMAIL_ADDRESS%5D"]
31
+ bar = chimped["batch%5B1%5D%5BEMAIL_ADDRESS%5D"]
32
+ assert_equal "mail@chimp.com", chimp
33
+ assert_equal "foo@bar.com", bar
34
+ end
35
+ end
36
+
37
+ context "converting a nested hash" do
38
+ setup do
39
+ @example_hash = { :vars => { :email_address =>"mail@chimp.com", :type => :html } }
40
+ end
41
+
42
+ should "include index keys" do
43
+ assert @example_hash.to_mailchimp.keys.include?("vars%5BEMAIL_ADDRESS%5D")
44
+ assert @example_hash.to_mailchimp.keys.include?("vars%5BTYPE%5D")
45
+ end
46
+ end
47
+ end
File without changes
@@ -0,0 +1,310 @@
1
+ $:.unshift File.expand_path("..", File.dirname(__FILE__))
2
+ require "test_helper"
3
+
4
+ class MonkeyWrench::ListTest < Test::Unit::TestCase
5
+ context "subscribing to a list" do
6
+ setup do
7
+ setup_config
8
+ mock_chimp_post(:lists)
9
+ @list = MonkeyWrench::List.find_by_name("A test list")
10
+ clear_fakeweb
11
+ end
12
+
13
+ context "multiple subscribers at once" do
14
+ should "subscribe users" do
15
+ form_params = {"batch[0][EMAIL]" => "mail@chimp.com",
16
+ "batch[0][TYPE]" => "html",
17
+ :id => "my-list-id"}
18
+ mock_chimp_post(:listBatchSubscribe, form_params)
19
+
20
+ subscribers = [{:email => "mail@chimp.com", :type => :html}]
21
+ expected = {:success => 1, :errors => []}
22
+ assert_equal expected, @list.subscribe(subscribers)
23
+ end
24
+
25
+ should "split more than ten subscribers into batches" do
26
+ first_batch = {:id => "my-list-id"}
27
+ subscribers = []
28
+ 10.times do |i|
29
+ first_batch["batch[#{i}][EMAIL]"] = "mail#{i}@chimp.com"
30
+ first_batch["batch[#{i}][TYPE]"] = "html"
31
+ subscribers << {:email => "mail#{i}@chimp.com", :type => :html}
32
+ end
33
+ mock_chimp_post(:listBatchSubscribe, first_batch,
34
+ true, 'listBatchSubscribe10')
35
+
36
+ second_batch = {:id => "my-list-id"}
37
+ 5.times do |i|
38
+ second_batch["batch[#{i}][EMAIL]"] = "mail1#{i}@chimp.com"
39
+ second_batch["batch[#{i}][TYPE]"] = "html"
40
+ subscribers << {:email => "mail1#{i}@chimp.com", :type => :html}
41
+ end
42
+ mock_chimp_post(:listBatchSubscribe, second_batch,
43
+ true, 'listBatchSubscribe5')
44
+
45
+ expected = {:success => 15, :errors => []}
46
+ assert_equal expected, @list.subscribe(subscribers)
47
+ end
48
+
49
+ should "send welcome email" do
50
+ form_params = {"merge_vars[FOO]" => "bar", :id => "my-list-id",
51
+ :email => "mail@chimp.com", :type => :html,
52
+ :send_welcome => true}
53
+ mock_chimp_post(:listSubscribe, form_params)
54
+
55
+ subscribers = [{:email => "mail@chimp.com", :type => :html, :foo => "bar"}]
56
+ expected = {:success => 1, :errors => []}
57
+ assert_equal expected, @list.subscribe(subscribers, :send_welcome => true)
58
+ end
59
+
60
+ should "opt-out from list" do
61
+ end
62
+
63
+ should "collate errors" do
64
+ form_params = {
65
+ "batch[0][EMAIL]" => "mail@chimp.com",
66
+ "batch[0][TYPE]" => "html",
67
+ "batch[1][EMAIL]" => "bademail@badmail",
68
+ "batch[1][TYPE]" => "html",
69
+ :id => "my-list-id"}
70
+ mock_chimp_post(:listBatchSubscribe, form_params, true, 'listBatchSubscribe_with_error')
71
+
72
+ subscribers = [
73
+ {:email => "mail@chimp.com", :type => :html},
74
+ {:email => "bademail@badmail", :type => :html}
75
+ ]
76
+ actual = @list.subscribe(subscribers)
77
+ assert_equal 1, actual[:success]
78
+ assert_equal 'Invalid Email Address: bademail@badmail', actual[:errors][0].message
79
+ assert_equal 502, actual[:errors][0].code
80
+ assert_equal 'Invalid_Email', actual[:errors][0].type
81
+ assert_equal({"EMAIL_TYPE"=>"html", "EMAIL"=>"bademail@badmail"}, actual[:errors][0].row)
82
+ end
83
+ end
84
+
85
+ context "a single subscriber" do
86
+ should "subsbscibe a user" do
87
+ form_params = { :type=>:html,
88
+ :update_existing=>true,
89
+ "merge_vars[MY_DATE]"=>"20090101",
90
+ :replace_interests=>false,
91
+ :double_optin=>false,
92
+ "merge_vars[FNAME]"=>"Joe",
93
+ :id => "my-list-id",
94
+ :send_welcome=>true,
95
+ :email => "mail@chimp.com" }
96
+ mock_chimp_post(:listSubscribe, form_params)
97
+
98
+ params = { :type => :html,
99
+ :double_optin => false,
100
+ :update_existing => true,
101
+ :replace_interests => false,
102
+ :send_welcome => true,
103
+ :fname => "Joe",
104
+ :my_date => "20090101"
105
+ }
106
+
107
+ expected = {:success => 1, :errors => []}
108
+ assert_equal expected, @list.subscribe("mail@chimp.com", params)
109
+ end
110
+ end
111
+ end
112
+
113
+ context "unsubscribing to a list" do
114
+ setup do
115
+ setup_config
116
+ mock_chimp_post(:lists)
117
+ @list = MonkeyWrench::List.find_by_name("A test list")
118
+ end
119
+
120
+ context "multiple subscribers at once" do
121
+ should "unsubscribe" do
122
+ form_params = {"emails[0]" => "mail@chimp.com", :id => "my-list-id"}
123
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
124
+ subscribers = ["mail@chimp.com"]
125
+
126
+ expected = {:success => 1, :errors => []}
127
+ assert_equal expected, @list.unsubscribe(subscribers)
128
+ end
129
+
130
+ should "delete subscriber" do
131
+ form_params = {"emails[0]" => "mail@chimp.com", :id => "my-list-id",
132
+ :delete_member => true}
133
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
134
+ subscribers = ["mail@chimp.com"]
135
+
136
+ expected = {:success => 1, :errors => []}
137
+ assert_equal expected, @list.unsubscribe(subscribers, :delete_member => true)
138
+ end
139
+
140
+ should "send goodbye" do
141
+ form_params = {"emails[0]" => "mail@chimp.com", :id => "my-list-id",
142
+ :send_goodbye => true}
143
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
144
+ subscribers = ["mail@chimp.com"]
145
+
146
+ expected = {:success => 1, :errors => []}
147
+ assert_equal expected, @list.unsubscribe(subscribers, :send_goodbye => true)
148
+ end
149
+
150
+ should "send unsubscribe notification" do
151
+ form_params = {"emails[0]" => "mail@chimp.com", :id => "my-list-id",
152
+ :send_notify => true}
153
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
154
+ subscribers = ["mail@chimp.com"]
155
+
156
+ expected = {:success => 1, :errors => []}
157
+ assert_equal expected, @list.unsubscribe(subscribers, :send_notify => true)
158
+ end
159
+ end
160
+
161
+ context "a single subscriber" do
162
+ should "unsubscribe" do
163
+ form_params = { "emails[0]" => "mail@chimp.com", :id => "my-list-id" }
164
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
165
+
166
+ expected = {:success => 1, :errors => []}
167
+ assert_equal expected, @list.unsubscribe("mail@chimp.com")
168
+ end
169
+ end
170
+ end
171
+
172
+ context "opting out of a list" do
173
+ setup do
174
+ setup_config
175
+ mock_chimp_post(:lists)
176
+ @list = MonkeyWrench::List.find_by_name("A test list")
177
+ end
178
+
179
+ context "multiple subscribers at once" do
180
+ should "opt out" do
181
+ form_params = { "batch[0][EMAIL]" => "mail@chimp.com", :id => "my-list-id",
182
+ "batch[1][EMAIL]" => "foo@bar.com"}
183
+ mock_chimp_post(:listBatchSubscribe, form_params)
184
+ form_params = { "emails[0]" => "mail@chimp.com", :id => "my-list-id",
185
+ "emails[1]" => "foo@bar.com",
186
+ :send_goodbye => false, :send_notify => false }
187
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
188
+ subscribers = ["mail@chimp.com", "foo@bar.com"]
189
+
190
+ expected = {:success => 1, :errors => []}
191
+ assert_equal expected, @list.opt_out(subscribers)
192
+ end
193
+ end
194
+
195
+ context "a single subscriber" do
196
+ should "opt out" do
197
+ form_params = { "batch[0][EMAIL]" => "mail@chimp.com", :id => "my-list-id" }
198
+ mock_chimp_post(:listBatchSubscribe, form_params)
199
+ form_params = { "emails[0]" => "mail@chimp.com", :id => "my-list-id",
200
+ :send_goodbye => false, :send_notify => false}
201
+ mock_chimp_post(:listBatchUnsubscribe, form_params)
202
+
203
+ expected = {:success => 1, :errors => []}
204
+ assert_equal expected, @list.opt_out("mail@chimp.com")
205
+ end
206
+ end
207
+ end
208
+
209
+ context "retrieving member information" do
210
+ setup do
211
+ setup_config
212
+ mock_chimp_post(:lists)
213
+ @list = MonkeyWrench::List.find_by_name("A test list")
214
+ end
215
+
216
+ should "list members" do
217
+ mock_chimp_post(:listMembers, :id => "my-list-id")
218
+
219
+ expected = [
220
+ MonkeyWrench::Member.new({"timestamp"=>"2009-11-12 15:46:20", "email"=>"david@email.com"}),
221
+ MonkeyWrench::Member.new({"timestamp"=>"2009-11-12 15:52:52", "email"=>"julie@email.com"}) ]
222
+ assert_equal expected, @list.members
223
+ end
224
+
225
+ should "iterate over all members" do
226
+ mock_chimp_post(:listMembers, {:id => "my-list-id", :start => 0, :limit => 15000 }, true, 'listMembers')
227
+ mock_chimp_post(:listMembers, {:id => "my-list-id", :start => 1, :limit => 15000 }, true, 'listMembers')
228
+ mock_chimp_post(:listMembers, {:id => "my-list-id", :start => 2, :limit => 15000 }, true, 'listMembers_none')
229
+
230
+ expected = [
231
+ MonkeyWrench::Member.new({"timestamp"=>"2009-11-12 15:46:20", "email"=>"david@email.com"}),
232
+ MonkeyWrench::Member.new({"timestamp"=>"2009-11-12 15:52:52", "email"=>"julie@email.com"}),
233
+ MonkeyWrench::Member.new({"timestamp"=>"2009-11-12 15:46:20", "email"=>"david@email.com"}),
234
+ MonkeyWrench::Member.new({"timestamp"=>"2009-11-12 15:52:52", "email"=>"julie@email.com"})
235
+ ]
236
+ actual = []
237
+ @list.each_member { |m| actual << m }
238
+ assert_equal expected, actual
239
+ end
240
+ end
241
+
242
+ context "updating members" do
243
+ setup do
244
+ setup_config
245
+ mock_chimp_post(:lists)
246
+ @list = MonkeyWrench::List.find_by_name("A test list")
247
+ end
248
+
249
+ should "accept single member's email address change as hash" do
250
+ member = {:email => "foo@bar.com", :new_email => "bar@foo.com"}
251
+ form_params = {:email_address => "foo@bar.com",
252
+ "merge_vars[EMAIL]" => 'bar@foo.com',
253
+ :replace_interests => true, :id => "my-list-id"}
254
+ mock_chimp_post(:listUpdateMember, form_params)
255
+ @list.update_members(member, :replace_interests => true)
256
+ end
257
+
258
+ should "accept single member's email address change as list" do
259
+ members = [{:email => "foo@bar.com", :new_email => "bar@foo.com"}]
260
+ form_params = {:email_address => "foo@bar.com",
261
+ "merge_vars[EMAIL]" => 'bar@foo.com',
262
+ :replace_interests => true, :id => "my-list-id"}
263
+ mock_chimp_post(:listUpdateMember, form_params)
264
+ @list.update_members(members, :replace_interests => true)
265
+ end
266
+
267
+ should "update multiple members emails addresses" do
268
+ members = [{:email => "foo@bar.com", :new_email => "bar@foo.com"},
269
+ {:email => "spock@vulcan.com", :new_email => "sylar@heroes.com"}
270
+ ]
271
+ form_params = {:email_address => "foo@bar.com",
272
+ "merge_vars[EMAIL]" => 'bar@foo.com',
273
+ :replace_interests => true, :id => "my-list-id"}
274
+ mock_chimp_post(:listUpdateMember, form_params)
275
+ form_params = {:email_address => "spock@vulcan.com",
276
+ "merge_vars[EMAIL]" => 'sylar@heroes.com',
277
+ :replace_interests => true, :id => "my-list-id"}
278
+ mock_chimp_post(:listUpdateMember, form_params)
279
+ @list.update_members(members, :replace_interests => true)
280
+ end
281
+ end
282
+
283
+ context "retrieving a members info" do
284
+ setup do
285
+ setup_config
286
+ mock_chimp_post(:lists)
287
+ @list = MonkeyWrench::List.find_by_name("A test list")
288
+ end
289
+
290
+ should "return the info" do
291
+ form_params = {:email_address => "david@email.com", :id => "my-list-id"}
292
+ mock_chimp_post(:listMemberInfo, form_params)
293
+ member = @list.member("david@email.com")
294
+ assert_equal "david@email.com", member.email
295
+ assert_equal "html", member.email_type
296
+ assert_equal "David", member.fname
297
+ assert_equal ["freetrial", "tutorials"], member.interests
298
+ end
299
+
300
+ should "raise on error" do
301
+ form_params = {:email_address => "david@email.com", :id => "my-list-id"}
302
+ mock_chimp_post(:listMemberInfo, form_params, false)
303
+ assert_raises(MonkeyWrench::Error) do
304
+ @list.member("david@email.com")
305
+ end
306
+ end
307
+
308
+ end
309
+
310
+ end