ferver 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,52 +1,28 @@
1
- require 'forwardable'
2
-
3
- # A representation of Ferver's file list
4
- #
1
+ # frozen_string_literal: true
5
2
  module Ferver
3
+ # A representation of Ferver's file list
6
4
  class FileList
7
5
  include Enumerable
8
6
 
9
- # Create a new instance with a path
7
+ # Create a new instance with given directory
10
8
  #
11
- def initialize(path)
12
- fail ArgumentError, 'No path is specified' if path.empty?
13
- fail DirectoryNotFoundError unless Dir.exist?(path)
14
-
15
- @configured_file_path = File.expand_path(path)
16
- @files = find_files.sort_by! { |f| f.name.downcase }
9
+ def initialize(files)
10
+ @files = files.sort_by { |f| f.name.downcase }
17
11
  end
18
12
 
19
13
  def each(&block)
20
- files.each(&block)
14
+ @files.each(&block)
21
15
  end
22
16
 
23
17
  def size
24
- files.size
18
+ @files.size
25
19
  end
26
20
 
27
- # Filename by its index
28
- # An id out of range with raise IndexError
21
+ # Fetch a file by its index
22
+ # An id out of range with raise FileNotFoundError
29
23
  #
30
24
  def file_by_id(id)
31
- files.fetch(id)
32
- end
33
-
34
- private
35
-
36
- attr_reader :configured_file_path, :files
37
-
38
- # Iterate through files in specified dir for files
39
- #
40
- def find_files
41
- [].tap do |results|
42
- Dir.foreach(configured_file_path) do |file_name|
43
- next if file_name == '.' || file_name == '..'
44
- next if file_name =~ /^\./ && !Ferver.configuration.serve_hidden?
45
-
46
- found_file = FoundFile.new(configured_file_path, file_name)
47
- results << found_file if found_file.valid?
48
- end
49
- end
25
+ @files.at(id) || raise(FileNotFoundError, "File id=#{id} not found")
50
26
  end
51
27
  end
52
28
  end
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module Ferver
2
3
  class FoundFile
3
4
  attr_reader :file_name, :path_to_file
4
5
 
5
- alias_method :name, :file_name
6
+ alias name file_name
6
7
 
7
8
  def initialize(directory, file_name)
8
9
  @file_name = file_name
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Ferver
2
- VERSION = '1.3.0'
3
+ VERSION = "1.3.1".freeze
3
4
  end
@@ -1,19 +1,18 @@
1
- require 'spec_helper'
2
-
3
- describe Ferver::Configuration do
1
+ # frozen_string_literal: true
2
+ RSpec.describe Ferver::Configuration do
4
3
  subject { described_class.new }
5
4
 
6
- describe 'configured directory path' do
7
- context 'with no path set' do
8
- it 'should return default path' do
9
- expect(subject.directory_path).to eq(Ferver::DEFAULT_FILE_SERVER_DIR_PATH)
5
+ describe "configured directory path" do
6
+ context "with no path set" do
7
+ it "should return default path" do
8
+ expect(subject.directory_path).to eq("./")
10
9
  end
11
10
  end
12
11
 
13
- context 'when directory is set' do
14
- let(:path) { '/foo/bar' }
12
+ context "when directory is set" do
13
+ let(:path) { "/foo/bar" }
15
14
 
16
- it 'should return default path' do
15
+ it "should return default path" do
17
16
  subject.directory_path = path
18
17
 
19
18
  expect(subject.directory_path).to eq(path)
@@ -36,4 +35,11 @@ describe Ferver::Configuration do
36
35
  end
37
36
  end
38
37
  end
38
+
39
+ describe "#directory" do
40
+ it "is a FerverDirectory with configuration" do
41
+ expect(Ferver::FerverDirectory).to receive(:new).with(subject).and_call_original
42
+ expect(subject.directory).to be_instance_of Ferver::FerverDirectory
43
+ end
44
+ end
39
45
  end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+ RSpec.describe Ferver::FerverDirectory do
3
+ subject { described_class.new config }
4
+
5
+ let(:config) { double("Ferver::Configuration", directory_path: path, serve_hidden?: serve_hidden) }
6
+ let(:path) { "/dev" }
7
+ let(:serve_hidden) { true }
8
+
9
+ before do
10
+ allow(Dir).to receive(:exist?).and_return true
11
+ end
12
+
13
+ describe "assertions" do
14
+ context "when path is empty" do
15
+ let(:path) { "" }
16
+
17
+ it "raises error" do
18
+ expect { described_class.new config }.to raise_error(ArgumentError, "No path is specified")
19
+ end
20
+ end
21
+
22
+ context "when directory does not exist" do
23
+ before do
24
+ allow(Dir).to receive(:exist?).and_return false
25
+ end
26
+
27
+ it "raises error" do
28
+ expect { described_class.new config }.to raise_error(Ferver::DirectoryNotFoundError)
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "#path" do
34
+ let(:path) { "/dev/random" }
35
+
36
+ it "is the path from config" do
37
+ expect(subject.path).to eq "/dev/random"
38
+ end
39
+ end
40
+
41
+ describe "#full_path" do
42
+ let(:path) { "./" }
43
+
44
+ it "is the full path to directory" do
45
+ expect(File).to receive(:expand_path).with("./").and_return("/my/home")
46
+ expect(subject.full_path).to eq "/my/home"
47
+ end
48
+ end
49
+
50
+ describe "#found_files" do
51
+ before(:each) do
52
+ allow(Dir).to receive(:foreach)
53
+ .and_yield(".")
54
+ .and_yield("..")
55
+ .and_yield("zero file")
56
+ .and_yield("normal_file.txt")
57
+ .and_yield(".hidden")
58
+ allow(File).to receive(:file?).at_most(3).times.and_return(true, true, true)
59
+ allow(File).to receive(:zero?).at_most(3).times.and_return(true, false, false)
60
+ end
61
+
62
+ context "when configured to serve all files" do
63
+ let(:serve_hidden) { true }
64
+
65
+ it "returns list of files matched" do
66
+ expect(subject.found_files.map(&:name)).to eq ["normal_file.txt", ".hidden"]
67
+ end
68
+ end
69
+
70
+ context "when configured not to serve hidden files" do
71
+ let(:serve_hidden) { false }
72
+
73
+ it "returns list of files matched" do
74
+ expect(subject.found_files.map(&:name)).to eq ["normal_file.txt"]
75
+ end
76
+ end
77
+ end
78
+ end
@@ -1,18 +1,22 @@
1
- require 'spec_helper'
2
-
3
- describe 'ferver' do
4
- let(:file_list) { double('Ferver::FileList') }
1
+ # frozen_string_literal: true
2
+ RSpec.describe "ferver" do
3
+ let(:ferver_directory) { double("Ferver::FerverDirectory", path: "/", full_path: "/path/to/files", found_files: []) }
4
+ before do
5
+ Ferver.configure do |conf|
6
+ conf.directory = ferver_directory
7
+ end
8
+ end
5
9
 
6
- context 'given a request to the server root' do
10
+ context "given a request to the server root" do
7
11
  before do
8
- get '/'
12
+ get "/"
9
13
  end
10
14
 
11
- it 'should return redirect' do
15
+ it "should return redirect" do
12
16
  expect(last_response).to be_redirect
13
17
  end
14
18
 
15
- it 'should redirect to file list' do
19
+ it "should redirect to file list" do
16
20
  follow_redirect!
17
21
 
18
22
  expect(last_response).to be_ok
@@ -20,130 +24,94 @@ describe 'ferver' do
20
24
  end
21
25
  end
22
26
 
23
- describe 'choosing directory to serve files from' do
24
- before do
25
- allow(file_list).to receive(:each_with_index)
26
- allow(file_list).to receive(:size).and_return(0)
27
- end
28
-
29
- context 'when no directory is specified' do
30
- it 'will use default directory' do
31
- expect(Ferver::FileList).to receive(:new).with('./').and_return(file_list)
32
-
33
- get '/files'
34
- end
35
- end
36
-
37
- context 'when the directory passed via configuration' do
27
+ describe "configuration error" do
28
+ context "when directory does not exist" do
38
29
  before do
39
- Ferver.configure do |conf|
40
- conf.directory_path = '/foo'
41
- end
30
+ allow(ferver_directory).to receive(:found_files).and_raise(Ferver::DirectoryNotFoundError)
42
31
  end
43
32
 
44
- it 'will use directory specified' do
45
- expect(Ferver::FileList).to receive(:new).with('/foo').and_return(file_list)
46
-
47
- get '/files'
48
- end
49
- end
50
-
51
- context 'when directory does not exist' do
52
- before do
53
- allow(Ferver::FileList).to receive(:new).and_raise(Ferver::DirectoryNotFoundError)
54
- end
55
-
56
- it 'will return server error status' do
57
- get '/files'
33
+ it "will return server error status" do
34
+ get "/files"
58
35
 
59
36
  expect(last_response.status).to eql 500
60
37
  end
61
38
  end
62
39
  end
63
40
 
64
- context 'given an empty list of files' do
41
+ context "given an empty list of files" do
65
42
  before do
66
- allow(file_list).to receive(:each_with_index)
67
- allow(file_list).to receive(:size).and_return(0)
68
- allow(Ferver::FileList).to receive(:new).and_return(file_list)
43
+ allow(ferver_directory).to receive(:found_files).and_return(EMPTY_FILE_LIST)
69
44
  end
70
45
 
71
- context 'when no content-type is requested' do
72
- before { get '/files' }
46
+ context "when no content-type is requested" do
47
+ before { get "/files" }
73
48
 
74
- it 'should return valid response' do
49
+ it "should return valid response" do
75
50
  expect(last_response).to be_ok
76
51
  end
77
52
 
78
- it 'should contain no file list in response content' do
79
- expect(last_response.body).not_to have_tag('li')
80
- expect(last_response.body).to have_tag('p', text: /0 files/)
53
+ it "should contain no file list in response content" do
54
+ expect(last_response.body).not_to have_tag("li")
55
+ expect(last_response.body).to have_tag("p", text: /0 files/)
81
56
  end
82
57
  end
83
58
 
84
- context 'when json content-type is requested' do
59
+ context "when json content-type is requested" do
85
60
  before do
86
- allow(file_list).to receive(:map).and_return([])
87
-
88
- get '/files', {}, 'HTTP_ACCEPT' => 'application/json'
61
+ get "/files", {}, "HTTP_ACCEPT" => "application/json"
89
62
  end
90
63
 
91
- it 'should return valid response' do
64
+ it "should return valid response" do
92
65
  expect(last_response).to be_ok
93
- expect(last_response.content_type).to include('application/json')
66
+ expect(last_response.content_type).to include("application/json")
94
67
  end
95
68
 
96
- it 'should contain no file list in response content' do
69
+ it "should contain no file list in response content" do
97
70
  list = JSON.parse last_response.body
98
71
  expect(list).to eq(EMPTY_FILE_LIST)
99
72
  end
100
73
  end
101
74
  end
102
75
 
103
- context 'given a list of files' do
104
- let(:file_1) { double('file', name: 'file1') }
105
- let(:file_2) { double('file', name: 'file2') }
76
+ context "given a list of files" do
77
+ let(:file_1) { double("file", name: "file1") }
78
+ let(:file_2) { double("file", name: "file2") }
106
79
  before do
107
- allow(file_list).to receive(:each_with_index).and_yield(file_1, 1).and_yield(file_2, 2)
108
- allow(file_list).to receive(:size).and_return(2)
109
- allow(Ferver::FileList).to receive(:new).and_return(file_list)
80
+ allow(ferver_directory).to receive(:found_files).and_return([file_1, file_2])
110
81
  end
111
82
 
112
- describe 'file list request' do
113
-
114
- context 'when no content-type is requested' do
115
- before { get '/files' }
83
+ describe "file list request" do
84
+ context "when no content-type is requested" do
85
+ before { get "/files" }
116
86
 
117
- it 'should return valid response' do
87
+ it "should return valid response" do
118
88
  expect(last_response).to be_ok
119
89
  end
120
90
 
121
- it 'should contain no file list in response content' do
122
- expect(last_response.body).to have_tag('li', count: 2)
123
- expect(last_response.body).to have_tag('p', text: /2 files/)
91
+ it "should contain no file list in response content" do
92
+ expect(last_response.body).to have_tag("li", count: 2)
93
+ expect(last_response.body).to have_tag("p", text: /2 files/)
124
94
  end
125
95
 
126
- it 'should list filenames' do
127
- expect(last_response.body).to have_tag('li') do
128
- with_tag('a', text: 'file1')
129
- with_tag('a', text: 'file2')
96
+ it "should list filenames" do
97
+ expect(last_response.body).to have_tag("li") do
98
+ with_tag("a", text: "file1")
99
+ with_tag("a", text: "file2")
130
100
  end
131
101
  end
132
102
  end
133
103
 
134
- context 'when json content-type is requested' do
104
+ context "when json content-type is requested" do
135
105
  before do
136
- allow(file_list).to receive(:map).and_return([file_1.name, file_2.name])
137
-
138
- get '/files', {}, 'HTTP_ACCEPT' => 'application/json'
106
+ get "/files", {}, "HTTP_ACCEPT" => "application/json"
139
107
  end
140
108
 
141
- it 'should return valid response' do
109
+ it "should return valid response" do
142
110
  expect(last_response).to be_ok
143
- expect(last_response.content_type).to include('application/json')
111
+ expect(last_response.content_type).to include("application/json")
144
112
  end
145
113
 
146
- it 'should contain no file list in response content' do
114
+ it "should contain no file list in response content" do
147
115
  list = JSON.parse last_response.body
148
116
  expect(list.count).to eq(2)
149
117
  expect(list).to match_array([file_1.name, file_2.name])
@@ -151,38 +119,35 @@ describe 'ferver' do
151
119
  end
152
120
  end
153
121
 
154
- describe 'downloading a file' do
155
-
156
- context 'when requesting a file out of range' do
122
+ describe "downloading a file" do
123
+ context "when requesting a file out of range" do
157
124
  before do
158
- allow(file_list).to receive(:file_by_id).with(3).and_raise(IndexError)
159
- get '/files/3'
125
+ get "/files/3"
160
126
  end
161
127
 
162
- it 'should return not_found' do
128
+ it "should return not_found" do
163
129
  expect(last_response).to be_not_found
164
130
  end
165
131
  end
166
132
 
167
- context 'when requesting invalid file id' do
168
- before { get '/files/foo' }
133
+ context "when requesting invalid file id" do
134
+ before { get "/files/foo" }
169
135
 
170
- it 'should return not_found' do
136
+ it "should return not_found" do
171
137
  expect(last_response).to be_bad_request
172
138
  end
173
139
  end
174
140
 
175
- context 'when requesting a valid file id' do
176
- before { get '/files/0' }
141
+ context "when requesting a valid file id" do
142
+ before { get "/files/0" }
177
143
 
178
- xit 'should return ok response' do
144
+ xit "should return ok response" do
179
145
  expect(last_response).to be_ok
180
146
  end
181
147
 
182
- xit 'should return octet-stream content-type' do
183
- expect(last_response.headers['Content-Type']).to eq('application/octet-stream')
148
+ xit "should return octet-stream content-type" do
149
+ expect(last_response.headers["Content-Type"]).to eq("application/octet-stream")
184
150
  end
185
-
186
151
  end
187
152
  end
188
153
  end