Add missing image model spec. Add shared specs to check image validations at any imageable model

This commit is contained in:
Senén Rodero Rodríguez
2017-09-15 19:02:49 +02:00
parent bb57c1a7f5
commit c6dabedb4a
13 changed files with 208 additions and 16 deletions

View File

@@ -0,0 +1,40 @@
class DirectUploadsController < ApplicationController
def destroy_upload
@document = Document.new(cached_attachment: params[:path])
@document.set_attachment_from_cached_attachment
@document.cached_attachment = nil
@document.documentable = @documentable
if @document.attachment.destroy
flash.now[:notice] = t "documents.actions.destroy.notice"
else
flash.now[:alert] = t "documents.actions.destroy.alert"
end
render :destroy
end
def upload
@document = Document.new(document_params.merge(user: current_user))
@document.documentable = @documentable
@document.valid?
if @document.valid?
@document.attachment.save
@document.set_cached_attachment_from_attachment(URI(request.url))
else
@document.attachment.destroy
end
end
private
def set_attachment_container_resource
@container_resource = params[:resource_type]
end
def find_attachment_container_resource
@uplo = params[:documentable_type].constantize.find_or_initialize_by(id: params[:documentable_id])
end
end

View File

@@ -12,8 +12,8 @@ module DocumentablesHelper
bytes_to_mega(documentable.class.max_file_size)
end
def accepted_content_types(documentable)
documentable.class.accepted_content_types
def accepted_content_types(documentable_class)
documentable_class.accepted_content_types
end
def accepted_content_types_extensions(documentable_class)
@@ -22,15 +22,15 @@ module DocumentablesHelper
.join(",")
end
def documentable_humanized_accepted_content_types(documentable)
documentable.class.accepted_content_types
def documentable_humanized_accepted_content_types(documentable_class)
documentable_class.accepted_content_types
.collect{ |content_type| content_type.split("/").last }
.join(", ")
end
def documentables_note(documentable)
t "documents.form.note", max_documents_allowed: max_documents_allowed(documentable),
accepted_content_types: documentable_humanized_accepted_content_types(documentable),
accepted_content_types: documentable_humanized_accepted_content_types(documentable.class),
max_file_size: max_file_size(documentable)
end

View File

@@ -0,0 +1,28 @@
class DirectUpload
include ActiveModel::Validations
attr_accessor :resource, :resource_type, :resource_id, :resource_relation,
:attachment, :cached_attachment
validates_presence_of :attachment, :resource_type, :resource_relation
validate :parent_resource_attachment_validations,
if: -> { attachment.present? && resource_type.present? && resource_relation.present? }
def parent_resource_attachment_validations
# Proposal or Budget::Investment
resource = resource_type.constantize.find_or_initialize_by(id: resource_id)
# Document or Image
relation = if resource.class.reflections[resource_relation].macro == :has_one
resource.send("build_#{resource_relation}", attachment: attachment)
else
resource.send(resource_relation).build(attachment: attachment)
end
relation.valid?
if relation.errors.has_key? :attachment
errors[:attachment] = relation.errors[:attachment]
end
end
end

View File

@@ -50,9 +50,13 @@ class Document < ActiveRecord::Base
private
def documentable_class
documentable_type.constantize if documentable_type.present?
end
def validate_attachment_size
if documentable.present? &&
attachment_file_size > documentable.class.max_file_size
if documentable_class.present? &&
attachment_file_size > documentable_class.max_file_size
errors[:attachment] = I18n.t("documents.errors.messages.in_between",
min: "0 Bytes",
max: "#{max_file_size(documentable)} MB")
@@ -60,11 +64,11 @@ class Document < ActiveRecord::Base
end
def validate_attachment_content_type
if documentable.present? &&
!accepted_content_types(documentable).include?(attachment_content_type)
if documentable_class &&
!accepted_content_types(documentable_class).include?(attachment_content_type)
errors[:attachment] = I18n.t("documents.errors.messages.wrong_content_type",
content_type: attachment_content_type,
accepted_content_types: documentable_humanized_accepted_content_types(documentable))
accepted_content_types: documentable_humanized_accepted_content_types(documentable_class))
end
end

View File

@@ -66,6 +66,10 @@ class Image < ActiveRecord::Base
attachment.reprocess!
end
def imageable_class
imageable_type.constantize if imageable_type.present?
end
def validate_image_dimensions
if attachment_of_valid_content_type?
dimensions = Paperclip::Geometry.from_file(attachment.queued_for_write[:original].path)
@@ -75,7 +79,7 @@ class Image < ActiveRecord::Base
end
def validate_attachment_size
if imageable.present? &&
if imageable_class &&
attachment_file_size > 1.megabytes
errors[:attachment] = I18n.t("images.errors.messages.in_between",
min: "0 Bytes",
@@ -84,7 +88,7 @@ class Image < ActiveRecord::Base
end
def validate_attachment_content_type
if imageable.present? && !attachment_of_valid_content_type?
if imageable_class && !attachment_of_valid_content_type?
errors[:attachment] = I18n.t("images.errors.messages.wrong_content_type",
content_type: attachment_content_type,
accepted_content_types: imageable_humanized_accepted_content_types)

View File

@@ -1,4 +1,4 @@
<div class="document-form <%= documentable_class(@document.documentable) %> row">
<div class="document-form <%= documentable_class(@document.documentable.class) %> row">
<div class="small-12 medium-9 column">
<%= back_link_to params[:from] %>
@@ -16,7 +16,7 @@
</li>
<li>
<%= t "documents.recommendation_two_html",
accepted_content_types: documentable_humanized_accepted_content_types(@document.documentable) %>
accepted_content_types: documentable_humanized_accepted_content_types(@document.documentable.class) %>
</li>
<li>
<%= t "documents.recommendation_three_html",

View File

@@ -819,4 +819,23 @@ LOREM_IPSUM
association :author, factory: :user
end
factory :direct_upload do
trait :proposal do
resource_type "Proposal"
end
trait :budget_investment do
resource_type "Budget::Investment"
end
trait :documents do
resource_relation "documents"
attachment { File.new("spec/fixtures/files/empty.pdf") }
end
trait :image do
resource_relation "image"
attachment { File.new("spec/fixtures/files/clippy.jpg") }
end
end
end

BIN
spec/fixtures/files/clippy.jpeg vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,19 @@
require 'rails_helper'
describe DirectUpload do
it "should be valid for different kind of combinations when attachment is valid" do
expect(build(:direct_upload, :proposal, :documents)).to be_valid
expect(build(:direct_upload, :proposal, :image)).to be_valid
expect(build(:direct_upload, :budget_investment, :documents)).to be_valid
expect(build(:direct_upload, :budget_investment, :image)).to be_valid
end
it "should not be valid for different kind of combinations when invalid atttachment content types" do
expect(build(:direct_upload, :proposal, :documents, attachment: File.new("spec/fixtures/files/clippy.png"))).not_to be_valid
expect(build(:direct_upload, :proposal, :image, attachment: File.new("spec/fixtures/files/empty.pdf"))).not_to be_valid
expect(build(:direct_upload, :budget_investment, :documents, attachment: File.new("spec/fixtures/files/clippy.png"))).not_to be_valid
expect(build(:direct_upload, :budget_investment, :image, attachment: File.new("spec/fixtures/files/empty.pdf"))).not_to be_valid
end
end

View File

@@ -0,0 +1,8 @@
require 'rails_helper'
describe Image do
it_behaves_like "image validations", "budget_investment_image"
it_behaves_like "image validations", "proposal_image"
end

View File

@@ -296,7 +296,7 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path,
from: send(documentable_path, arguments))
expect(page).to have_content "You can upload up to a maximum of #{max_file_size(documentable)} documents."
expect(page).to have_content "You can upload #{documentable_humanized_accepted_content_types(documentable)} files."
expect(page).to have_content "You can upload #{documentable_humanized_accepted_content_types(documentable.class)} files."
expect(page).to have_content "You can upload files up to #{max_file_size(documentable)} MB."
end

View File

@@ -5,7 +5,7 @@ shared_examples "document validations" do |documentable_factory|
let!(:document) { build(:document, documentable_factory.to_sym) }
let!(:documentable) { document.documentable }
let!(:maxfilesize) { max_file_size(document.documentable) }
let!(:acceptedcontenttypes) { accepted_content_types(document.documentable) }
let!(:acceptedcontenttypes) { accepted_content_types(document.documentable.class) }
it "should be valid" do
expect(document).to be_valid

View File

@@ -0,0 +1,70 @@
shared_examples "image validations" do |imageable_factory|
include ImagesHelper
include ImageablesHelper
let!(:image) { build(:image, imageable_factory.to_sym) }
let!(:imageable) { image.imageable }
let!(:acceptedcontenttypes) { imageable_accepted_content_types }
it "should be valid" do
expect(image).to be_valid
end
it "should not be valid without a title" do
image.title = nil
expect(image).to_not be_valid
end
it "should not be valid without an attachment" do
image.attachment = nil
expect(image).to_not be_valid
end
it "should be valid for all accepted content types" do
acceptedcontenttypes.each do |content_type|
extension = content_type.split("/").last
image.attachment = File.new("spec/fixtures/files/clippy.#{extension}")
expect(image).to be_valid
end
end
it "should not be valid for png and gif image content types" do
["gif", "png"].each do |content_type|
extension = content_type.split("/").last
image.attachment = File.new("spec/fixtures/files/clippy.#{extension}")
expect(image).not_to be_valid
end
end
it "should not be valid for attachments larger than imageable max_file_size definition" do
image.stub(:attachment_file_size).and_return(Image::MAX_IMAGE_SIZE + 1.byte)
expect(image).to_not be_valid
expect(image.errors[:attachment]).to include "must be in between 0 Bytes and 1 MB"
end
it "should not be valid without a user_id" do
image.user_id = nil
expect(image).to_not be_valid
end
it "should not be valid without a imageable_id" do
image.save
image.imageable_id = nil
expect(image).to_not be_valid
end
it "should not be valid without a imageable_type" do
image.save
image.imageable_type = nil
expect(image).to_not be_valid
end
end