Skip to content

Commit

Permalink
Add 'greater_than' and 'within' to FileSizeValidator
Browse files Browse the repository at this point in the history
ref #18
  • Loading branch information
unasuke committed Jan 27, 2022
1 parent b5c3772 commit 9ca0354
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 23 deletions.
24 changes: 24 additions & 0 deletions lib/mini_paperclip/validators/file_size_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,32 @@ def validate_each(record, attribute, value)
record.errors.add(attachment_file_size_name, :less_than, count: count)
end
end

if check_value = options[:greater_than]
unless attachment_file_size > check_value
count = ActiveSupport::NumberHelper.number_to_human_size(check_value)
record.errors.add(attribute, :greater_than, count: count)
record.errors.add(attachment_file_size_name, :greater_than, count: count)
end
end

if check_value = (options[:within] || options[:in])
unless check_value.include?(attachment_file_size)
record.errors.add(attribute, :within, count: formatted_range(check_value))
record.errors.add(attachment_file_size_name, :within, count: formatted_range(check_value))
end
end
end
end

private

def formatted_range(range)
dots = range.exclude_end? ? "..." : ".."
first = ActiveSupport::NumberHelper.number_to_human_size(range.begin)
last = ActiveSupport::NumberHelper.number_to_human_size(range.last)
"#{first}#{dots}#{last}"
end
end
end
end
153 changes: 130 additions & 23 deletions spec/mini_paperclip/validators/file_size_validator_spec.rb
Original file line number Diff line number Diff line change
@@ -1,28 +1,135 @@
RSpec.describe MiniPaperclip::Validators::FileSizeValidator do
it "#validate_each with valid file size" do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
less_than: 1.megabytes,
)
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(1.kilobytes)
expect(mock).to_not receive(:errors)
validator.validate_each(mock, :img, attachment)
describe "less_than" do
it "#validate_each with valid file size" do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
less_than: 1.megabytes,
)
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(1.kilobytes)
expect(mock).to_not receive(:errors)
validator.validate_each(mock, :img, attachment)
end

it "#validate_each with invalid file size" do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
less_than: 1.megabytes,
)
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(2.megabytes)
errors_mock = double('Errors')
allow(mock).to receive(:errors).and_return(errors_mock)
expect(errors_mock).to receive(:add).with(:img, :less_than, { count: "1 MB" })
expect(errors_mock).to receive(:add).with("img_file_size", :less_than, { count: "1 MB" })
validator.validate_each(mock, :img, attachment)
end
end

describe "greater_than" do
it "#validate_each with valid file size" do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
greater_than: 1.megabytes,
)
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(2.megabytes)
expect(mock).to_not receive(:errors)
validator.validate_each(mock, :img, attachment)
end

it "#validate_each with invalid file size" do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
greater_than: 1.megabytes,
)
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(1.kilobytes)
errors_mock = double('Errors')
allow(mock).to receive(:errors).and_return(errors_mock)
expect(errors_mock).to receive(:add).with(:img, :greater_than, { count: "1 MB" })
expect(errors_mock).to receive(:add).with("img_file_size", :greater_than, { count: "1 MB" })
validator.validate_each(mock, :img, attachment)
end
end

describe "within (1.megabytes..2.megabytes)" do
let(:validator) do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
within: 1.megabytes..2.megabytes,
)
end

context "valid case" do
[1.megabytes, 1.5.megabytes, 2.megabytes].each do |file_size|
it "returns no error when file size is #{file_size}" do
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(file_size)
expect(mock).to_not receive(:errors)
validator.validate_each(mock, :img, attachment)
end
end
end

context "too large (2.megabytes + 1)" do
it "returns error" do
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(2.megabytes + 1)
errors_mock = double('Errors')
allow(mock).to receive(:errors).and_return(errors_mock)
expect(errors_mock).to receive(:add).with(:img, :within, { count: "1 MB..2 MB" })
expect(errors_mock).to receive(:add).with("img_file_size", :within, { count: "1 MB..2 MB" })
validator.validate_each(mock, :img, attachment)
end
end

context "too small (1.megabytes - 1)" do
it "returns error" do
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(1.megabytes - 1)
errors_mock = double('Errors')
allow(mock).to receive(:errors).and_return(errors_mock)
expect(errors_mock).to receive(:add).with(:img, :within, { count: "1 MB..2 MB" })
expect(errors_mock).to receive(:add).with("img_file_size", :within, { count: "1 MB..2 MB" })
validator.validate_each(mock, :img, attachment)
end
end
end

it "#validate_each with invalid file size" do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
less_than: 1.megabytes,
)
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(2.megabytes)
errors_mock = double('Errors')
allow(mock).to receive(:errors).and_return(errors_mock)
expect(errors_mock).to receive(:add).with(:img, :less_than, { count: "1 MB" })
expect(errors_mock).to receive(:add).with("img_file_size", :less_than, { count: "1 MB" })
validator.validate_each(mock, :img, attachment)
describe "alias 'in' (1.megabytes...3.megabytes)" do
let(:validator) do
validator = MiniPaperclip::Validators::FileSizeValidator.new(
attributes: :img,
in: 1.megabytes...3.megabytes,
)
end
[1.megabytes, 1.5.megabytes, 3.megabytes - 1 ].each do |file_size|
it "returns no error when file size is #{file_size}" do
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(file_size)
expect(mock).to_not receive(:errors)
validator.validate_each(mock, :img, attachment)
end
end

it "returns error when file size is 3.megebaytes" do
mock = double('Record')
attachment = double('Attachment')
allow(mock).to receive(:read_attribute_for_validation).with('img_file_size').and_return(3.megabytes)
errors_mock = double('Errors')
allow(mock).to receive(:errors).and_return(errors_mock)
expect(errors_mock).to receive(:add).with(:img, :within, { count: "1 MB...3 MB" })
expect(errors_mock).to receive(:add).with("img_file_size", :within, { count: "1 MB...3 MB" })
validator.validate_each(mock, :img, attachment)
end
end
end

0 comments on commit 9ca0354

Please sign in to comment.