Validating File Extension Allowlist Functionality in CarrierWave
This test suite thoroughly validates the file extension allowlist functionality in CarrierWave, ensuring proper handling of allowed and restricted file uploads. It covers both allowlist and legacy whitelist implementations, with comprehensive case sensitivity and regular expression support testing.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
carrierwaveuploader/carrierwave
spec/uploader/extension_allowlist_spec.rb
require 'spec_helper'
describe CarrierWave::Uploader do
before do
@uploader_class = Class.new(CarrierWave::Uploader::Base)
@uploader = @uploader_class.new
end
after do
FileUtils.rm_rf(public_path)
end
describe '#cache!' do
before do
allow(CarrierWave).to receive(:generate_cache_id).and_return('1369894322-345-1234-2255')
end
context "when there is no allowlist" do
it "does not raise an integrity error" do
allow(@uploader).to receive(:extension_allowlist).and_return(nil)
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.not_to raise_error
end
end
context "when there is an allowlist" do
context "when the allowlist is an array of values" do
it "does not raise an integrity error when the file has an allowlisted extension" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(jpg gif png))
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.not_to raise_error
end
it "raises an integrity error if the file has not an allowlisted extension" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(txt doc xls))
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.to raise_error(CarrierWave::IntegrityError, 'You are not allowed to upload "jpg" files, allowed types: txt, doc, xls')
end
it "raises an integrity error if the file has not an allowlisted extension" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(txt doc xls))
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.to raise_error(CarrierWave::IntegrityError)
end
it "raises an integrity error if the file has not an allowlisted extension, using start of string matcher" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(txt))
expect {
@uploader.cache!(File.open(file_path('bork.ttxt')))
}.to raise_error(CarrierWave::IntegrityError)
end
it "raises an integrity error if the file has not an allowlisted extension, using end of string matcher" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(txt))
expect {
@uploader.cache!(File.open(file_path('bork.txtt')))
}.to raise_error(CarrierWave::IntegrityError)
end
it "compares extensions in a case insensitive manner when capitalized extension provided" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(jpg gif png))
expect {
@uploader.cache!(File.open(file_path('case.JPG')))
}.not_to raise_error
end
it "compares extensions in a case insensitive manner when lowercase extension provided" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(JPG GIF PNG))
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.not_to raise_error
end
it "accepts extensions as regular expressions" do
allow(@uploader).to receive(:extension_allowlist).and_return([/jpe?g/, 'gif', 'png'])
expect {
@uploader.cache!(File.open(file_path('test.jpeg')))
}.not_to raise_error
end
it "accepts extensions as regular expressions in a case insensitive manner" do
allow(@uploader).to receive(:extension_allowlist).and_return([/jpe?g/, 'gif', 'png'])
expect {
@uploader.cache!(File.open(file_path('case.JPG')))
}.not_to raise_error
end
end
context "when the allowlist is a single value" do
it "accepts a single extension string value" do
allow(@uploader).to receive(:extension_allowlist).and_return('jpeg')
expect { @uploader.cache!(File.open(file_path('test.jpg'))) }.to raise_error(CarrierWave::IntegrityError)
end
it "accepts a single extension regular expression value" do
allow(@uploader).to receive(:extension_allowlist).and_return(/jpe?g/)
expect { @uploader.cache!(File.open(file_path('bork.txt')))}.to raise_error(CarrierWave::IntegrityError)
end
end
end
context "when there is a whitelist" do
it "uses the whitelist but shows deprecation" do
allow(@uploader).to receive(:extension_whitelist).and_return(%w(txt doc xls))
expect(CarrierWave.deprecator).to receive(:warn).with('#extension_whitelist is deprecated, use #extension_allowlist instead.')
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.to raise_error(CarrierWave::IntegrityError)
end
it "looks for extension_allowlist first for I18n translation" do
allow(@uploader).to receive(:extension_allowlist).and_return(%w(txt doc xls))
change_locale_and_store_translations(:nl, :errors => {
:messages => {
:extension_whitelist_error => "this will not be used",
:extension_allowlist_error => "Het is niet toegestaan om %{extension} bestanden te uploaden; toegestane bestandstypes: %{allowed_types}"
}
}) do
expect {
@uploader.cache!(File.open(file_path('test.jpg')))
}.to raise_error(CarrierWave::IntegrityError, 'Het is niet toegestaan om "jpg" bestanden te uploaden; toegestane bestandstypes: txt, doc, xls')
end
end
end
end
end