mailmanager 1.0.14 → 1.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Changelog +7 -1
- data/Gemfile.lock +11 -1
- data/README.rdoc +19 -0
- data/config/cucumber.yml +11 -0
- data/features/create_list.feature +18 -0
- data/features/step_definitions/create_list_steps.rb +4 -0
- data/features/step_definitions/global_steps.rb +24 -0
- data/features/support/env.rb +2 -0
- data/lib/mailmanager/lib.rb +37 -1
- data/lib/mailmanager/list.rb +9 -0
- data/lib/mailmanager/version.rb +1 -1
- data/lib/mailmanager.rb +6 -3
- data/mailmanager.gemspec +1 -0
- data/spec/lib/mailmanager/lib_spec.rb +68 -28
- metadata +21 -3
data/.gitignore
CHANGED
data/Changelog
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
Current version is 1.0.
|
1
|
+
Current version is 1.0.15
|
2
|
+
|
3
|
+
changes since 1.0.14
|
4
|
+
- added a Cucumber integration test suite
|
5
|
+
- fixed a list creation bug when Mailman outputs to an aliases db directly
|
6
|
+
- added a delete_list method
|
7
|
+
- raise exception when attempting to create a mailing list that already exists
|
2
8
|
|
3
9
|
changes since 1.0.13
|
4
10
|
- more detailed error report when creating a new list fails
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mailmanager (1.0.
|
4
|
+
mailmanager (1.0.15)
|
5
5
|
json (~> 1.4.6)
|
6
6
|
open4 (~> 1.0.1)
|
7
7
|
|
@@ -14,7 +14,15 @@ GEM
|
|
14
14
|
ci_reporter (1.6.4)
|
15
15
|
builder (>= 2.1.2)
|
16
16
|
columnize (0.3.2)
|
17
|
+
cucumber (0.10.0)
|
18
|
+
builder (>= 2.1.2)
|
19
|
+
diff-lcs (~> 1.1.2)
|
20
|
+
gherkin (~> 2.3.2)
|
21
|
+
json (~> 1.4.6)
|
22
|
+
term-ansicolor (~> 1.0.5)
|
17
23
|
diff-lcs (1.1.2)
|
24
|
+
gherkin (2.3.3)
|
25
|
+
json (~> 1.4.6)
|
18
26
|
json (1.4.6)
|
19
27
|
linecache19 (0.5.11)
|
20
28
|
ruby_core_source (>= 0.1.4)
|
@@ -37,6 +45,7 @@ GEM
|
|
37
45
|
ruby-debug-base19 (>= 0.11.19)
|
38
46
|
ruby_core_source (0.1.4)
|
39
47
|
archive-tar-minitar (>= 0.5.2)
|
48
|
+
term-ansicolor (1.0.5)
|
40
49
|
|
41
50
|
PLATFORMS
|
42
51
|
ruby
|
@@ -44,6 +53,7 @@ PLATFORMS
|
|
44
53
|
DEPENDENCIES
|
45
54
|
ZenTest (~> 4.4.2)
|
46
55
|
ci_reporter
|
56
|
+
cucumber
|
47
57
|
mailmanager!
|
48
58
|
rspec (~> 2.4.0)
|
49
59
|
ruby-debug19
|
data/README.rdoc
CHANGED
@@ -83,6 +83,25 @@ Exposing new list properties works something like this:
|
|
83
83
|
That should get you started hacking on the gem. If you get stuck or are trying to
|
84
84
|
do anything more complex, please feel free to e-mail me: cap10morgan@gmail.com.
|
85
85
|
|
86
|
+
== Testing
|
87
|
+
|
88
|
+
The RSpec suite should run out of the box with the 'rake spec' command.
|
89
|
+
Feel free to open a GitHub issue if they do not.
|
90
|
+
|
91
|
+
You'll need a local working installation of GNU Mailman 2.1.14 (or a later version
|
92
|
+
of 2.1.x, probably) to run the Cucumber integration tests. Make a symlink to the
|
93
|
+
root directory of your Mailman install in the mailmanager directory. It should be
|
94
|
+
named "mailman". So if you are in the top-level mailmanager directory and your
|
95
|
+
Mailman installation is in /usr/local/mailman, you would run this command:
|
96
|
+
ln -s /usr/local/mailman mailman
|
97
|
+
|
98
|
+
Once that's done, you should be able to just run 'cucumber' in the top-level
|
99
|
+
mailmanager directory.
|
100
|
+
|
101
|
+
_MAKE SURE THIS IS NOT A MAILMAN INSTALLATION YOU CARE ABOUT!_ The Cucumber test
|
102
|
+
suite will start by deleting all mailing lists so it can have a clean slate to
|
103
|
+
test with.
|
104
|
+
|
86
105
|
== Contributing
|
87
106
|
|
88
107
|
- Fork on GitHub
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
<%
|
2
|
+
all_opts = "--color"
|
3
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
4
|
+
rerun_opts = "#{all_opts} " + (rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}")
|
5
|
+
std_opts = "#{all_opts} --format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
|
6
|
+
%>
|
7
|
+
default: <%= std_opts %> features
|
8
|
+
wip: --tags @wip:3 --wip features
|
9
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
10
|
+
autotest: <%= rerun_opts %>
|
11
|
+
autotest-all: <%= std_opts %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: Creating a new list
|
2
|
+
As a developer using MailManager
|
3
|
+
In order to create new mailing lists
|
4
|
+
I want MailManager to offer this feature
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given MailManager is initialized on "./mailman"
|
8
|
+
|
9
|
+
Scenario: Creating a new list
|
10
|
+
Given no lists exist
|
11
|
+
When I create a new list "foo"
|
12
|
+
Then I should have a list named "foo"
|
13
|
+
|
14
|
+
Scenario: Creating a list with the same name as an existing list
|
15
|
+
Given no lists exist
|
16
|
+
When I create a new list "foo"
|
17
|
+
Then it should raise MailManager::ListNameConflictError when I create a new list "foo"
|
18
|
+
And I should have 1 list
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Given /^MailManager is initialized on "([^\"]+)"$/ do |mailman_root|
|
2
|
+
@mailmanager = MailManager.init(mailman_root)
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^no lists exist$/ do
|
6
|
+
@mailmanager.list_names.each do |list_name|
|
7
|
+
@mailmanager.delete_list(list_name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /^it should raise (.+?) when (.+)$/ do |exception,when_step|
|
12
|
+
lambda {
|
13
|
+
When when_step
|
14
|
+
}.should raise_error(eval(exception))
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^I should have (\d+) lists?$/ do |num|
|
18
|
+
@mailmanager.should have(num.to_i).lists
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^I should have a list named "([^"]*)"$/ do |list_name|
|
22
|
+
@mailmanager.list_names.should include(list_name)
|
23
|
+
end
|
24
|
+
|
data/lib/mailmanager/lib.rb
CHANGED
@@ -3,6 +3,12 @@ module MailManager
|
|
3
3
|
class MailmanExecuteError < StandardError #:nodoc:
|
4
4
|
end
|
5
5
|
|
6
|
+
class ListNotFoundError < StandardError #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
class ListNameConflictError < StandardError #:nodoc:
|
10
|
+
end
|
11
|
+
|
6
12
|
class Lib #:nodoc:all
|
7
13
|
|
8
14
|
def mailmanager
|
@@ -15,8 +21,33 @@ module MailManager
|
|
15
21
|
parse_output(cmd, out)
|
16
22
|
end
|
17
23
|
|
24
|
+
def list_names
|
25
|
+
lists.map { |list| list.name }
|
26
|
+
end
|
27
|
+
|
18
28
|
def create_list(params)
|
29
|
+
raise ArgumentError, "Missing :name param" if params[:name].nil?
|
30
|
+
list_name = params[:name]
|
31
|
+
raise ListNameConflictError, "List \"#{list_name}\" already exists" if list_names.include?(list_name)
|
19
32
|
cmd = :newlist
|
33
|
+
# create the list
|
34
|
+
out = command(cmd, params)
|
35
|
+
# get the new list
|
36
|
+
begin
|
37
|
+
get_list(list_name)
|
38
|
+
rescue ListNotFoundError
|
39
|
+
raise MailmanExecuteError, "List creation failed: #{out}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_list(list_name)
|
44
|
+
raise ListNotFoundError, "#{list_name} does not exist" unless list_names.include?(list_name)
|
45
|
+
MailManager::List.new(list_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete_list(params)
|
49
|
+
params = {:name => params} unless params.respond_to?(:has_key?)
|
50
|
+
cmd = :rmlist
|
20
51
|
out = command(cmd, params)
|
21
52
|
parse_output(cmd, out)
|
22
53
|
end
|
@@ -141,7 +172,7 @@ module MailManager
|
|
141
172
|
mailman_cmd = "#{mailmanager.root}/bin/#{cmd.to_s} "
|
142
173
|
# delete opts as we handle them explicitly
|
143
174
|
stdin = nil
|
144
|
-
stdin = opts.delete(:stdin) if opts.has_key?(:stdin)
|
175
|
+
stdin = opts.delete(:stdin) if opts.respond_to?(:has_key?) && opts.has_key?(:stdin)
|
145
176
|
case cmd
|
146
177
|
when :newlist
|
147
178
|
mailman_cmd += "-q "
|
@@ -152,6 +183,9 @@ module MailManager
|
|
152
183
|
escape(opts.delete(key))
|
153
184
|
}.join(' ')
|
154
185
|
mailman_cmd += "#{mailman_cmd_suffix} "
|
186
|
+
when :rmlist
|
187
|
+
raise ArgumentError, "Missing :name param" if opts[:name].nil?
|
188
|
+
mailman_cmd += "#{escape(opts.delete(:name))} "
|
155
189
|
when :withlist
|
156
190
|
raise ArgumentError, "Missing :name param" if opts[:name].nil?
|
157
191
|
proxy_path = File.dirname(__FILE__)
|
@@ -211,6 +245,8 @@ module MailManager
|
|
211
245
|
end
|
212
246
|
raise MailmanExecuteError, "Error getting name of newly created list. Mailman sent:\n#{output}" if list_name.nil?
|
213
247
|
return_obj = MailManager::List.new(list_name)
|
248
|
+
when :rmlist
|
249
|
+
return_obj = output =~ /Removing list info/
|
214
250
|
when :list_lists
|
215
251
|
lists = []
|
216
252
|
puts "Output from Mailman:\n#{output}" if MailManager.debug
|
data/lib/mailmanager/list.rb
CHANGED
@@ -35,6 +35,15 @@ module MailManager
|
|
35
35
|
lib.create_list(params)
|
36
36
|
end
|
37
37
|
|
38
|
+
def self.delete(list_name) #:nodoc:
|
39
|
+
lib.delete_list(list_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Deletes the list, but not the archives
|
43
|
+
def delete
|
44
|
+
self.class.delete(self.name)
|
45
|
+
end
|
46
|
+
|
38
47
|
# Returns the list's email address
|
39
48
|
def address
|
40
49
|
result = lib.list_address(self)
|
data/lib/mailmanager/version.rb
CHANGED
data/lib/mailmanager.rb
CHANGED
@@ -82,7 +82,7 @@ module MailManager
|
|
82
82
|
# Only retrieves the list names, doesn't wrap them in MailManager::List
|
83
83
|
# instances.
|
84
84
|
def list_names
|
85
|
-
|
85
|
+
@lib.list_names
|
86
86
|
end
|
87
87
|
|
88
88
|
# Create a new list. Returns an instance of MailManager::List. Params are:
|
@@ -96,8 +96,11 @@ module MailManager
|
|
96
96
|
# Get an existing list as a MailManager::List instance. Raises an exception if
|
97
97
|
# the list doesn't exist.
|
98
98
|
def get_list(list_name)
|
99
|
-
|
100
|
-
|
99
|
+
@lib.get_list(list_name)
|
100
|
+
end
|
101
|
+
|
102
|
+
def delete_list(list_name)
|
103
|
+
MailManager::List.delete(list_name)
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
data/mailmanager.gemspec
CHANGED
@@ -5,6 +5,14 @@ describe MailManager::Lib do
|
|
5
5
|
let(:subject) { MailManager::Lib.new }
|
6
6
|
let(:fake_root) { '/foo/bar' }
|
7
7
|
let(:process) { mock(Process::Status) }
|
8
|
+
let(:list_result) { <<EOF
|
9
|
+
3 matching mailing lists found:
|
10
|
+
Foo - [no description available]
|
11
|
+
BarBar - Dummy list
|
12
|
+
Mailman - Mailman site list
|
13
|
+
EOF
|
14
|
+
}
|
15
|
+
let(:list_result_after_create) { list_result + "\n Bar - [no description available]\n" }
|
8
16
|
|
9
17
|
before :each do
|
10
18
|
subject.stub(:mailmanager).and_return(mailmanager)
|
@@ -14,47 +22,48 @@ describe MailManager::Lib do
|
|
14
22
|
|
15
23
|
describe "#lists" do
|
16
24
|
it "should return all existing lists" do
|
17
|
-
list_result = <<EOF
|
18
|
-
3 matching mailing lists found:
|
19
|
-
Foo - [no description available]
|
20
|
-
BarBar - Dummy list
|
21
|
-
Mailman - Mailman site list
|
22
|
-
EOF
|
23
25
|
subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
|
24
|
-
and_return([list_result,process])
|
26
|
+
and_return([list_result, process])
|
25
27
|
subject.lists.should have(3).lists
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
31
|
describe "#create_list" do
|
32
|
+
before :each do
|
33
|
+
subject.stub(:run_command).with("#{fake_root}/bin/list_lists 2>&1", nil).
|
34
|
+
and_return([list_result, process])
|
35
|
+
end
|
36
|
+
|
30
37
|
it "should raise an argument error if list name is missing" do
|
31
38
|
lambda {
|
32
39
|
subject.create_list(:admin_email => 'foo@bar.baz', :admin_password => 'qux')
|
33
40
|
}.should raise_error(ArgumentError)
|
34
41
|
end
|
42
|
+
|
35
43
|
it "should raise an argument error if list admin email is missing" do
|
36
44
|
lambda {
|
37
|
-
subject.create_list(:name => '
|
45
|
+
subject.create_list(:name => 'bar', :admin_password => 'qux')
|
38
46
|
}.should raise_error(ArgumentError)
|
39
47
|
end
|
48
|
+
|
40
49
|
it "should raise an argument error if admin password is missing" do
|
41
50
|
lambda {
|
42
|
-
subject.create_list(:name => '
|
51
|
+
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz')
|
43
52
|
}.should raise_error(ArgumentError)
|
44
53
|
end
|
45
54
|
|
46
55
|
context "with valid list params" do
|
47
56
|
let(:new_aliases) {
|
48
|
-
['
|
49
|
-
'
|
50
|
-
'
|
51
|
-
'
|
52
|
-
'
|
53
|
-
'
|
54
|
-
'
|
55
|
-
'
|
56
|
-
'
|
57
|
-
'
|
57
|
+
['bar: "|/foo/bar/mail/mailman post bar"',
|
58
|
+
'bar-admin: "|/foo/bar/mail/mailman admin bar"',
|
59
|
+
'bar-bounces: "|/foo/bar/mail/mailman bounces bar"',
|
60
|
+
'bar-confirm: "|/foo/bar/mail/mailman confirm bar"',
|
61
|
+
'bar-join: "|/foo/bar/mail/mailman join bar"',
|
62
|
+
'bar-leave: "|/foo/bar/mail/mailman leave bar"',
|
63
|
+
'bar-owner: "|/foo/bar/mail/mailman owner bar"',
|
64
|
+
'bar-request: "|/foo/bar/mail/mailman request bar"',
|
65
|
+
'bar-subscribe: "|/foo/bar/mail/mailman subscribe bar"',
|
66
|
+
'bar-unsubscribe: "|/foo/bar/mail/mailman unsubscribe bar"']
|
58
67
|
}
|
59
68
|
let(:new_list_return) {
|
60
69
|
prefix =<<EOF
|
@@ -62,24 +71,55 @@ To finish creating your mailing list, you must edit your /etc/aliases (or
|
|
62
71
|
equivalent) file by adding the following lines, and possibly running the
|
63
72
|
`newaliases' program:
|
64
73
|
|
65
|
-
##
|
74
|
+
## bar mailing list
|
66
75
|
EOF
|
67
76
|
prefix+new_aliases.join("\n")
|
68
77
|
}
|
69
|
-
let(:fake_aliases_file) { mock(File) }
|
70
78
|
|
71
|
-
|
72
|
-
|
73
|
-
|
79
|
+
it "should create the list" do
|
80
|
+
subject.should_receive(:run_command).
|
81
|
+
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
82
|
+
and_return([new_list_return, process])
|
83
|
+
subject.should_receive(:run_command).
|
84
|
+
with("#{fake_root}/bin/list_lists 2>&1", nil).
|
85
|
+
and_return([list_result, process], [list_result_after_create, process])
|
86
|
+
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
|
87
|
+
:admin_password => 'qux')
|
74
88
|
end
|
75
89
|
|
76
|
-
it "should
|
90
|
+
it "should not rely on the aliases setup output" do
|
91
|
+
# https://www.pivotaltracker.com/story/show/9422507
|
92
|
+
subject.should_receive(:run_command).
|
93
|
+
with("#{fake_root}/bin/newlist -q \"bar\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
|
94
|
+
and_return(["", process])
|
77
95
|
subject.should_receive(:run_command).
|
78
|
-
with("#{fake_root}/bin/
|
79
|
-
and_return([
|
80
|
-
subject.create_list(:name => '
|
96
|
+
with("#{fake_root}/bin/list_lists 2>&1", nil).
|
97
|
+
and_return([list_result, process], [list_result_after_create, process])
|
98
|
+
subject.create_list(:name => 'bar', :admin_email => 'foo@bar.baz',
|
81
99
|
:admin_password => 'qux')
|
82
100
|
end
|
101
|
+
|
102
|
+
it "should raise an exception if the list already exists" do
|
103
|
+
# https://www.pivotaltracker.com/story/show/9421449
|
104
|
+
subject.should_not_receive(:run_command).
|
105
|
+
with("#{fake_root}/bin/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil)
|
106
|
+
subject.should_receive(:run_command).
|
107
|
+
with("#{fake_root}/bin/list_lists 2>&1", nil).
|
108
|
+
and_return([list_result, process])
|
109
|
+
lambda {
|
110
|
+
subject.create_list(:name => 'foo', :admin_email => 'foo@bar.baz',
|
111
|
+
:admin_password => 'qux')
|
112
|
+
}.should raise_error(MailManager::ListNameConflictError)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#delete_list" do
|
118
|
+
it "should delete the list" do
|
119
|
+
subject.should_receive(:run_command).
|
120
|
+
with("#{fake_root}/bin/rmlist \"foo\" 2>&1", nil).
|
121
|
+
and_return(["Removing list info", process])
|
122
|
+
subject.delete_list('foo')
|
83
123
|
end
|
84
124
|
end
|
85
125
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 1.0.
|
8
|
+
- 15
|
9
|
+
version: 1.0.15
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Wes Morgan
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01
|
17
|
+
date: 2011-02-01 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -103,6 +103,19 @@ dependencies:
|
|
103
103
|
version: "0"
|
104
104
|
type: :development
|
105
105
|
version_requirements: *id006
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: cucumber
|
108
|
+
prerelease: false
|
109
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
type: :development
|
118
|
+
version_requirements: *id007
|
106
119
|
description: Ruby wrapper library for GNU Mailman's admin functions
|
107
120
|
email: MorganW@dnc.org
|
108
121
|
executables: []
|
@@ -121,6 +134,11 @@ files:
|
|
121
134
|
- LICENSE
|
122
135
|
- README.rdoc
|
123
136
|
- Rakefile
|
137
|
+
- config/cucumber.yml
|
138
|
+
- features/create_list.feature
|
139
|
+
- features/step_definitions/create_list_steps.rb
|
140
|
+
- features/step_definitions/global_steps.rb
|
141
|
+
- features/support/env.rb
|
124
142
|
- lib/mailmanager.rb
|
125
143
|
- lib/mailmanager/lib.rb
|
126
144
|
- lib/mailmanager/list.rb
|