leifcr-refile 0.6.3
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.
- checksums.yaml +7 -0
- data/app/assets/javascripts/refile.js +125 -0
- data/config/locales/en.yml +10 -0
- data/config/routes.rb +5 -0
- data/lib/refile.rb +510 -0
- data/lib/refile/app.rb +186 -0
- data/lib/refile/attacher.rb +190 -0
- data/lib/refile/attachment.rb +108 -0
- data/lib/refile/attachment/active_record.rb +133 -0
- data/lib/refile/attachment_definition.rb +83 -0
- data/lib/refile/backend/file_system.rb +120 -0
- data/lib/refile/backend/s3.rb +1 -0
- data/lib/refile/backend_macros.rb +45 -0
- data/lib/refile/custom_logger.rb +48 -0
- data/lib/refile/file.rb +102 -0
- data/lib/refile/file_double.rb +13 -0
- data/lib/refile/image_processing.rb +1 -0
- data/lib/refile/rails.rb +54 -0
- data/lib/refile/rails/attachment_helper.rb +121 -0
- data/lib/refile/random_hasher.rb +11 -0
- data/lib/refile/signature.rb +36 -0
- data/lib/refile/simple_form.rb +17 -0
- data/lib/refile/type.rb +28 -0
- data/lib/refile/version.rb +3 -0
- data/spec/refile/active_record_helper.rb +35 -0
- data/spec/refile/app_spec.rb +424 -0
- data/spec/refile/attachment/active_record_spec.rb +568 -0
- data/spec/refile/attachment_helper_spec.rb +78 -0
- data/spec/refile/attachment_spec.rb +589 -0
- data/spec/refile/backend/file_system_spec.rb +5 -0
- data/spec/refile/backend_examples.rb +228 -0
- data/spec/refile/backend_macros_spec.rb +83 -0
- data/spec/refile/custom_logger_spec.rb +21 -0
- data/spec/refile/features/direct_upload_spec.rb +63 -0
- data/spec/refile/features/multiple_upload_spec.rb +122 -0
- data/spec/refile/features/normal_upload_spec.rb +144 -0
- data/spec/refile/features/presigned_upload_spec.rb +31 -0
- data/spec/refile/features/simple_form_spec.rb +8 -0
- data/spec/refile/fixtures/hello.txt +1 -0
- data/spec/refile/fixtures/image.jpg +0 -0
- data/spec/refile/fixtures/large.txt +44 -0
- data/spec/refile/fixtures/monkey.txt +1 -0
- data/spec/refile/fixtures/world.txt +1 -0
- data/spec/refile/spec_helper.rb +72 -0
- data/spec/refile_spec.rb +355 -0
- metadata +143 -0
@@ -0,0 +1,144 @@
|
|
1
|
+
require "refile/test_app"
|
2
|
+
|
3
|
+
feature "Normal HTTP Post file uploads" do
|
4
|
+
scenario "Successfully upload a file" do
|
5
|
+
visit "/normal/posts/new"
|
6
|
+
fill_in "Title", with: "A cool post"
|
7
|
+
attach_file "Document", path("hello.txt")
|
8
|
+
click_button "Create"
|
9
|
+
|
10
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
11
|
+
expect(page).to have_selector(".content-type", text: "text/plain")
|
12
|
+
expect(page).to have_selector(".size", text: "6")
|
13
|
+
expect(page).to have_selector(".filename", text: "hello.txt")
|
14
|
+
expect(download_link("Document")).to eq("hello")
|
15
|
+
end
|
16
|
+
|
17
|
+
scenario "Fail to upload a file that is too large" do
|
18
|
+
visit "/normal/posts/new"
|
19
|
+
fill_in "Title", with: "A cool post"
|
20
|
+
attach_file "Document", path("large.txt")
|
21
|
+
click_button "Create"
|
22
|
+
|
23
|
+
expect(page).to have_selector(".field_with_errors")
|
24
|
+
expect(page).to have_content("Document is too large")
|
25
|
+
end
|
26
|
+
|
27
|
+
scenario "Fail to upload a file that has the wrong format" do
|
28
|
+
visit "/normal/posts/new"
|
29
|
+
fill_in "Title", with: "A cool post"
|
30
|
+
attach_file "Image", path("hello.txt")
|
31
|
+
click_button "Create"
|
32
|
+
|
33
|
+
expect(page).to have_selector(".field_with_errors")
|
34
|
+
expect(page).to have_content("You are not allowed to upload text/plain file format. Allowed types: image/jpeg, image/gif, and image/png.")
|
35
|
+
end
|
36
|
+
|
37
|
+
scenario "Fail to upload a file that has the wrong format then submit" do
|
38
|
+
visit "/normal/posts/new"
|
39
|
+
fill_in "Title", with: "A cool post"
|
40
|
+
attach_file "Image", path("hello.txt")
|
41
|
+
click_button "Create"
|
42
|
+
|
43
|
+
expect(page).to have_selector(".field_with_errors")
|
44
|
+
expect(page).to have_content("You are not allowed to upload text/plain file format. Allowed types: image/jpeg, image/gif, and image/png.")
|
45
|
+
click_button "Create"
|
46
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
47
|
+
expect(page).not_to have_link("Document")
|
48
|
+
end
|
49
|
+
|
50
|
+
scenario "Successfully update a record with an attached file" do
|
51
|
+
visit "/normal/posts/new"
|
52
|
+
fill_in "Title", with: "A cool post"
|
53
|
+
attach_file "Image", path("image.jpg")
|
54
|
+
click_button "Create"
|
55
|
+
|
56
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
57
|
+
click_link("Edit")
|
58
|
+
|
59
|
+
fill_in "Title", with: "A very cool post"
|
60
|
+
|
61
|
+
click_button "Update"
|
62
|
+
expect(page).to have_selector("h1", text: "A very cool post")
|
63
|
+
end
|
64
|
+
|
65
|
+
# FIXME: the only reason this is js:true is because the rack_test driver
|
66
|
+
# doesn't submit file+metadata correctly.
|
67
|
+
scenario "Upload a file via form redisplay", js: true do
|
68
|
+
visit "/normal/posts/new"
|
69
|
+
attach_file "Document", path("hello.txt")
|
70
|
+
click_button "Create"
|
71
|
+
fill_in "Title", with: "A cool post"
|
72
|
+
click_button "Create"
|
73
|
+
|
74
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
75
|
+
expect(page).to have_selector(".content-type", text: "text/plain")
|
76
|
+
expect(page).to have_selector(".size", text: "6")
|
77
|
+
expect(page).to have_selector(".filename", text: "hello.txt")
|
78
|
+
expect(download_link("Document")).to eq("hello")
|
79
|
+
end
|
80
|
+
|
81
|
+
scenario "Format conversion" do
|
82
|
+
visit "/normal/posts/new"
|
83
|
+
fill_in "Title", with: "A cool post"
|
84
|
+
attach_file "Document", path("hello.txt")
|
85
|
+
click_button "Create"
|
86
|
+
|
87
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
88
|
+
expect(download_link("Convert to Upper")).to eq("HELLO")
|
89
|
+
end
|
90
|
+
|
91
|
+
scenario "Successfully remove an uploaded file" do
|
92
|
+
visit "/normal/posts/new"
|
93
|
+
fill_in "Title", with: "A cool post"
|
94
|
+
attach_file "Document", path("hello.txt")
|
95
|
+
click_button "Create"
|
96
|
+
|
97
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
98
|
+
expect(page).to have_selector(:link, "Document")
|
99
|
+
click_link("Edit")
|
100
|
+
|
101
|
+
check "Remove document"
|
102
|
+
click_button "Update"
|
103
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
104
|
+
expect(page).not_to have_selector(:link, "Document")
|
105
|
+
expect(page).not_to have_selector(".content-type", text: "text/plain")
|
106
|
+
expect(page).not_to have_selector(".size", text: "6")
|
107
|
+
expect(page).not_to have_selector(".filename", text: "hello.txt")
|
108
|
+
end
|
109
|
+
|
110
|
+
scenario "Successfully remove a record with an uploaded file" do
|
111
|
+
visit "/normal/posts/new"
|
112
|
+
fill_in "Title", with: "A cool post about to be deleted"
|
113
|
+
attach_file "Document", path("hello.txt")
|
114
|
+
click_button "Create"
|
115
|
+
|
116
|
+
expect(page).to have_selector("h1", text: "A cool post about to be deleted")
|
117
|
+
click_link("Delete")
|
118
|
+
expect(page).to_not have_content("A cool post about to be deleted")
|
119
|
+
end
|
120
|
+
|
121
|
+
scenario "Upload a file from a remote URL" do
|
122
|
+
url = "http://www.example.com/foo/bar/some_file.png?some-query-string=true"
|
123
|
+
|
124
|
+
stub_request(:get, url).to_return(
|
125
|
+
status: 200,
|
126
|
+
body: "abc",
|
127
|
+
headers: {
|
128
|
+
"Content-Length" => 3,
|
129
|
+
"Content-Type" => "image/png"
|
130
|
+
}
|
131
|
+
)
|
132
|
+
|
133
|
+
visit "/normal/posts/new"
|
134
|
+
fill_in "Title", with: "A cool post"
|
135
|
+
fill_in "Remote document url", with: url
|
136
|
+
click_button "Create"
|
137
|
+
|
138
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
139
|
+
expect(download_link("Document")).to eq("abc")
|
140
|
+
expect(page).to have_selector(".content-type", text: "image/png")
|
141
|
+
expect(page).to have_selector(".size", text: "3")
|
142
|
+
expect(page).to have_selector(".filename", text: "some_file.png", exact: true)
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "refile/test_app"
|
2
|
+
|
3
|
+
feature "Direct HTTP post file uploads", :js do
|
4
|
+
scenario "Successfully upload a file" do
|
5
|
+
visit "/presigned/posts/new"
|
6
|
+
fill_in "Title", with: "A cool post"
|
7
|
+
attach_file "Document", path("hello.txt")
|
8
|
+
|
9
|
+
expect(page).to have_content("Presign start")
|
10
|
+
expect(page).to have_content("Presign complete")
|
11
|
+
expect(page).to have_content("Upload started")
|
12
|
+
expect(page).to have_content("Upload complete token accepted")
|
13
|
+
expect(page).to have_content("Upload success token accepted")
|
14
|
+
|
15
|
+
click_button "Create"
|
16
|
+
|
17
|
+
expect(page).to have_selector("h1", text: "A cool post")
|
18
|
+
expect(download_link("Document")).to eq("hello")
|
19
|
+
end
|
20
|
+
|
21
|
+
scenario "Fail to upload a file that is too large" do
|
22
|
+
visit "/presigned/posts/new"
|
23
|
+
fill_in "Title", with: "A cool post"
|
24
|
+
attach_file "Document", path("large.txt")
|
25
|
+
|
26
|
+
expect(page).to have_content("Presign start")
|
27
|
+
expect(page).to have_content("Presign complete")
|
28
|
+
expect(page).to have_content("Upload started")
|
29
|
+
expect(page).to have_content("Upload failure too large")
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
hello
|
Binary file
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec massa arcu,
|
2
|
+
convallis a tellus vitae, placerat rhoncus nisi. Nullam molestie volutpat
|
3
|
+
turpis vitae viverra. Integer nulla nisl, dictum et rutrum quis, auctor ut dui.
|
4
|
+
Nulla imperdiet ante a lorem molestie tempor. Suspendisse pharetra in mauris
|
5
|
+
mollis dapibus. Nullam pretium fringilla justo, faucibus condimentum elit
|
6
|
+
rutrum ac. Vivamus sem justo, congue id lobortis nec, viverra ac lacus. Donec
|
7
|
+
eu vestibulum risus, at efficitur nisl. Maecenas sed elit a dui malesuada
|
8
|
+
ultricies at eget est. Duis lobortis tincidunt pellentesque.
|
9
|
+
|
10
|
+
Quisque in nisl felis. Quisque a neque nec diam posuere mattis. Donec a nibh
|
11
|
+
cursus, tempus est iaculis, gravida odio. Pellentesque eleifend enim eget
|
12
|
+
placerat dignissim. Cum sociis natoque penatibus et magnis dis parturient
|
13
|
+
montes, nascetur ridiculus mus. In non ex in augue feugiat convallis. Duis
|
14
|
+
varius at sapien vitae molestie. Suspendisse sit amet aliquet quam, quis
|
15
|
+
condimentum nibh.
|
16
|
+
|
17
|
+
Donec a quam quis ipsum imperdiet semper. In ac scelerisque elit, non fermentum
|
18
|
+
nisl. Nulla dapibus velit eget ullamcorper blandit. Maecenas justo diam,
|
19
|
+
porttitor eget nunc dictum, sollicitudin lacinia lectus. Pellentesque non augue
|
20
|
+
urna. In felis ipsum, posuere vitae sapien non, aliquet maximus nibh.
|
21
|
+
Suspendisse potenti. Aenean venenatis euismod congue. Praesent quis ullamcorper
|
22
|
+
sapien. In hac habitasse platea dictumst. Morbi semper augue dapibus, posuere
|
23
|
+
justo sit amet, convallis felis. Vivamus condimentum elementum ex, quis rhoncus
|
24
|
+
purus pulvinar et. Nunc vel risus sem. Suspendisse porttitor convallis massa,
|
25
|
+
molestie sollicitudin metus semper a. Donec ac cursus tortor. Nam felis nulla,
|
26
|
+
pretium eu tempus at, euismod eu erat.
|
27
|
+
|
28
|
+
Donec vel tempus augue. Pellentesque sit amet ante in odio malesuada facilisis
|
29
|
+
nec sit amet turpis. Donec vitae iaculis mauris. Aenean venenatis interdum
|
30
|
+
quam, nec tincidunt mauris aliquam vel. Nunc ultrices arcu euismod velit
|
31
|
+
ultricies, id laoreet arcu venenatis. Donec euismod scelerisque magna, nec
|
32
|
+
interdum lorem ornare nec. Morbi blandit volutpat velit, consequat maximus
|
33
|
+
justo mattis non. In pellentesque malesuada consectetur. Cras convallis mi ut
|
34
|
+
nibh rutrum ullamcorper. Nam finibus consequat erat a feugiat. Donec laoreet
|
35
|
+
risus eget enim interdum dictum. Duis orci lectus, scelerisque tempus volutpat
|
36
|
+
eget, ullamcorper eu felis. Aliquam tempor in dui sit amet dapibus. Nulla sed
|
37
|
+
metus vestibulum, dignissim odio et, dapibus eros. Praesent semper arcu ut
|
38
|
+
augue suscipit, ac ornare tortor auctor. Suspendisse a velit dui.
|
39
|
+
|
40
|
+
Etiam nec est ut ex laoreet iaculis vel id enim. Vivamus ac hendrerit leo.
|
41
|
+
Vestibulum auctor nibh nec arcu rhoncus, a condimentum quam accumsan. Ut justo
|
42
|
+
augue, laoreet at bibendum vel, aliquet vitae est. Aliquam accumsan ac diam nec
|
43
|
+
pretium. Nulla dictum velit nec elementum mollis. Interdum et malesuada fames
|
44
|
+
ac ante ipsum primis in faucibus.
|
@@ -0,0 +1 @@
|
|
1
|
+
monkey
|
@@ -0,0 +1 @@
|
|
1
|
+
world
|
@@ -0,0 +1,72 @@
|
|
1
|
+
ENV["RACK_ENV"] = "test"
|
2
|
+
|
3
|
+
require "refile"
|
4
|
+
require "refile/backend_examples"
|
5
|
+
require "webmock/rspec"
|
6
|
+
require "refile/file_double"
|
7
|
+
|
8
|
+
tmp_path = Dir.mktmpdir
|
9
|
+
|
10
|
+
WebMock.disable_net_connect!(allow_localhost: true)
|
11
|
+
|
12
|
+
at_exit do
|
13
|
+
FileUtils.remove_entry_secure(tmp_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
Refile.store = Refile::Backend::FileSystem.new(File.expand_path("default_store", tmp_path))
|
17
|
+
Refile.cache = Refile::Backend::FileSystem.new(File.expand_path("default_cache", tmp_path))
|
18
|
+
|
19
|
+
class FakePresignBackend < Refile::Backend::FileSystem
|
20
|
+
def presign
|
21
|
+
id = Refile::RandomHasher.new.hash
|
22
|
+
Refile::Signature.new(as: "file", id: id, url: "/presigned/posts/upload", fields: { id: id, token: "xyz123" })
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Refile.secret_key = "144c82de680afe5e8e91fc7cf13c22b2f8d2d4b1a4a0e92531979b12e2fa8b6dd6239c65be28517f27f442bfba11572a8bef80acf44a11f465ba85dde85488d5"
|
27
|
+
|
28
|
+
Refile.backends["limited_cache"] = FakePresignBackend.new(File.expand_path("default_cache", tmp_path), max_size: 100)
|
29
|
+
|
30
|
+
Refile.allow_uploads_to = %w[cache limited_cache]
|
31
|
+
|
32
|
+
Refile.allow_origin = "*"
|
33
|
+
|
34
|
+
Refile.app_host = "http://localhost:56120"
|
35
|
+
|
36
|
+
Refile.processor(:reverse) do |file|
|
37
|
+
StringIO.new(file.read.reverse)
|
38
|
+
end
|
39
|
+
|
40
|
+
Refile.processor(:upcase, proc { |file| StringIO.new(file.read.upcase) })
|
41
|
+
|
42
|
+
Refile.logger = Logger.new(nil)
|
43
|
+
|
44
|
+
Refile.processor(:concat) do |file, *words|
|
45
|
+
tempfile = Tempfile.new("concat")
|
46
|
+
tempfile.write(file.read)
|
47
|
+
words.each do |word|
|
48
|
+
tempfile.write(word)
|
49
|
+
end
|
50
|
+
tempfile.close
|
51
|
+
File.open(tempfile.path, "r")
|
52
|
+
end
|
53
|
+
|
54
|
+
Refile.processor(:convert_case) do |file, options = {}|
|
55
|
+
case options[:format]
|
56
|
+
when "up" then StringIO.new(file.read.upcase)
|
57
|
+
when "down" then StringIO.new(file.read.downcase)
|
58
|
+
else file
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
module PathHelper
|
63
|
+
def path(filename)
|
64
|
+
File.expand_path(File.join("fixtures", filename), File.dirname(__FILE__))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
RSpec.configure do |config|
|
69
|
+
config.include PathHelper
|
70
|
+
end
|
71
|
+
|
72
|
+
RSpec::Expectations.configuration.warn_about_potential_false_positives = false
|
data/spec/refile_spec.rb
ADDED
@@ -0,0 +1,355 @@
|
|
1
|
+
require "refile"
|
2
|
+
|
3
|
+
RSpec.describe Refile do
|
4
|
+
before do
|
5
|
+
allow(Refile).to receive(:token).and_return("token")
|
6
|
+
allow(Refile).to receive(:app_host).and_return(nil)
|
7
|
+
allow(Refile).to receive(:mount_point).and_return(nil)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:klass) do
|
11
|
+
Class.new do
|
12
|
+
extend Refile::Attachment
|
13
|
+
attr_accessor :document_id
|
14
|
+
attachment :document
|
15
|
+
end
|
16
|
+
end
|
17
|
+
let(:instance) { klass.new }
|
18
|
+
|
19
|
+
describe ".extract_filename" do
|
20
|
+
it "extracts filename from original_filename" do
|
21
|
+
name = Refile.extract_filename(double(original_filename: "/foo/bar/baz.png"))
|
22
|
+
expect(name).to eq("baz.png")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "extracts filename from path" do
|
26
|
+
name = Refile.extract_filename(double(path: "/foo/bar/baz.png"))
|
27
|
+
expect(name).to eq("baz.png")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns nil if it can't determine filename" do
|
31
|
+
name = Refile.extract_filename(double)
|
32
|
+
expect(name).to be_nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe ".extract_content_type" do
|
37
|
+
it "extracts content type" do
|
38
|
+
name = Refile.extract_content_type(double(content_type: "image/jpeg"))
|
39
|
+
expect(name).to eq("image/jpeg")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "extracts content type from extension" do
|
43
|
+
name = Refile.extract_content_type(double(original_filename: "test.png"))
|
44
|
+
expect(name).to eq("image/png")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns nil if it can't determine content type" do
|
48
|
+
name = Refile.extract_filename(double)
|
49
|
+
expect(name).to be_nil
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns nil if it has an unknown content type" do
|
53
|
+
name = Refile.extract_content_type(double(original_filename: "foo.blah"))
|
54
|
+
expect(name).to be_nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe ".app_url" do
|
59
|
+
it "generates a root url when all options unset" do
|
60
|
+
expect(Refile.app_url).to eq("/")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "uses supplied host option" do
|
64
|
+
expect(Refile.app_url(host: "http://example.org")).to eq("http://example.org/")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "falls back to Refile.app_host" do
|
68
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
69
|
+
|
70
|
+
expect(Refile.app_url).to eq("http://elabs.se/")
|
71
|
+
end
|
72
|
+
|
73
|
+
it "adds a prefix" do
|
74
|
+
expect(Refile.app_url(prefix: "/moo")).to eq("/moo")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "takes prefix from Refile.mount_point" do
|
78
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
79
|
+
expect(Refile.app_url).to eq("/attachments")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe ".file_url" do
|
84
|
+
let(:file) { Refile.cache.upload(Refile::FileDouble.new("hello")) }
|
85
|
+
let(:id) { file.id }
|
86
|
+
|
87
|
+
it "generates a url from an attachment" do
|
88
|
+
expect(Refile.file_url(file, filename: "document")).to eq("/token/cache/#{id}/document")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "uses supplied host option" do
|
92
|
+
expect(Refile.file_url(file, host: "http://example.org", filename: "document")).to eq("http://example.org/token/cache/#{id}/document")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "falls back to Refile.app_host" do
|
96
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
97
|
+
|
98
|
+
expect(Refile.file_url(file, filename: "document")).to eq("http://elabs.se/token/cache/#{id}/document")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "falls back to Refile.cdn_host" do
|
102
|
+
allow(Refile).to receive(:cdn_host).and_return("http://foo.cloudfront.com")
|
103
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
104
|
+
|
105
|
+
expect(Refile.file_url(file, filename: "document")).to eq("http://foo.cloudfront.com/token/cache/#{id}/document")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "adds a prefix" do
|
109
|
+
expect(Refile.file_url(file, prefix: "/moo", filename: "document")).to eq("/moo/token/cache/#{id}/document")
|
110
|
+
end
|
111
|
+
|
112
|
+
it "takes prefix from Refile.mount_point" do
|
113
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
114
|
+
expect(Refile.file_url(file, filename: "document")).to eq("/attachments/token/cache/#{id}/document")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "adds an escaped filename" do
|
118
|
+
expect(Refile.file_url(file, filename: "test.png")).to eq("/token/cache/#{id}/test.png")
|
119
|
+
expect(Refile.file_url(file, filename: "tes/t.png")).to eq("/token/cache/#{id}/tes%2Ft.png")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "adds a format" do
|
123
|
+
expect(Refile.file_url(file, format: "png", filename: "document")).to eq("/token/cache/#{id}/document.png")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "avoids extension duplication by specifying format" do
|
127
|
+
expect(Refile.file_url(file, format: "png", filename: "document.png")).to eq("/token/cache/#{id}/document.png")
|
128
|
+
end
|
129
|
+
|
130
|
+
context "with no file" do
|
131
|
+
it "returns nil" do
|
132
|
+
expect(Refile.file_url(nil, filename: "document")).to be_nil
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe ".attachment_url" do
|
138
|
+
let(:id) { instance.document_attacher.cache_id }
|
139
|
+
|
140
|
+
context "with file" do
|
141
|
+
before do
|
142
|
+
instance.document = Refile::FileDouble.new("hello")
|
143
|
+
end
|
144
|
+
|
145
|
+
it "generates a url from an attachment" do
|
146
|
+
expect(Refile.attachment_url(instance, :document)).to eq("/token/cache/#{id}/document")
|
147
|
+
end
|
148
|
+
|
149
|
+
it "uses supplied host option" do
|
150
|
+
expect(Refile.attachment_url(instance, :document, host: "http://example.org")).to eq("http://example.org/token/cache/#{id}/document")
|
151
|
+
end
|
152
|
+
|
153
|
+
it "falls back to Refile.app_host" do
|
154
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
155
|
+
|
156
|
+
expect(Refile.attachment_url(instance, :document)).to eq("http://elabs.se/token/cache/#{id}/document")
|
157
|
+
end
|
158
|
+
|
159
|
+
it "falls back to Refile.cdn_host" do
|
160
|
+
allow(Refile).to receive(:cdn_host).and_return("http://foo.cloudfront.com")
|
161
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
162
|
+
|
163
|
+
expect(Refile.attachment_url(instance, :document)).to eq("http://foo.cloudfront.com/token/cache/#{id}/document")
|
164
|
+
end
|
165
|
+
|
166
|
+
it "adds a prefix" do
|
167
|
+
expect(Refile.attachment_url(instance, :document, prefix: "/moo")).to eq("/moo/token/cache/#{id}/document")
|
168
|
+
end
|
169
|
+
|
170
|
+
it "takes prefix from Refile.mount_point" do
|
171
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
172
|
+
expect(Refile.attachment_url(instance, :document)).to eq("/attachments/token/cache/#{id}/document")
|
173
|
+
end
|
174
|
+
|
175
|
+
it "adds an escaped filename" do
|
176
|
+
expect(Refile.attachment_url(instance, :document, filename: "test.png")).to eq("/token/cache/#{id}/test.png")
|
177
|
+
expect(Refile.attachment_url(instance, :document, filename: "tes/t.png")).to eq("/token/cache/#{id}/tes%2Ft.png")
|
178
|
+
end
|
179
|
+
|
180
|
+
it "adds a format" do
|
181
|
+
expect(Refile.attachment_url(instance, :document, format: "png")).to eq("/token/cache/#{id}/document.png")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "with file with content type" do
|
186
|
+
before do
|
187
|
+
instance.document = Refile::FileDouble.new("hello", content_type: "image/png")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "adds format inferred from content type" do
|
191
|
+
expect(Refile.attachment_url(instance, :document)).to eq("/token/cache/#{id}/document.png")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "with file with filename" do
|
196
|
+
before do
|
197
|
+
instance.document = Refile::FileDouble.new("hello", "hello.html")
|
198
|
+
end
|
199
|
+
|
200
|
+
it "adds filename" do
|
201
|
+
expect(Refile.attachment_url(instance, :document)).to eq("/token/cache/#{id}/hello.html")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "with no file" do
|
206
|
+
it "returns nil" do
|
207
|
+
expect(Refile.attachment_url(instance, :document)).to be_nil
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe ".upload_url" do
|
213
|
+
it "generates an upload url" do
|
214
|
+
expect(Refile.upload_url(Refile.cache)).to eq("/cache")
|
215
|
+
end
|
216
|
+
|
217
|
+
it "uses supplied host option" do
|
218
|
+
expect(Refile.upload_url(Refile.cache, host: "http://example.org")).to eq("http://example.org/cache")
|
219
|
+
end
|
220
|
+
|
221
|
+
it "falls back to Refile.app_host" do
|
222
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
223
|
+
|
224
|
+
expect(Refile.upload_url(Refile.cache)).to eq("http://elabs.se/cache")
|
225
|
+
end
|
226
|
+
|
227
|
+
it "does not fall back to Refile.cdn_host" do
|
228
|
+
allow(Refile).to receive(:cdn_host).and_return("http://foo.cloudfront.com")
|
229
|
+
|
230
|
+
expect(Refile.upload_url(Refile.cache)).to eq("/cache")
|
231
|
+
end
|
232
|
+
|
233
|
+
it "adds a prefix" do
|
234
|
+
expect(Refile.upload_url(Refile.cache, prefix: "/moo")).to eq("/moo/cache")
|
235
|
+
end
|
236
|
+
|
237
|
+
it "takes prefix from Refile.mount_point" do
|
238
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
239
|
+
expect(Refile.upload_url(Refile.cache)).to eq("/attachments/cache")
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
describe ".presign_url" do
|
244
|
+
it "generates an upload url" do
|
245
|
+
expect(Refile.presign_url(Refile.cache)).to eq("/cache/presign")
|
246
|
+
end
|
247
|
+
|
248
|
+
it "uses supplied host option" do
|
249
|
+
expect(Refile.presign_url(Refile.cache, host: "http://example.org")).to eq("http://example.org/cache/presign")
|
250
|
+
end
|
251
|
+
|
252
|
+
it "falls back to Refile.app_host" do
|
253
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
254
|
+
|
255
|
+
expect(Refile.presign_url(Refile.cache)).to eq("http://elabs.se/cache/presign")
|
256
|
+
end
|
257
|
+
|
258
|
+
it "does not fall back to Refile.cdn_host" do
|
259
|
+
allow(Refile).to receive(:cdn_host).and_return("http://foo.cloudfront.com")
|
260
|
+
|
261
|
+
expect(Refile.presign_url(Refile.cache)).to eq("/cache/presign")
|
262
|
+
end
|
263
|
+
|
264
|
+
it "adds a prefix" do
|
265
|
+
expect(Refile.presign_url(Refile.cache, prefix: "/moo")).to eq("/moo/cache/presign")
|
266
|
+
end
|
267
|
+
|
268
|
+
it "takes prefix from Refile.mount_point" do
|
269
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
270
|
+
expect(Refile.presign_url(Refile.cache)).to eq("/attachments/cache/presign")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe ".attachment_upload_url" do
|
275
|
+
it "generates an upload url" do
|
276
|
+
expect(Refile.attachment_upload_url(instance, :document)).to eq("/cache")
|
277
|
+
end
|
278
|
+
|
279
|
+
it "uses supplied host option" do
|
280
|
+
expect(Refile.attachment_upload_url(instance, :document, host: "http://example.org")).to eq("http://example.org/cache")
|
281
|
+
end
|
282
|
+
|
283
|
+
it "falls back to Refile.app_host" do
|
284
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
285
|
+
|
286
|
+
expect(Refile.attachment_upload_url(instance, :document)).to eq("http://elabs.se/cache")
|
287
|
+
end
|
288
|
+
|
289
|
+
it "does not fall back to Refile.cdn_host" do
|
290
|
+
allow(Refile).to receive(:cdn_host).and_return("http://foo.cloudfront.com")
|
291
|
+
|
292
|
+
expect(Refile.attachment_upload_url(instance, :document)).to eq("/cache")
|
293
|
+
end
|
294
|
+
|
295
|
+
it "adds a prefix" do
|
296
|
+
expect(Refile.attachment_upload_url(instance, :document, prefix: "/moo")).to eq("/moo/cache")
|
297
|
+
end
|
298
|
+
|
299
|
+
it "takes prefix from Refile.mount_point" do
|
300
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
301
|
+
expect(Refile.attachment_upload_url(instance, :document)).to eq("/attachments/cache")
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
describe ".attachment_presign_url" do
|
306
|
+
it "generates an upload url" do
|
307
|
+
expect(Refile.attachment_presign_url(instance, :document)).to eq("/cache/presign")
|
308
|
+
end
|
309
|
+
|
310
|
+
it "uses supplied host option" do
|
311
|
+
expect(Refile.attachment_presign_url(instance, :document, host: "http://example.org")).to eq("http://example.org/cache/presign")
|
312
|
+
end
|
313
|
+
|
314
|
+
it "falls back to Refile.app_host" do
|
315
|
+
allow(Refile).to receive(:app_host).and_return("http://elabs.se")
|
316
|
+
|
317
|
+
expect(Refile.attachment_presign_url(instance, :document)).to eq("http://elabs.se/cache/presign")
|
318
|
+
end
|
319
|
+
|
320
|
+
it "does not fall back to Refile.cdn_host" do
|
321
|
+
allow(Refile).to receive(:cdn_host).and_return("http://foo.cloudfront.com")
|
322
|
+
|
323
|
+
expect(Refile.attachment_presign_url(instance, :document)).to eq("/cache/presign")
|
324
|
+
end
|
325
|
+
|
326
|
+
it "adds a prefix" do
|
327
|
+
expect(Refile.attachment_presign_url(instance, :document, prefix: "/moo")).to eq("/moo/cache/presign")
|
328
|
+
end
|
329
|
+
|
330
|
+
it "takes prefix from Refile.mount_point" do
|
331
|
+
allow(Refile).to receive(:mount_point).and_return("/attachments")
|
332
|
+
expect(Refile.attachment_presign_url(instance, :document)).to eq("/attachments/cache/presign")
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
describe ".token" do
|
337
|
+
before do
|
338
|
+
allow(Refile).to receive(:token).and_call_original
|
339
|
+
end
|
340
|
+
|
341
|
+
it "returns digest of given path and secret token" do
|
342
|
+
allow(Refile).to receive(:secret_key).and_return("abcd1234")
|
343
|
+
|
344
|
+
path = "/store/f5f2e4/document.pdf"
|
345
|
+
token = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), "abcd1234", path)
|
346
|
+
expect(Refile.token(path)).to eq(token)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "returns raise error when secret token is nil" do
|
350
|
+
allow(Refile).to receive(:secret_key).and_return(nil)
|
351
|
+
|
352
|
+
expect { Refile.token("/store/f5f2e4/document.pdf") }.to raise_error(RuntimeError, /Refile\.secret_key was not set/)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|