-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Image attachment content type validation fix for ActiveStorage #4021
Conversation
Failed on paperclip
|
core/spec/models/spree/image_spec.rb
Outdated
describe 'validations' do | ||
let(:valid_image_file) { File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', 'blank.jpg')) } | ||
let(:invalid_image_file) { File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', 'file.txt')) } | ||
let(:image) { create(:image) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that using this syntax the specs should work with both adapters:
subject { create(:image, attachment: valid_image_file) }
@@ -107,6 +107,8 @@ def filename | |||
|
|||
def url(style = default_style) | |||
attachment.url(style) | |||
rescue ActiveStorage::FileNotFoundError | |||
'/images/corrupted-image.png' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This image is not provided by the system, and I think it shouldn't because the frontend and the backend have separate assets folders while this concern code would serve both of them. One alternative could be using a base64 string here with a standard broken image icon, but it's not ideal as well.
On a side note: what about removing this fix from this PR and opening another one just for the other issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed temporary fix to be brought up in another branch
Removed AS:FileNotFileError catch from this PR. Will patch that fix in another PR for further Discussion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a couple of suggestions. When done, can you please also squash all the commits into a single one for a better git history when the PR will get merged?
core/spec/models/spree/image_spec.rb
Outdated
@@ -9,6 +9,26 @@ | |||
let(:default_style) { :product } | |||
end | |||
|
|||
describe 'validations' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like there's no need for the describe
blocks here since we don't have any shared object between the test cases into it. What about just using two different tests as:
it 'is valid when attachment has allowed content type' do
image = build(:image,
attachment: File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', 'blank.jpg'))
)
expect(image).to be_valid
end
it 'is not valid when attachment has restricted content type' do
image = build(:image,
attachment: File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', 'file.txt'))
)
expect(image).to_not be_valid
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This syntax has been implemented!
b5af38f
to
60c6b56
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @cpfergus1! 🎉
end | ||
|
||
def accepted_image_types | ||
%w(image/jpeg image/jpg image/png image/gif) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about having the list of accepted mime types in a constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defined in a ENV constant or where would the constant be defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, no... I mean as a constant in Spree::Image::ActiveStorageAttachment
, like in:
module Spree::Image::ActiveStorageAttachment
ACCEPTED_IMAGE_TYPES = %w(....).freeze
end
I mean, it's information that doesn't depend on the state of an object, and it has no computational logic, so in my view, it belongs to the constants domain.
Sorry not having been clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thank you for clarifying
core/spec/lib/search/base_spec.rb
Outdated
@@ -22,11 +22,12 @@ | |||
|
|||
context "when include_images is included in the initialization params" do | |||
let(:params) { { include_images: true, keyword: @product1.name, taxon: @taxon.id } } | |||
let(:image_file) { File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', 'blank.jpg')) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As we are using File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', **)
in several place, what do you think about extracting it to a test helper method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a great idea, I can certainly implement this now.
core/spec/models/spree/image_spec.rb
Outdated
@@ -9,6 +9,18 @@ | |||
let(:default_style) { :product } | |||
end | |||
|
|||
it 'is valid when attachment has allowed content type' do | |||
image = build(:image, | |||
attachment: File.open(File.join('lib', 'spree', 'testing_support', 'fixtures', 'blank.jpg'))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like to put a blank line between Given/Then/When contexts in the specs... However, I think this is not consistently used in the codebase, so feel free to ignore the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not noticing this in the rest of the examples, I think I will leave it as is to conform for the time being. Thanks for the suggestion!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job @cpfergus1 . I think this validation is definitely the first step to have in place before attempting to fix edge cases 👏 👏
08f1a4d
to
3ddee2d
Compare
@@ -3,10 +3,15 @@ | |||
module Spree::Image::ActiveStorageAttachment | |||
extend ActiveSupport::Concern | |||
include Spree::ActiveStorageAdapter | |||
ACCEPTED_IMAGE_TYPES = %w(image/jpeg image/jpg image/png image/gif).freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about adding an application configuration for this so that it's easier to configure for stores that want to restrict the list further?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a side note: we can see also how Paperclip is restricting file types and use the same config for Paperclip as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I replaced both %() in paperclipattachment and activestorage attachment with an new application configuration: Spree::Config.allowed_image_mime_types.
This commit implements validations for content type. Specifically,this new validation ensures image file types .png/.jpeg/.jpg/.gif are the only accepted file formats at this time, but can be edited by altering the accepted_image_types method to allow other formats should the developer desire to implement that functionality. This method was tested by building the objects and testing validity with both a valid image file and an invalid .txt file. Commit History: Created validation tests for images Implemented validation of filetypes Renamed validation Patched file not found error for url Core test update to be compatible with new validation Core test update to be compatible with new validation Updated test to have file names Implemented compatible syntax for AS and Paperclip Separate NoFileError to another branch Refactored validation tests Returned mistakenly deleted white space Removed describe block Changed accepted image types method to constant Implemented application configuration for Image MIME types Added documentation to configuration
Commit History: Changed file name to represent module name Removed unnecessary line breaks
Description
Ref #4017
This PR aimed to solve the bugs described in Issue #4017 by implementing a validation for content type and to handle a FileNotFound error when ActiveStorage fails to upload to a remote service such as S3.
The validation allows file types jpeg, png, jpg and gif. More file types can be added and removed by editing the accepted_image_types definition found in active_storage_attachment.rb. Validation tests have been added to the image_spec.rb in core.
The handling of the FileNotFound error maybe a temporary fix as we are aiming to discover another pathway to handle the exception and remove the invalid objects simultaneously. Currently when the error is raised on method call, it returns a corrupted image file path.
Checklist: