60 6: |
44 6: |
61 7: |
45 7: |
62 8: |
46 8: |
63 9: |
47 9: |
64 EOF |
48 EOF |
65 |
49 |
66 |
50 |
67 it "can create a list" |
51 it "can create a list" |
68 it "can add a new subscriber" |
52 it "can add a new subscriber" |
69 it "can remove a current subscriber" |
53 it "can remove a current subscriber" |
70 it "can edit the list's text files" |
54 it "can edit the list's text files" |
71 |
55 |
72 |
56 |
73 ### |
57 ### |
74 ### List manager functions |
58 ### List manager functions |
75 ### |
59 ### |
76 describe "list manager functions" do |
60 describe "list manager functions" do |
77 |
61 |
78 before( :each ) do |
62 before( :each ) do |
79 @listpath = TEST_LISTDIR.dup |
63 @listpath = TEST_LISTDIR.dup |
80 @list = Ezmlm::List.new( @listpath ) |
64 @list = Ezmlm::List.new( @listpath ) |
81 end |
65 end |
82 |
66 |
83 |
67 |
84 it "can return the configured list name" do |
68 it "can return the configured list name" do |
85 @list.stub!( :config ).and_return({ 'L' => :the_list_name }) |
69 allow(@list).to receive( :config ).and_return({ 'L' => :the_list_name }) |
86 @list.name.should == :the_list_name |
70 expect(@list.name).to eq(:the_list_name) |
87 end |
71 end |
88 |
72 |
89 |
73 |
90 it "can return the configured list host" do |
74 it "can return the configured list host" do |
91 @list.stub!( :config ).and_return({ 'H' => :the_list_host }) |
75 allow(@list).to receive( :config ).and_return({ 'H' => :the_list_host }) |
92 @list.host.should == :the_list_host |
76 expect(@list.host).to eq(:the_list_host) |
93 end |
77 end |
94 |
78 |
95 |
79 |
96 it "can return the configured list address" do |
80 it "can return the configured list address" do |
97 @list.stub!( :config ).and_return({ 'L' => TEST_LIST_NAME, 'H' => TEST_LIST_HOST }) |
81 allow(@list).to receive( :config ).and_return({ 'L' => TEST_LIST_NAME, 'H' => TEST_LIST_HOST }) |
98 @list.address.should == "%s@%s" % [ TEST_LIST_NAME, TEST_LIST_HOST ] |
82 expect(@list.address).to eq("%s@%s" % [ TEST_LIST_NAME, TEST_LIST_HOST ]) |
99 end |
83 end |
100 |
84 |
101 |
85 |
102 CONFIG_KEYS = %w[ F X D T L H C 0 3 4 5 6 7 8 9 ] |
86 CONFIG_KEYS = %w[ F X D T L H C 0 3 4 5 6 7 8 9 ] |
103 |
87 |
104 it "can fetch the list config as a Hash" do |
88 it "can fetch the list config as a Hash" do |
105 config_path = mock( "Mock config path" ) |
89 config_path = double( "Mock config path" ) |
106 @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path ) |
90 expect(@listpath).to receive( :+ ).with( 'config' ).and_return( config_path ) |
107 config_path.should_receive( :exist? ).and_return( true ) |
91 expect(config_path).to receive( :exist? ).and_return( true ) |
108 config_path.should_receive( :read ).and_return( TEST_CONFIG ) |
92 expect(config_path).to receive( :read ).and_return( TEST_CONFIG ) |
109 |
93 |
110 @list.config.should be_an_instance_of( Hash ) |
94 expect(@list.config).to be_an_instance_of( Hash ) |
111 @list.config.should have( CONFIG_KEYS.length ).members |
95 expect(@list.config.size).to eq(CONFIG_KEYS.length) |
112 @list.config.keys.should include( *CONFIG_KEYS ) |
96 expect(@list.config.keys).to include( *CONFIG_KEYS ) |
113 end |
97 end |
114 |
98 |
115 |
99 |
116 it "raises an error if the list config file doesn't exist" do |
100 it "raises an error if the list config file doesn't exist" do |
117 config_path = mock( "Mock config path" ) |
101 config_path = double( "Mock config path" ) |
118 @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path ) |
102 expect(@listpath).to receive( :+ ).with( 'config' ).and_return( config_path ) |
119 config_path.should_receive( :exist? ).and_return( false ) |
103 expect(config_path).to receive( :exist? ).and_return( false ) |
120 |
104 |
121 lambda { |
105 expect { |
122 @list.config |
106 @list.config |
123 }.should raise_error( RuntimeError, /does not exist/ ) |
107 }.to raise_error( RuntimeError, /does not exist/ ) |
124 end |
108 end |
125 |
109 |
126 |
110 |
127 it "can return a list of subscribers' email addresses" do |
111 it "can return a list of subscribers' email addresses" do |
128 subscribers_dir = TEST_LISTDIR + 'subscribers' |
112 subscribers_dir = TEST_LISTDIR + 'subscribers' |
129 |
113 |
130 expectation = Pathname.should_receive( :glob ).with( subscribers_dir + '*' ) |
114 expectation = expect(Pathname).to receive( :glob ).with( subscribers_dir + '*' ) |
131 |
115 |
132 TEST_SUBSCRIBERS.each do |email| |
116 TEST_SUBSCRIBERS.each do |email| |
133 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
117 mock_subfile = double( "Mock subscribers file for '#{email}'" ) |
134 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
118 expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" ) |
135 |
119 |
136 expectation.and_yield( mock_subfile ) |
120 expectation.and_yield( mock_subfile ) |
137 end |
121 end |
138 |
122 |
139 subscribers = @list.subscribers |
123 subscribers = @list.subscribers |
140 |
124 |
141 subscribers.should have(TEST_SUBSCRIBERS.length).members |
125 expect(subscribers.size).to eq(TEST_SUBSCRIBERS.length) |
142 subscribers.should include( *TEST_SUBSCRIBERS ) |
126 expect(subscribers).to include( *TEST_SUBSCRIBERS ) |
143 end |
127 end |
144 |
128 |
145 |
129 |
146 ### Subscriber moderation |
130 ### Subscriber moderation |
147 |
131 |
148 it "knows that subscription moderation is enabled if the dir/modsub file exists" do |
132 it "knows that subscription moderation is enabled if the dir/modsub file exists" do |
149 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
133 modsub_path_obj = double( "Mock 'modsub' path object" ) |
150 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
134 expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
151 modsub_path_obj.should_receive( :exist? ).and_return( true ) |
135 expect(modsub_path_obj).to receive( :exist? ).and_return( true ) |
152 |
136 |
153 @list.should be_closed() |
137 expect(@list).to be_closed() |
154 end |
138 end |
155 |
139 |
156 it "knows that subscription moderation is enabled if the dir/remote file exists" do |
140 it "knows that subscription moderation is enabled if the dir/remote file exists" do |
157 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
141 modsub_path_obj = double( "Mock 'modsub' path object" ) |
158 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
142 expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
159 modsub_path_obj.should_receive( :exist? ).and_return( false ) |
143 expect(modsub_path_obj).to receive( :exist? ).and_return( false ) |
160 |
144 |
161 remote_path_obj = mock( "Mock 'remote' path object" ) |
145 remote_path_obj = double( "Mock 'remote' path object" ) |
162 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
146 expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
163 remote_path_obj.should_receive( :exist? ).and_return( true ) |
147 expect(remote_path_obj).to receive( :exist? ).and_return( true ) |
164 |
148 |
165 @list.should be_closed() |
149 expect(@list).to be_closed() |
166 end |
150 end |
167 |
151 |
168 |
152 |
169 it "knows that subscription moderation is disabled if neither the dir/modsub nor " + |
153 it "knows that subscription moderation is disabled if neither the dir/modsub nor " + |
170 "dir/remote files exist" do |
154 "dir/remote files exist" do |
171 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
155 modsub_path_obj = double( "Mock 'modsub' path object" ) |
172 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
156 expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
173 modsub_path_obj.should_receive( :exist? ).and_return( false ) |
157 expect(modsub_path_obj).to receive( :exist? ).and_return( false ) |
174 |
158 |
175 remote_path_obj = mock( "Mock 'remote' path object" ) |
159 remote_path_obj = double( "Mock 'remote' path object" ) |
176 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
160 expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
177 remote_path_obj.should_receive( :exist? ).and_return( false ) |
161 expect(remote_path_obj).to receive( :exist? ).and_return( false ) |
178 |
162 |
179 @list.should_not be_closed() |
163 expect(@list).not_to be_closed() |
180 end |
164 end |
181 |
165 |
182 |
166 |
183 it "returns an empty array of subscription moderators for an open list" do |
167 it "returns an empty array of subscription moderators for an open list" do |
184 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
168 modsub_path_obj = double( "Mock 'modsub' path object" ) |
185 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
169 expect(@listpath).to receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
186 modsub_path_obj.should_receive( :exist? ).and_return( false ) |
170 expect(modsub_path_obj).to receive( :exist? ).and_return( false ) |
187 |
171 |
188 remote_path_obj = mock( "Mock 'remote' path object" ) |
172 remote_path_obj = double( "Mock 'remote' path object" ) |
189 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
173 expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
190 remote_path_obj.should_receive( :exist? ).and_return( false ) |
174 expect(remote_path_obj).to receive( :exist? ).and_return( false ) |
191 |
175 |
192 @list.subscription_moderators.should be_empty() |
176 expect(@list.subscription_moderators).to be_empty() |
193 end |
177 end |
194 |
178 |
195 it "can return a list of subscription moderators' email addresses" do |
179 it "can return a list of subscription moderators' email addresses" do |
196 # Test the moderation config files for existence |
180 # Test the moderation config files for existence |
197 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
181 modsub_path_obj = double( "Mock 'modsub' path object" ) |
198 @listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
182 expect(@listpath).to receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
199 modsub_path_obj.should_receive( :exist? ).twice.and_return( true ) |
183 expect(modsub_path_obj).to receive( :exist? ).twice.and_return( true ) |
200 remote_path_obj = mock( "Mock 'remote' path object" ) |
184 remote_path_obj = double( "Mock 'remote' path object" ) |
201 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
185 expect(@listpath).to receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
202 remote_path_obj.should_receive( :exist? ).once.and_return( true ) |
186 expect(remote_path_obj).to receive( :exist? ).once.and_return( true ) |
203 |
187 |
204 # Try to read directory names from both config files |
188 # Try to read directory names from both config files |
205 modsub_path_obj.should_receive( :read ).with( 1 ).and_return( nil ) |
189 expect(modsub_path_obj).to receive( :read ).with( 1 ).and_return( nil ) |
206 remote_path_obj.should_receive( :read ).with( 1 ).and_return( nil ) |
190 expect(remote_path_obj).to receive( :read ).with( 1 ).and_return( nil ) |
207 |
191 |
208 # Read subscribers from the default directory |
192 # Read subscribers from the default directory |
209 subscribers_dir = mock( "Mock moderator subscribers directory" ) |
193 subscribers_dir = double( "Mock moderator subscribers directory" ) |
210 @listpath.should_receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir ) |
194 expect(@listpath).to receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir ) |
211 subscribers_dir.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
195 expect(subscribers_dir).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
212 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
196 expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir ) |
213 |
197 |
214 TEST_MODERATORS.each do |email| |
198 TEST_MODERATORS.each do |email| |
215 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
199 mock_subfile = double( "Mock subscribers file for '#{email}'" ) |
216 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
200 expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" ) |
217 |
201 |
218 expectation.and_yield( mock_subfile ) |
202 expectation.and_yield( mock_subfile ) |
219 end |
203 end |
220 |
204 |
221 mods = @list.subscription_moderators |
205 mods = @list.subscription_moderators |
222 mods.should have(TEST_MODERATORS.length).members |
206 expect(mods.size).to eq(TEST_MODERATORS.length) |
223 mods.should include( *TEST_MODERATORS ) |
207 expect(mods).to include( *TEST_MODERATORS ) |
224 end |
208 end |
225 |
209 |
226 |
210 |
227 it "can return a list of subscription moderators' email addresses when the moderators " + |
211 it "can return a list of subscription moderators' email addresses when the moderators " + |
228 "directory has been customized" do |
212 "directory has been customized" do |
229 # Test the moderation config files for existence |
213 # Test the moderation config files for existence |
230 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
214 modsub_path_obj = double( "Mock 'modsub' path object" ) |
231 @listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
215 expect(@listpath).to receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
232 modsub_path_obj.should_receive( :exist? ).twice.and_return( true ) |
216 expect(modsub_path_obj).to receive( :exist? ).twice.and_return( true ) |
233 @listpath.should_receive( :+ ).with( 'remote' ) |
217 expect(@listpath).to receive( :+ ).with( 'remote' ) |
234 |
218 |
235 # Try to read directory names from both config files |
219 # Try to read directory names from both config files |
236 modsub_path_obj.should_receive( :read ).with( 1 ).and_return( '/' ) |
220 expect(modsub_path_obj).to receive( :read ).with( 1 ).and_return( '/' ) |
237 modsub_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
221 expect(modsub_path_obj).to receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
238 |
222 |
239 custom_mod_path = mock( "Mock path object for customized moderator dir" ) |
223 custom_mod_path = double( "Mock path object for customized moderator dir" ) |
240 Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
224 expect(Pathname).to receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
241 |
225 |
242 # Read subscribers from the default file |
226 # Read subscribers from the default file |
243 custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
227 expect(custom_mod_path).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
244 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
228 expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir ) |
245 |
229 |
246 TEST_MODERATORS.each do |email| |
230 TEST_MODERATORS.each do |email| |
247 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
231 mock_subfile = double( "Mock subscribers file for '#{email}'" ) |
248 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
232 expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" ) |
249 |
233 |
250 expectation.and_yield( mock_subfile ) |
234 expectation.and_yield( mock_subfile ) |
251 end |
235 end |
252 |
236 |
253 mods = @list.subscription_moderators |
237 mods = @list.subscription_moderators |
254 mods.should have(TEST_MODERATORS.length).members |
238 expect(mods.size).to eq(TEST_MODERATORS.length) |
255 mods.should include( *TEST_MODERATORS ) |
239 expect(mods).to include( *TEST_MODERATORS ) |
256 end |
240 end |
257 |
241 |
258 it "can get a list of modererators when remote subscription moderation is enabled" + |
242 it "can get a list of modererators when remote subscription moderation is enabled" + |
259 " and the modsub configuration is empty" do |
243 " and the modsub configuration is empty" do |
260 # Test the moderation config files for existence |
244 # Test the moderation config files for existence |
261 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
245 modsub_path_obj = double( "Mock 'modsub' path object" ) |
262 @listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
246 expect(@listpath).to receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
263 modsub_path_obj.should_receive( :exist? ).twice.and_return( false ) |
247 expect(modsub_path_obj).to receive( :exist? ).twice.and_return( false ) |
264 remote_path_obj = mock( "Mock 'remote' path object" ) |
248 remote_path_obj = double( "Mock 'remote' path object" ) |
265 @listpath.should_receive( :+ ).with( 'remote' ).twice.and_return( remote_path_obj ) |
249 expect(@listpath).to receive( :+ ).with( 'remote' ).twice.and_return( remote_path_obj ) |
266 remote_path_obj.should_receive( :exist? ).twice.and_return( true ) |
250 expect(remote_path_obj).to receive( :exist? ).twice.and_return( true ) |
267 |
251 |
268 # Try to read directory names from both config files |
252 # Try to read directory names from both config files |
269 remote_path_obj.should_receive( :read ).with( 1 ).and_return( '/' ) |
253 expect(remote_path_obj).to receive( :read ).with( 1 ).and_return( '/' ) |
270 remote_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
254 expect(remote_path_obj).to receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
271 |
255 |
272 custom_mod_path = mock( "Mock path object for customized moderator dir" ) |
256 custom_mod_path = double( "Mock path object for customized moderator dir" ) |
273 Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
257 expect(Pathname).to receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
274 |
258 |
275 # Read subscribers from the default file |
259 # Read subscribers from the default file |
276 custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
260 expect(custom_mod_path).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
277 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
261 expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir ) |
278 |
262 |
279 TEST_MODERATORS.each do |email| |
263 TEST_MODERATORS.each do |email| |
280 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
264 mock_subfile = double( "Mock subscribers file for '#{email}'" ) |
281 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
265 expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" ) |
282 |
266 |
283 expectation.and_yield( mock_subfile ) |
267 expectation.and_yield( mock_subfile ) |
284 end |
268 end |
285 |
269 |
286 mods = @list.subscription_moderators |
270 mods = @list.subscription_moderators |
287 mods.should have(TEST_MODERATORS.length).members |
271 expect(mods.size).to eq(TEST_MODERATORS.length) |
288 mods.should include( *TEST_MODERATORS ) |
272 expect(mods).to include( *TEST_MODERATORS ) |
289 end |
273 end |
290 |
274 |
291 ### Message moderation |
275 ### Message moderation |
292 |
276 |
293 it "knows that subscription moderation is enabled if the dir/modpost file exists" do |
277 it "knows that subscription moderation is enabled if the dir/modpost file exists" do |
294 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
278 modpost_path_obj = double( "Mock 'modpost' path object" ) |
295 @listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
279 expect(@listpath).to receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
296 modpost_path_obj.should_receive( :exist? ).and_return( true ) |
280 expect(modpost_path_obj).to receive( :exist? ).and_return( true ) |
297 |
281 |
298 @list.should be_moderated() |
282 expect(@list).to be_moderated() |
299 end |
283 end |
300 |
284 |
301 it "knows that subscription moderation is disabled if the dir/modpost file doesn't exist" do |
285 it "knows that subscription moderation is disabled if the dir/modpost file doesn't exist" do |
302 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
286 modpost_path_obj = double( "Mock 'modpost' path object" ) |
303 @listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
287 expect(@listpath).to receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
304 modpost_path_obj.should_receive( :exist? ).and_return( false ) |
288 expect(modpost_path_obj).to receive( :exist? ).and_return( false ) |
305 |
289 |
306 @list.should_not be_moderated() |
290 expect(@list).not_to be_moderated() |
307 end |
291 end |
308 |
292 |
309 |
293 |
310 it "returns an empty array of message moderators for an open list" do |
294 it "returns an empty array of message moderators for an open list" do |
311 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
295 modpost_path_obj = double( "Mock 'modpost' path object" ) |
312 @listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
296 expect(@listpath).to receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
313 modpost_path_obj.should_receive( :exist? ).and_return( false ) |
297 expect(modpost_path_obj).to receive( :exist? ).and_return( false ) |
314 |
298 |
315 @list.message_moderators.should be_empty() |
299 expect(@list.message_moderators).to be_empty() |
316 end |
300 end |
317 |
301 |
318 |
302 |
319 it "can return a list of message moderators' email addresses" do |
303 it "can return a list of message moderators' email addresses" do |
320 # Test the moderation config file for existence |
304 # Test the moderation config file for existence |
321 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
305 modpost_path_obj = double( "Mock 'modpost' path object" ) |
322 @listpath.should_receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj ) |
306 expect(@listpath).to receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj ) |
323 modpost_path_obj.should_receive( :exist? ).twice.and_return( true ) |
307 expect(modpost_path_obj).to receive( :exist? ).twice.and_return( true ) |
324 |
308 |
325 # Try to read directory names from the config file |
309 # Try to read directory names from the config file |
326 modpost_path_obj.should_receive( :read ).with( 1 ).and_return( nil ) |
310 expect(modpost_path_obj).to receive( :read ).with( 1 ).and_return( nil ) |
327 |
311 |
328 # Read subscribers from the default directory |
312 # Read subscribers from the default directory |
329 subscribers_dir = mock( "Mock moderator subscribers directory" ) |
313 subscribers_dir = double( "Mock moderator subscribers directory" ) |
330 @listpath.should_receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir ) |
314 expect(@listpath).to receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir ) |
331 subscribers_dir.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
315 expect(subscribers_dir).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
332 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
316 expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir ) |
333 |
317 |
334 TEST_MODERATORS.each do |email| |
318 TEST_MODERATORS.each do |email| |
335 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
319 mock_subfile = double( "Mock subscribers file for '#{email}'" ) |
336 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
320 expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" ) |
337 |
321 |
338 expectation.and_yield( mock_subfile ) |
322 expectation.and_yield( mock_subfile ) |
339 end |
323 end |
340 |
324 |
341 mods = @list.message_moderators |
325 mods = @list.message_moderators |
342 mods.should have(TEST_MODERATORS.length).members |
326 expect(mods.size).to eq(TEST_MODERATORS.length) |
343 mods.should include( *TEST_MODERATORS ) |
327 expect(mods).to include( *TEST_MODERATORS ) |
344 end |
328 end |
345 |
329 |
346 |
330 |
347 it "can return a list of message moderators' email addresses when the moderators " + |
331 it "can return a list of message moderators' email addresses when the moderators " + |
348 "directory has been customized" do |
332 "directory has been customized" do |
349 # Test the moderation config files for existence |
333 # Test the moderation config files for existence |
350 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
334 modpost_path_obj = double( "Mock 'modpost' path object" ) |
351 @listpath.should_receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj ) |
335 expect(@listpath).to receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj ) |
352 modpost_path_obj.should_receive( :exist? ).twice.and_return( true ) |
336 expect(modpost_path_obj).to receive( :exist? ).twice.and_return( true ) |
353 |
337 |
354 # Try to read directory names from both config files |
338 # Try to read directory names from both config files |
355 modpost_path_obj.should_receive( :read ).with( 1 ).and_return( '/' ) |
339 expect(modpost_path_obj).to receive( :read ).with( 1 ).and_return( '/' ) |
356 modpost_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
340 expect(modpost_path_obj).to receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
357 |
341 |
358 custom_mod_path = mock( "Mock path object for customized moderator dir" ) |
342 custom_mod_path = double( "Mock path object for customized moderator dir" ) |
359 Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
343 expect(Pathname).to receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
360 |
344 |
361 # Read subscribers from the default file |
345 # Read subscribers from the default file |
362 custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
346 expect(custom_mod_path).to receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
363 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
347 expectation = expect(Pathname).to receive( :glob ).with( :mod_sub_dir ) |
364 |
348 |
365 TEST_MODERATORS.each do |email| |
349 TEST_MODERATORS.each do |email| |
366 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
350 mock_subfile = double( "Mock subscribers file for '#{email}'" ) |
367 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
351 expect(mock_subfile).to receive( :read ).and_return( "T#{email}\0" ) |
368 |
352 |
369 expectation.and_yield( mock_subfile ) |
353 expectation.and_yield( mock_subfile ) |
370 end |
354 end |
371 |
355 |
372 mods = @list.message_moderators |
356 mods = @list.message_moderators |
373 mods.should have(TEST_MODERATORS.length).members |
357 expect(mods.size).to eq(TEST_MODERATORS.length) |
374 mods.should include( *TEST_MODERATORS ) |
358 expect(mods).to include( *TEST_MODERATORS ) |
375 end |
359 end |
376 |
360 |
377 |
361 |
378 ### List owner |
362 ### List owner |
379 |
363 |
380 it "returns nil when the list doesn't have an owner in its config" do |
364 it "returns nil when the list doesn't have an owner in its config" do |
381 @list.stub!( :config ).and_return({ '5' => nil }) |
365 allow(@list).to receive( :config ).and_return({ '5' => nil }) |
382 @list.owner.should == nil |
366 expect(@list.owner).to eq(nil) |
383 end |
367 end |
384 |
368 |
385 |
369 |
386 it "can return the email address of the list owner" do |
370 it "can return the email address of the list owner" do |
387 @list.stub!( :config ).and_return({ '5' => TEST_OWNER }) |
371 allow(@list).to receive( :config ).and_return({ '5' => TEST_OWNER }) |
388 @list.owner.should == TEST_OWNER |
372 expect(@list.owner).to eq(TEST_OWNER) |
389 end |
373 end |
390 |
374 |
391 end |
375 end |
392 |
376 |
393 |
377 |
394 ### |
378 ### |
395 ### Archive functions |
379 ### Archive functions |
396 ### |
380 ### |
397 describe "archive functions" do |
381 describe "archive functions" do |
398 |
382 |
399 before( :each ) do |
383 before( :each ) do |
400 @listpath = TEST_LISTDIR.dup |
384 @listpath = TEST_LISTDIR.dup |
401 @list = Ezmlm::List.new( @listpath ) |
385 @list = Ezmlm::List.new( @listpath ) |
402 end |
386 end |
403 |
387 |
404 |
388 |
405 it "can return the count of archived posts" do |
389 it "can return the count of archived posts" do |
406 numpath_obj = mock( "num file path object" ) |
390 numpath_obj = double( "num file path object" ) |
407 @listpath.should_receive( :+ ).with( 'num' ).and_return( numpath_obj ) |
391 expect(@listpath).to receive( :+ ).with( 'num' ).and_return( numpath_obj ) |
408 |
392 |
409 numpath_obj.should_receive( :exist? ).and_return( true ) |
393 expect(numpath_obj).to receive( :exist? ).and_return( true ) |
410 numpath_obj.should_receive( :read ).and_return( "1723:123123123" ) |
394 expect(numpath_obj).to receive( :read ).and_return( "1723:123123123" ) |
411 |
395 |
412 @list.message_count.should == 1723 |
396 expect(@list.message_count).to eq(1723) |
413 end |
397 end |
414 |
398 |
415 it "can return the count of archived posts to a list that hasn't been posted to" do |
399 it "can return the count of archived posts to a list that hasn't been posted to" do |
416 numpath_obj = mock( "num file path object" ) |
400 numpath_obj = double( "num file path object" ) |
417 @listpath.should_receive( :+ ).with( 'num' ).and_return( numpath_obj ) |
401 expect(@listpath).to receive( :+ ).with( 'num' ).and_return( numpath_obj ) |
418 |
402 |
419 numpath_obj.should_receive( :exist? ).and_return( false ) |
403 expect(numpath_obj).to receive( :exist? ).and_return( false ) |
420 |
404 |
421 @list.message_count.should == 0 |
405 expect(@list.message_count).to eq(0) |
422 end |
406 end |
423 |
407 |
424 |
408 |
425 |
409 |
426 TEST_ARCHIVE_DIR = TEST_LISTDIR + 'archive' |
410 TEST_ARCHIVE_DIR = TEST_LISTDIR + 'archive' |
427 TEST_ARCHIVE_SUBDIRS = %w[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ] |
411 TEST_ARCHIVE_SUBDIRS = %w[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 ] |
428 TEST_POST_FILES = %w[ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 ] |
412 TEST_POST_FILES = %w[ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 ] |
429 |
413 |
430 before( :each ) do |
414 before( :each ) do |
433 @archive_subdir_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| TEST_ARCHIVE_DIR + pn } |
417 @archive_subdir_paths = TEST_ARCHIVE_SUBDIRS.collect {|pn| TEST_ARCHIVE_DIR + pn } |
434 @archive_post_paths = TEST_POST_FILES.collect {|pn| |
418 @archive_post_paths = TEST_POST_FILES.collect {|pn| |
435 TEST_ARCHIVE_DIR + TEST_ARCHIVE_SUBDIRS.last + pn |
419 TEST_ARCHIVE_DIR + TEST_ARCHIVE_SUBDIRS.last + pn |
436 } |
420 } |
437 end |
421 end |
438 |
422 |
439 |
423 |
440 it "can return a TMail::Mail object parsed from the last archived post" do |
424 it "can return a TMail::Mail object parsed from the last archived post" do |
441 # need to find the last message |
425 # need to find the last message |
442 archive_path_obj = mock( "archive path" ) |
426 archive_path_obj = double( "archive path" ) |
443 |
427 |
444 @listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
428 expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
445 archive_path_obj.should_receive( :exist? ).and_return( true ) |
429 expect(archive_path_obj).to receive( :exist? ).and_return( true ) |
446 |
430 |
447 # Find the last numbered directory under the archive dir |
431 # Find the last numbered directory under the archive dir |
448 archive_path_obj.should_receive( :+ ).with( '[0-9]*' ). |
432 expect(archive_path_obj).to receive( :+ ).with( '[0-9]*' ). |
449 and_return( :archive_dir_globpath ) |
433 and_return( :archive_dir_globpath ) |
450 Pathname.should_receive( :glob ).with( :archive_dir_globpath ). |
434 expect(Pathname).to receive( :glob ).with( :archive_dir_globpath ). |
451 and_return( @archive_subdir_paths ) |
435 and_return( @archive_subdir_paths ) |
452 |
436 |
453 # Find the last numbered file under the last numbered directory we found |
437 # Find the last numbered file under the last numbered directory we found |
454 # above. |
438 # above. |
455 @archive_subdir_paths.last.should_receive( :+ ).with( '[0-9]*' ). |
439 expect(@archive_subdir_paths.last).to receive( :+ ).with( '[0-9]*' ). |
456 and_return( :archive_post_pathglob ) |
440 and_return( :archive_post_pathglob ) |
457 Pathname.should_receive( :glob ).with( :archive_post_pathglob ). |
441 expect(Pathname).to receive( :glob ).with( :archive_post_pathglob ). |
458 and_return( @archive_post_paths ) |
442 and_return( @archive_post_paths ) |
459 |
443 |
460 TMail::Mail.should_receive( :load ).with( @archive_post_paths.last.to_s ). |
444 expect(TMail::Mail).to receive( :load ).with( @archive_post_paths.last.to_s ). |
461 and_return( :mail_object ) |
445 and_return( :mail_object ) |
462 |
446 |
463 @list.last_post.should == :mail_object |
447 expect(@list.last_post).to eq(:mail_object) |
464 end |
448 end |
465 |
449 |
466 |
450 |
467 it "returns nil for the last post if there is no archive directory for the list" do |
451 it "returns nil for the last post if there is no archive directory for the list" do |
468 archive_path_obj = mock( "archive path" ) |
452 archive_path_obj = double( "archive path" ) |
469 |
453 |
470 @listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
454 expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
471 archive_path_obj.should_receive( :exist? ).and_return( false ) |
455 expect(archive_path_obj).to receive( :exist? ).and_return( false ) |
472 @list.last_post.should == nil |
456 expect(@list.last_post).to eq(nil) |
473 end |
457 end |
474 |
458 |
475 |
459 |
476 it "returns nil for the last post if there haven't been any posts to the list" do |
460 it "returns nil for the last post if there haven't been any posts to the list" do |
477 archive_path_obj = mock( "archive path" ) |
461 archive_path_obj = double( "archive path" ) |
478 mail_object = mock( "Mock TMail object" ) |
462 mail_object = double( "Mock TMail object" ) |
479 |
463 |
480 @listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
464 expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
481 archive_path_obj.should_receive( :exist? ).and_return( true ) |
465 expect(archive_path_obj).to receive( :exist? ).and_return( true ) |
482 |
466 |
483 # Find the last numbered directory under the archive dir |
467 # Find the last numbered directory under the archive dir |
484 archive_path_obj.should_receive( :+ ).with( '[0-9]*' ). |
468 expect(archive_path_obj).to receive( :+ ).with( '[0-9]*' ). |
485 and_return( :archive_dir_globpath ) |
469 and_return( :archive_dir_globpath ) |
486 Pathname.should_receive( :glob ).with( :archive_dir_globpath ).and_return( [] ) |
470 expect(Pathname).to receive( :glob ).with( :archive_dir_globpath ).and_return( [] ) |
487 |
471 |
488 @list.last_post.should == nil |
472 expect(@list.last_post).to eq(nil) |
489 end |
473 end |
490 |
474 |
491 |
475 |
492 it "raises a RuntimeError if the last archive directory doesn't have any messages in it" do |
476 it "raises a RuntimeError if the last archive directory doesn't have any messages in it" do |
493 archive_path_obj = mock( "archive path" ) |
477 archive_path_obj = double( "archive path" ) |
494 mail_object = mock( "Mock TMail object" ) |
478 mail_object = double( "Mock TMail object" ) |
495 |
479 |
496 @listpath.should_receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
480 expect(@listpath).to receive( :+ ).with( 'archive' ).and_return( archive_path_obj ) |
497 archive_path_obj.should_receive( :exist? ).and_return( true ) |
481 expect(archive_path_obj).to receive( :exist? ).and_return( true ) |
498 |
482 |
499 # Find the last numbered directory under the archive dir |
483 # Find the last numbered directory under the archive dir |
500 archive_path_obj.should_receive( :+ ).with( '[0-9]*' ). |
484 expect(archive_path_obj).to receive( :+ ).with( '[0-9]*' ). |
501 and_return( :archive_dir_globpath ) |
485 and_return( :archive_dir_globpath ) |
502 Pathname.should_receive( :glob ).with( :archive_dir_globpath ). |
486 expect(Pathname).to receive( :glob ).with( :archive_dir_globpath ). |
503 and_return( @archive_subdir_paths ) |
487 and_return( @archive_subdir_paths ) |
504 |
488 |
505 @archive_subdir_paths.last.should_receive( :+ ).with( '[0-9]*' ). |
489 expect(@archive_subdir_paths.last).to receive( :+ ).with( '[0-9]*' ). |
506 and_return( :archive_post_pathglob ) |
490 and_return( :archive_post_pathglob ) |
507 Pathname.should_receive( :glob ).with( :archive_post_pathglob ). |
491 expect(Pathname).to receive( :glob ).with( :archive_post_pathglob ). |
508 and_return( [] ) |
492 and_return( [] ) |
509 |
493 |
510 lambda { |
494 expect { |
511 @list.last_post |
495 @list.last_post |
512 }.should raise_error( RuntimeError, /unexpectedly empty/i ) |
496 }.to raise_error( RuntimeError, /unexpectedly empty/i ) |
513 end |
497 end |
514 |
498 |
515 |
499 |
516 it "can fetch the date of the last archived post" do |
500 it "can fetch the date of the last archived post" do |
517 mail_object = mock( "Mock TMail object" ) |
501 mail_object = double( "Mock TMail object" ) |
518 |
502 |
519 @list.should_receive( :last_post ).and_return( mail_object ) |
503 expect(@list).to receive( :last_post ).and_return( mail_object ) |
520 mail_object.should_receive( :date ).and_return( :the_message_date ) |
504 expect(mail_object).to receive( :date ).and_return( :the_message_date ) |
521 |
505 |
522 @list.last_message_date.should == :the_message_date |
506 expect(@list.last_message_date).to eq(:the_message_date) |
523 end |
507 end |
524 |
508 |
525 |
509 |
526 it "can fetch the date of the last archived post" do |
510 it "can fetch the date of the last archived post" do |
527 mail_object = mock( "Mock TMail object" ) |
511 mail_object = double( "Mock TMail object" ) |
528 |
512 |
529 @list.should_receive( :last_post ).and_return( mail_object ) |
513 expect(@list).to receive( :last_post ).and_return( mail_object ) |
530 mail_object.should_receive( :date ).and_return( :the_message_date ) |
514 expect(mail_object).to receive( :date ).and_return( :the_message_date ) |
531 |
515 |
532 @list.last_message_date.should == :the_message_date |
516 expect(@list.last_message_date).to eq(:the_message_date) |
533 end |
517 end |
534 |
518 |
535 |
519 |
536 it "can fetch the author of the last archived post" do |
520 it "can fetch the author of the last archived post" do |
537 mail_object = mock( "Mock TMail object" ) |
521 mail_object = double( "Mock TMail object" ) |
538 |
522 |
539 @list.should_receive( :last_post ).and_return( mail_object ) |
523 expect(@list).to receive( :last_post ).and_return( mail_object ) |
540 mail_object.should_receive( :from ).and_return( :the_message_author ) |
524 expect(mail_object).to receive( :from ).and_return( :the_message_author ) |
541 |
525 |
542 @list.last_message_author.should == :the_message_author |
526 expect(@list.last_message_author).to eq(:the_message_author) |
543 end |
527 end |
544 |
528 |
545 |
529 |
546 it "can fetch the subject of the last archived post" do |
530 it "can fetch the subject of the last archived post" do |
547 mail_object = mock( "Mock TMail object" ) |
531 mail_object = double( "Mock TMail object" ) |
548 |
532 |
549 @list.should_receive( :last_post ).and_return( mail_object ) |
533 expect(@list).to receive( :last_post ).and_return( mail_object ) |
550 mail_object.should_receive( :from ).and_return( :the_message_author ) |
534 expect(mail_object).to receive( :from ).and_return( :the_message_author ) |
551 |
535 |
552 @list.last_message_author.should == :the_message_author |
536 expect(@list.last_message_author).to eq(:the_message_author) |
553 end |
537 end |
554 |
538 |
555 end |
539 end |
556 |
540 |
557 |
541 |
558 it "can fetch the body of an archived post by message id" |
542 it "can fetch the body of an archived post by message id" |
559 it "can fetch the header of an archived post by message id" |
543 it "can fetch the header of an archived post by message id" |
560 |
544 |
561 it "can return a hash of the subjects of all archived posts to message ids" |
545 it "can return a hash of the subjects of all archived posts to message ids" |
562 it "can return an Array of the subjects of all archived posts" |
546 it "can return an Array of the subjects of all archived posts" |
563 |
547 |
564 it "can return a hash of the threads of all archived posts to message ids" |
548 it "can return a hash of the threads of all archived posts to message ids" |
565 it "can return an Array of the threads of all archived posts" |
549 it "can return an Array of the threads of all archived posts" |
566 |
550 |