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 CHANGED
@@ -3,3 +3,4 @@ pkg/mailmanager-*.gem
3
3
  html/*
4
4
  doc/*
5
5
  results/*
6
+ mailman
data/Changelog CHANGED
@@ -1,4 +1,10 @@
1
- Current version is 1.0.14
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.13)
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
@@ -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,4 @@
1
+ When /^I create a new list "([^"]*)"$/ do |list_name|
2
+ @mailmanager.create_list(:name => list_name, :admin_email => 'cuke@foo.org', :admin_password => 'greenisgood')
3
+ end
4
+
@@ -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
+
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', File.dirname(__FILE__))
2
+ require "mailmanager"
@@ -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
@@ -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)
@@ -1,3 +1,3 @@
1
1
  module MailManager
2
- VERSION = '1.0.14'
2
+ VERSION = '1.0.15'
3
3
  end
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
- lists.map { |list| list.name }
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
- raise "#{list_name} list does not exist" unless list_names.include?(list_name.downcase)
100
- MailManager::List.new(list_name)
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
@@ -27,4 +27,5 @@ spec = Gem::Specification.new do |s|
27
27
  s.add_development_dependency('ZenTest', '~>4.4.2')
28
28
  s.add_development_dependency('ruby-debug19')
29
29
  s.add_development_dependency('ci_reporter')
30
+ s.add_development_dependency('cucumber')
30
31
  end
@@ -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 => 'foo', :admin_password => 'qux')
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 => 'foo', :admin_email => 'foo@bar.baz')
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
- ['foo: "|/foo/bar/mail/mailman post foo"',
49
- 'foo-admin: "|/foo/bar/mail/mailman admin foo"',
50
- 'foo-bounces: "|/foo/bar/mail/mailman bounces foo"',
51
- 'foo-confirm: "|/foo/bar/mail/mailman confirm foo"',
52
- 'foo-join: "|/foo/bar/mail/mailman join foo"',
53
- 'foo-leave: "|/foo/bar/mail/mailman leave foo"',
54
- 'foo-owner: "|/foo/bar/mail/mailman owner foo"',
55
- 'foo-request: "|/foo/bar/mail/mailman request foo"',
56
- 'foo-subscribe: "|/foo/bar/mail/mailman subscribe foo"',
57
- 'foo-unsubscribe: "|/foo/bar/mail/mailman unsubscribe foo"']
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
- ## foo mailing list
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
- before :each do
72
- File.stub(:open).with('/etc/aliases', 'a').and_return(fake_aliases_file)
73
- subject.stub(:run_newaliases_command)
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 create the list" do
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/newlist -q \"foo\" \"foo@bar.baz\" \"qux\" 2>&1", nil).
79
- and_return([new_list_return,process])
80
- subject.create_list(:name => 'foo', :admin_email => 'foo@bar.baz',
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
- - 14
9
- version: 1.0.14
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-31 00:00:00 -05:00
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