mailmanager 1.0.18 → 1.0.19

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,4 +1,11 @@
1
- Current version is 1.0.18
1
+ Current version is 1.0.19
2
+
3
+ changes since 1.0.18
4
+ - added optional custom_headers arg to MailManager::List#inject
5
+ - added new MailManager::List#inject_raw method to inject raw emails
6
+ - updated to new simplecov-rcov version w/ better coverage calculation
7
+ - documentation errors fixed
8
+ - cleaned up the tests and code a bit
2
9
 
3
10
  changes since 1.0.17
4
11
  - added host_name getter/setter for lists
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mailmanager (1.0.18)
4
+ mailmanager (1.0.19)
5
5
  json (~> 1.4.6)
6
6
  open4 (~> 1.0.1)
7
7
 
@@ -48,7 +48,7 @@ GEM
48
48
  simplecov (0.3.9)
49
49
  simplecov-html (>= 0.3.7)
50
50
  simplecov-html (0.3.9)
51
- simplecov-rcov (0.1.2)
51
+ simplecov-rcov (0.1.4)
52
52
  simplecov
53
53
  term-ansicolor (1.0.5)
54
54
 
@@ -63,4 +63,4 @@ DEPENDENCIES
63
63
  rspec (~> 2.4.0)
64
64
  ruby-debug19
65
65
  simplecov
66
- simplecov-rcov
66
+ simplecov-rcov (~> 0.1.4)
@@ -6,7 +6,7 @@ for details.
6
6
  It is licensed under the New BSD License (see the LICENSE file for details).
7
7
 
8
8
  MailManager has been tested with Mailman 2.1.14. It has NOT been tested with any
9
- release of Mailman 3 (in alpha as of 1/19/2011). It requires Python 2.6 or higher.
9
+ release of Mailman 3 (in alpha as of 1/19/2011). It requires Python 2.4 or higher.
10
10
  Note that while Mailman itself requires Python, it can work with older versions. So
11
11
  check your Python version before using this.
12
12
 
@@ -21,7 +21,7 @@ check your Python version before using this.
21
21
  foo_list = mm.get_list('foo')
22
22
  new_list = mm.create_list(:name => 'newlist', :admin_email => 'me@here.com', :admin_password => 'secret')
23
23
  new_list.add_member('bar@baz.com')
24
- new_list.members (returns ['foo@baz.com'])
24
+ new_list.members -> ['bar@baz.com']
25
25
 
26
26
  == Hacking
27
27
 
@@ -64,6 +64,7 @@ module MailManager
64
64
  params = {:listname => list.name, :stdin => message}
65
65
  params[:queue] = queue unless queue.nil?
66
66
  command(cmd, params)
67
+ {'result' => 'success'}
67
68
  end
68
69
 
69
70
  def list_address(list)
@@ -154,7 +155,7 @@ module MailManager
154
155
  end
155
156
 
156
157
  def command(cmd, params = {})
157
- mailman_cmd = "#{mailmanager.root}/bin/#{cmd.to_s} "
158
+ mailman_cmd = "#{MailManager.python} #{mailmanager.root}/bin/#{cmd.to_s} "
158
159
  # delete params as we handle them explicitly
159
160
  stdin = nil
160
161
  stdin = params.delete(:stdin) if params.respond_to?(:has_key?) && params.has_key?(:stdin)
@@ -174,7 +175,7 @@ module MailManager
174
175
  when :withlist
175
176
  raise ArgumentError, "Missing :name param" if params[:name].nil?
176
177
  proxy_path = File.dirname(__FILE__)
177
- mailman_cmd = "PYTHONPATH=#{proxy_path} #{MailManager.python} #{mailman_cmd}"
178
+ mailman_cmd = "PYTHONPATH=#{proxy_path} #{mailman_cmd}"
178
179
  mailman_cmd += "-q -r listproxy.command #{escape(params.delete(:name))} " +
179
180
  "#{params.delete(:wlcmd)} "
180
181
  if !params[:arg].nil? && params[:arg].length > 0
@@ -108,15 +108,31 @@ module MailManager
108
108
  end
109
109
 
110
110
  # Injects a message into the list.
111
- def inject(from, subject, message)
111
+ def inject(from, subj, message, custom_headers=nil)
112
112
  inject_message =<<EOF
113
113
  From: #{from}
114
114
  To: #{address}
115
- Subject: #{subject}
116
-
117
- #{message}
115
+ Subject: #{subj}
118
116
  EOF
119
- lib.inject(self, inject_message)
117
+ if !custom_headers.nil?
118
+ raise ArgumentError, "custom headers arg should be a hash" unless custom_headers.respond_to?(:each_pair)
119
+ headers = []
120
+ custom_headers.each_pair { |hdr, val|
121
+ headers << "#{hdr}: #{val}"
122
+ }
123
+ inject_message += headers.join("\n")
124
+ end
125
+ inject_message += "\n#{message}"
126
+ result = lib.inject(self, inject_message)
127
+ result['result'].to_sym
128
+ end
129
+
130
+ # Injects a raw message into the list. You must send a properly formatted
131
+ # email to this method. You probably want to set the To: header to the list's
132
+ # address. You can get that from MailManager::List#address
133
+ def inject_raw(message)
134
+ result = lib.inject(self, message)
135
+ result['result'].to_sym
120
136
  end
121
137
 
122
138
  # Returns the info URL for the list
@@ -1,3 +1,3 @@
1
1
  module MailManager
2
- VERSION = '1.0.18'
2
+ VERSION = '1.0.19'
3
3
  end
@@ -29,5 +29,5 @@ spec = Gem::Specification.new do |s|
29
29
  s.add_development_dependency('ci_reporter')
30
30
  s.add_development_dependency('cucumber')
31
31
  s.add_development_dependency('simplecov')
32
- s.add_development_dependency('simplecov-rcov')
32
+ s.add_development_dependency('simplecov-rcov', '~>0.1.4')
33
33
  end
@@ -4,6 +4,7 @@ describe MailManager::Lib do
4
4
  let(:mailmanager) { mock(MailManager) }
5
5
  let(:subject) { MailManager::Lib.new }
6
6
  let(:fake_root) { '/foo/bar' }
7
+ let(:python) { '/usr/bin/env python' }
7
8
  let(:process) { mock(Process::Status) }
8
9
  let(:list_result) { <<EOF
9
10
  3 matching mailing lists found:
@@ -22,7 +23,7 @@ EOF
22
23
 
23
24
  describe "#lists" do
24
25
  it "should return all existing lists" do
25
- subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
26
+ subject.stub(:run_command).with("#{python} #{fake_root}/bin/list_lists 2>&1", nil).
26
27
  and_return([list_result, process])
27
28
  subject.lists.should have(3).lists
28
29
  end
@@ -30,7 +31,7 @@ EOF
30
31
 
31
32
  describe "#create_list" do
32
33
  before :each do
33
- subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
34
+ subject.stub(:run_command).with("#{python} #{fake_root}/bin/list_lists 2>&1", nil).
34
35
  and_return([list_result, process])
35
36
  end
36
37
 
@@ -78,7 +79,7 @@ EOF
78
79
 
79
80
  it "should create the list" do
80
81
  subject.should_receive(:run_command).
81
- with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
82
+ with("#{python} #{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
82
83
  and_return([new_list_return, process])
83
84
  subject.stub(:list_names).and_return([],['bar'])
84
85
  subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
@@ -88,7 +89,7 @@ EOF
88
89
  it "should not rely on the aliases setup output" do
89
90
  # https://www.pivotaltracker.com/story/show/9422507
90
91
  subject.should_receive(:run_command).
91
- with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
92
+ with("#{python} #{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
92
93
  and_return(["", process])
93
94
  subject.stub(:list_names).and_return([],['bar'])
94
95
  subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
@@ -98,7 +99,7 @@ EOF
98
99
  it "should raise an exception if the list already exists" do
99
100
  # https://www.pivotaltracker.com/story/show/9421449
100
101
  subject.should_not_receive(:run_command).
101
- with("#{fake_root}/bin/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil)
102
+ with("#{python} #{fake_root}/bin/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil)
102
103
  subject.stub(:list_names).and_return(['foo'])
103
104
  lambda {
104
105
  subject.create_list(:name => 'foo', :admin_email => 'foo@bar.baz',
@@ -108,7 +109,7 @@ EOF
108
109
 
109
110
  it "should raise a MailmanExecuteError if the list creation fails on the Mailman side" do
110
111
  subject.should_receive(:run_command).
111
- with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
112
+ with("#{python} #{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
112
113
  and_return(["", process])
113
114
  subject.stub(:get_list).and_raise(MailManager::ListNotFoundError)
114
115
  lambda {
@@ -122,7 +123,7 @@ EOF
122
123
  describe "#delete_list" do
123
124
  it "should delete the list" do
124
125
  subject.should_receive(:run_command).
125
- with("#{fake_root}/bin/rmlist \"foo\" 2>&1", nil).
126
+ with("#{python} #{fake_root}/bin/rmlist \"foo\" 2>&1", nil).
126
127
  and_return(["Removing list info", process])
127
128
  subject.stub(:list_names).and_return(['foo'])
128
129
  subject.delete_list('foo')
@@ -144,19 +145,52 @@ EOF
144
145
  let(:regular_members) { ['me@here.com', 'you@there.org'] }
145
146
  let(:digest_members) { ['them@that.net'] }
146
147
 
147
- let(:cmd) { "PYTHONPATH=#{File.expand_path('lib/mailmanager')} " +
148
- "/usr/bin/env python " +
149
- "#{fake_root}/bin/withlist -q -r listproxy.command \"foo\" " }
148
+ describe "#inject" do
149
+ it "should tell Mailman to inject a message into the list" do
150
+ test_message = <<EOF
151
+ From: "Morgan, Wesley" <MorganW@dnc.org>
152
+ To: "labs@mailman-dev.dnc.org" <labs@mailman-dev.dnc.org>
153
+ Sender: "labs-bounces@mailman-dev.dnc.org" <labs-bounces@mailman-dev.dnc.org>
154
+ Content-Class: urn:content-classes:message
155
+ Date: Tue, 18 Jan 2011 13:26:59 -0500
156
+ Subject: [Labs] is this thing on?
157
+ Thread-Topic: is this thing on?
158
+ Thread-Index: Acu3PUssIxkW+1TESgmnlPvaBgroVQ==
159
+ Message-ID: <C3DA7B38-E1F9-4331-9025-D066DA7376F2@dnc.org>
160
+ List-Help: <mailto:labs-request@mailman-dev.dnc.org?subject=help>
161
+ List-Subscribe: <http://mailman-dev.dnc.org/mailman/listinfo/labs>,
162
+ <mailto:labs-request@mailman-dev.dnc.org?subject=subscribe>
163
+ List-Unsubscribe: <http://mailman-dev.dnc.org/mailman/options/labs>,
164
+ <mailto:labs-request@mailman-dev.dnc.org?subject=unsubscribe>
165
+ Accept-Language: en-US
166
+ Content-Language: en-US
167
+ X-Auto-Response-Suppress: All
168
+ acceptlanguage: en-US
169
+ Content-Type: text/plain; charset="us-ascii"
170
+ Content-Transfer-Encoding: quoted-printable
171
+ MIME-Version: 1.0
172
+
173
+ Cello?
174
+ _______________________________________________
175
+ Labs mailing list
176
+ Labs@mailman-dev.dnc.org
177
+ http://mailman-dev.dnc.org/mailman/listinfo/labs
178
+
179
+ EOF
180
+ test_message = "message!"
181
+ test_mailman_cmd(:inject, :inject, nil, nil, test_message)
182
+ end
183
+ end
150
184
 
151
185
  describe "#regular_members" do
152
186
  it "should ask Mailman for the regular list members" do
153
- test_mailman_cmd(:regular_members, :getRegularMemberKeys, regular_members)
187
+ test_withlist_cmd(:regular_members, :getRegularMemberKeys, regular_members)
154
188
  end
155
189
  end
156
190
 
157
191
  describe "#digest_members" do
158
192
  it "should ask Mailman for the digest list members" do
159
- test_mailman_cmd(:digest_members, :getDigestMemberKeys, digest_members)
193
+ test_withlist_cmd(:digest_members, :getDigestMemberKeys, digest_members)
160
194
  end
161
195
  end
162
196
 
@@ -190,14 +224,14 @@ EOF
190
224
 
191
225
  describe "#moderators" do
192
226
  it "should ask Mailman for the list's moderators" do
193
- test_mailman_cmd(:moderators, :moderator, ['phb@bigcorp.com', 'nhb@smallstartup.com'])
227
+ test_withlist_cmd(:moderators, :moderator, ['phb@bigcorp.com', 'nhb@smallstartup.com'])
194
228
  end
195
229
  end
196
230
 
197
231
  describe "#add_moderator" do
198
232
  it "should ask Mailman to add the moderator to the list" do
199
233
  subject.should_receive(:moderators).with(list).and_return({'result' => 'success', 'return' => []})
200
- test_mailman_cmd(:add_moderator, 'moderator.append', nil, 'foo@bar.com')
234
+ test_withlist_cmd(:add_moderator, 'moderator.append', nil, 'foo@bar.com')
201
235
  end
202
236
 
203
237
  it "should raise ModeratorAlreadyExistsError if they already a moderator" do
@@ -211,7 +245,7 @@ EOF
211
245
  describe "#delete_moderator" do
212
246
  it "should ask Mailman to delete the moderator from the list" do
213
247
  subject.should_receive(:moderators).with(list).and_return({'result' => 'success', 'return' => ['foo@bar.com']})
214
- test_mailman_cmd(:delete_moderator, 'moderator.remove', nil, 'foo@bar.com')
248
+ test_withlist_cmd(:delete_moderator, 'moderator.remove', nil, 'foo@bar.com')
215
249
  end
216
250
 
217
251
  it "should raise ModeratorNotFoundError if they are not already a moderator" do
@@ -261,32 +295,49 @@ EOF
261
295
 
262
296
  def test_method_getter(lib_method, return_value, *args)
263
297
  cc_mailman_method = camel_case("get_#{lib_method.to_s}")
264
- test_mailman_cmd(lib_method, cc_mailman_method, return_value, *args)
298
+ test_withlist_cmd(lib_method, cc_mailman_method, return_value, *args)
265
299
  end
266
300
 
267
301
  def test_method_setter(lib_method, *args)
268
302
  cc_mailman_method = camel_case(lib_method.to_s)
269
- test_mailman_cmd(lib_method, cc_mailman_method, nil, *args)
303
+ test_withlist_cmd(lib_method, cc_mailman_method, nil, *args)
270
304
  end
271
305
 
272
306
  def test_attr_getter(attr, return_value)
273
- test_mailman_cmd(attr, attr, return_value)
307
+ test_withlist_cmd(attr, attr, return_value)
274
308
  end
275
309
 
276
310
  def test_attr_setter(attr, *args)
277
- test_mailman_cmd("set_#{attr}", attr, nil, *args)
311
+ test_withlist_cmd("set_#{attr}", attr, nil, *args)
278
312
  end
279
313
 
280
- def test_mailman_cmd(lib_method, mailman_method, return_value=nil, *args)
314
+ def test_withlist_cmd(lib_method, mailman_method, return_value=nil, *args)
315
+ test_mailman_cmd(lib_method, :withlist, mailman_method, return_value=nil, *args)
316
+ end
317
+
318
+ def test_mailman_cmd(lib_method, mailman_cmd, mailman_sub_cmd, return_value=nil, *args)
319
+ command = "/usr/bin/env python " +
320
+ "#{fake_root}/bin/#{mailman_cmd.to_s} "
321
+ command += "--listname=" if mailman_cmd.to_sym == :inject
322
+ if mailman_cmd.to_sym == :withlist
323
+ command = "PYTHONPATH=#{File.expand_path('lib/mailmanager')} #{command}"
324
+ command += "-q -r listproxy.command "
325
+ end
326
+ command += "\"foo\" "
281
327
  if return_value.is_a?(Hash)
282
328
  result = return_value
283
329
  else
284
330
  result = {"result" => "success"}
285
331
  result["return"] = return_value unless return_value.nil?
286
332
  end
333
+ cmd_arg = command
334
+ cmd_arg += "#{mailman_sub_cmd.to_s} " unless mailman_sub_cmd.nil?
335
+ cmd_arg += "#{cmd_args(*args)}" unless mailman_cmd.to_sym == :inject
336
+ cmd_arg += "2>&1"
337
+ stdin_arg = mailman_cmd.to_sym == :inject ? args[0] : nil
287
338
  subject.should_receive(:run_command).
288
- with(cmd+"#{mailman_method.to_s} #{cmd_args(*args)}2>&1", nil).
289
- and_return([JSON.generate(result),process])
339
+ with(cmd_arg, stdin_arg).and_return([JSON.generate(result),process])
340
+ # with(mailman_cmd+"#{mailman_method.to_s} #{cmd_args(*args)}2>&1", nil).
290
341
  subject.send(lib_method, list, *args).should == result
291
342
  end
292
343
 
@@ -114,6 +114,52 @@ describe MailManager::List do
114
114
  end
115
115
  end
116
116
 
117
+ context "when injecting a message" do
118
+ let(:from) { 'Foo Bar <foo@bar.name>' }
119
+ let(:to) { 'list@foo.org' }
120
+ let(:subj) { 'Test Subject' }
121
+ let(:message) { 'Test Message' }
122
+ let(:headers) { {'X-Custom-1' => 'foo', 'X-Custom-2' => 'bar'} }
123
+ let(:raw_message_pre) { <<EOF
124
+ From: #{from}
125
+ To: #{to}
126
+ Subject: #{subj}
127
+ EOF
128
+ }
129
+ let(:raw_message) { raw_message_pre + "\n#{message}" }
130
+ let(:msg_with_headers) {
131
+ headers_arr = []
132
+ headers.each_pair { |hdr, val|
133
+ headers_arr << "#{hdr}: #{val}"
134
+ }
135
+ raw_message_pre + headers_arr.join("\n") + "\n#{message}"
136
+ }
137
+
138
+ describe "#inject" do
139
+ it "should tell lib to inject a message into the list" do
140
+ lib.stub(:list_address).with(subject).and_return({'result' => 'success', 'return' => to})
141
+ lib.should_receive(:inject).with(subject, raw_message).
142
+ and_return({'result' => 'success'})
143
+ subject.inject(from, subj, message)
144
+ end
145
+
146
+ it "should accept custom headers" do
147
+ lib.stub(:list_address).with(subject).and_return({'result' => 'success', 'return' => to})
148
+ lib.should_receive(:inject).with(subject, msg_with_headers).
149
+ and_return({'result' => 'success'})
150
+ subject.inject(from, subj, message, headers)
151
+ end
152
+ end
153
+
154
+ describe "#inject_raw" do
155
+ it "should tell lib to inject whatever you send it" do
156
+ lib.should_receive(:inject).with(subject, raw_message).
157
+ and_return({'result' => 'success'})
158
+ subject.inject_raw(raw_message)
159
+ end
160
+ end
161
+ end
162
+
117
163
  context "host_name accessors" do
118
164
  let(:host_name) { 'groups.foo.org' }
119
165
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: mailmanager
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.0.18
5
+ version: 1.0.19
6
6
  platform: ruby
7
7
  authors:
8
8
  - Wes Morgan
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-02-10 00:00:00 -05:00
13
+ date: 2011-02-11 00:00:00 -05:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -107,9 +107,9 @@ dependencies:
107
107
  requirement: &id009 !ruby/object:Gem::Requirement
108
108
  none: false
109
109
  requirements:
110
- - - ">="
110
+ - - ~>
111
111
  - !ruby/object:Gem::Version
112
- version: "0"
112
+ version: 0.1.4
113
113
  type: :development
114
114
  version_requirements: *id009
115
115
  description: Ruby wrapper library for GNU Mailman's admin functions