ruby-net-nntp 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +145 -128
- data/CHANGELOG.debian +5 -0
- data/Manifest.txt +37 -0
- data/README.txt +69 -0
- data/Rakefile +28 -0
- data/build-stamp +0 -0
- data/lib/net/nntp.rb +261 -327
- data/lib/net/nntp/request.rb +840 -0
- data/lib/net/nntp/response.rb +731 -0
- data/lib/net/nntp/version.rb +2 -1
- data/script/console +12 -0
- data/spec/net/nntp/request_spec.rb +771 -0
- data/spec/net/nntp/response_spec.rb +994 -0
- data/spec/net/nntp_spec.rb +634 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/stories/all.rb +2 -0
- data/spec/stories/helper.rb +17 -0
- data/spec/stories/net/nntp.rb +7 -0
- data/spec/stories/net/nntp.story +12 -0
- data/spec/stories/steps/nntp.rb +18 -0
- data/tasks/ann.rake +81 -0
- data/tasks/bones.rake +21 -0
- data/tasks/gem.rake +126 -0
- data/tasks/git.rake +41 -0
- data/tasks/manifest.rake +49 -0
- data/tasks/mercurial.rake +6 -0
- data/tasks/notes.rake +28 -0
- data/tasks/pallet.rake +17 -0
- data/tasks/post_load.rake +39 -0
- data/tasks/rdoc.rake +51 -0
- data/tasks/rubyforge.rake +57 -0
- data/tasks/setup.rb +268 -0
- data/tasks/spec.rake +55 -0
- data/tasks/svn.rake +48 -0
- data/tasks/test.rake +38 -0
- metadata +57 -33
- data/README +0 -46
- data/lib/net/nntp/article.rb +0 -188
- data/lib/net/nntp/group.rb +0 -83
- data/test/functional/test_nntp.rb +0 -288
- data/test/mock/mock_socket.rb +0 -359
- data/test/unit/test_nntp_article.rb +0 -98
- data/test/unit/test_nntp_group.rb +0 -60
data/lib/net/nntp/version.rb
CHANGED
data/script/console
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
$: << 'lib'
|
3
|
+
|
4
|
+
require 'irb'
|
5
|
+
require 'net/nntp'
|
6
|
+
|
7
|
+
Net::NNTP.logger=Log4r::Logger['net::nntp'] || Log4r::Logger.new('net::nntp')
|
8
|
+
Net::NNTP.logger.outputters = Log4r::Outputter.stdout
|
9
|
+
Log4r::Outputter.stdout.formatter = Log4r::PatternFormatter.new(:pattern => '%d [%5l] : %m')
|
10
|
+
|
11
|
+
IRB.start(__FILE__)
|
12
|
+
|
@@ -0,0 +1,771 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), %w[.. .. spec_helper])
|
2
|
+
def body
|
3
|
+
<<-EOF
|
4
|
+
From: "Demo User" <nobody@example.net>
|
5
|
+
Newsgroups: misc.test
|
6
|
+
Subject: I am just a test article
|
7
|
+
Organization: An Example Net
|
8
|
+
|
9
|
+
This is just a test article.
|
10
|
+
.
|
11
|
+
With a special property.
|
12
|
+
EOF
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_body
|
16
|
+
<<-EOF
|
17
|
+
From: Demo User <nobody@example.net>
|
18
|
+
Subject: I am just a test article
|
19
|
+
Newsgroups: misc.test
|
20
|
+
Organization: An Example Net
|
21
|
+
|
22
|
+
This is just a test article.
|
23
|
+
.
|
24
|
+
With a special property.
|
25
|
+
EOF
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'Requests with body', :shared => true do
|
29
|
+
|
30
|
+
it 'should read the body from a string' do
|
31
|
+
@req.body = @body
|
32
|
+
@req.body.to_s.should == @check_body
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should read the body from an IO object' do
|
36
|
+
raw = StringIO.new
|
37
|
+
raw << @body
|
38
|
+
raw.rewind
|
39
|
+
@req.body = raw
|
40
|
+
@req.body.to_s.should == @check_body
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should let the body be filled from a block' do
|
44
|
+
raw = StringIO.new
|
45
|
+
raw << @body
|
46
|
+
raw.rewind
|
47
|
+
@req.instance_variable_set(:@body, nil)
|
48
|
+
@req.body { raw.string }
|
49
|
+
@req.body.to_s.should == @check_body
|
50
|
+
@req.instance_variable_set(:@body, nil)
|
51
|
+
@req.body { raw }
|
52
|
+
@req.body.to_s.should == @check_body
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
describe Net::NNTP::Request do
|
58
|
+
before do
|
59
|
+
@req = Net::NNTP::Request.new('help')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should be able to generate a command' do
|
63
|
+
@req.command.should == "HELP\r\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should accept general responses as valid' do
|
67
|
+
@req.valid_response?(Net::NNTP::NotImplemented.new(@req, '500', 'Not Implemented')).should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should return the indicating capability' do
|
71
|
+
@req.capability.should == 'mandatory'
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
describe Net::NNTP::Help do
|
77
|
+
before do
|
78
|
+
@req = Net::NNTP::Help.new
|
79
|
+
end
|
80
|
+
it 'should generate a HELP command' do
|
81
|
+
@req.command.should == "HELP\r\n"
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should accept HelpResponse as valid' do
|
85
|
+
@req.valid_response?(Net::NNTP::HelpResponse.new(@req, '100', 'Help')).should be_true
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should have "mandatory" as indicating capability' do
|
89
|
+
@req.capability.should == 'mandatory'
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
describe Net::NNTP::Capabilities do
|
95
|
+
before do
|
96
|
+
@req = Net::NNTP::Capabilities.new
|
97
|
+
end
|
98
|
+
it 'should generate a CAPABILITIES command' do
|
99
|
+
@req.command.should == "CAPABILITIES\r\n"
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should accept CapabilityList as valid' do
|
103
|
+
@req.valid_response?(Net::NNTP::CapabilityList.new(@req, '101', 'Capabilities')).should be_true
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should have "mandatory" as indicating capability' do
|
107
|
+
@req.capability.should == 'mandatory'
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
describe Net::NNTP::Modereader do
|
113
|
+
before do
|
114
|
+
@req = Net::NNTP::Modereader.new
|
115
|
+
end
|
116
|
+
it 'should generate a MODE READER command' do
|
117
|
+
@req.command.should == "MODE READER\r\n"
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should accept PostingAllowed as valid' do
|
121
|
+
@req.valid_response?(Net::NNTP::PostingAllowed.new(@req, '200', 'welcome')).should be_true
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should accept PostingProhibited as valid' do
|
125
|
+
@req.valid_response?(Net::NNTP::PostingProhibited.new(@req, '201', 'not allowed')).should be_true
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should have "mode-reader" as indicating capability' do
|
129
|
+
@req.capability.should == 'mode-reader'
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
describe Net::NNTP::Authinfo do
|
135
|
+
before do
|
136
|
+
@req = Net::NNTP::Authinfo.new('user', 'test')
|
137
|
+
end
|
138
|
+
it 'should generate an AUTHINFO USER command' do
|
139
|
+
@req.command.should == "AUTHINFO USER test\r\n"
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should generate an AUTHINFO PASS command' do
|
143
|
+
@req = Net::NNTP::Authinfo.new('pass', 'test')
|
144
|
+
@req.command.should == "AUTHINFO PASS test\r\n"
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should accept PasswordRequired as valid' do
|
148
|
+
@req.valid_response?(Net::NNTP::PasswordRequired.new(@req, '381', 'need password')).should be_true
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should accept AuthenticationAccepted as valid' do
|
152
|
+
@req.valid_response?(Net::NNTP::AuthenticationAccepted.new(@req, '281', 'need password')).should be_true
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should accept AuthenticationFailed as valid' do
|
156
|
+
@req.valid_response?(Net::NNTP::AuthenticationFailed.new(@req, '481', 'authentication failed')).should be_true
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should accept AuthenticationOutOfSequence as valid' do
|
160
|
+
@req.valid_response?(Net::NNTP::AuthenticationOutOfSequence.new(@req, '482', 'authentication out of sequence')).should be_true
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should have "authinfo" as indicating capability' do
|
164
|
+
@req.capability.should == 'authinfo'
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
describe Net::NNTP::Quit do
|
170
|
+
before do
|
171
|
+
@req = Net::NNTP::Quit.new
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should generate a QUIT command' do
|
175
|
+
@req.command.should == "QUIT\r\n"
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should accept ConnectionClosing as valid' do
|
179
|
+
@req.valid_response?(Net::NNTP::ConnectionClosing.new(@req, '205', 'connection closing')).should be_true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe Net::NNTP::Group do
|
184
|
+
before do
|
185
|
+
@req = Net::NNTP::Group.new('example.group')
|
186
|
+
end
|
187
|
+
it 'should generate a GROUP command with a group parameter' do
|
188
|
+
@req.command.should == "GROUP example.group\r\n"
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should accept GroupSelected as valid' do
|
192
|
+
@req.valid_response?(Net::NNTP::GroupSelected.new(@req, '211', '1234 234 567 misc.test')).should be_true
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should have "reader" as indicating capability' do
|
196
|
+
@req.capability.should == 'reader'
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
describe Net::NNTP::Listgroup do
|
202
|
+
before do
|
203
|
+
@req = Net::NNTP::Listgroup.new
|
204
|
+
end
|
205
|
+
it 'should generate a LISTGROUP command without parameters' do
|
206
|
+
@req.command.should == "LISTGROUP\r\n"
|
207
|
+
end
|
208
|
+
it 'should generate a LISTGROUP command with a group parameter' do
|
209
|
+
@req = Net::NNTP::Listgroup.new('example.group')
|
210
|
+
@req.command.should == "LISTGROUP example.group\r\n"
|
211
|
+
end
|
212
|
+
it 'should generate a LISTGROUP command with group and open range parameter' do
|
213
|
+
@req = Net::NNTP::Listgroup.new('example.group', {:start => 1000})
|
214
|
+
@req.command.should == "LISTGROUP example.group 1000-\r\n"
|
215
|
+
end
|
216
|
+
it 'should generate a LISTGROUP command with group and range parameter' do
|
217
|
+
@req = Net::NNTP::Listgroup.new('example.group', {:start => 1000, :end => 10000})
|
218
|
+
@req.command.should == "LISTGROUP example.group 1000-10000\r\n"
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'should accept GroupSelected as valid' do
|
222
|
+
@req.valid_response?(Net::NNTP::GroupSelected.new(@req, '211', '1234 234 567 misc.test')).should be_true
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'should accept GroupUnknown as valid' do
|
226
|
+
@req.valid_response?(Net::NNTP::GroupUnknown.new(@req, '411', 'no such group')).should be_true
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should accept NoGroupSelected as valid' do
|
230
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should have "reader" as indicating capability' do
|
234
|
+
@req.capability.should == 'reader'
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|
239
|
+
describe Net::NNTP::Last do
|
240
|
+
before do
|
241
|
+
@req = Net::NNTP::Last.new
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'should generate a LAST command' do
|
245
|
+
@req.command.should == "LAST\r\n"
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'should accept ArticleSelected as valid' do
|
249
|
+
@req.valid_response?(Net::NNTP::ArticleSelected.new(@req, '223', ' 111 <abc@def.com>')).should be_true
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should accept NoGroupSelected as valid' do
|
253
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should accept InvalidArticle as valid' do
|
257
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'should accept NoPreviousArticle as valid' do
|
261
|
+
@req.valid_response?(Net::NNTP::NoPreviousArticle.new(@req, '422', 'no previous article')).should be_true
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'should have "reader" as indicating capability' do
|
265
|
+
@req.capability.should == 'reader'
|
266
|
+
end
|
267
|
+
|
268
|
+
end
|
269
|
+
|
270
|
+
describe Net::NNTP::Next do
|
271
|
+
before do
|
272
|
+
@req = Net::NNTP::Next.new
|
273
|
+
end
|
274
|
+
it 'should generate a NEXT command' do
|
275
|
+
@req.command.should == "NEXT\r\n"
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should accept ArticleSelected as valid' do
|
279
|
+
@req.valid_response?(Net::NNTP::ArticleSelected.new(@req, '223', ' 111 <abc@def.com>')).should be_true
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should accept NoGroupSelected as valid' do
|
283
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'should accept InvalidArticle as valid' do
|
287
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'should accept NoNextArticle as valid' do
|
291
|
+
@req.valid_response?(Net::NNTP::NoNextArticle.new(@req, '421', 'no next article')).should be_true
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'should have "reader" as indicating capability' do
|
295
|
+
@req.capability.should == 'reader'
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
describe Net::NNTP::Article do
|
301
|
+
before do
|
302
|
+
@req = Net::NNTP::Article.new
|
303
|
+
end
|
304
|
+
it 'should generate a ARTICLE command without parameters' do
|
305
|
+
@req.command.should == "ARTICLE\r\n"
|
306
|
+
end
|
307
|
+
it 'should generate a ARTICLE command with numeric parameter' do
|
308
|
+
@req = Net::NNTP::Article.new(1234)
|
309
|
+
@req.command.should == "ARTICLE 1234\r\n"
|
310
|
+
end
|
311
|
+
it 'should generate a ARTICLE command with string parameter' do
|
312
|
+
@req = Net::NNTP::Article.new('<msg.id@test.host>')
|
313
|
+
@req.command.should == "ARTICLE <msg.id@test.host>\r\n"
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'should accept ArticleResponse as valid' do
|
317
|
+
@req.valid_response?(Net::NNTP::ArticleResponse.new(@req, '220', '1234 <msg.id@test.host>')).should be_true
|
318
|
+
end
|
319
|
+
|
320
|
+
it 'should accept NoGroupSelected as valid' do
|
321
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'should accept InvalidArticle as valid' do
|
325
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'should accept InvalidNumberOrRange as valid' do
|
329
|
+
@req.valid_response?(Net::NNTP::InvalidNumberOrRange.new(@req, '423', 'invalid number or range')).should be_true
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'should accept NoSuchMessageid as valid' do
|
333
|
+
@req.valid_response?(Net::NNTP::NoSuchMessageid.new(@req, '430', 'not found')).should be_true
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'should have "reader" as indicating capability' do
|
337
|
+
@req.capability.should == 'reader'
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
|
342
|
+
describe Net::NNTP::Head do
|
343
|
+
before do
|
344
|
+
@req = Net::NNTP::Head.new
|
345
|
+
end
|
346
|
+
it 'should generate a HEAD command without parameters' do
|
347
|
+
@req.command.should == "HEAD\r\n"
|
348
|
+
end
|
349
|
+
it 'should generate a HEAD command with numeric parameter' do
|
350
|
+
@req = Net::NNTP::Head.new('1234')
|
351
|
+
@req.command.should == "HEAD 1234\r\n"
|
352
|
+
end
|
353
|
+
it 'should generate a HEAD command with string parameter' do
|
354
|
+
@req = Net::NNTP::Head.new('<msg.id@test.host>')
|
355
|
+
@req.command.should == "HEAD <msg.id@test.host>\r\n"
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'should accept HeaderResponse as valid' do
|
359
|
+
@req.valid_response?(Net::NNTP::HeaderResponse.new(@req, '221', 'headers follow')).should be_true
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'should accept NoGroupSelected as valid' do
|
363
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
364
|
+
end
|
365
|
+
|
366
|
+
it 'should accept InvalidArticle as valid' do
|
367
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
368
|
+
end
|
369
|
+
|
370
|
+
it 'should accept InvalidNumberOrRange as valid' do
|
371
|
+
@req.valid_response?(Net::NNTP::InvalidNumberOrRange.new(@req, '423', 'invalid number or range')).should be_true
|
372
|
+
end
|
373
|
+
|
374
|
+
it 'should accept NoSuchMessageid as valid' do
|
375
|
+
@req.valid_response?(Net::NNTP::NoSuchMessageid.new(@req, '430', 'not found')).should be_true
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
describe Net::NNTP::Body do
|
381
|
+
before do
|
382
|
+
@req = Net::NNTP::Body.new
|
383
|
+
end
|
384
|
+
it 'should generate a BODY command without parameters' do
|
385
|
+
@req.command.should == "BODY\r\n"
|
386
|
+
end
|
387
|
+
it 'should generate a BODY command with numeric parameter' do
|
388
|
+
@req = Net::NNTP::Body.new('1234')
|
389
|
+
@req.command.should == "BODY 1234\r\n"
|
390
|
+
end
|
391
|
+
it 'should generate a BODY command with string parameter' do
|
392
|
+
@req = Net::NNTP::Body.new('<msg.id@test.host>')
|
393
|
+
@req.command.should == "BODY <msg.id@test.host>\r\n"
|
394
|
+
end
|
395
|
+
|
396
|
+
it 'should accept BodyResponse as valid' do
|
397
|
+
@req.valid_response?(Net::NNTP::BodyResponse.new(@req, '222', 'body follows')).should be_true
|
398
|
+
end
|
399
|
+
|
400
|
+
it 'should accept NoGroupSelected as valid' do
|
401
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'should accept InvalidArticle as valid' do
|
405
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'should accept InvalidNumberOrRange as valid' do
|
409
|
+
@req.valid_response?(Net::NNTP::InvalidNumberOrRange.new(@req, '423', 'invalid number or range')).should be_true
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'should accept NoSuchMessageid as valid' do
|
413
|
+
@req.valid_response?(Net::NNTP::NoSuchMessageid.new(@req, '430', 'not found')).should be_true
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'should have "reader" as indicating capability' do
|
417
|
+
@req.capability.should == 'reader'
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
421
|
+
|
422
|
+
describe Net::NNTP::Stat do
|
423
|
+
before do
|
424
|
+
@req = Net::NNTP::Stat.new
|
425
|
+
end
|
426
|
+
it 'should generate a STAT command without parameters' do
|
427
|
+
@req.command.should == "STAT\r\n"
|
428
|
+
end
|
429
|
+
it 'should generate a STAT command with numeric parameter' do
|
430
|
+
@req = Net::NNTP::Stat.new('1234')
|
431
|
+
@req.command.should == "STAT 1234\r\n"
|
432
|
+
end
|
433
|
+
it 'should generate a STAT command with string parameter' do
|
434
|
+
@req = Net::NNTP::Stat.new('<msg.id@test.host>')
|
435
|
+
@req.command.should == "STAT <msg.id@test.host>\r\n"
|
436
|
+
end
|
437
|
+
|
438
|
+
it 'should accept ArticleSelected as valid' do
|
439
|
+
@req.valid_response?(Net::NNTP::ArticleSelected.new(@req, '223', ' 1234 <msg.id@test.host>')).should be_true
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'should accept NoGroupSelected as valid' do
|
443
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'should accept InvalidArticle as valid' do
|
447
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
448
|
+
end
|
449
|
+
|
450
|
+
it 'should accept InvalidNumberOrRange as valid' do
|
451
|
+
@req.valid_response?(Net::NNTP::InvalidNumberOrRange.new(@req, '423', 'invalid number or range')).should be_true
|
452
|
+
end
|
453
|
+
|
454
|
+
it 'should accept NoSuchMessageid as valid' do
|
455
|
+
@req.valid_response?(Net::NNTP::NoSuchMessageid.new(@req, '430', 'not found')).should be_true
|
456
|
+
end
|
457
|
+
|
458
|
+
end
|
459
|
+
|
460
|
+
describe Net::NNTP::Post do
|
461
|
+
before do
|
462
|
+
@req = Net::NNTP::Post.new(nil)
|
463
|
+
@body = body()
|
464
|
+
@check_body = check_body()
|
465
|
+
end
|
466
|
+
it 'should generate a POST command' do
|
467
|
+
@req.command.should == "POST\r\n"
|
468
|
+
end
|
469
|
+
|
470
|
+
it 'should have the correct body' do
|
471
|
+
@req = Net::NNTP::Post.new(@body)
|
472
|
+
@req.body.to_s.should == @check_body
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'should accept ArticleReceived as valid' do
|
476
|
+
@req.valid_response?(Net::NNTP::ArticleReceived.new(@req, '240', 'Posting OK')).should be_true
|
477
|
+
end
|
478
|
+
|
479
|
+
it 'should accept PostArticle as valid' do
|
480
|
+
@req.valid_response?(Net::NNTP::PostArticle.new(@req, '340', 'go ahead')).should be_true
|
481
|
+
end
|
482
|
+
|
483
|
+
it 'should accept PostingNotPermitted as valid' do
|
484
|
+
@req.valid_response?(Net::NNTP::PostingNotPermitted.new(@req, '440', 'no go')).should be_true
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'should accept PostingFailed as valid' do
|
488
|
+
@req.valid_response?(Net::NNTP::PostingFailed.new(@req, '441', 'no go')).should be_true
|
489
|
+
end
|
490
|
+
|
491
|
+
it_should_behave_like 'Requests with body'
|
492
|
+
end
|
493
|
+
|
494
|
+
describe Net::NNTP::Ihave do
|
495
|
+
before do
|
496
|
+
@req = Net::NNTP::Ihave.new('<i.am.an.article.you.will.want@example.com>')
|
497
|
+
@body = body()
|
498
|
+
@check_body = check_body()
|
499
|
+
end
|
500
|
+
it 'should generate an IHAVE command with correct parameter' do
|
501
|
+
@req.command.should == "IHAVE <i.am.an.article.you.will.want@example.com>\r\n"
|
502
|
+
end
|
503
|
+
|
504
|
+
it 'should throw ParameterError if the message-id is nil or doesn\'t match' do
|
505
|
+
lambda {
|
506
|
+
@req = Net::NNTP::Ihave.new(nil, "From: demo.user@example.com")
|
507
|
+
}.should raise_error(::Net::NNTP::ParameterError, /must not be nil/i)
|
508
|
+
|
509
|
+
lambda {
|
510
|
+
@req = Net::NNTP::Ihave.new('malformedmessageid123', "From: demo.user@example.com")
|
511
|
+
}.should raise_error(::Net::NNTP::ParameterError, /malformed messageid/i)
|
512
|
+
end
|
513
|
+
|
514
|
+
it 'should have the correct body' do
|
515
|
+
@req = Net::NNTP::Ihave.new("<demo.article@example.com>", body())
|
516
|
+
@req.body.to_s.should == check_body()
|
517
|
+
end
|
518
|
+
|
519
|
+
it 'should accept TransferOK as valid' do
|
520
|
+
@req.valid_response?(Net::NNTP::TransferOK.new(@req, '235', 'Transfer OK')).should be_true
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'should accept TransferArticle as valid' do
|
524
|
+
@req.valid_response?(Net::NNTP::TransferArticle.new(@req, '335', 'Go ahead')).should be_true
|
525
|
+
end
|
526
|
+
|
527
|
+
it 'should accept ArticleNotWanted as valid' do
|
528
|
+
@req.valid_response?(Net::NNTP::ArticleNotWanted.new(@req, '435', 'Go away')).should be_true
|
529
|
+
end
|
530
|
+
|
531
|
+
it 'should accept TransferNotPossible as valid' do
|
532
|
+
@req.valid_response?(Net::NNTP::TransferOK.new(@req, '436', 'Transfer failed')).should be_true
|
533
|
+
end
|
534
|
+
|
535
|
+
it 'should accept TransferRejected as valid' do
|
536
|
+
@req.valid_response?(Net::NNTP::TransferRejected.new(@req, '437', 'Transfer rejected')).should be_true
|
537
|
+
end
|
538
|
+
|
539
|
+
it 'should have "ihave" as indicating capability' do
|
540
|
+
@req.capability.should == 'ihave'
|
541
|
+
end
|
542
|
+
it_should_behave_like 'Requests with body'
|
543
|
+
|
544
|
+
end
|
545
|
+
|
546
|
+
describe Net::NNTP::Date do
|
547
|
+
before do
|
548
|
+
@req = Net::NNTP::Date.new()
|
549
|
+
end
|
550
|
+
it 'should generate a DATE command' do
|
551
|
+
@req.command.should == "DATE\r\n"
|
552
|
+
end
|
553
|
+
|
554
|
+
it 'should accept DateResponse as valid' do
|
555
|
+
@req.valid_response?(Net::NNTP::DateResponse.new(@req, '111', '20080519 17:00:00')).should be_true
|
556
|
+
end
|
557
|
+
|
558
|
+
it 'should have "reader" as indicating capability' do
|
559
|
+
@req.capability.should == 'reader'
|
560
|
+
end
|
561
|
+
|
562
|
+
end
|
563
|
+
|
564
|
+
describe Net::NNTP::Newgroups do
|
565
|
+
before do
|
566
|
+
@req = Net::NNTP::Newgroups.new('2008-11-01 10:12:30', true)
|
567
|
+
end
|
568
|
+
it 'should generate a NEWGROUPS command with correct parameters' do
|
569
|
+
@req.command.should == "NEWGROUPS 20081101 101230 GMT\r\n"
|
570
|
+
@req = Net::NNTP::Newgroups.new('2008-11-01 10:12:30', false)
|
571
|
+
@req.command.should == "NEWGROUPS 20081101 101230\r\n"
|
572
|
+
end
|
573
|
+
|
574
|
+
it 'should accept NewgroupsResponse as valid' do
|
575
|
+
@req.valid_response?(Net::NNTP::NewgroupsResponse.new(@req, '231', 'list follows')).should be_true
|
576
|
+
end
|
577
|
+
|
578
|
+
it 'should have "reader" as indicating capability' do
|
579
|
+
@req.capability.should == 'reader'
|
580
|
+
end
|
581
|
+
|
582
|
+
end
|
583
|
+
|
584
|
+
describe Net::NNTP::Newnews do
|
585
|
+
before do
|
586
|
+
@req = Net::NNTP::Newnews.new(%w{alt.test at.test}, '20081101 101230', true)
|
587
|
+
end
|
588
|
+
it 'should generate a NEWNEWS command with correct parameters' do
|
589
|
+
@req.command.should == "NEWNEWS alt.test,at.test 20081101 101230 GMT\r\n"
|
590
|
+
@req = Net::NNTP::Newnews.new(%w{alt.test at.test}, '20081101 101230', false)
|
591
|
+
@req.command.should == "NEWNEWS alt.test,at.test 20081101 101230\r\n"
|
592
|
+
end
|
593
|
+
|
594
|
+
it 'should accept NewnewsResponse as valid' do
|
595
|
+
@req.valid_response?(Net::NNTP::NewnewsResponse.new(@req, '230', 'list follows')).should be_true
|
596
|
+
end
|
597
|
+
|
598
|
+
end
|
599
|
+
|
600
|
+
describe Net::NNTP::List do
|
601
|
+
before do
|
602
|
+
@req = Net::NNTP::List.new
|
603
|
+
end
|
604
|
+
it 'should generate LIST commands with correct parameters' do
|
605
|
+
@req.command.should == "LIST\r\n"
|
606
|
+
@req = Net::NNTP::List.new('ACTIVE')
|
607
|
+
@req.command.should == "LIST ACTIVE\r\n"
|
608
|
+
@req.keyword.should == "ACTIVE"
|
609
|
+
@req = Net::NNTP::List.new('ACTIVE', '*.test')
|
610
|
+
@req.command.should == "LIST ACTIVE *.test\r\n"
|
611
|
+
@req.keyword.should == "ACTIVE"
|
612
|
+
@req = Net::NNTP::List.new('ACTIVE.TIMES')
|
613
|
+
@req.command.should == "LIST ACTIVE.TIMES\r\n"
|
614
|
+
@req.keyword.should == "ACTIVE.TIMES"
|
615
|
+
@req = Net::NNTP::List.new('ACTIVE.TIMES', 'tx.*')
|
616
|
+
@req.command.should == "LIST ACTIVE.TIMES tx.*\r\n"
|
617
|
+
@req.keyword.should == "ACTIVE.TIMES"
|
618
|
+
@req = Net::NNTP::List.new('NEWSGROUPS')
|
619
|
+
@req.command.should == "LIST NEWSGROUPS\r\n"
|
620
|
+
@req.keyword.should == "NEWSGROUPS"
|
621
|
+
@req = Net::NNTP::List.new('NEWSGROUPS', 'alt.*')
|
622
|
+
@req.command.should == "LIST NEWSGROUPS alt.*\r\n"
|
623
|
+
@req.keyword.should == "NEWSGROUPS"
|
624
|
+
@req = Net::NNTP::List.new('HEADERS', :msgid => '<another.msgid@example.com>')
|
625
|
+
@req.command.should == "LIST HEADERS <another.msgid@example.com>\r\n"
|
626
|
+
@req.keyword.should == "HEADERS"
|
627
|
+
@req = Net::NNTP::List.new('HEADERS', :start => 100)
|
628
|
+
@req.command.should == "LIST HEADERS 100-\r\n"
|
629
|
+
@req.keyword.should == "HEADERS"
|
630
|
+
@req = Net::NNTP::List.new('HEADERS', :start => 100, :end => 200)
|
631
|
+
@req.command.should == "LIST HEADERS 100-200\r\n"
|
632
|
+
@req.keyword.should == "HEADERS"
|
633
|
+
@req = Net::NNTP::List.new('distrib.pats')
|
634
|
+
@req.command.should == "LIST DISTRIB.PATS\r\n"
|
635
|
+
@req.keyword.should == "DISTRIB.PATS"
|
636
|
+
@req = Net::NNTP::List.new('OVERVIEW.FMT')
|
637
|
+
@req.command.should == "LIST OVERVIEW.FMT\r\n"
|
638
|
+
@req.keyword.should == "OVERVIEW.FMT"
|
639
|
+
end
|
640
|
+
|
641
|
+
it 'should accept ListInformationFollows as valid' do
|
642
|
+
@req.valid_response?(Net::NNTP::ListInformationFollows.new(@req, '215', 'list information follows')).should be_true
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'should have "list" as indicating capability' do
|
646
|
+
@req.capability.should == 'list'
|
647
|
+
end
|
648
|
+
|
649
|
+
end
|
650
|
+
|
651
|
+
describe Net::NNTP::Over do
|
652
|
+
before do
|
653
|
+
@req = Net::NNTP::Over.new
|
654
|
+
end
|
655
|
+
it 'should generate OVER commands with correct parameters' do
|
656
|
+
@req.command.should == "OVER\r\n"
|
657
|
+
@req = Net::NNTP::Over.new(:msgid => '<an.other@example.com>')
|
658
|
+
@req.command.should == "OVER <an.other@example.com>\r\n"
|
659
|
+
@req = Net::NNTP::Over.new(:start => 100)
|
660
|
+
@req.command.should == "OVER 100-\r\n"
|
661
|
+
@req = Net::NNTP::Over.new(:start => 100, :end => 200)
|
662
|
+
@req.command.should == "OVER 100-200\r\n"
|
663
|
+
end
|
664
|
+
|
665
|
+
it 'should accept OverviewInformation as valid' do
|
666
|
+
@req.valid_response?(Net::NNTP::OverviewInformation.new(@req, '224', 'information follows')).should be_true
|
667
|
+
end
|
668
|
+
|
669
|
+
it 'should accept NoGroupSelected as valid' do
|
670
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
671
|
+
end
|
672
|
+
|
673
|
+
it 'should accept InvalidArticle as valid' do
|
674
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
675
|
+
end
|
676
|
+
|
677
|
+
it 'should accept InvalidNumberOrRange as valid' do
|
678
|
+
@req.valid_response?(Net::NNTP::InvalidNumberOrRange.new(@req, '423', 'invalid number or range')).should be_true
|
679
|
+
end
|
680
|
+
|
681
|
+
it 'should accept NoSuchMessageid as valid' do
|
682
|
+
@req.valid_response?(Net::NNTP::NoSuchMessageid.new(@req, '430', 'not found')).should be_true
|
683
|
+
end
|
684
|
+
|
685
|
+
it 'should have "over" as indicating capability' do
|
686
|
+
@req.capability.should == 'over'
|
687
|
+
end
|
688
|
+
|
689
|
+
end
|
690
|
+
|
691
|
+
describe Net::NNTP::Hdr do
|
692
|
+
before do
|
693
|
+
@req = Net::NNTP::Hdr.new('Subject')
|
694
|
+
end
|
695
|
+
it 'should generate HDR @reqs with correct parameters' do
|
696
|
+
@req.command.should == "HDR Subject\r\n"
|
697
|
+
@req = Net::NNTP::Hdr.new('Subject', :msgid => '<i.am.here@example.com>')
|
698
|
+
@req.command.should == "HDR Subject <i.am.here@example.com>\r\n"
|
699
|
+
@req = Net::NNTP::Hdr.new('Subject', :start => 100)
|
700
|
+
@req.command.should == "HDR Subject 100-\r\n"
|
701
|
+
@req = Net::NNTP::Hdr.new('Subject', :start => 100, :end => 200)
|
702
|
+
@req.command.should == "HDR Subject 100-200\r\n"
|
703
|
+
end
|
704
|
+
|
705
|
+
it 'should accept HdrResponse as valid' do
|
706
|
+
@req.valid_response?(Net::NNTP::HdrResponse.new(@req, '225', 'header information follows')).should be_true
|
707
|
+
end
|
708
|
+
|
709
|
+
it 'should accept NoGroupSelected as valid' do
|
710
|
+
@req.valid_response?(Net::NNTP::NoGroupSelected.new(@req, '412', 'no newsgroup selected')).should be_true
|
711
|
+
end
|
712
|
+
|
713
|
+
it 'should accept InvalidArticle as valid' do
|
714
|
+
@req.valid_response?(Net::NNTP::InvalidArticle.new(@req, '420', 'no such article number')).should be_true
|
715
|
+
end
|
716
|
+
|
717
|
+
it 'should accept InvalidNumberOrRange as valid' do
|
718
|
+
@req.valid_response?(Net::NNTP::InvalidNumberOrRange.new(@req, '423', 'invalid number or range')).should be_true
|
719
|
+
end
|
720
|
+
|
721
|
+
it 'should accept NoSuchMessageid as valid' do
|
722
|
+
@req.valid_response?(Net::NNTP::NoSuchMessageid.new(@req, '430', 'not found')).should be_true
|
723
|
+
end
|
724
|
+
|
725
|
+
it 'should have "hdr" as indicating capability' do
|
726
|
+
@req.capability.should == 'hdr'
|
727
|
+
end
|
728
|
+
|
729
|
+
end
|
730
|
+
|
731
|
+
describe Net::NNTP::Xhdr do
|
732
|
+
before do
|
733
|
+
@req = Net::NNTP::Xhdr.new('Subject')
|
734
|
+
end
|
735
|
+
it 'should generage XHDR @reqs with correct parameters' do
|
736
|
+
@req.command.should == "XHDR Subject\r\n"
|
737
|
+
@req = Net::NNTP::Xhdr.new('Subject', :msgid => '<i.am.here@example.com>')
|
738
|
+
@req.command.should == "XHDR Subject <i.am.here@example.com>\r\n"
|
739
|
+
@req = Net::NNTP::Xhdr.new('Subject', :start => 100)
|
740
|
+
@req.command.should == "XHDR Subject 100-\r\n"
|
741
|
+
@req = Net::NNTP::Xhdr.new('Subject', :start => 100, :end => 200)
|
742
|
+
@req.command.should == "XHDR Subject 100-200\r\n"
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
describe Net::NNTP::Xover do
|
747
|
+
before do
|
748
|
+
@req = Net::NNTP::Xover.new
|
749
|
+
end
|
750
|
+
it 'should generate XOVER commands with correct parameters' do
|
751
|
+
@req.command.should == "XOVER\r\n"
|
752
|
+
@req = Net::NNTP::Xover.new(:start => 100)
|
753
|
+
@req.command.should == "XOVER 100-\r\n"
|
754
|
+
@req = Net::NNTP::Xover.new(:start => 100, :end => 200)
|
755
|
+
@req.command.should == "XOVER 100-200\r\n"
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
describe Net::NNTP::Xpat do
|
760
|
+
before do
|
761
|
+
@req = Net::NNTP::Xpat.new('Subject', ['is*', '*example*'], :msgid => '<is.an.example@example.com>')
|
762
|
+
end
|
763
|
+
it 'should generate XPAT commands with correct parameters' do
|
764
|
+
@req.command.should == "XPAT Subject <is.an.example@example.com> is* *example*\r\n"
|
765
|
+
@req = Net::NNTP::Xpat.new('Subject', ['is*', '*example*'], :start => 100)
|
766
|
+
@req.command.should == "XPAT Subject 100- is* *example*\r\n"
|
767
|
+
@req = Net::NNTP::Xpat.new('Subject', ['is*', '*example*'], :start => 100, :end => 300)
|
768
|
+
@req.command.should == "XPAT Subject 100-300 is* *example*\r\n"
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|