fake_ftp 0.0.9 → 0.1.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.
@@ -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