ruby-net-nntp 0.2.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,634 @@
1
+ require File.join(File.dirname(__FILE__), %w[.. spec_helper])
2
+
3
+ describe Net::NNTP do
4
+ before(:each) do
5
+ @nntp = Net::NNTP.new
6
+ end
7
+
8
+ it 'should have server and port defaulting to localhost' do
9
+ @nntp.host.should == 'localhost'
10
+ @nntp.port.should == 119
11
+ end
12
+
13
+ it 'should be able to process an option hash as argument' do
14
+ nntp = Net::NNTP.new :host => '0.0.0.0', :port => 11911
15
+ nntp.host.should == '0.0.0.0'
16
+ nntp.port.should == 11911
17
+ end
18
+
19
+ it 'should be able to connect' do
20
+ socket = flexmock('socket')
21
+ socket.should_receive(:readline).and_return('200 Mock Server ready')
22
+ socket.should_receive(:closed?).once.and_return(false)
23
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
24
+ tcpsocket.should_receive(:new).once.and_return(socket)
25
+ response = @nntp.connect
26
+ response.should be_kind_of(Net::NNTP::PostingAllowed)
27
+ response.code.should == '200'
28
+ response.message.should == 'Mock Server ready'
29
+ @nntp.should be_connected
30
+ end
31
+
32
+ it 'should be able to close the connection' do
33
+ socket = flexmock('socket')
34
+ socket.should_receive(:readline).once.and_return('200 Mock Server ready').ordered
35
+ socket.should_receive(:closed?).twice.and_return(false).ordered
36
+ socket.should_receive(:close).once.and_return(nil).ordered
37
+ socket.should_receive(:closed?).once.and_return(true).ordered
38
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
39
+ tcpsocket.should_receive(:new).once.and_return(socket)
40
+ response = @nntp.connect
41
+ response.should be_kind_of(Net::NNTP::PostingAllowed)
42
+ response.code.should == '200'
43
+ response.message.should == 'Mock Server ready'
44
+ @nntp.should be_connected
45
+ @nntp.close
46
+ @nntp.should_not be_connected
47
+ end
48
+
49
+ it 'should be able to authenticate automagically' do
50
+ socket = flexmock('socket')
51
+ socket.should_receive(:closed?).and_return(false)
52
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
53
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
54
+ tcpsocket.should_receive(:new).once.and_return(socket)
55
+ response = @nntp.connect
56
+ response.should be_kind_of(Net::NNTP::PostingAllowed)
57
+ socket.should_receive(:write).once.with("GROUP alt.test\r\n").ordered
58
+ socket.should_receive(:readline).once.and_return("480 Authentication required\r\n").ordered
59
+ request = Net::NNTP::Group.new('alt.test')
60
+ response = @nntp.process(request)
61
+ response.should be_kind_of(Net::NNTP::AuthenticationRequired)
62
+ socket.should_receive(:write).once.with("AUTHINFO USER user\r\n").ordered
63
+ socket.should_receive(:readline).once.and_return("381 Password next\r\n").ordered
64
+ socket.should_receive(:write).once.with("AUTHINFO PASS example\r\n").ordered
65
+ socket.should_receive(:readline).once.and_return("281 Welcome\r\n").ordered
66
+ request = Net::NNTP::Authinfo.new('user', 'user')
67
+ response = @nntp.process(request)
68
+ response.should be_kind_of(Net::NNTP::PasswordRequired)
69
+ request = Net::NNTP::Authinfo.new('pass', 'example')
70
+ response = @nntp.process(request)
71
+ response.should be_kind_of(Net::NNTP::AuthenticationAccepted)
72
+ end
73
+
74
+ it 'should be able to process a request and chain the request to the response' do
75
+ socket = flexmock('socket')
76
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
77
+ tcpsocket.should_receive(:new).once.and_return(socket)
78
+ socket.should_expect { |s|
79
+ s.should_be_strict
80
+ s.readline { "200 Mock server ready\r\n" }.once
81
+ s.closed? { false }
82
+ s.write("GROUP alt.test\r\n")
83
+ s.readline {"211 1234 3000234 3002322 misc.test\r\n"}
84
+ }
85
+ response = @nntp.connect
86
+ request = Net::NNTP::Group.new('alt.test')
87
+ @response = @nntp.process(request)
88
+ @response.should == @nntp.last_response
89
+ @response.request.should == request
90
+ end
91
+
92
+ it 'should be able to initialize with a block and close the socket on exiting' do
93
+ socket = flexmock('socket')
94
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
95
+ tcpsocket.should_receive(:new).once.and_return(socket)
96
+ socket.should_expect {|s|
97
+ s.should_be_strict
98
+ s.readline { "200 Mock server ready" }
99
+ s.closed? {false}
100
+ s.write("GROUP misc.test\r\n")
101
+ s.readline {"211 1234 3000234 3002322 misc.test\r\n"}
102
+ s.closed? { false }
103
+ s.close
104
+ s.closed? { true }
105
+ }
106
+ nntp = Net::NNTP.new {|n|
107
+ n.connect
108
+ @response = n.group 'misc.test'
109
+ }
110
+ nntp.should_not be_connected
111
+ end
112
+
113
+ it 'should be able to initialize with a block and close the socket on exception in block' do
114
+ socket = flexmock('socket')
115
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
116
+ tcpsocket.should_receive(:new).once.and_return(socket)
117
+ socket.should_expect {|s|
118
+ s.should_be_strict
119
+ s.readline { "200 Mock server ready" }
120
+ s.closed? { false }
121
+ s.close
122
+ }
123
+ proc do
124
+ Net::NNTP.new {|n|
125
+ n.connect
126
+ raise "some error"
127
+ }
128
+ end.should raise_error(RuntimeError)
129
+ end
130
+
131
+ it 'should record the current group response' do
132
+ socket = flexmock('socket')
133
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
134
+ tcpsocket.should_receive(:new).once.and_return(socket)
135
+ socket.should_receive(:closed?).and_return(false)
136
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
137
+ socket.should_receive(:write).once.with("GROUP alt.test\r\n").ordered
138
+ socket.should_receive(:readline).once.and_return("211 1234 3000234 3002322 misc.test\r\n").ordered
139
+ response = @nntp.connect
140
+ request = Net::NNTP::Group.new('alt.test')
141
+ @response = @nntp.process(request)
142
+ @response.should == @nntp.last_response
143
+ @nntp.current_group.should == @response
144
+ end
145
+
146
+ it 'should record the current selected article' do
147
+ socket = flexmock('socket')
148
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
149
+ tcpsocket.should_receive(:new).once.and_return(socket)
150
+ socket.should_expect { |s|
151
+ s.should_be_strict
152
+ s.readline { "200 Mock Server ready\r\n" }.once
153
+ s.closed? { false }
154
+ s.write("GROUP alt.test\r\n")
155
+ s.readline {"211 1234 3000234 3002322 misc.test\r\n"}.once
156
+ s.closed? { false }
157
+ s.write("NEXT\r\n")
158
+ s.readline {"223 3000237 <668929@example.org> retrieved\r\n"}.once
159
+ }
160
+ #socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
161
+ #socket.should_receive(:closed?).once.and_return(false).ordered
162
+ #socket.should_receive(:write).once.with("GROUP alt.test\r\n").ordered
163
+ #socket.should_receive(:readline).once.and_return("211 1234 3000234 3002322 misc.test\r\n")
164
+ #socket.should_receive(:closed?).once.and_return(false).ordered
165
+ #socket.should_receive(:write).once.with("NEXT\r\n").ordered
166
+ #socket.should_receive(:readline).once.and_return("223 3000237 <668929@example.org> retrieved\r\n").ordered
167
+ response = @nntp.connect
168
+ request = Net::NNTP::Group.new('alt.test')
169
+ @response = @nntp.process(request)
170
+ request = Net::NNTP::Next.new
171
+ @response = @nntp.process(request)
172
+ @nntp.current_article.should == @response
173
+ @nntp.current_article.number.should == 3000237
174
+ end
175
+
176
+ it 'should be able to proxy the authentication cycle' do
177
+ socket = flexmock('socket')
178
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
179
+ tcpsocket.should_receive(:new).once.and_return(socket)
180
+ socket.should_receive(:closed?).and_return(false)
181
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
182
+ socket.should_receive(:write).once.with("GROUP alt.test\r\n").ordered
183
+ socket.should_receive(:readline).once.and_return("480 Authentication required\r\n").ordered
184
+ socket.should_receive(:write).once.with("AUTHINFO USER user\r\n").ordered
185
+ socket.should_receive(:readline).once.and_return("381 Password next\r\n").ordered
186
+ socket.should_receive(:write).once.with("AUTHINFO PASS example\r\n").ordered
187
+ socket.should_receive(:readline).once.and_return("281 Welcome\r\n").ordered
188
+ response = @nntp.connect
189
+ request = Net::NNTP::Group.new('alt.test')
190
+ response = @nntp.process(request)
191
+ @nntp.authenticate('user', 'example').should be_true
192
+ end
193
+
194
+ it 'should be able to reconnect and reauthenticate and replay group and article selection' do
195
+ socket = flexmock('socket')
196
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
197
+ tcpsocket.should_receive(:new).twice.and_return(socket)
198
+ socket.should_expect { |s|
199
+ s.should_be_strict
200
+ s.readline {"200 Mock Server ready\r\n"}
201
+ s.closed? { false }
202
+ s.write("GROUP alt.test\r\n")
203
+ s.readline {"480 Authentication required\r\n"}
204
+ s.closed? { false }
205
+ s.write("AUTHINFO USER user\r\n")
206
+ s.readline {"381 Password next\r\n"}
207
+ s.closed? { false }
208
+ s.write("AUTHINFO PASS example\r\n")
209
+ s.readline {"281 Welcome\r\n"}
210
+ s.closed? { false }
211
+ s.write("GROUP alt.test\r\n")
212
+ s.readline {"211 1234 3000234 3002322 misc.test\r\n"}
213
+ s.closed? { false }
214
+ s.write("STAT\r\n")
215
+ s.readline {"223 3000234 <434234@example.com>\r\n"}
216
+ s.closed? { false }
217
+ s.closed? { false }
218
+ s.close { false }
219
+ s.readline {"200 Mock Server ready\r\n"}
220
+ s.closed? { false }
221
+ s.write("AUTHINFO USER user\r\n")
222
+ s.readline {"381 Password next\r\n"}
223
+ s.closed? { false }
224
+ s.write("AUTHINFO PASS example\r\n")
225
+ s.readline {"281 Welcome\r\n"}
226
+ s.closed? { false }
227
+ s.write("GROUP alt.test\r\n")
228
+ s.readline {"211 1234 3000234 3002322 misc.test\r\n"}
229
+ s.closed? { false }
230
+ s.write("STAT\r\n").once.ordered
231
+ s.readline {"223 3000234 <434234@example.com>\r\n"}
232
+ }
233
+ response = @nntp.connect
234
+ request = Net::NNTP::Group.new('alt.test')
235
+ response = @nntp.process(request)
236
+ @nntp.authenticate('user', 'example').should be_true
237
+ @nntp.group 'alt.test'
238
+ @nntp.stat
239
+ @nntp.reconnect
240
+ end
241
+
242
+ it 'should be able to proxy an ARTICLE command' do
243
+ socket = flexmock('socket')
244
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
245
+ tcpsocket.should_receive(:new).once.and_return(socket)
246
+ socket.should_receive(:closed?).and_return(false)
247
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
248
+ @nntp.connect
249
+ socket.should_receive(:write).once.with("ARTICLE <this.message.id@is.not.invalid.in.my.net>\r\n").ordered
250
+ lines = "220 3000234 <45223423@example.com>\r\nPath: pathost!demo!whitehouse!not-for-mail\r\nFrom: \Demo User\ <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nDate: 6 Oct 1998 04:38:40 -0500\r\nOrganization: An Example Net, Uncertain, Texas\r\nMessage-ID: <45223423@example.com>\r\n\r\nThis is just a test article.\r\n.\r\n"
251
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
252
+ @response = @nntp.article('<this.message.id@is.not.invalid.in.my.net>')
253
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
254
+ @response.article.subject.should == 'I am just a test article'
255
+ end
256
+
257
+ it 'should be able to proxy a BODY command' do
258
+ socket = flexmock('socket')
259
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
260
+ tcpsocket.should_receive(:new).once.and_return(socket)
261
+ socket.should_receive(:closed?).and_return(false)
262
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
263
+ @nntp.connect
264
+ socket.should_receive(:write).once.with("BODY <45223423@example.com>\r\n").ordered
265
+ lines = "222 3000234 <45223423@example.com>\r\nThis is just a test article.\r\n.\r\n"
266
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
267
+ @response = @nntp.body('<45223423@example.com>')
268
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
269
+ end
270
+
271
+ it 'should be able to proxy a HEAD command' do
272
+ socket = flexmock('socket')
273
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
274
+ tcpsocket.should_receive(:new).once.and_return(socket)
275
+ socket.should_receive(:closed?).and_return(false)
276
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
277
+ @nntp.connect
278
+ socket.should_receive(:write).once.with("HEAD <this.message.id@is.not.invalid.in.my.net>\r\n").ordered
279
+ lines ="221 3000234 <45223423@example.com>\r\nPath: pathost!demo!whitehouse!not-for-mail\r\nFrom: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nDate: 6 Oct 1998 04:38:40 -0500\r\nOrganization: An Example Net, Uncertain, Texas\r\nMessage-ID: <45223423@example.com>\r\n.\r\n"
280
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
281
+ @response = @nntp.head('<this.message.id@is.not.invalid.in.my.net>')
282
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
283
+ @response.header['subject'].to_s.should == 'I am just a test article'
284
+ @response['subject'].should == 'I am just a test article'
285
+ end
286
+
287
+ it 'should be able to proxy a HELP command' do
288
+ socket = flexmock('socket')
289
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
290
+ tcpsocket.should_receive(:new).once.and_return(socket)
291
+ socket.should_receive(:closed?).and_return(false)
292
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
293
+ @nntp.connect
294
+ socket.should_receive(:write).once.with("HELP\r\n").ordered
295
+ lines = "100 Help text follows\r\nThis is some help text. There is no specific\r\nformatting requirement for this test, though\r\nit is customary for it to list the valid commands\r\nand give a brief definition of what they do.\r\n.\r\n"
296
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
297
+ @response = @nntp.help
298
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
299
+ end
300
+
301
+ it 'should be able to proxy a GROUP command' do
302
+ socket = flexmock('socket')
303
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
304
+ tcpsocket.should_receive(:new).once.and_return(socket)
305
+ socket.should_receive(:closed?).and_return(false)
306
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
307
+ @nntp.connect
308
+ socket.should_receive(:write).once.with("GROUP misc.test\r\n").ordered
309
+ socket.should_receive(:readline).once.and_return("211 1234 3000234 3002322 misc.test\r\n").ordered
310
+ @response = @nntp.group('misc.test')
311
+ @response.should == Net::NNTP::GroupSelected.new(@response.request, '211', '1234 3000234 3002322 misc.test')
312
+ end
313
+
314
+ it 'should be able to proxy a NEXT command' do
315
+ socket = flexmock('socket')
316
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
317
+ tcpsocket.should_receive(:new).once.and_return(socket)
318
+ socket.should_receive(:closed?).and_return(false)
319
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
320
+ @nntp.connect
321
+ socket.should_receive(:write).once.with("NEXT\r\n").ordered
322
+ socket.should_receive(:readline).once.and_return("412 No group selected\r\n").ordered
323
+ @response = @nntp.next
324
+ @response.should be_a_kind_of(Net::NNTP::NoGroupSelected)
325
+ socket.should_receive(:write).once.with("GROUP misc.test\r\n").ordered
326
+ socket.should_receive(:readline).once.and_return("211 1234 3000234 3002322 misc.test\r\n").ordered
327
+ @response = @nntp.group('misc.test')
328
+ socket.should_receive(:write).once.with("NEXT\r\n").ordered
329
+ socket.should_receive(:readline).once.and_return("223 3000237 <668929@example.org> retrieved\r\n").ordered
330
+ @response = @nntp.next
331
+ @response.should == Net::NNTP::ArticleSelected.new(@response.request, '223', '3000237 <668929@example.org> retrieved')
332
+ end
333
+
334
+ it 'should be able to proxy a LAST command' do
335
+ socket = flexmock('socket')
336
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
337
+ tcpsocket.should_receive(:new).once.and_return(socket)
338
+ socket.should_receive(:closed?).and_return(false)
339
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
340
+ @nntp.connect
341
+ socket.should_receive(:write).once.with("LAST\r\n").ordered
342
+ socket.should_receive(:readline).once.and_return("412 No group selected\r\n").ordered
343
+ @response = @nntp.last
344
+ @response.should be_a_kind_of(Net::NNTP::NoGroupSelected)
345
+ socket.should_receive(:write).once.with("GROUP misc.test\r\n").ordered
346
+ socket.should_receive(:readline).once.and_return("211 1234 3000234 3002322 misc.test\r\n").ordered
347
+ @response = @nntp.group('misc.test')
348
+ socket.should_receive(:write).once.with("LAST\r\n").ordered
349
+ socket.should_receive(:readline).once.and_return("422 No previous article\r\n").ordered
350
+ @response = @nntp.last
351
+ @response.should be_a_kind_of(Net::NNTP::NoPreviousArticle)
352
+ socket.should_receive(:write).once.with("NEXT\r\n").ordered
353
+ socket.should_receive(:readline).once.and_return("223 3000237 <668929@example.org> retrieved\r\n")
354
+ @response = @nntp.next
355
+ @response.should == Net::NNTP::ArticleSelected.new(@response.request, '223', '3000237 <668929@example.org> retrieved')
356
+ socket.should_receive(:write).once.with("LAST\r\n").ordered
357
+ socket.should_receive(:readline).once.and_return("223 3000234 <45223423@example.com> retrieved\r\n")
358
+ @response = @nntp.last
359
+ @response.should == Net::NNTP::ArticleSelected.new(@response.request, '223', '3000234 <45223423@example.com> retrieved')
360
+ end
361
+
362
+ it 'should be able to proxy a LIST (ACTIVE) command' do
363
+ socket = flexmock('socket')
364
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
365
+ tcpsocket.should_receive(:new).once.and_return(socket)
366
+ socket.should_receive(:closed?).and_return(false)
367
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
368
+ @nntp.connect
369
+ socket.should_receive(:write).once.with("LIST\r\n").ordered
370
+ lines ="215 List information follows\r\nat.test 3 5 y\r\nalt.test 8 30 y\r\n.\r\n"
371
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
372
+ @response = @nntp.list
373
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
374
+ @response.list[0].name.should == 'at.test'
375
+ @response.list[0].high.should == 5
376
+ @response.list[0].low.should == 3
377
+ @response.list[0].status.should == 'y'
378
+ end
379
+
380
+ it 'should be able to proxy a LISTGROUP command' do
381
+ socket = flexmock('socket')
382
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
383
+ tcpsocket.should_receive(:new).once.and_return(socket)
384
+ socket.should_receive(:closed?).and_return(false)
385
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
386
+ @nntp.connect
387
+ socket.should_receive(:write).once.with("LISTGROUP\r\n").ordered
388
+ lines = "211 2000 3000234 3002322 misc.test list follows\r\n3000234\r\n3000237\r\n3000238\r\n3000239\r\n3002322\r\n.\r\n"
389
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
390
+ @response = @nntp.listgroup
391
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
392
+ @response.list.should == %w(3000234 3000237 3000238 3000239 3002322)
393
+ end
394
+
395
+ it 'should be able to proxy a QUIT command' do
396
+ socket = flexmock('socket')
397
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
398
+ tcpsocket.should_receive(:new).once.and_return(socket)
399
+ socket.should_receive(:closed?).and_return(false)
400
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
401
+ @nntp.connect
402
+ socket.should_receive(:write).once.with("QUIT\r\n").ordered
403
+ socket.should_receive(:readline).and_return("501 good bye\r\n")
404
+ @response = @nntp.quit
405
+ @response.message.should == 'good bye'
406
+ end
407
+
408
+ it 'should be able to proxy a STAT command' do
409
+ socket = flexmock('socket')
410
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
411
+ tcpsocket.should_receive(:new).once.and_return(socket)
412
+ socket.should_receive(:closed?).and_return(false)
413
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
414
+ @nntp.connect
415
+ socket.should_receive(:write).once.with("STAT <45223423@example.com>\r\n").ordered
416
+ socket.should_receive(:readline).and_return("223 0 <45223423@example.com>\r\n")
417
+ @response = @nntp.stat('<45223423@example.com>')
418
+ @response.code.should == '223'
419
+ @response.number.should == 0
420
+ @response.message_id.should == '<45223423@example.com>'
421
+ end
422
+
423
+ it 'should be able to proxy a HDR command' do
424
+ socket = flexmock('socket')
425
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
426
+ tcpsocket.should_receive(:new).once.and_return(socket)
427
+ socket.should_receive(:closed?).and_return(false)
428
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
429
+ @nntp.connect
430
+ socket.should_receive(:write).once.with("HDR Subject 3000234-3000238\r\n").ordered
431
+ lines = "225 Headers follow\r\n3000234 I am just a test article\r\n3000235\r\n3000237 Re: I am just a test article\r\n3000238 Ditto\r\n.\r\n"
432
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
433
+ @response = @nntp.hdr('Subject', :start => 3000234, :end => 3000238)
434
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
435
+ end
436
+
437
+ it 'should be able to proxy a XHDR command' do
438
+ socket = flexmock('socket')
439
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
440
+ tcpsocket.should_receive(:new).once.and_return(socket)
441
+ socket.should_receive(:closed?).and_return(false)
442
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
443
+ @nntp.connect
444
+ socket.should_receive(:write).once.with("XHDR Subject 3000234-3000238\r\n").ordered
445
+ lines = "221 Headers follow\r\n3000234 I am just a test article\r\n3000235\r\n3000237 Re: I am just a test article\r\n3000238 Ditto\r\n.\r\n"
446
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
447
+ @response = @nntp.xhdr('Subject', :start => 3000234, :end => 3000238)
448
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
449
+ end
450
+
451
+ it 'should be able to proxy an OVER command' do
452
+ socket = flexmock('socket')
453
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
454
+ tcpsocket.should_receive(:new).once.and_return(socket)
455
+ socket.should_receive(:closed?).and_return(false)
456
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
457
+ @nntp.connect
458
+ socket.should_receive(:write).once.with("OVER\r\n").ordered
459
+ lines = "224 Overview Information follows\r\n3000234 I am just a test article \"Demo User\" <nobody@example.com> 6 Oct 1998 04:38:40 -0500 <45223423@example.com> <45454@example.net> 1234 17 Xref: news.example.com misc.test:3000363\r\n.\r\n"
460
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
461
+ @response = @nntp.over
462
+ @response.optional_headers['xref'].should == 'news.example.com misc.test:3000363'
463
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
464
+ end
465
+
466
+ it 'should be able to proxy an XOVER command' do
467
+ socket = flexmock('socket')
468
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
469
+ tcpsocket.should_receive(:new).once.and_return(socket)
470
+ socket.should_receive(:closed?).and_return(false)
471
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
472
+ @nntp.connect
473
+ socket.should_receive(:write).once.with("XOVER\r\n").ordered
474
+ lines = "224 Overview Information follows\r\n3000234 I am just a test article \"Demo User\" <nobody@example.com> 6 Oct 1998 04:38:40 -0500 <45223423@example.com> <45454@example.net> 1234 17 Xref: news.example.com misc.test:3000363\r\n.\r\n"
475
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
476
+ @response = @nntp.xover
477
+ @response.optional_headers['xref'].should == 'news.example.com misc.test:3000363'
478
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
479
+ end
480
+
481
+ it 'should be able to process a posting request' do
482
+ body = "From: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nOrganization: An Example Net\r\n\r\nThis is just a test article.\r\n.but with a trick.\r\n..\r\n.\r\n"
483
+ stuffed = body.gsub(/^\./m, "..")
484
+ article = TMail::Mail.parse(body)
485
+ article_stuffed = TMail::Mail.parse(stuffed)
486
+ socket = flexmock('socket')
487
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
488
+ tcpsocket.should_receive(:new).once.and_return(socket)
489
+ socket.should_receive(:closed?).and_return(false)
490
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
491
+ @nntp.connect
492
+ socket.should_receive(:write).once.with("POST\r\n").ordered
493
+ socket.should_receive(:readline).once.and_return("340 Gimmeh!\r\n").ordered
494
+ article_stuffed.to_s.split(/\r?\n/).each do |line|
495
+ line += "\r\n"
496
+ socket.should_receive(:write).once.with(line).ordered
497
+ end
498
+ socket.should_receive(:write).once.with(".\r\n").ordered
499
+ socket.should_receive(:readline).once.and_return("240 done!\r\n").ordered
500
+ request = Net::NNTP::Post.new
501
+ request.body = body
502
+ response = @nntp.process request
503
+ response.should be_kind_of(Net::NNTP::ArticleReceived)
504
+ end
505
+
506
+ it 'should handle a posting rejection gracefully' do
507
+ body ="From: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nOrganization: An Example Net\r\n\r\nThis is just a test article.\r\n.but with a trick.\r\n..\r\n.\r\n"
508
+ stuffed = body.gsub(/^\./m, "..")
509
+ article = TMail::Mail.parse(body)
510
+ article_stuffed = TMail::Mail.parse(stuffed)
511
+ socket = flexmock('socket')
512
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
513
+ tcpsocket.should_receive(:new).once.and_return(socket)
514
+ socket.should_receive(:closed?).and_return(false)
515
+ socket.should_receive(:readline).once.and_return("201 Mock Server ready - no posting\r\n").ordered
516
+ @nntp.connect
517
+ socket.should_receive(:write).once.with("POST\r\n").ordered
518
+ socket.should_receive(:readline).once.and_return("440 Naaah!\r\n").ordered
519
+ request = Net::NNTP::Post.new
520
+ request.body = body
521
+ response = @nntp.process request
522
+ response.should be_kind_of(Net::NNTP::PostingNotPermitted)
523
+ end
524
+
525
+ it 'should be able to process an ihave request' do
526
+ body = "From: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nOrganization: An Example Net\r\nMessage-ID: <45223423@example.com>\r\n\r\nThis is just a test article.\r\n.but with a trick.\r\n..\r\n.\r\n"
527
+ stuffed = body.gsub(/^\./m, "..")
528
+ article = TMail::Mail.parse(body)
529
+ article_stuffed = TMail::Mail.parse(stuffed).to_s
530
+ socket = flexmock('socket')
531
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
532
+ tcpsocket.should_receive(:new).once.and_return(socket)
533
+ socket.should_receive(:closed?).and_return(false)
534
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
535
+ @nntp.connect
536
+ socket.should_receive(:write).once.with("IHAVE <45223423@example.com>\r\n").ordered
537
+ socket.should_receive(:readline).once.and_return("335 Hand over already!\r\n").ordered
538
+ article_stuffed.split(/\r?\n/).each do |line|
539
+ line += "\r\n"
540
+ socket.should_receive(:write).once.with(line).ordered
541
+ end
542
+ socket.should_receive(:write).once.with(".\r\n").ordered
543
+ socket.should_receive(:readline).once.and_return("235 done!\r\n").ordered
544
+ request = Net::NNTP::Ihave.new('<45223423@example.com>')
545
+ request.body = body
546
+ response = @nntp.process request
547
+ response.should be_kind_of(Net::NNTP::TransferOK)
548
+ end
549
+
550
+ it 'should handle an ihave rejection gracefully' do
551
+ body ="Path: pathost!demo!whitehouse!not-for-mail\r\nFrom: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nDate: 6 Oct 1998 04:38:40 -0500\r\nOrganization: An Example Net, Uncertain, Texas\r\nMessage-ID: <45223423@example.com>\r\n\r\nThis is just a test article.\r\n.with special properties\r\n...\r\n..\r\n.\r\n"
552
+ stuffed = body.gsub(/^\./m, "..")
553
+ article = TMail::Mail.parse(body)
554
+ article_stuffed = TMail::Mail.parse(stuffed).to_s
555
+ socket = flexmock('socket')
556
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
557
+ tcpsocket.should_receive(:new).once.and_return(socket)
558
+ socket.should_receive(:closed?).and_return(false)
559
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
560
+ @nntp.connect
561
+ socket.should_receive(:write).once.with("IHAVE <45223423@example.com>\r\n").ordered
562
+ socket.should_receive(:readline).once.and_return("437 not for yoo!\r\n").ordered
563
+ request = Net::NNTP::Ihave.new('<45223423@example.com>')
564
+ request.body = body
565
+ response = @nntp.process request
566
+ response.should be_kind_of(Net::NNTP::TransferRejected)
567
+ end
568
+
569
+ it 'should be able to process a dotstuffed article response' do
570
+ socket = flexmock('socket')
571
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
572
+ tcpsocket.should_receive(:new).once.and_return(socket)
573
+ socket.should_receive(:closed?).and_return(false)
574
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
575
+ @nntp.connect
576
+ socket.should_receive(:write).once.with("ARTICLE <this.message.id@is.not.invalid.in.my.net>\r\n").ordered
577
+ lines ="220 3000234 <45223423@example.com>\r\nPath: pathost!demo!whitehouse!not-for-mail\r\nFrom: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nDate: 6 Oct 1998 04:38:40 -0500\r\nOrganization: An Example Net, Uncertain, Texas\r\nMessage-ID: <45223423@example.com>\r\n\r\nThis is just a test article.\r\n.with special properties\r\n...\r\n..\r\n.\r\n"
578
+ preamble ="This is just a test article.\r\nwith special properties\r\n..\r\n.\r\n\r\n"
579
+ socket.should_receive(:readline).and_return(*lines.scan(/.*\r\n/))
580
+ @response = @nntp.article('<this.message.id@is.not.invalid.in.my.net>')
581
+ @response.raw.should == lines.scan(/.*\r\n/)[1..-1].join
582
+ @response.article.subject.should == 'I am just a test article'
583
+ @response.article.preamble.should == preamble
584
+ end
585
+
586
+ it 'should be able to proxy a POST request' do
587
+ body ="From: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nOrganization: An Example Net\r\n\r\nThis is just a test article.\r\n.but with a trick.\r\n..\r\n.\r\n"
588
+ stuffed = body.gsub(/^\./m, "..")
589
+ article = TMail::Mail.parse(body)
590
+ article_stuffed = TMail::Mail.parse(stuffed)
591
+ socket = flexmock('socket')
592
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
593
+ tcpsocket.should_receive(:new).once.and_return(socket)
594
+ socket.should_receive(:closed?).and_return(false)
595
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
596
+ @nntp.connect
597
+ socket.should_receive(:write).once.with("POST\r\n").ordered
598
+ socket.should_receive(:readline).once.and_return("340 Gimmeh!\r\n").ordered
599
+ article_stuffed.to_s.split(/\r?\n/).each do |line|
600
+ line += "\r\n"
601
+ socket.should_receive(:write).once.with(line).ordered
602
+ end
603
+ socket.should_receive(:write).once.with(".\r\n").ordered
604
+ socket.should_receive(:readline).once.and_return("240 done!\r\n").ordered
605
+ response = @nntp.post(body)
606
+ response.should be_kind_of(Net::NNTP::ArticleReceived)
607
+ end
608
+
609
+ it 'should be able to proxy an IHAVE command' do
610
+ body = "From: \"Demo User\" <nobody@example.net>\r\nNewsgroups: misc.test\r\nSubject: I am just a test article\r\nOrganization: An Example Net\r\nMessage-ID: <45223423@example.com>\r\n\r\nThis is just a test article.\r\n.but with a trick.\r\n..\r\n.\r\n"
611
+ stuffed = body.gsub(/^\./m, "..")
612
+ article = TMail::Mail.parse(body)
613
+ article_stuffed = TMail::Mail.parse(stuffed).to_s
614
+ socket = flexmock('socket')
615
+ tcpsocket = flexmock(TCPSocket, 'tcpsocket')
616
+ tcpsocket.should_receive(:new).once.and_return(socket)
617
+ socket.should_receive(:closed?).and_return(false)
618
+ socket.should_receive(:readline).once.and_return("200 Mock Server ready\r\n").ordered
619
+ @nntp.connect
620
+ socket.should_receive(:write).once.with("IHAVE <45223423@example.com>\r\n").ordered
621
+ socket.should_receive(:readline).once.and_return("335 Hand over already!\r\n").ordered
622
+ article_stuffed.to_s.split(/\r?\n/).each do |line|
623
+ line += "\r\n"
624
+ socket.should_receive(:write).once.with(line).ordered
625
+ end
626
+ socket.should_receive(:write).once.with(".\r\n").ordered
627
+ socket.should_receive(:readline).once.and_return("235 done!\r\n").ordered
628
+ response = @nntp.ihave('<45223423@example.com>', body)
629
+ response.should be_kind_of(Net::NNTP::TransferOK)
630
+ end
631
+
632
+
633
+ end
634
+ # EOF