24 |
24 |
25 describe Ezmlm::List do |
25 describe Ezmlm::List do |
26 include Ezmlm::SpecHelpers |
26 include Ezmlm::SpecHelpers |
27 |
27 |
28 |
28 |
29 it "is well-tested" |
29 LISTDIR = Pathname.new( 'list' ) |
30 |
30 |
|
31 TEST_SUBSCRIBERS = %w[ |
|
32 pete.chaffee@toadsmackers.com |
|
33 dolphinzombie@alahalohamorra.com |
|
34 piratebanker@yahoo.com |
|
35 ] |
|
36 |
|
37 TEST_MODERATORS = %w[ |
|
38 dolphinzombie@alahalohamorra.com |
|
39 ] |
|
40 |
|
41 TEST_OWNER = 'listowner@rumpus-the-whale.info' |
|
42 |
|
43 TEST_CUSTOM_MODERATORS_DIR = '/foo/bar/clowns' |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 it "can create a new list" |
|
49 |
|
50 ### |
|
51 ### List manager functions |
|
52 ### |
|
53 describe "list manager functions" do |
|
54 |
|
55 before( :each ) do |
|
56 @listpath = LISTDIR.dup |
|
57 @list = Ezmlm::List.new( @listpath ) |
|
58 end |
|
59 |
|
60 |
|
61 it "can return a list of subscribers' email addresses" do |
|
62 subscribers_dir = LISTDIR + 'subscribers' |
|
63 |
|
64 expectation = Pathname.should_receive( :glob ).with( subscribers_dir + '*' ) |
|
65 |
|
66 TEST_SUBSCRIBERS.each do |email| |
|
67 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
|
68 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
|
69 |
|
70 expectation.and_yield( mock_subfile ) |
|
71 end |
|
72 |
|
73 subscribers = @list.subscribers |
|
74 |
|
75 subscribers.should have(TEST_SUBSCRIBERS.length).members |
|
76 subscribers.should include( *TEST_SUBSCRIBERS ) |
|
77 end |
|
78 |
|
79 |
|
80 ### Subscriber moderation |
|
81 |
|
82 it "knows that subscription moderation is enabled if the dir/modsub file exists" do |
|
83 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
|
84 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
|
85 modsub_path_obj.should_receive( :exist? ).and_return( true ) |
|
86 |
|
87 @list.should be_closed() |
|
88 end |
|
89 |
|
90 it "knows that subscription moderation is enabled if the dir/remote file exists" do |
|
91 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
|
92 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
|
93 modsub_path_obj.should_receive( :exist? ).and_return( false ) |
|
94 |
|
95 remote_path_obj = mock( "Mock 'remote' path object" ) |
|
96 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
|
97 remote_path_obj.should_receive( :exist? ).and_return( true ) |
|
98 |
|
99 @list.should be_closed() |
|
100 end |
|
101 |
|
102 |
|
103 it "knows that subscription moderation is disabled if neither the dir/modsub nor " + |
|
104 "dir/remote files exist" do |
|
105 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
|
106 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
|
107 modsub_path_obj.should_receive( :exist? ).and_return( false ) |
|
108 |
|
109 remote_path_obj = mock( "Mock 'remote' path object" ) |
|
110 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
|
111 remote_path_obj.should_receive( :exist? ).and_return( false ) |
|
112 |
|
113 @list.should_not be_closed() |
|
114 end |
|
115 |
|
116 |
|
117 it "returns an empty array of subscription moderators for an open list" do |
|
118 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
|
119 @listpath.should_receive( :+ ).with( 'modsub' ).and_return( modsub_path_obj ) |
|
120 modsub_path_obj.should_receive( :exist? ).and_return( false ) |
|
121 |
|
122 remote_path_obj = mock( "Mock 'remote' path object" ) |
|
123 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
|
124 remote_path_obj.should_receive( :exist? ).and_return( false ) |
|
125 |
|
126 @list.subscription_moderators.should be_empty() |
|
127 end |
|
128 |
|
129 it "can return a list of subscription moderators' email addresses" do |
|
130 # Test the moderation config files for existence |
|
131 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
|
132 @listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
|
133 modsub_path_obj.should_receive( :exist? ).twice.and_return( true ) |
|
134 remote_path_obj = mock( "Mock 'remote' path object" ) |
|
135 @listpath.should_receive( :+ ).with( 'remote' ).and_return( remote_path_obj ) |
|
136 remote_path_obj.should_receive( :exist? ).once.and_return( true ) |
|
137 |
|
138 # Try to read directory names from both config files |
|
139 modsub_path_obj.should_receive( :read ).with( 1 ).and_return( nil ) |
|
140 remote_path_obj.should_receive( :read ).with( 1 ).and_return( nil ) |
|
141 |
|
142 # Read subscribers from the default directory |
|
143 subscribers_dir = mock( "Mock moderator subscribers directory" ) |
|
144 @listpath.should_receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir ) |
|
145 subscribers_dir.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
|
146 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
|
147 |
|
148 TEST_MODERATORS.each do |email| |
|
149 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
|
150 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
|
151 |
|
152 expectation.and_yield( mock_subfile ) |
|
153 end |
|
154 |
|
155 mods = @list.subscription_moderators |
|
156 mods.should have(TEST_MODERATORS.length).members |
|
157 mods.should include( *TEST_MODERATORS ) |
|
158 end |
|
159 |
|
160 |
|
161 it "can return a list of subscription moderators' email addresses when the moderators " + |
|
162 "directory has been customized" do |
|
163 # Test the moderation config files for existence |
|
164 modsub_path_obj = mock( "Mock 'modsub' path object" ) |
|
165 @listpath.should_receive( :+ ).with( 'modsub' ).twice.and_return( modsub_path_obj ) |
|
166 modsub_path_obj.should_receive( :exist? ).twice.and_return( true ) |
|
167 @listpath.should_receive( :+ ).with( 'remote' ) |
|
168 |
|
169 # Try to read directory names from both config files |
|
170 modsub_path_obj.should_receive( :read ).with( 1 ).and_return( '/' ) |
|
171 modsub_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
|
172 |
|
173 custom_mod_path = mock( "Mock path object for customized moderator dir" ) |
|
174 Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
|
175 |
|
176 # Read subscribers from the default file |
|
177 custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
|
178 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
|
179 |
|
180 TEST_MODERATORS.each do |email| |
|
181 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
|
182 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
|
183 |
|
184 expectation.and_yield( mock_subfile ) |
|
185 end |
|
186 |
|
187 mods = @list.subscription_moderators |
|
188 mods.should have(TEST_MODERATORS.length).members |
|
189 mods.should include( *TEST_MODERATORS ) |
|
190 end |
|
191 |
|
192 |
|
193 ### Message moderation |
|
194 |
|
195 it "knows that subscription moderation is enabled if the dir/modpost file exists" do |
|
196 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
|
197 @listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
|
198 modpost_path_obj.should_receive( :exist? ).and_return( true ) |
|
199 |
|
200 @list.should be_moderated() |
|
201 end |
|
202 |
|
203 it "knows that subscription moderation is disabled if the dir/modpost file doesn't exist" do |
|
204 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
|
205 @listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
|
206 modpost_path_obj.should_receive( :exist? ).and_return( false ) |
|
207 |
|
208 @list.should_not be_moderated() |
|
209 end |
|
210 |
|
211 |
|
212 it "returns an empty array of message moderators for an open list" do |
|
213 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
|
214 @listpath.should_receive( :+ ).with( 'modpost' ).and_return( modpost_path_obj ) |
|
215 modpost_path_obj.should_receive( :exist? ).and_return( false ) |
|
216 |
|
217 @list.message_moderators.should be_empty() |
|
218 end |
|
219 |
|
220 |
|
221 it "can return a list of message moderators' email addresses" do |
|
222 # Test the moderation config file for existence |
|
223 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
|
224 @listpath.should_receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj ) |
|
225 modpost_path_obj.should_receive( :exist? ).twice.and_return( true ) |
|
226 |
|
227 # Try to read directory names from the config file |
|
228 modpost_path_obj.should_receive( :read ).with( 1 ).and_return( nil ) |
|
229 |
|
230 # Read subscribers from the default directory |
|
231 subscribers_dir = mock( "Mock moderator subscribers directory" ) |
|
232 @listpath.should_receive( :+ ).with( 'mod/subscribers' ).and_return( subscribers_dir ) |
|
233 subscribers_dir.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
|
234 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
|
235 |
|
236 TEST_MODERATORS.each do |email| |
|
237 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
|
238 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
|
239 |
|
240 expectation.and_yield( mock_subfile ) |
|
241 end |
|
242 |
|
243 mods = @list.message_moderators |
|
244 mods.should have(TEST_MODERATORS.length).members |
|
245 mods.should include( *TEST_MODERATORS ) |
|
246 end |
|
247 |
|
248 |
|
249 it "can return a list of message moderators' email addresses when the moderators " + |
|
250 "directory has been customized" do |
|
251 # Test the moderation config files for existence |
|
252 modpost_path_obj = mock( "Mock 'modpost' path object" ) |
|
253 @listpath.should_receive( :+ ).with( 'modpost' ).twice.and_return( modpost_path_obj ) |
|
254 modpost_path_obj.should_receive( :exist? ).twice.and_return( true ) |
|
255 |
|
256 # Try to read directory names from both config files |
|
257 modpost_path_obj.should_receive( :read ).with( 1 ).and_return( '/' ) |
|
258 modpost_path_obj.should_receive( :read ).with().and_return( TEST_CUSTOM_MODERATORS_DIR ) |
|
259 |
|
260 custom_mod_path = mock( "Mock path object for customized moderator dir" ) |
|
261 Pathname.should_receive( :new ).with( TEST_CUSTOM_MODERATORS_DIR ).and_return( custom_mod_path ) |
|
262 |
|
263 # Read subscribers from the default file |
|
264 custom_mod_path.should_receive( :+ ).with( '*' ).and_return( :mod_sub_dir ) |
|
265 expectation = Pathname.should_receive( :glob ).with( :mod_sub_dir ) |
|
266 |
|
267 TEST_MODERATORS.each do |email| |
|
268 mock_subfile = mock( "Mock subscribers file for '#{email}'" ) |
|
269 mock_subfile.should_receive( :read ).and_return( "T#{email}\0" ) |
|
270 |
|
271 expectation.and_yield( mock_subfile ) |
|
272 end |
|
273 |
|
274 mods = @list.message_moderators |
|
275 mods.should have(TEST_MODERATORS.length).members |
|
276 mods.should include( *TEST_MODERATORS ) |
|
277 end |
|
278 |
|
279 |
|
280 ### List owner |
|
281 |
|
282 TEST_CONFIG_WITHOUT_OWNER = <<-"EOF".gsub( /^\t+/, '' ) |
|
283 F:-aBCDeFGHijKlMnOpQrStUVWXYZ |
|
284 X: |
|
285 D:/var/qmail/alias/lists/waffle-lovers/ |
|
286 T:/var/qmail/alias/.qmail-waffle-lovers |
|
287 L:waffle-lovers |
|
288 H:lists.syrup.info |
|
289 C: |
|
290 0: |
|
291 3: |
|
292 4: |
|
293 5: |
|
294 6: |
|
295 7: |
|
296 8: |
|
297 9: |
|
298 EOF |
|
299 |
|
300 it "returns nil when the list doesn't have an owner in its config" do |
|
301 config_path_obj = mock( "Config path object" ) |
|
302 @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path_obj ) |
|
303 config_path_obj.should_receive( :read ).and_return( TEST_CONFIG_WITHOUT_OWNER ) |
|
304 |
|
305 @list.owner.should == nil |
|
306 end |
|
307 |
|
308 |
|
309 TEST_CONFIG_WITH_OWNER = <<-"EOF".gsub( /^\t+/, '' ) |
|
310 F:-aBCDeFGHijKlMnOpQrStUVWXYZ |
|
311 X: |
|
312 D:/var/qmail/alias/lists/waffle-lovers/ |
|
313 T:/var/qmail/alias/.qmail-waffle-lovers |
|
314 L:waffle-lovers |
|
315 H:lists.syrup.info |
|
316 C: |
|
317 0: |
|
318 3: |
|
319 4: |
|
320 5:#{TEST_OWNER} |
|
321 6: |
|
322 7: |
|
323 8: |
|
324 9: |
|
325 EOF |
|
326 |
|
327 it "can return the email address of the list owner" do |
|
328 config_path_obj = mock( "Config path object" ) |
|
329 @listpath.should_receive( :+ ).with( 'config' ).and_return( config_path_obj ) |
|
330 config_path_obj.should_receive( :read ).and_return( TEST_CONFIG_WITH_OWNER ) |
|
331 |
|
332 @list.owner.should == TEST_OWNER |
|
333 end |
|
334 |
|
335 end |
|
336 |
|
337 ### |
|
338 ### Archive functions |
|
339 ### |
|
340 it "can return the count of archived posts" |
|
341 |
|
342 it "can return a hash of the subjects of all archived posts to message ids" |
|
343 it "can return an Array of the subjects of all archived posts" |
|
344 |
|
345 it "can return a hash of the threads of all archived posts to message ids" |
|
346 it "can return an Array of the threads of all archived posts" |
|
347 |
|
348 it "can return a hash of the authors of all archived posts to message ids" |
|
349 it "can return an Array of the authors of all archived posts" |
|
350 |
|
351 |
|
352 it "can fetch the body of an archived post by message id" |
|
353 it "can fetch the header of an archived post by message id" |
|
354 |
|
355 it "can fetch the date of the last archived post" |
|
356 it "can fetch the author of the last archived post" |
|
357 it "can fetch the subject of the last archived post" |
|
358 |
31 end |
359 end |
32 |
360 |
33 |
361 |