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