fake_ftp 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,3 @@
1
1
  module FakeFtp
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -8,48 +8,63 @@ describe FakeFtp::File do
8
8
 
9
9
  it "has a name attribute" do
10
10
  @file.name = "some name"
11
- @file.name.should == "some name"
11
+ expect(@file.name).to eql("some name")
12
+ end
13
+
14
+ it "has a last_modified_time attribute" do
15
+ now = Time.now
16
+ @file.last_modified_time = now
17
+ expect(@file.last_modified_time).to eql(now)
12
18
  end
13
19
 
14
20
  it "has a bytes attribute" do
15
21
  @file.bytes = 87
16
- @file.bytes.should == 87
22
+ expect(@file.bytes).to eql(87)
17
23
  end
18
24
 
19
25
  it "has a data attribute" do
20
26
  @file.data = 'some data'
21
- @file.data.should == 'some data'
22
- @file.bytes.should == 'some data'.length
27
+ expect(@file.data).to eql('some data')
28
+ expect(@file.bytes).to eql('some data'.length)
23
29
  end
24
30
  end
25
31
 
26
32
  context 'setup' do
27
33
  it "can be initialized without attributes" do
28
34
  file = FakeFtp::File.new
29
- file.name.should be_nil
30
- file.bytes.should be_nil
31
- file.instance_variable_get(:@type).should be_nil
35
+ expect(file.name).to be_nil
36
+ expect(file.bytes).to be_nil
37
+ expect(file.instance_variable_get(:@type)).to be_nil
32
38
  end
33
39
 
34
40
  it "can be initialized with name" do
35
41
  file = FakeFtp::File.new('filename')
36
- file.name.should == 'filename'
37
- file.bytes.should be_nil
38
- file.instance_variable_get(:@type).should be_nil
42
+ expect(file.name).to eql('filename')
43
+ expect(file.bytes).to be_nil
44
+ expect(file.instance_variable_get(:@type)).to be_nil
39
45
  end
40
46
 
41
47
  it "can be initialized with name and bytes" do
42
48
  file = FakeFtp::File.new('filename', 104)
43
- file.name.should == 'filename'
44
- file.bytes.should == 104
45
- file.instance_variable_get(:@type).should be_nil
49
+ expect(file.name).to eql('filename')
50
+ expect(file.bytes).to eql(104)
51
+ expect(file.instance_variable_get(:@type)).to be_nil
46
52
  end
47
-
53
+
48
54
  it "can be initialized with name and bytes and type" do
49
55
  file = FakeFtp::File.new('filename', 104, :passive)
50
- file.name.should == 'filename'
51
- file.bytes.should == 104
52
- file.instance_variable_get(:@type).should == :passive
56
+ expect(file.name).to eql('filename')
57
+ expect(file.bytes).to eql(104)
58
+ expect(file.instance_variable_get(:@type)).to eql(:passive)
59
+ end
60
+
61
+ it "can be initialized with name and bytes and type and last_modified_time" do
62
+ time = Time.now
63
+ file = FakeFtp::File.new('filename', 104, :passive, time)
64
+ expect(file.name).to eql('filename')
65
+ expect(file.bytes).to eql(104)
66
+ expect(file.instance_variable_get(:@type)).to eql(:passive)
67
+ expect(file.last_modified_time).to eql(time)
53
68
  end
54
69
  end
55
70
 
@@ -60,12 +75,12 @@ describe FakeFtp::File do
60
75
 
61
76
  it "should be true if type is :passive" do
62
77
  @file.type = :passive
63
- @file.passive?.should be_true
78
+ expect(@file.passive?).to be_true
64
79
  end
65
80
 
66
81
  it "should be false if type is :active" do
67
82
  @file.type = :active
68
- @file.passive?.should be_false
83
+ expect(@file.passive?).to be_false
69
84
  end
70
85
  end
71
86
 
@@ -76,12 +91,12 @@ describe FakeFtp::File do
76
91
 
77
92
  it "should be true if type is :active" do
78
93
  @file.type = :active
79
- @file.active?.should be_true
94
+ expect(@file.active?).to be_true
80
95
  end
81
96
 
82
97
  it "should be false if type is :passive" do
83
98
  @file.type = :passive
84
- @file.active?.should be_false
99
+ expect(@file.active?).to be_false
85
100
  end
86
101
  end
87
102
  end
@@ -4,53 +4,53 @@ require 'net/ftp'
4
4
  describe FakeFtp::Server, 'setup' do
5
5
  it "starts a server on port n" do
6
6
  server = FakeFtp::Server.new(21212)
7
- server.port.should == 21212
7
+ expect(server.port).to eql(21212)
8
8
  end
9
9
 
10
10
  it "should defaults to port 21" do
11
11
  server = FakeFtp::Server.new
12
- server.port.should == 21
12
+ expect(server.port).to eql(21)
13
13
  end
14
14
 
15
15
  it "starts a passive server on port p" do
16
16
  server = FakeFtp::Server.new(21212, 21213)
17
- server.passive_port.should == 21213
17
+ expect(server.passive_port).to eql(21213)
18
18
  end
19
19
 
20
20
  it "should start and stop" do
21
21
  server = FakeFtp::Server.new(21212)
22
- server.is_running?.should be_false
22
+ expect(server.is_running?).to be_false
23
23
  server.start
24
- server.is_running?.should be_true
24
+ expect(server.is_running?).to be_true
25
25
  server.stop
26
- server.is_running?.should be_false
26
+ expect(server.is_running?).to be_false
27
27
  end
28
28
 
29
29
  it "should default :mode to :active" do
30
30
  server = FakeFtp::Server.new(21212, 21213)
31
- server.mode.should == :active
31
+ expect(server.mode).to eql(:active)
32
32
  end
33
33
 
34
34
  it "should start and stop passive port" do
35
35
  server = FakeFtp::Server.new(21212, 21213)
36
- server.is_running?(21213).should be_false
36
+ expect(server.is_running?(21213)).to be_false
37
37
  server.start
38
- server.is_running?(21213).should be_true
38
+ expect(server.is_running?(21213)).to be_true
39
39
  server.stop
40
- server.is_running?(21213).should be_false
40
+ expect(server.is_running?(21213)).to be_false
41
41
  end
42
42
 
43
43
  it "should raise if attempting to use a bound port" do
44
44
  server = FakeFtp::Server.new(21212)
45
45
  server.start
46
- proc { FakeFtp::Server.new(21212) }.should raise_error(Errno::EADDRINUSE, "Address already in use - 21212")
46
+ expect { FakeFtp::Server.new(21212) }.to raise_error(Errno::EADDRINUSE, "Address already in use - 21212")
47
47
  server.stop
48
48
  end
49
49
 
50
50
  it "should raise if attempting to use a bound passive_port" do
51
51
  server = FakeFtp::Server.new(21212, 21213)
52
52
  server.start
53
- proc { FakeFtp::Server.new(21214, 21213) }.should raise_error(Errno::EADDRINUSE, "Address already in use - 21213")
53
+ expect { FakeFtp::Server.new(21214, 21213) }.to raise_error(Errno::EADDRINUSE, "Address already in use - 21213")
54
54
  server.stop
55
55
  end
56
56
  end
@@ -62,106 +62,96 @@ describe FakeFtp::Server, 'files' do
62
62
  before { server.instance_variable_set(:@files, [file]) }
63
63
 
64
64
  it "returns filenames from :files" do
65
- server.files.should include('filename')
65
+ expect(server.files).to include('filename')
66
66
  end
67
67
 
68
68
  it "can be accessed with :file" do
69
- server.file('filename').should == file
69
+ expect(server.file('filename')).to eql(file)
70
70
  end
71
71
 
72
72
  it "can reset files" do
73
73
  server.reset
74
- server.files.should == []
74
+ expect(server.files).to eql([])
75
75
  end
76
76
  end
77
77
 
78
78
  describe FakeFtp::Server, 'commands' do
79
79
  let(:server) { FakeFtp::Server.new(21212, 21213) }
80
+ let(:client) { TCPSocket.open('127.0.0.1', 21212) }
80
81
 
81
82
  before { server.start }
82
- after { server.stop }
83
+ after {
84
+ client.close
85
+ server.stop
86
+ }
83
87
 
84
88
  context 'general' do
85
- before :each do
86
- @client = TCPSocket.open('127.0.0.1', 21212)
87
- end
88
-
89
- after :each do
90
- @client.close
91
- end
92
89
 
93
90
  it "should accept connections" do
94
- @client.gets.should == "220 Can has FTP?\r\n"
91
+ expect(client.gets).to eql("220 Can has FTP?\r\n")
95
92
  end
96
93
 
97
94
  it "should get unknown command response when nothing is sent" do
98
- @client.gets
99
- @client.puts
100
- @client.gets.should == "500 Unknown command\r\n"
95
+ client.gets
96
+ client.puts
97
+ expect(client.gets).to eql("500 Unknown command\r\n")
101
98
  end
102
99
 
103
100
  it "accepts QUIT" do
104
- @client.gets
105
- @client.puts "QUIT"
106
- @client.gets.should == "221 OMG bye!\r\n"
101
+ client.gets
102
+ client.puts "QUIT"
103
+ expect(client.gets).to eql("221 OMG bye!\r\n")
107
104
  end
108
105
 
109
106
  it "should accept multiple commands in one session" do
110
- @client.gets
111
- @client.puts "USER thing"
112
- @client.gets
113
- @client.puts "PASS thing"
114
- @client.gets
115
- @client.puts "ACCT thing"
116
- @client.gets
117
- @client.puts "USER thing"
107
+ client.gets
108
+ client.puts "USER thing"
109
+ client.gets
110
+ client.puts "PASS thing"
111
+ client.gets
112
+ client.puts "ACCT thing"
113
+ client.gets
114
+ client.puts "USER thing"
118
115
  end
119
116
  end
120
117
 
121
118
  context 'passive' do
122
- after :each do
123
- @client.close
124
- end
125
119
 
126
120
  it "accepts PASV" do
127
- server.mode.should == :active
128
- @client = TCPSocket.open('127.0.0.1', 21212)
129
- @client.gets
130
- @client.puts "PASV"
131
- @client.gets.should == "227 Entering Passive Mode (127,0,0,1,82,221)\r\n"
132
- server.mode.should == :passive
121
+ expect(server.mode).to eql(:active)
122
+ client.gets
123
+ client.puts "PASV"
124
+ expect(client.gets).to eql("227 Entering Passive Mode (127,0,0,1,82,221)\r\n")
125
+ expect(server.mode).to eql(:passive)
133
126
  end
134
127
 
135
128
  it "responds with correct PASV port" do
136
129
  server.stop
137
130
  server.passive_port = 21111
138
131
  server.start
139
- @client = TCPSocket.open('127.0.0.1', 21212)
140
- @client.gets
141
- @client.puts "PASV"
142
- @client.gets.should == "227 Entering Passive Mode (127,0,0,1,82,119)\r\n"
132
+ client.gets
133
+ client.puts "PASV"
134
+ expect(client.gets).to eql("227 Entering Passive Mode (127,0,0,1,82,119)\r\n")
143
135
  end
144
136
 
145
137
  it "does not accept PASV if no port set" do
146
138
  server.stop
147
139
  server.passive_port = nil
148
140
  server.start
149
- @client = TCPSocket.open('127.0.0.1', 21212)
150
- @client.gets
151
- @client.puts "PASV"
152
- @client.gets.should == "502 Aww hell no, use Active\r\n"
141
+ client.gets
142
+ client.puts "PASV"
143
+ expect(client.gets).to eql("502 Aww hell no, use Active\r\n")
153
144
  end
154
145
  end
155
146
 
156
147
  context 'active' do
157
148
  before :each do
158
- @client = TCPSocket.open('127.0.0.1', 21212)
159
- @client.gets
149
+ client.gets
160
150
 
161
151
  @data_server = ::TCPServer.new('127.0.0.1', 21216)
162
152
  @data_connection = Thread.new do
163
153
  @server_client = @data_server.accept
164
- @server_client.should_not be_nil
154
+ expect(@server_client).to_not be_nil
165
155
  end
166
156
  end
167
157
 
@@ -169,188 +159,252 @@ describe FakeFtp::Server, 'commands' do
169
159
  @data_server.close
170
160
  @data_server = nil
171
161
  @data_connection = nil
172
- @client.close
173
162
  end
174
163
 
175
164
  it "accepts PORT and connects to port" do
176
- @client.puts "PORT 127,0,0,1,82,224"
177
- @client.gets.should == "200 Okay\r\n"
165
+ client.puts "PORT 127,0,0,1,82,224"
166
+ expect(client.gets).to eql("200 Okay\r\n")
178
167
 
179
168
  @data_connection.join
180
169
  end
181
170
 
182
171
  it "should switch to :active on port command" do
183
- server.mode.should == :active
184
- @client.puts 'PASV'
185
- @client.gets
186
- server.mode.should == :passive
172
+ expect(server.mode).to eql(:active)
173
+ client.puts 'PASV'
174
+ client.gets
175
+ expect(server.mode).to eql(:passive)
187
176
 
188
- @client.puts "PORT 127,0,0,1,82,224"
189
- @client.gets.should == "200 Okay\r\n"
177
+ client.puts "PORT 127,0,0,1,82,224"
178
+ expect(client.gets).to eql("200 Okay\r\n")
190
179
 
191
180
  @data_connection.join
192
181
 
193
- server.mode.should == :active
182
+ expect(server.mode).to eql(:active)
194
183
  end
195
184
  end
196
185
 
197
186
  context 'authentication commands' do
198
187
  before :each do
199
- @client = TCPSocket.open('127.0.0.1', 21212)
200
- @client.gets ## connection successful response
201
- end
202
-
203
- after :each do
204
- @client.close
188
+ client.gets ## connection successful response
205
189
  end
206
190
 
207
191
  it "accepts USER" do
208
- @client.puts "USER some_dude"
209
- @client.gets.should == "331 send your password\r\n"
192
+ client.puts "USER some_dude"
193
+ expect(client.gets).to eql("331 send your password\r\n")
210
194
  end
211
195
 
212
196
  it "accepts anonymous USER" do
213
- @client.puts "USER anonymous"
214
- @client.gets.should == "230 logged in\r\n"
197
+ client.puts "USER anonymous"
198
+ expect(client.gets).to eql("230 logged in\r\n")
215
199
  end
216
200
 
217
201
  it "accepts PASS" do
218
- @client.puts "PASS password"
219
- @client.gets.should == "230 logged in\r\n"
202
+ client.puts "PASS password"
203
+ expect(client.gets).to eql("230 logged in\r\n")
220
204
  end
221
205
 
222
206
  it "accepts ACCT" do
223
- @client.puts "ACCT"
224
- @client.gets.should == "230 WHATEVER!\r\n"
207
+ client.puts "ACCT"
208
+ expect(client.gets).to eql("230 WHATEVER!\r\n")
225
209
  end
226
210
  end
227
211
 
228
212
  context 'directory commands' do
229
213
  before :each do
230
- @client = TCPSocket.open('127.0.0.1', 21212)
231
- @client.gets ## connection successful response
232
- end
233
-
234
- after :each do
235
- @client.close
214
+ client.gets ## connection successful response
236
215
  end
237
216
 
238
217
  it "returns directory on PWD" do
239
- @client.puts "PWD"
240
- @client.gets.should == "257 \"/pub\" is current directory\r\n"
218
+ client.puts "PWD"
219
+ expect(client.gets).to eql("257 \"/pub\" is current directory\r\n")
241
220
  end
242
221
 
243
222
  it "says OK to any CWD, CDUP, without doing anything" do
244
- @client.puts "CWD somewhere/else"
245
- @client.gets.should == "250 OK!\r\n"
246
- @client.puts "CDUP"
247
- @client.gets.should == "250 OK!\r\n"
248
- end
249
-
250
- it "does not respond to MKD" do
251
- @client.puts "MKD some_dir"
252
- @client.gets.should == "500 Unknown command\r\n"
223
+ client.puts "CWD somewhere/else"
224
+ expect(client.gets).to eql("250 OK!\r\n")
225
+ client.puts "CDUP"
226
+ expect(client.gets).to eql("250 OK!\r\n")
253
227
  end
254
228
  end
255
229
 
256
230
  context 'file commands' do
257
231
  before :each do
258
- @client = TCPSocket.open('127.0.0.1', 21212)
259
- @client.gets ## connection successful response
260
- end
261
-
262
- after :each do
263
- @client.close
232
+ client.gets ## connection successful response
264
233
  end
265
234
 
266
235
  it "accepts TYPE ascii" do
267
- @client.puts "TYPE A"
268
- @client.gets.should == "200 Type set to A.\r\n"
236
+ client.puts "TYPE A"
237
+ expect(client.gets).to eql("200 Type set to A.\r\n")
269
238
  end
270
239
 
271
240
  it "accepts TYPE image" do
272
- @client.puts "TYPE I"
273
- @client.gets.should == "200 Type set to I.\r\n"
241
+ client.puts "TYPE I"
242
+ expect(client.gets).to eql("200 Type set to I.\r\n")
274
243
  end
275
244
 
276
245
  it "does not accept TYPEs other than ascii or image" do
277
- @client.puts "TYPE E"
278
- @client.gets.should == "504 We don't allow those\r\n"
279
- @client.puts "TYPE N"
280
- @client.gets.should == "504 We don't allow those\r\n"
281
- @client.puts "TYPE T"
282
- @client.gets.should == "504 We don't allow those\r\n"
283
- @client.puts "TYPE C"
284
- @client.gets.should == "504 We don't allow those\r\n"
285
- @client.puts "TYPE L"
286
- @client.gets.should == "504 We don't allow those\r\n"
246
+ client.puts "TYPE E"
247
+ expect(client.gets).to eql("504 We don't allow those\r\n")
248
+ client.puts "TYPE N"
249
+ expect(client.gets).to eql("504 We don't allow those\r\n")
250
+ client.puts "TYPE T"
251
+ expect(client.gets).to eql("504 We don't allow those\r\n")
252
+ client.puts "TYPE C"
253
+ expect(client.gets).to eql("504 We don't allow those\r\n")
254
+ client.puts "TYPE L"
255
+ expect(client.gets).to eql("504 We don't allow those\r\n")
287
256
  end
288
257
 
289
258
  context 'passive' do
259
+ let(:data_client) { TCPSocket.open('127.0.0.1', 21213) }
260
+
290
261
  before :each do
291
- @client.puts 'PASV'
292
- @client.gets.should == "227 Entering Passive Mode (127,0,0,1,82,221)\r\n"
262
+ client.puts 'PASV'
263
+ expect(client.gets).to eql("227 Entering Passive Mode (127,0,0,1,82,221)\r\n")
293
264
  end
294
265
 
295
266
  it "accepts STOR with filename" do
296
- @client.puts "STOR some_file"
297
- @client.gets.should == "125 Do it!\r\n"
298
- @data_client = TCPSocket.open('127.0.0.1', 21213)
299
- @data_client.puts "1234567890"
300
- @data_client.close
301
- @client.gets.should == "226 Did it!\r\n"
302
- server.files.should include('some_file')
303
- server.file('some_file').bytes.should == 10
267
+ client.puts "STOR some_file"
268
+ expect(client.gets).to eql("125 Do it!\r\n")
269
+ data_client.puts "1234567890"
270
+ data_client.close
271
+ expect(client.gets).to eql("226 Did it!\r\n")
272
+ expect(server.files).to include('some_file')
273
+ expect(server.file('some_file').bytes).to eql(10)
274
+ expect(server.file('some_file').data).to eql("1234567890")
275
+ end
276
+
277
+ it "accepts STOR with filename and trailing newline" do
278
+ client.puts "STOR some_file"
279
+ client.gets
280
+ # puts tries to be smart and only write a single \n
281
+ data_client.puts "1234567890\n\n"
282
+ data_client.close
283
+ expect(client.gets).to eql("226 Did it!\r\n")
284
+ expect(server.files).to include('some_file')
285
+ expect(server.file('some_file').bytes).to eql(11)
286
+ expect(server.file('some_file').data).to eql("1234567890\n")
287
+ end
288
+
289
+ it "accepts STOR with filename and long file" do
290
+ client.puts "STOR some_file"
291
+ expect(client.gets).to eql("125 Do it!\r\n")
292
+ data_client.puts("1234567890" * 10_000)
293
+ data_client.close
294
+ expect(client.gets).to eql("226 Did it!\r\n")
295
+ expect(server.files).to include('some_file')
296
+ end
297
+
298
+ it "accepts STOR with streams" do
299
+ client.puts "STOR some_file"
300
+ expect(client.gets).to eql("125 Do it!\r\n")
301
+ data_client.write "1234567890"
302
+ data_client.flush
303
+ data_client.write "1234567890"
304
+ data_client.flush
305
+ data_client.close
306
+ expect(client.gets).to eql("226 Did it!\r\n")
307
+ expect(server.file('some_file').data).to eql("12345678901234567890")
304
308
  end
305
309
 
306
310
  it "does not accept RETR without a filename" do
307
- @client.puts "RETR"
308
- @client.gets.should == "501 No filename given\r\n"
311
+ client.puts "RETR"
312
+ expect(client.gets).to eql("501 No filename given\r\n")
309
313
  end
310
314
 
311
315
  it "does not serve files that do not exist" do
312
- @client.puts "RETR some_file"
313
- @client.gets.should == "550 File not found\r\n"
316
+ client.puts "RETR some_file"
317
+ expect(client.gets).to eql("550 File not found\r\n")
314
318
  end
315
319
 
316
320
  it "accepts RETR with a filename" do
317
321
  server.add_file('some_file', '1234567890')
318
- @client.puts "RETR some_file"
319
- @client.gets.should == "150 File status ok, about to open data connection\r\n"
320
- @data_client = TCPSocket.open('127.0.0.1', 21213)
321
- data = @data_client.read(1024)
322
- @data_client.close
323
- data.should == '1234567890'
324
- @client.gets.should == "226 File transferred\r\n"
322
+ client.puts "RETR some_file"
323
+ expect(client.gets).to eql("150 File status ok, about to open data connection\r\n")
324
+ data = data_client.read(1024)
325
+ data_client.close
326
+ expect(data).to eql('1234567890')
327
+ expect(client.gets).to eql("226 File transferred\r\n")
328
+ end
329
+
330
+ it "accepts DELE with a filename" do
331
+ server.add_file('some_file', '1234567890')
332
+ client.puts "DELE some_file"
333
+ expect(client.gets).to eql("250 Delete operation successful.\r\n")
334
+ expect(server.files).to_not include('some_file')
335
+ end
336
+
337
+ it "gives error message when trying to delete a file that does not exist" do
338
+ client.puts "DELE non_existing_file"
339
+ expect(client.gets).to eql("550 Delete operation failed.\r\n")
325
340
  end
326
341
 
327
342
  it "accepts a LIST command" do
328
343
  server.add_file('some_file', '1234567890')
329
344
  server.add_file('another_file', '1234567890')
330
- @client.puts "LIST"
331
- @client.gets.should == "150 Listing status ok, about to open data connection\r\n"
332
- @data_client = TCPSocket.open('127.0.0.1', 21213)
333
- data = @data_client.read(2048)
334
- @data_client.close
335
- data.should == [
345
+ client.puts "LIST"
346
+ expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
347
+ data = data_client.read(2048)
348
+ data_client.close
349
+ expect(data).to eql([
336
350
  "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file('some_file').created.strftime('%b %d %H:%M')}\tsome_file",
337
351
  "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file('another_file').created.strftime('%b %d %H:%M')}\tanother_file",
338
- ].join("\n")
339
- @client.gets.should == "226 List information transferred\r\n"
352
+ ].join("\n"))
353
+ expect(client.gets).to eql("226 List information transferred\r\n")
354
+ end
355
+
356
+ it "accepts a LIST command with a wildcard argument" do
357
+ files = ['test.jpg', 'test-2.jpg', 'test.txt']
358
+ files.each do |file|
359
+ server.add_file(file, '1234567890')
360
+ end
361
+
362
+ client.puts "LIST *.jpg"
363
+ expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
364
+
365
+ data = data_client.read(2048)
366
+ data_client.close
367
+ expect(data).to eql(files[0,2].map do |file|
368
+ "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file(file).created.strftime('%b %d %H:%M')}\t#{file}"
369
+ end.join("\n"))
370
+ expect(client.gets).to eql("226 List information transferred\r\n")
371
+ end
372
+
373
+ it "accepts a LIST command with multiple wildcard arguments" do
374
+ files = ['test.jpg', 'test.gif', 'test.txt']
375
+ files.each do |file|
376
+ server.add_file(file, '1234567890')
377
+ end
378
+
379
+ client.puts "LIST *.jpg *.gif"
380
+ expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
381
+
382
+ data = data_client.read(2048)
383
+ data_client.close
384
+ expect(data).to eql(files[0,2].map do |file|
385
+ "-rw-r--r--\t1\towner\tgroup\t10\t#{server.file(file).created.strftime('%b %d %H:%M')}\t#{file}"
386
+ end.join("\n"))
387
+ expect(client.gets).to eql("226 List information transferred\r\n")
340
388
  end
341
389
 
342
390
  it "accepts an NLST command" do
343
391
  server.add_file('some_file', '1234567890')
344
392
  server.add_file('another_file', '1234567890')
345
- @client.puts "NLST"
346
- @client.gets.should == "150 Listing status ok, about to open data connection\r\n"
347
- @data_client = TCPSocket.open('127.0.0.1', 21213)
348
- data = @data_client.read(1024)
349
- @data_client.close
350
- data.should == "some_file\nanother_file"
351
- @client.gets.should == "226 List information transferred\r\n"
393
+ client.puts "NLST"
394
+ expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
395
+ data = data_client.read(1024)
396
+ data_client.close
397
+ expect(data).to eql("some_file\nanother_file")
398
+ expect(client.gets).to eql("226 List information transferred\r\n")
352
399
  end
353
400
 
401
+ it "should allow mdtm" do
402
+ filename = "file.txt"
403
+ now = Time.now
404
+ server.add_file(filename, "some dummy content", now)
405
+ client.puts "MDTM #{filename}"
406
+ expect(client.gets).to eql("213 #{now.strftime("%Y%m%d%H%M%S")}\r\n")
407
+ end
354
408
  end
355
409
 
356
410
  context 'active' do
@@ -367,58 +421,123 @@ describe FakeFtp::Server, 'commands' do
367
421
  @data_server = nil
368
422
  end
369
423
 
424
+ it 'creates a directory on MKD' do
425
+ client.puts "MKD some_dir"
426
+ expect(client.gets).to eql("257 OK!\r\n")
427
+ end
428
+
429
+ it 'should save the directory after you CWD' do
430
+ client.puts "CWD /somewhere/else"
431
+ expect(client.gets).to eql("250 OK!\r\n")
432
+ client.puts "PWD"
433
+ expect(client.gets).to eql("257 \"/somewhere/else\" is current directory\r\n")
434
+ end
435
+
436
+ it 'CWD should add a / to the beginning of the directory' do
437
+ client.puts "CWD somewhere/else"
438
+ expect(client.gets).to eql("250 OK!\r\n")
439
+ client.puts "PWD"
440
+ expect(client.gets).to eql("257 \"/somewhere/else\" is current directory\r\n")
441
+ end
442
+
443
+ it 'should not change the directory on CDUP' do
444
+ client.puts "CDUP"
445
+ expect(client.gets).to eql("250 OK!\r\n")
446
+ client.puts "PWD"
447
+ expect(client.gets).to eql("257 \"/pub\" is current directory\r\n")
448
+ end
449
+
370
450
  it "sends error message if no PORT received" do
371
- @client.puts "STOR some_file"
372
- @client.gets.should == "425 Ain't no data port!\r\n"
451
+ client.puts "STOR some_file"
452
+ expect(client.gets).to eql("425 Ain't no data port!\r\n")
373
453
  end
374
454
 
375
455
  it "accepts STOR with filename" do
376
- @client.puts "PORT 127,0,0,1,82,224"
377
- @client.gets.should == "200 Okay\r\n"
456
+ client.puts "PORT 127,0,0,1,82,224"
457
+ expect(client.gets).to eql("200 Okay\r\n")
378
458
 
379
- @client.puts "STOR some_other_file"
380
- @client.gets.should == "125 Do it!\r\n"
459
+ client.puts "STOR some_other_file"
460
+ expect(client.gets).to eql("125 Do it!\r\n")
381
461
 
382
462
  @data_connection.join
383
463
  @server_client.print "12345"
384
464
  @server_client.close
385
465
 
386
- @client.gets.should == "226 Did it!\r\n"
387
- server.files.should include('some_other_file')
388
- server.file('some_other_file').bytes.should == 5
466
+ expect(client.gets).to eql("226 Did it!\r\n")
467
+ expect(server.files).to include('some_other_file')
468
+ expect(server.file('some_other_file').bytes).to eql(5)
389
469
  end
390
470
 
391
471
  it "accepts RETR with a filename" do
392
- @client.puts "PORT 127,0,0,1,82,224"
393
- @client.gets.should == "200 Okay\r\n"
472
+ client.puts "PORT 127,0,0,1,82,224"
473
+ expect(client.gets).to eql("200 Okay\r\n")
394
474
 
395
475
  server.add_file('some_file', '1234567890')
396
- @client.puts "RETR some_file"
397
- @client.gets.should == "150 File status ok, about to open data connection\r\n"
476
+ client.puts "RETR some_file"
477
+ expect(client.gets).to eql("150 File status ok, about to open data connection\r\n")
398
478
 
399
479
  @data_connection.join
400
480
  data = @server_client.read(1024)
401
481
  @server_client.close
402
482
 
403
- data.should == '1234567890'
404
- @client.gets.should == "226 File transferred\r\n"
483
+ expect(data).to eql('1234567890')
484
+ expect(client.gets).to eql("226 File transferred\r\n")
485
+ end
486
+
487
+ it "accepts RNFR without filename" do
488
+ client.puts "RNFR"
489
+ expect(client.gets).to eql("501 Send path name.\r\n")
490
+ end
491
+
492
+ it "accepts RNTO without RNFR" do
493
+ client.puts "RNTO some_other_file"
494
+ expect(client.gets).to eql("503 Send RNFR first.\r\n")
495
+ end
496
+
497
+ it "accepts RNTO and RNFR without filename" do
498
+ client.puts "RNFR from_file"
499
+ expect(client.gets).to eql("350 Send RNTO to complete rename.\r\n")
500
+
501
+ client.puts "RNTO"
502
+ expect(client.gets).to eql("501 Send path name.\r\n")
503
+ end
504
+
505
+ it "accepts RNTO and RNFR for not existing file" do
506
+ client.puts "RNFR from_file"
507
+ expect(client.gets).to eql("350 Send RNTO to complete rename.\r\n")
508
+
509
+ client.puts "RNTO to_file"
510
+ expect(client.gets).to eql("550 File not found.\r\n")
511
+ end
512
+
513
+ it "accepts RNTO and RNFR" do
514
+ server.add_file('from_file', '1234567890')
515
+
516
+ client.puts "RNFR from_file"
517
+ expect(client.gets).to eql("350 Send RNTO to complete rename.\r\n")
518
+
519
+ client.puts "RNTO to_file"
520
+ expect(client.gets).to eql("250 Path renamed.\r\n")
521
+
522
+ expect(server.files).to include('to_file')
523
+ expect(server.files).to_not include('from_file')
405
524
  end
406
525
 
407
526
  it "accepts an NLST command" do
408
- @client.puts "PORT 127,0,0,1,82,224"
409
- @client.gets.should == "200 Okay\r\n"
527
+ client.puts "PORT 127,0,0,1,82,224"
528
+ expect(client.gets).to eql("200 Okay\r\n")
410
529
 
411
530
  server.add_file('some_file', '1234567890')
412
531
  server.add_file('another_file', '1234567890')
413
- @client.puts "NLST"
414
- @client.gets.should == "150 Listing status ok, about to open data connection\r\n"
532
+ client.puts "NLST"
533
+ expect(client.gets).to eql("150 Listing status ok, about to open data connection\r\n")
415
534
 
416
535
  @data_connection.join
417
536
  data = @server_client.read(1024)
418
537
  @server_client.close
419
538
 
420
- data.should == "some_file\nanother_file"
421
- @client.gets.should == "226 List information transferred\r\n"
539
+ expect(data).to eql("some_file\nanother_file")
540
+ expect(client.gets).to eql("226 List information transferred\r\n")
422
541
  end
423
542
  end
424
543
  end
@@ -437,54 +556,68 @@ describe FakeFtp::Server, 'with ftp client' do
437
556
  end
438
557
 
439
558
  it 'should accept connections' do
440
- proc { client.connect('127.0.0.1', 21212) }.should_not raise_error
559
+ expect { client.connect('127.0.0.1', 21212) }.to_not raise_error
441
560
  end
442
561
 
443
562
  context "" do
444
563
  before { client.connect("127.0.0.1", 21212) }
445
564
 
446
565
  it "should allow anonymous authentication" do
447
- proc { client.login }.should_not raise_error
566
+ expect { client.login }.to_not raise_error
448
567
  end
449
568
 
450
569
  it "should allow named authentication" do
451
- proc { client.login('someone', 'password') }.should_not raise_error
570
+ expect { client.login('someone', 'password') }.to_not raise_error
452
571
  end
453
572
 
454
573
  it "should allow client to quit" do
455
- proc { client.login('someone', 'password') }.should_not raise_error
456
- proc { client.quit }.should_not raise_error
574
+ expect { client.login('someone', 'password') }.to_not raise_error
575
+ expect { client.quit }.to_not raise_error
576
+ end
577
+
578
+ it "should allow mtime" do
579
+ filename = 'someone'
580
+ time = Time.now
581
+ server.add_file(filename, "some data", time)
582
+
583
+ client.passive = false
584
+ mtime = client.mtime(filename)
585
+ expect(mtime.to_s).to eql(time.to_s)
586
+
587
+ client.passive = true
588
+ mtime = client.mtime(filename)
589
+ expect(mtime.to_s).to eql(time.to_s)
457
590
  end
458
591
 
459
592
  it "should put files using PASV" do
460
- File.stat(text_filename).size.should == 20
593
+ expect(File.stat(text_filename).size).to eql(20)
461
594
 
462
595
  client.passive = true
463
- proc { client.put(text_filename) }.should_not raise_error
596
+ expect { client.put(text_filename) }.to_not raise_error
464
597
 
465
- server.files.should include('text_file.txt')
466
- server.file('text_file.txt').bytes.should == 20
467
- server.file('text_file.txt').should be_passive
468
- server.file('text_file.txt').should_not be_active
598
+ expect(server.files).to include('text_file.txt')
599
+ expect(server.file('text_file.txt').bytes).to eql(20)
600
+ expect(server.file('text_file.txt')).to be_passive
601
+ expect(server.file('text_file.txt')).to_not be_active
469
602
  end
470
603
 
471
604
  it "should put files using active" do
472
- File.stat(text_filename).size.should == 20
605
+ expect(File.stat(text_filename).size).to eql(20)
473
606
 
474
607
  client.passive = false
475
- proc { client.put(text_filename) }.should_not raise_error
608
+ expect { client.put(text_filename) }.to_not raise_error
476
609
 
477
- server.files.should include('text_file.txt')
478
- server.file('text_file.txt').bytes.should == 20
479
- server.file('text_file.txt').should_not be_passive
480
- server.file('text_file.txt').should be_active
610
+ expect(server.files).to include('text_file.txt')
611
+ expect(server.file('text_file.txt').bytes).to eql(20)
612
+ expect(server.file('text_file.txt')).to_not be_passive
613
+ expect(server.file('text_file.txt')).to be_active
481
614
  end
482
615
 
483
616
  xit "should disconnect clients on close" do
484
617
  # TODO: when this succeeds, we can care less about manually closing clients
485
618
  # otherwise we get a CLOSE_WAIT process hanging around that blocks our port
486
619
  server.stop
487
- client.closed?.should be_true
620
+ expect(client.closed?).to be_true
488
621
  end
489
622
  end
490
623
  end