Merge pull request #4600 from consul/active_storage

Remove Paperclip and use just Active Storage
This commit is contained in:
Javi Martín
2022-02-24 16:32:18 +01:00
committed by GitHub
85 changed files with 424 additions and 577 deletions

View File

@@ -19,6 +19,7 @@ gem "dalli", "~> 2.7.11"
gem "delayed_job_active_record", "~> 4.1.6"
gem "devise", "~> 4.8.0"
gem "devise-security", "~> 0.16.0"
gem "file_validators", "~> 3.0.0"
gem "font-awesome-sass", "~> 5.15.1" # Remember to update vendor/assets/images/fontawesome when updating this gem
gem "foundation-rails", "~> 6.6.2.0"
gem "foundation_rails_helper", "~> 4.0.0"
@@ -33,12 +34,12 @@ gem "jquery-fileupload-rails"
gem "jquery-rails", "~> 4.4.0"
gem "jquery-ui-rails", "~> 6.0.1"
gem "kaminari", "~> 1.2.1"
gem "mini_magick", "~> 4.11.0"
gem "omniauth", "~> 2.0.4"
gem "omniauth-facebook", "~> 8.0.0"
gem "omniauth-google-oauth2", "~> 1.0.0"
gem "omniauth-rails_csrf_protection", "~> 1.0.0"
gem "omniauth-twitter", "~> 1.4.0"
gem "paperclip", "~> 6.1.0"
gem "paranoia", "~> 2.4.3"
gem "pg", "~> 1.2.3"
gem "pg_search", "~> 2.3.5"

View File

@@ -250,6 +250,9 @@ GEM
faraday-patron (1.0.0)
faraday-rack (1.0.0)
ffi (1.15.4)
file_validators (3.0.0)
activemodel (>= 3.2)
mime-types (>= 1.0)
font-awesome-sass (5.15.1)
sassc (>= 1.11)
foundation-rails (6.6.2.0)
@@ -370,9 +373,7 @@ GEM
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0704)
mimemagic (0.3.10)
nokogiri (~> 1)
rake
mini_magick (4.11.0)
mini_mime (1.1.0)
mini_portile2 (2.6.1)
minitest (5.14.4)
@@ -426,12 +427,6 @@ GEM
omniauth-oauth (~> 1.1)
rack
orm_adapter (0.5.0)
paperclip (6.1.0)
activemodel (>= 4.2.0)
activesupport (>= 4.2.0)
mime-types
mimemagic (~> 0.3.0)
terrapin (~> 0.6.0)
parallel (1.20.1)
paranoia (2.4.3)
activerecord (>= 4.0, < 6.2)
@@ -722,6 +717,7 @@ DEPENDENCIES
erb_lint (~> 0.0.37)
factory_bot_rails (~> 6.2.0)
faker (~> 2.18.0)
file_validators (~> 3.0.0)
font-awesome-sass (~> 5.15.1)
foundation-rails (~> 6.6.2.0)
foundation_rails_helper (~> 4.0.0)
@@ -742,12 +738,12 @@ DEPENDENCIES
launchy (~> 2.5.0)
letter_opener_web (~> 1.4.0)
mdl (~> 0.11.0)
mini_magick (~> 4.11.0)
omniauth (~> 2.0.4)
omniauth-facebook (~> 8.0.0)
omniauth-google-oauth2 (~> 1.0.0)
omniauth-rails_csrf_protection (~> 1.0.0)
omniauth-twitter (~> 1.4.0)
paperclip (~> 6.1.0)
paranoia (~> 2.4.3)
pg (~> 1.2.3)
pg_search (~> 2.3.5)

View File

@@ -12,7 +12,7 @@
<!-- remove conditional once specs have image validations -->
<td>
<% if card.image.present? %>
<%= link_to t("admin.shared.show_image"), card.image_url(:large),
<%= link_to t("admin.shared.show_image"), card.image.variant(:large),
title: card.image.title, target: "_blank" %>
<% end %>
</td>

View File

@@ -7,7 +7,7 @@
<%= f.text_field :title, placeholder: t("#{plural_name}.form.title_placeholder") %>
</div>
<% if attachable.attachment.exists? && attachable.attachment.styles.keys.include?(:thumb) %>
<% if attachable.attachment.attached? && attachable.attachment.image? %>
<%= render_image(attachable, :thumb, false) %>
<% end %>

View File

@@ -1,6 +1,6 @@
<% if budget.image.present? %>
<div class="budget-header with-background-image"
style="background-image: url(<%= asset_url budget.image.attachment.url(:large) %>);">
style="background-image: url(<%= polymorphic_path(budget.image.variant(:large)) %>);">
<% else %>
<div class="budget-header">
<% end %>

View File

@@ -1,6 +1,6 @@
<div id="<%= dom_id(investment) %>" class="investments-list-item">
<% if investment.image.present? %>
<%= image_tag investment.image_url(:large), alt: investment.image.title.unicode_normalize %>
<%= image_tag investment.image.variant(:large), alt: investment.image.title.unicode_normalize %>
<% else %>
<%= image_tag "budget_investment_no_image.jpg", alt: investment.title %>
<% end %>

View File

@@ -55,7 +55,7 @@
<% if phase.image.present? %>
<div class="budget-phase-image">
<%= image_tag phase.image.attachment.url(:large), alt: "" %>
<%= image_tag phase.image.variant(:large), alt: "" %>
</div>
<% end %>
</div>

View File

@@ -9,7 +9,7 @@
<% if proposal.image.present? %>
<div class="small-12 medium-6 large-3 column">
<div class="feed-image">
<%= image_tag proposal.image_url(:thumb),
<%= image_tag proposal.image.variant(:thumb),
alt: proposal.image.title.unicode_normalize %>
</div>
</div>

View File

@@ -15,9 +15,9 @@ class DirectUploadsController < ApplicationController
@direct_upload.relation.set_cached_attachment_from_attachment
render json: { cached_attachment: @direct_upload.relation.cached_attachment,
filename: @direct_upload.relation.attachment.original_filename,
filename: @direct_upload.relation.attachment_file_name,
destroy_link: render_destroy_upload_link(@direct_upload),
attachment_url: @direct_upload.relation.attachment.url }
attachment_url: polymorphic_path(@direct_upload.relation.attachment) }
else
render json: { errors: @direct_upload.errors[:attachment].join(", ") },
status: :unprocessable_entity

View File

@@ -49,7 +49,13 @@ module ApplicationHelper
end
def image_path_for(filename)
SiteCustomization::Image.image_path_for(filename) || filename
image = SiteCustomization::Image.image_for(filename)
if image
polymorphic_path(image)
else
filename
end
end
def content_block(name, locale = I18n.locale)

View File

@@ -3,7 +3,7 @@ module DocumentsHelper
info_text = "#{document.humanized_content_type} | #{number_to_human_size(document.attachment_file_size)}"
link_to safe_join([document.title, tag.small("(#{info_text})")], " "),
document.attachment.url,
document.attachment,
target: "_blank",
title: t("shared.target_blank")
end

View File

@@ -2,11 +2,7 @@ module ImagesHelper
def image_absolute_url(image, version)
return "" unless image
if Paperclip::Attachment.default_options[:storage] == :filesystem
URI(request.url) + image.attachment.url(version)
else
image.attachment.url(version)
end
polymorphic_url(image.variant(version))
end
def image_class(image)
@@ -14,7 +10,8 @@ module ImagesHelper
end
def render_image(image, version, show_caption = true)
version = image.persisted? ? version : :original
render "images/image", image: image, version: version, show_caption: show_caption
render "images/image", image: image,
version: (version if image.persisted?),
show_caption: show_caption
end
end

View File

@@ -24,8 +24,9 @@ module WelcomeHelper
end
def calculate_image_path(recommended, image_default)
if recommended.respond_to?(:image) && recommended.image.present? && recommended.image.attachment.exists?
recommended.image.attachment.send("url", :medium)
if recommended.respond_to?(:image) && recommended.image.present? &&
recommended.image.attachment.attached?
recommended.image.variant(:medium)
elsif image_default.present?
image_default
end

View File

@@ -1,5 +1,4 @@
class Ckeditor::Asset < ApplicationRecord
include Ckeditor::Orm::ActiveRecord::AssetBase
include Ckeditor::Backend::ActiveStorage
include Ckeditor::Backend::Paperclip
end

View File

@@ -1,16 +1,14 @@
class Ckeditor::Picture < Ckeditor::Asset
include HasAttachment
attr_accessor :data
has_one_attached :storage_data
has_attachment :data,
url: "/ckeditor_assets/pictures/:id/:style_:basename.:extension",
path: ":rails_root/public/ckeditor_assets/pictures/:id/:style_:basename.:extension",
styles: { content: "800>", thumb: "118x100#" }
validates_attachment_presence :data
validates_attachment_size :data, less_than: 2.megabytes
validates_attachment_content_type :data, content_type: /\Aimage/
validates :storage_data, file_content_type: { allow: /^image\/.*/ }, file_size: { less_than: 2.megabytes }
def url_content
url(:content)
rails_representation_url(storage_data.variant(resize: "800>"), only_path: true)
end
def url_thumb
rails_representation_url(storage_data.variant(resize: "118x100"), only_path: true)
end
end

View File

@@ -3,20 +3,32 @@ module Attachable
extend ActiveSupport::Concern
included do
has_attachment :attachment
attr_accessor :cached_attachment
# Disable paperclip security validation due to polymorphic configuration
# Paperclip do not allow to use Procs on valiations definition
do_not_validate_attachment_file_type :attachment
validate :attachment_presence
validate :validate_attachment_content_type, if: -> { attachment.present? }
validate :validate_attachment_size, if: -> { attachment.present? }
before_save :set_attachment_from_cached_attachment, if: -> { cached_attachment.present? }
validates :attachment,
file_content_type: {
allow: ->(record) { record.accepted_content_types },
if: -> { association_class && attachment.attached? },
message: ->(record, *) do
I18n.t("#{record.model_name.plural}.errors.messages.wrong_content_type",
content_type: record.attachment_content_type,
accepted_content_types: record.class.humanized_accepted_content_types)
end
},
file_size: {
less_than_or_equal_to: ->(record) { record.max_file_size.megabytes },
if: -> { association_class && attachment.attached? },
message: ->(record, *) do
I18n.t("#{record.model_name.plural}.errors.messages.in_between",
min: "0 Bytes",
max: "#{record.max_file_size} MB")
end
}
Paperclip.interpolates :prefix do |attachment, style|
attachment.instance.prefix(attachment, style)
end
before_validation :set_attachment_from_cached_attachment, if: -> { cached_attachment.present? }
end
def association_class
@@ -26,54 +38,37 @@ module Attachable
end
def set_cached_attachment_from_attachment
self.cached_attachment = if filesystem_storage?
attachment.path
else
attachment.url
end
self.cached_attachment = attachment.signed_id
end
def set_attachment_from_cached_attachment
if filesystem_storage?
File.open(cached_attachment) { |file| self.attachment = file }
self.attachment = cached_attachment
end
def attachment_file_name
attachment.filename.to_s if attachment.attached?
end
def attachment_content_type
attachment.blob.content_type if attachment.attached?
end
def attachment_file_size
if attachment.attached?
attachment.blob.byte_size
else
self.attachment = URI.parse(cached_attachment).open
0
end
end
def prefix(attachment, _style)
if attachment.instance.persisted?
":attachment/:id_partition"
else
"cached_attachments/user/#{attachment.instance.user_id}"
end
def file_path
ActiveStorage::Blob.service.path_for(attachment.blob.key)
end
private
def filesystem_storage?
Paperclip::Attachment.default_options[:storage] == :filesystem
end
def validate_attachment_size
if association_class && attachment_file_size > max_file_size.megabytes
errors.add(:attachment, I18n.t("#{model_name.plural}.errors.messages.in_between",
min: "0 Bytes",
max: "#{max_file_size} MB"))
end
end
def validate_attachment_content_type
if association_class && !accepted_content_types.include?(attachment_content_type)
message = I18n.t("#{model_name.plural}.errors.messages.wrong_content_type",
content_type: attachment_content_type,
accepted_content_types: self.class.humanized_accepted_content_types)
errors.add(:attachment, message)
end
end
def attachment_presence
if attachment.blank? && cached_attachment.blank?
unless attachment.attached?
errors.add(:attachment, I18n.t("errors.messages.blank"))
end
end

View File

@@ -2,22 +2,15 @@ module HasAttachment
extend ActiveSupport::Concern
class_methods do
def has_attachment(attribute, paperclip_options = {})
has_one_attached :"storage_#{attribute}"
has_attached_file attribute, paperclip_options
alias_method :"paperclip_#{attribute}=", :"#{attribute}="
def has_attachment(attribute)
has_one_attached attribute
define_method :"#{attribute}=" do |file|
if file.is_a?(IO) || file.is_a?(Tempfile) && !file.is_a?(Ckeditor::Http::QqFile)
send(:"storage_#{attribute}").attach(io: file, filename: File.basename(file.path))
elsif file.nil?
send(:"storage_#{attribute}").detach
if file.nil?
send(attribute).detach
else
send(:"storage_#{attribute}").attach(file)
send(attribute).attach(file)
end
send(:"paperclip_#{attribute}=", file)
end
end
end

View File

@@ -4,9 +4,5 @@ module Imageable
included do
has_one :image, as: :imageable, inverse_of: :imageable, dependent: :destroy
accepts_nested_attributes_for :image, allow_destroy: true, update_only: true
def image_url(style)
image&.attachment&.url(style) || ""
end
end
end

View File

@@ -34,7 +34,7 @@ class DirectUpload
end
def save_attachment
@relation.attachment.save
@relation.attachment.blob.save!
end
def persisted?
@@ -53,7 +53,7 @@ class DirectUpload
def relation_attributtes
{
paperclip_attachment: @attachment,
attachment: @attachment,
cached_attachment: @cached_attachment,
user: @user
}

View File

@@ -1,11 +1,6 @@
class Document < ApplicationRecord
include Attachable
has_attachment :attachment, url: "/system/:class/:prefix/:style/:hash.:extension",
hash_data: ":class/:style/:custom_hash_data",
use_timestamp: false,
hash_secret: Rails.application.secrets.secret_key_base
belongs_to :user
belongs_to :documentable, polymorphic: true, touch: true
@@ -16,23 +11,10 @@ class Document < ApplicationRecord
scope :admin, -> { where(admin: true) }
Paperclip.interpolates :custom_hash_data do |attachment, _style|
attachment.instance.custom_hash_data(attachment)
end
def self.humanized_accepted_content_types
Setting.accepted_content_types_for("documents").join(", ")
end
def custom_hash_data(attachment)
original_filename = if attachment.instance.persisted?
attachment.instance.title
else
attachment.instance.attachment_file_name
end
"#{attachment.instance.user_id}/#{original_filename}"
end
def humanized_content_type
attachment_content_type.split("/").last.upcase
end

View File

@@ -1,15 +1,13 @@
class Image < ApplicationRecord
include Attachable
has_attachment :attachment, styles: {
large: "x#{Setting["uploads.images.min_height"]}",
medium: "300x300#",
thumb: "140x245#"
},
url: "/system/:class/:prefix/:style/:hash.:extension",
hash_data: ":class/:style",
use_timestamp: false,
hash_secret: Rails.application.secrets.secret_key_base
def self.styles
{
large: { resize: "x#{Setting["uploads.images.min_height"]}" },
medium: { combine_options: { gravity: "center", resize: "300x300^", crop: "300x300+0+0" }},
thumb: { combine_options: { gravity: "center", resize: "140x245^", crop: "140x245+0+0" }}
}
end
belongs_to :user
belongs_to :imageable, polymorphic: true, touch: true
@@ -19,7 +17,7 @@ class Image < ApplicationRecord
validates :user_id, presence: true
validates :imageable_id, presence: true, if: -> { persisted? }
validates :imageable_type, presence: true, if: -> { persisted? }
validate :validate_image_dimensions, if: -> { attachment.present? && attachment.dirty? }
validate :validate_image_dimensions, if: -> { attachment.attached? && attachment.new_record? }
def self.max_file_size
Setting["uploads.images.max_size"].to_i
@@ -41,6 +39,14 @@ class Image < ApplicationRecord
self.class.accepted_content_types
end
def variant(style)
if style
attachment.variant(self.class.styles[style])
else
attachment
end
end
private
def association_name
@@ -52,14 +58,17 @@ class Image < ApplicationRecord
end
def validate_image_dimensions
if attachment_of_valid_content_type?
if accepted_content_types.include?(attachment_content_type)
return true if imageable_class == Widget::Card
dimensions = Paperclip::Geometry.from_file(attachment.queued_for_write[:original].path)
attachment.analyze unless attachment.analyzed?
width = attachment.metadata[:width]
height = attachment.metadata[:height]
min_width = Setting["uploads.images.min_width"].to_i
min_height = Setting["uploads.images.min_height"].to_i
errors.add(:attachment, :min_image_width, required_min_width: min_width) if dimensions.width < min_width
errors.add(:attachment, :min_image_height, required_min_height: min_height) if dimensions.height < min_height
errors.add(:attachment, :min_image_width, required_min_width: min_width) if width < min_width
errors.add(:attachment, :min_image_height, required_min_height: min_height) if height < min_height
end
end
@@ -77,8 +86,4 @@ class Image < ApplicationRecord
end
end
end
def attachment_of_valid_content_type?
attachment.present? && accepted_content_types.include?(attachment_content_type)
end
end

View File

@@ -14,7 +14,7 @@ class SiteCustomization::Image < ApplicationRecord
has_attachment :image
validates :name, presence: true, uniqueness: true, inclusion: { in: VALID_IMAGES.keys }
validates_attachment_content_type :image, content_type: ["image/png", "image/jpeg"]
validates :image, file_content_type: { allow: ["image/png", "image/jpeg"], if: -> { image.attached? }}
validate :check_image
def self.all_images
@@ -23,11 +23,10 @@ class SiteCustomization::Image < ApplicationRecord
end
end
def self.image_path_for(filename)
def self.image_for(filename)
image_name = filename.split(".").first
imageable = find_by(name: image_name)
imageable.present? && imageable.image.exists? ? imageable.image.url : nil
find_by(name: image_name)&.persisted_image
end
def required_width
@@ -38,19 +37,29 @@ class SiteCustomization::Image < ApplicationRecord
VALID_IMAGES[name]&.second
end
def persisted_image
image if persisted_attachment?
end
def persisted_attachment?
image.attachment&.persisted?
end
private
def check_image
return unless image?
return unless image.attached?
dimensions = Paperclip::Geometry.from_file(image.queued_for_write[:original].path)
image.analyze unless image.analyzed?
width = image.metadata[:width]
height = image.metadata[:height]
if name == "logo_header"
errors.add(:image, :image_width, required_width: required_width) unless dimensions.width <= required_width
errors.add(:image, :image_width, required_width: required_width) unless width <= required_width
else
errors.add(:image, :image_width, required_width: required_width) unless dimensions.width == required_width
errors.add(:image, :image_width, required_width: required_width) unless width == required_width
end
errors.add(:image, :image_height, required_height: required_height) unless dimensions.height == required_height
errors.add(:image, :image_height, required_height: required_height) unless height == required_height
end
end

View File

@@ -40,14 +40,14 @@
</td>
<td class="small">
<%= link_to t("admin.milestones.index.show_image"),
milestone.image_url(:large),
milestone.image.variant(:large),
target: :_blank if milestone.image.present? %>
</td>
<td class="small">
<% if milestone.documents.present? %>
<% milestone.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
document.attachment,
target: "_blank",
rel: "nofollow" %><br>
<% end %>

View File

@@ -33,7 +33,7 @@
<% @answer.documents.each do |document| %>
<tr>
<td>
<%= link_to document.title, document.attachment.url %>
<%= link_to document.title, document.attachment %>
</td>
<td>
<%= render Admin::TableActionsComponent.new(document,
@@ -42,7 +42,7 @@
) do |actions| %>
<%= actions.action(:download,
text: t("documents.buttons.download_document"),
path: document.attachment.url,
path: document.attachment,
target: "_blank",
rel: "nofollow") %>

View File

@@ -22,8 +22,8 @@
<tr id="<%= dom_id(document) %>" class="document">
<td><%= document.title %></td>
<td><%= document.attachment.content_type %></td>
<td><%= number_to_human_size(document.attachment.size) %></td>
<td><%= link_to document.title, document.attachment.url, target: :blank %></td>
<td><%= number_to_human_size(document.attachment.byte_size) %></td>
<td><%= link_to document.title, document.attachment, target: :blank %></td>
<td>
<div class="small-12 medium-6 column">
<%= render Admin::TableActionsComponent.new(

View File

@@ -16,12 +16,12 @@
<td class="small-12 medium-8">
<%= form_for([:admin, image], html: { id: "edit_#{dom_id(image)}" }) do |f| %>
<div class="small-12 medium-6 large-6 column">
<%= image_tag image.image.url if image.image.exists? %>
<%= image_tag image.image if image.persisted_attachment? %>
<%= f.file_field :image, label: false %>
</div>
<div class="small-12 medium-6 large-6 column">
<%= f.submit(t("admin.site_customization.images.index.update"), class: "button hollow") %>
<%= link_to t("admin.site_customization.images.index.delete"), admin_site_customization_image_path(image), method: :delete, class: "button hollow alert" if image.image.exists? %>
<%= link_to t("admin.site_customization.images.index.delete"), admin_site_customization_image_path(image), method: :delete, class: "button hollow alert" if image.persisted_attachment? %>
</div>
<% end %>
</td>

View File

@@ -1,9 +1,9 @@
<% milestone = first_milestone_with_image(investment) %>
<% if milestone&.image.present? %>
<%= image_tag milestone.image_url(:large), alt: milestone.image.title %>
<%= image_tag milestone.image.variant(:large), alt: milestone.image.title %>
<% elsif investment.image.present? %>
<%= image_tag investment.image_url(:large), alt: investment.image.title %>
<%= image_tag investment.image.variant(:large), alt: investment.image.title %>
<% else %>
<%= image_tag "budget_execution_no_image.jpg", alt: investment.title %>
<% end %>

View File

@@ -5,7 +5,7 @@
<div class="row">
<div class="small-12 medium-3 large-2 column text-center">
<%= image_tag investment.image_url(:thumb), alt: investment.image.title.unicode_normalize %>
<%= image_tag investment.image.variant(:thumb), alt: investment.image.title.unicode_normalize %>
</div>
<div class="small-12 medium-6 large-7 column">

View File

@@ -3,8 +3,8 @@
social_url: budget_investments_path(investment),
social_title: investment.title,
social_description: investment.description,
twitter_image_url: (investment.image.present? ? investment.image_url(:thumb) : nil),
og_image_url: (investment.image.present? ? investment.image_url(:thumb) : nil) %>
twitter_image_url: (investment.image.present? ? polymorphic_path(investment.image.variant(:thumb)) : nil),
og_image_url: (investment.image.present? ? polymorphic_path(investment.image.variant(:thumb)) : nil) %>
<% end %>
<% cache [locale_and_user_status(investment),

View File

@@ -1,5 +1,5 @@
<p>
<%= link_to document.attachment.url, target: "_blank" do %>
<%= link_to document.attachment, target: "_blank" do %>
<%= document.title %>
(<%= document.humanized_content_type %>
&nbsp;|&nbsp;

View File

@@ -15,7 +15,7 @@
</table>
<% if @proposal.image.present? %>
<%= image_tag @proposal.image.attachment.url(:large), style: "width: 100%; box-shadow: -16px 61px 49px -19px rgba(0,0,0,0.1);" %>
<%= image_tag @proposal.image.variant(:large), style: "width: 100%; box-shadow: -16px 61px 49px -19px rgba(0,0,0,0.1);" %>
<% else %>
<%= image_tag "default_mailing.jpg", style: "width: 100%; box-shadow: -16px 61px 49px -19px rgba(0,0,0,0.1);" %>
<% end %>

View File

@@ -9,7 +9,7 @@
</div>
<div class="margin-bottom">
<%= image_tag(proposal.image_url(:large).presence || "default_mailing.jpg") %>
<%= image_tag(proposal.image&.variant(:large).presence || "default_mailing.jpg") %>
</div>
<div class="mail-body">

View File

@@ -18,7 +18,7 @@
</p>
<div class="proposal-image">
<% if proposal.image.present? %>
<div class="overflow-image" style="background-image: url(<%= asset_url proposal.image.attachment.url(:large) %>);"></div>
<div class="overflow-image" style="background-image: url(<%= polymorphic_path(proposal.image.variant(:large)) %>);"></div>
<% else %>
<div class="overflow-image" style="background-image: url(<%= asset_url "default_mailing.jpg" %>);"></div>
<% end %>

View File

@@ -23,7 +23,7 @@
</p>
<div class="proposal-image">
<% if proposal.image.present? %>
<div class="overflow-image" style="background-image: url(<%= asset_url proposal.image.attachment.url(:large) %>);"></div>
<div class="overflow-image" style="background-image: url(<%= polymorphic_url(proposal.image.variant(:large)) %>);"></div>
<% else %>
<div class="overflow-image" style="background-image:url('<%= "file://#{Rails.root.join("app","assets","images","default_mailing.jpg")}" %>');"></div>
<% end %>

View File

@@ -1,6 +1,6 @@
<li id="<%= dom_id(document) %>">
<%= link_to t("documents.buttons.download_document"),
document.attachment.url, target: "_blank",
document.attachment, target: "_blank",
rel: "nofollow", class: "button hollow medium float-right" %>
<strong><%= document.title %></strong>

View File

@@ -1,6 +1,6 @@
<div id="image" class="small-12 column text-center image-preview">
<figure>
<%= image_tag image.attachment.url(version),
<%= image_tag image.variant(version),
class: image_class(image),
alt: image.title.unicode_normalize,
title: image.title.unicode_normalize %>

View File

@@ -45,7 +45,7 @@
<% if @process.image.present? %>
<hr>
<%= image_tag(@process.image_url(:large), alt: @process.title, id: "image") %>
<%= image_tag(@process.image.variant(:large), alt: @process.title, id: "image") %>
<% end %>
<% if process.draft_publication.enabled? %>

View File

@@ -7,7 +7,7 @@
<% if proposal.image.present? %>
<div class="row">
<div class="small-12 medium-3 large-2 column text-center">
<%= image_tag proposal.image_url(:thumb),
<%= image_tag proposal.image.variant(:thumb),
alt: proposal.image.title.unicode_normalize %>
</div>
<div class="small-12 medium-6 large-7 column margin-top">

View File

@@ -22,7 +22,7 @@
</p>
<% end %>
<%= image_tag(milestone.image_url(:large), { id: "image_#{milestone.id}", alt: milestone.image.title, class: "margin" }) if milestone.image.present? %>
<%= image_tag(milestone.image.variant(:large), { id: "image_#{milestone.id}", alt: milestone.image.title, class: "margin" }) if milestone.image.present? %>
<p>
<%= sanitize_and_auto_link milestone.description %>
@@ -37,7 +37,7 @@
<% milestone.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
document.attachment,
target: "_blank",
rel: "nofollow" %><br>
<small>

View File

@@ -18,8 +18,8 @@
<% answer.images.reverse.each_with_index do |image, index| %>
<li class="orbit-slide <%= is_active_class(index) %>">
<%= link_to image.attachment.url(:original), target: "_blank" do %>
<%= image_tag image.attachment.url(:original),
<%= link_to image.attachment, target: "_blank" do %>
<%= image_tag image.attachment,
class: "orbit-image",
alt: image.title.unicode_normalize %>
<% end %>

View File

@@ -23,7 +23,7 @@
<div class="small-12 medium-3 column">
<div class="image-container" data-equalizer-watch>
<% if poll.image.present? %>
<%= image_tag poll.image_url(:large), alt: poll.image.title.unicode_normalize %>
<%= image_tag poll.image.variant(:large), alt: poll.image.title.unicode_normalize %>
<% end %>
</div>
</div>

View File

@@ -86,7 +86,7 @@
<% answer.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
document.attachment,
target: "_blank",
rel: "nofollow" %><br>
<% end %>

View File

@@ -8,7 +8,7 @@
<% if proposal.image.present? %>
<div class="row">
<div class="small-12 medium-3 large-2 column text-center">
<%= image_tag proposal.image_url(:thumb),
<%= image_tag proposal.image.variant(:thumb),
alt: proposal.image.title.unicode_normalize %>
</div>

View File

@@ -6,8 +6,8 @@
social_url: proposal_url(@proposal),
social_title: @proposal.title,
social_description: @proposal.summary,
twitter_image_url: (@proposal.image.present? ? @proposal.image_url(:thumb) : nil),
og_image_url: (@proposal.image.present? ? @proposal.image_url(:thumb) : nil) %>
twitter_image_url: (@proposal.image.present? ? polymorphic_path(@proposal.image.variant(:thumb)) : nil),
og_image_url: (@proposal.image.present? ? polymorphic_path(@proposal.image.variant(:thumb)) : nil) %>
<% end %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: proposal_url(@proposal) %>

View File

@@ -4,7 +4,7 @@
<figure class="figure-card">
<div class="gradient"></div>
<% if card.image.present? %>
<%= image_tag(card.image_url(:large), alt: card.image.title) %>
<%= image_tag(card.image.variant(:large), alt: card.image.title) %>
<% end %>
<figcaption>
<% if card.label.present? %>

View File

@@ -16,7 +16,7 @@
<% if header.image.present? %>
<div class="small-12 medium-6 column">
<%= image_tag(header.image_url(:large),
<%= image_tag(header.image.variant(:large),
class: "margin",
alt: header.image.title) %>
</div>

View File

@@ -169,6 +169,7 @@ ignore_unused:
- "admin.dashboard.administrator_tasks.index.filter*"
- "admin.dashboard.actions.index.default.*"
- "admin.users.index.filter*"
- "errors.messages.allowed_file_content_types"
- "moderation.comments.index.filter*"
- "moderation.comments.index.orders.*"
- "moderation.debates.index.filter*"

View File

@@ -1,13 +0,0 @@
class Paperclip::UrlGenerator
private
# Code copied from the paperclip gem, only replacing
# `URI.escape` with `URI::DEFAULT_PARSER.escape`
def escape_url(url)
if url.respond_to?(:escape)
url.escape
else
URI::DEFAULT_PARSER.escape(url).gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
end
end
end

View File

@@ -150,6 +150,7 @@ en:
submit_button: Save changes
errors:
messages:
allowed_file_content_types: "content type must be one of %{types}"
user_not_found: User not found
invalid_date_range: "Invalid date range"
form:

View File

@@ -150,6 +150,7 @@ es:
submit_button: Guardar cambios
errors:
messages:
allowed_file_content_types: "el tipo de contenido debe ser uno de los siguientes: %{types}"
user_not_found: Usuario no encontrado
invalid_date_range: "El rango de fechas no es válido"
form:

View File

@@ -15,14 +15,12 @@ end
def add_image_to(imageable)
# imageable should respond to #title & #author
File.open(INVESTMENT_IMAGE_FILES.sample) do |file|
imageable.image = Image.create!({
imageable: imageable,
title: imageable.title,
attachment: file,
user: imageable.author
})
end
imageable.image = Image.create!({
imageable: imageable,
title: imageable.title,
attachment: Rack::Test::UploadedFile.new(INVESTMENT_IMAGE_FILES.sample),
user: imageable.author
})
imageable.save!
end

View File

@@ -12,14 +12,12 @@ end
def add_image_to(imageable)
# imageable should respond to #title & #author
File.open(IMAGE_FILES.sample) do |file|
imageable.image = Image.create!({
imageable: imageable,
title: imageable.title,
attachment: file,
user: imageable.author
})
end
imageable.image = Image.create!({
imageable: imageable,
title: imageable.title,
attachment: Rack::Test::UploadedFile.new(IMAGE_FILES.sample),
user: imageable.author
})
imageable.save!
end

View File

@@ -1,7 +1,7 @@
section "Creating header and cards for the homepage" do
def create_image_attachment(type)
{
cached_attachment: Rails.root.join("db/dev_seeds/images/#{type}_background.jpg"),
attachment: Rack::Test::UploadedFile.new("db/dev_seeds/images/#{type}_background.jpg"),
title: "#{type}_background.jpg",
user: User.first
}

View File

@@ -14,9 +14,9 @@ module Ckeditor
module ClassMethods
def self.extended(base)
base.class_eval do
before_save :apply_data
before_validation :apply_data
validate do
if data.nil? || storage_file.nil?
if data.nil? || file.nil?
errors.add(:data, :not_data_present, message: "data must be present")
end
end
@@ -46,25 +46,19 @@ module Ckeditor
protected
def storage_file
@storage_file ||= storage_data
def file
@file ||= storage_data
end
def blob
@blob ||= ::ActiveStorage::Blob.find(storage_file.attachment.blob_id)
@blob ||= ::ActiveStorage::Blob.find(file.attachment.blob_id)
end
def apply_data
non_paperclip_data = if data.is_a?(::Paperclip::Attachment)
file.instance_variable_get("@target")
else
data
end
if non_paperclip_data.is_a?(Ckeditor::Http::QqFile)
storage_data.attach(io: non_paperclip_data, filename: non_paperclip_data.original_filename)
if data.is_a?(Ckeditor::Http::QqFile)
storage_data.attach(io: data, filename: data.original_filename)
else
storage_data.attach(non_paperclip_data)
storage_data.attach(data)
end
self.data_file_name = storage_data.blob.filename

View File

@@ -1,98 +1,9 @@
# This code is based on Thoughtbot's guide to migrating from Paperclip
# to Active Storage:
# https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md
namespace :active_storage do
desc "Copy paperclip's attachment database columns to active storage"
task migrate_from_paperclip: :environment do
logger = ApplicationLogger.new
connection = ActiveRecord::Base.connection.raw_connection
statement_name = "active_storage_statement"
unless connection.exec("SELECT COUNT(*) FROM pg_prepared_statements WHERE name='#{statement_name}'").each_row.to_a[0][0] > 0
connection.prepare(statement_name, <<-SQL)
with rows as(
INSERT INTO active_storage_blobs (
key, filename, content_type, metadata, byte_size, checksum, created_at
) VALUES ($1, $2, $3, '{}', $4, $5, $6) RETURNING id
)
INSERT INTO active_storage_attachments (
name, record_type, record_id, blob_id, created_at
) VALUES ($7, $8, $9, (SELECT id FROM rows), $10)
SQL
end
Rails.application.eager_load!
models = ActiveRecord::Base.descendants.reject(&:abstract_class?)
paperclip_storage = Paperclip::Attachment.default_options[:storage]
ActiveRecord::Base.transaction do
models.each do |model|
next if model.name == "OldPassword" && !model.table_exists?
attachments = model.column_names.map do |c|
if c =~ /(.+)_file_name$/
$1
end
end.compact
if attachments.blank?
next
end
model.find_each.each do |instance|
attachments.each do |attachment|
next if instance.send(:"storage_#{attachment}").attached?
source = if paperclip_storage == :filesystem
instance.send(attachment).path
else
instance.send(attachment).url
end
next if source.blank? || source == "/images/original/missing.png"
file = if paperclip_storage == :filesystem
File.read(source) if File.exist?(source)
else
Net::HTTP.get(URI(source))
end
connection.exec_prepared(
statement_name, [
SecureRandom.uuid, # Alternatively instance.send("#{attachment}_file_name"),
instance.send("#{attachment}_file_name"),
instance.send("#{attachment}_content_type"),
instance.send("#{attachment}_file_size"),
file && Digest::MD5.base64digest(file) || SecureRandom.hex(32),
instance.updated_at.iso8601,
"storage_#{attachment}",
model.name,
instance.id,
instance.updated_at.iso8601
])
end
end
end
end
ActiveStorage::Attachment.find_each do |attachment|
blob = attachment.blob
next if blob.service.exist?(blob.key) || !attachment.record
name = attachment.name.delete_prefix("storage_")
paperclip_attachment = attachment.record.send(name)
next unless paperclip_attachment.exists?
source_file = if paperclip_storage == :filesystem
paperclip_attachment.path
else
URI.parse(paperclip_attachment.url).open.read
end
logger.info "Copying #{paperclip_attachment.url} to active storage"
blob.service.upload(blob.key, source_file)
end
desc "Updates ActiveStorage::Attachment old records created when we were also using paperclip"
task remove_paperclip_compatibility_in_existing_attachments: :environment do
ApplicationLogger.new.info "Updating Active Storage attachment records"
ActiveStorage::Attachment.where("name ILIKE 'storage_%'")
.where.not(record_type: "Ckeditor::Asset")
.update_all("name = replace(name, 'storage_', '')")
end
end

View File

@@ -2,10 +2,10 @@ namespace :consul do
desc "Runs tasks needed to upgrade to the latest version"
task execute_release_tasks: ["settings:rename_setting_keys",
"settings:add_new_settings",
"execute_release_1.4.0_tasks"]
"execute_release_1.5.0_tasks"]
desc "Runs tasks needed to upgrade from 1.3.0 to 1.4.0"
task "execute_release_1.4.0_tasks": [
"active_storage:migrate_from_paperclip"
desc "Runs tasks needed to upgrade from 1.4.0 to 1.5.0"
task "execute_release_1.5.0_tasks": [
"active_storage:remove_paperclip_compatibility_in_existing_attachments"
]
end

View File

@@ -1,18 +1,8 @@
namespace :files do
desc "Removes cached attachments which weren't deleted for some reason"
task remove_old_cached_attachments: :environment do
paths = Dir.glob(Rails.root.join("public/system/*/cached_attachments/**/*"))
logger = ApplicationLogger.new
paths.each do |path|
if File.file?(path)
if File.mtime(path) < 1.day.ago
File.delete(path)
logger.info "The file #{path} has been removed"
end
else
Dir.delete(path) if Dir.empty?(path)
end
end
ActiveStorage::Blob.unattached
.where("active_storage_blobs.created_at <= ?", 1.day.ago)
.find_each(&:purge_later)
end
end

View File

@@ -8,38 +8,4 @@ describe ProposalsController do
expect { get :index }.to raise_exception(FeatureFlags::FeatureDisabled)
end
end
describe "PUT update" do
let(:file) { Rails.root.join("spec/hacked") }
before do
File.delete(file) if File.exist?(file)
InvisibleCaptcha.timestamp_enabled = false
end
after { InvisibleCaptcha.timestamp_enabled = true }
it "ignores malicious cached attachments with remote storages" do
allow_any_instance_of(Image).to receive(:filesystem_storage?).and_return(false)
user = create(:user)
proposal = create(:proposal, author: user)
sign_in user
begin
put :update, params: {
id: proposal,
proposal: {
image_attributes: {
title: "Hacked!",
user_id: user.id,
cached_attachment: "| touch #{file}"
}
}
}
rescue StandardError
ensure
expect(file).not_to exist
end
end
end
end

View File

@@ -58,7 +58,7 @@ FactoryBot.define do
end
factory :site_customization_image, class: "SiteCustomization::Image" do
image { File.new("spec/fixtures/files/logo_header.png") }
image { Rack::Test::UploadedFile.new("spec/fixtures/files/logo_header.png") }
name { "logo_header" }
end

View File

@@ -1,6 +1,6 @@
FactoryBot.define do
factory :image do
attachment { File.new("spec/fixtures/files/clippy.jpg") }
attachment { Rack::Test::UploadedFile.new("spec/fixtures/files/clippy.jpg") }
title { "Lorem ipsum dolor sit amet" }
association :user, factory: :user
@@ -16,7 +16,7 @@ FactoryBot.define do
factory :document do
sequence(:title) { |n| "Document title #{n}" }
association :user, factory: :user
attachment { File.new("spec/fixtures/files/empty.pdf") }
attachment { Rack::Test::UploadedFile.new("spec/fixtures/files/empty.pdf") }
trait :proposal_document do
association :documentable, factory: :proposal
@@ -47,11 +47,11 @@ FactoryBot.define do
trait :documents do
resource_relation { "documents" }
attachment { File.new("spec/fixtures/files/empty.pdf") }
attachment { Rack::Test::UploadedFile.new("spec/fixtures/files/empty.pdf") }
end
trait :image do
resource_relation { "image" }
attachment { File.new("spec/fixtures/files/clippy.jpg") }
attachment { Rack::Test::UploadedFile.new("spec/fixtures/files/clippy.jpg") }
end
initialize_with { new(attributes) }
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -26,7 +26,7 @@ describe RemoteCensusApi do
end
describe "request messages" do
let(:valid_response) { File.read("spec/fixtures/files/remote_census_api/valid.xml") }
let(:valid_response) { File.read(file_fixture("remote_census_api/valid.xml")) }
def request_with(params)
{ "request" => params }

View File

@@ -1,88 +1,67 @@
require "rails_helper"
describe "active storage tasks" do
describe "migrate_from_paperclip" do
describe "remove_paperclip_compatibility_in_existing_attachments" do
let(:run_rake_task) do
Rake::Task["active_storage:migrate_from_paperclip"].reenable
Rake.application.invoke_task("active_storage:migrate_from_paperclip")
Rake::Task["active_storage:remove_paperclip_compatibility_in_existing_attachments"].reenable
Rake.application.invoke_task("active_storage:remove_paperclip_compatibility_in_existing_attachments")
end
let(:storage_root) { ActiveStorage::Blob.service.root }
before { FileUtils.rm_rf storage_root }
it "updates old regular attachments" do
document = create(:document)
image = create(:image)
site_customization_image = create(:site_customization_image)
it "migrates records and attachments" do
document = create(:document,
attachment: nil,
paperclip_attachment: File.new("spec/fixtures/files/clippy.pdf"))
document.attachment.attachment.update_column(:name, "storage_attachment")
image.attachment.attachment.update_column(:name, "storage_attachment")
site_customization_image.image.attachment.update_column(:name, "storage_image")
expect(ActiveStorage::Attachment.count).to eq 0
expect(ActiveStorage::Blob.count).to eq 0
expect(test_storage_file_paths.count).to eq 0
document.reload
image.reload
site_customization_image.reload
expect(document.attachment.attachment).to be nil
expect(image.attachment.attachment).to be nil
expect(site_customization_image.image.attachment).to be nil
run_rake_task
document.reload
image.reload
site_customization_image.reload
expect(ActiveStorage::Attachment.count).to eq 1
expect(ActiveStorage::Blob.count).to eq 1
expect(document.storage_attachment.filename).to eq "clippy.pdf"
expect(test_storage_file_paths.count).to eq 1
expect(storage_file_path(document)).to eq test_storage_file_paths.first
expect(document.attachment.attachment.name).to eq "attachment"
expect(image.attachment.attachment.name).to eq "attachment"
expect(site_customization_image.reload.image.attachment.name).to eq "image"
end
it "migrates records with deleted files ignoring the files" do
document = create(:document,
attachment: nil,
paperclip_attachment: File.new("spec/fixtures/files/clippy.pdf"))
FileUtils.rm(document.attachment.path)
it "does not modify old ckeditor attachments" do
image = Ckeditor::Picture.create!(data: fixture_file_upload("clippy.png"))
expect(image.storage_data.attachment.name).to eq "storage_data"
run_rake_task
image.reload
expect(image.storage_data.attachment.name).to eq "storage_data"
end
it "does not modify new regular attachments" do
document = create(:document)
image = create(:image)
site_customization_image = create(:site_customization_image)
expect(document.attachment.attachment.name).to eq "attachment"
expect(image.attachment.attachment.name).to eq "attachment"
expect(site_customization_image.image.attachment.name).to eq "image"
run_rake_task
document.reload
image.reload
site_customization_image.reload
expect(ActiveStorage::Attachment.count).to eq 1
expect(ActiveStorage::Blob.count).to eq 1
expect(document.storage_attachment.filename).to eq "clippy.pdf"
expect(test_storage_file_paths.count).to eq 0
end
it "does not migrate already migrated records" do
document = create(:document, attachment: File.new("spec/fixtures/files/clippy.pdf"))
migrated_file = test_storage_file_paths.first
attachment_id = document.storage_attachment.attachment.id
blob_id = document.storage_attachment.blob.id
run_rake_task
document.reload
expect(ActiveStorage::Attachment.count).to eq 1
expect(ActiveStorage::Blob.count).to eq 1
expect(document.storage_attachment.attachment.id).to eq attachment_id
expect(document.storage_attachment.blob.id).to eq blob_id
expect(test_storage_file_paths.count).to eq 1
expect(storage_file_path(document)).to eq migrated_file
expect(test_storage_file_paths.first).to eq migrated_file
end
it "does not migrate files for deleted records" do
document = create(:document, attachment: File.new("spec/fixtures/files/clippy.pdf"))
FileUtils.rm storage_file_path(document)
Document.delete_all
run_rake_task
expect(ActiveStorage::Attachment.count).to eq 1
expect(ActiveStorage::Blob.count).to eq 1
expect(document.storage_attachment.filename).to eq "clippy.pdf"
expect(test_storage_file_paths.count).to eq 0
end
def test_storage_file_paths
Dir.glob("#{storage_root}/**/*").select { |file_or_folder| File.file?(file_or_folder) }
end
def storage_file_path(record)
ActiveStorage::Blob.service.path_for(record.storage_attachment.blob.key)
expect(document.attachment.attachment.name).to eq "attachment"
expect(image.attachment.attachment.name).to eq "attachment"
expect(site_customization_image.reload.image.attachment.name).to eq "image"
end
end
end

View File

@@ -11,26 +11,26 @@ describe "files tasks" do
image = build(:image)
document = build(:document)
image.attachment.save
document.attachment.save
image.attachment.blob.save!
document.attachment.blob.save!
travel_to(2.days.from_now) { run_rake_task }
expect(File.exists?(image.attachment.path)).to be false
expect(File.exists?(document.attachment.path)).to be false
expect(File.exists?(image.file_path)).to be false
expect(File.exists?(document.file_path)).to be false
end
it "does not delete recent cached attachments" do
image = build(:image)
document = build(:document)
image.attachment.save
document.attachment.save
image.attachment.blob.save!
document.attachment.blob.save!
travel_to(2.minutes.from_now) { run_rake_task }
expect(File.exists?(image.attachment.path)).to be true
expect(File.exists?(document.attachment.path)).to be true
expect(File.exists?(image.file_path)).to be true
expect(File.exists?(document.file_path)).to be true
end
it "does not delete old regular attachments" do
@@ -39,8 +39,8 @@ describe "files tasks" do
travel_to(2.days.from_now) { run_rake_task }
expect(File.exists?(image.attachment.path)).to be true
expect(File.exists?(document.attachment.path)).to be true
expect(File.exists?(image.file_path)).to be true
expect(File.exists?(document.file_path)).to be true
end
end
end

View File

@@ -10,10 +10,10 @@ describe DirectUpload do
end
it "is not valid for different kind of combinations with 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
expect(build(:direct_upload, :proposal, :documents, attachment: fixture_file_upload("clippy.png"))).not_to be_valid
expect(build(:direct_upload, :proposal, :image, attachment: fixture_file_upload("empty.pdf"))).not_to be_valid
expect(build(:direct_upload, :budget_investment, :documents, attachment: fixture_file_upload("clippy.png"))).not_to be_valid
expect(build(:direct_upload, :budget_investment, :image, attachment: fixture_file_upload("empty.pdf"))).not_to be_valid
end
it "is not valid without resource_type" do
@@ -34,13 +34,14 @@ describe DirectUpload do
end
context "save_attachment" do
it "saves uploaded file" do
proposal_document_direct_upload = build(:direct_upload, :proposal, :documents)
it "saves uploaded file without creating an attachment record" do
direct_upload = build(:direct_upload, :proposal, :documents)
proposal_document_direct_upload.save_attachment
direct_upload.save_attachment
expect(File.exist?(proposal_document_direct_upload.relation.attachment.path)).to eq(true)
expect(proposal_document_direct_upload.relation.attachment.path).to include("cached_attachments")
expect(File.exist?(direct_upload.relation.file_path)).to be true
expect(direct_upload.relation.attachment.blob).to be_persisted
expect(direct_upload.relation.attachment.attachment).not_to be_persisted
end
end
end

View File

@@ -4,14 +4,11 @@ describe Document do
it_behaves_like "document validations", "budget_investment_document"
it_behaves_like "document validations", "proposal_document"
it "stores attachments with both Paperclip and Active Storage" do
document = create(:document, attachment: File.new("spec/fixtures/files/clippy.pdf"))
it "stores attachments with Active Storage" do
document = create(:document, attachment: fixture_file_upload("clippy.pdf"))
expect(document.attachment).to exist
expect(document.attachment_file_name).to eq "clippy.pdf"
expect(document.storage_attachment).to be_attached
expect(document.storage_attachment.filename).to eq "clippy.pdf"
expect(document.attachment).to be_attached
expect(document.attachment.filename).to eq "clippy.pdf"
end
context "scopes" do

View File

@@ -4,13 +4,10 @@ describe Image do
it_behaves_like "image validations", "budget_investment_image"
it_behaves_like "image validations", "proposal_image"
it "stores attachments with both Paperclip and Active Storage" do
image = create(:image, attachment: File.new("spec/fixtures/files/clippy.jpg"))
it "stores attachments with Active Storage" do
image = create(:image, attachment: fixture_file_upload("clippy.jpg"))
expect(image.attachment).to exist
expect(image.attachment_file_name).to eq "clippy.jpg"
expect(image.storage_attachment).to be_attached
expect(image.storage_attachment.filename).to eq "clippy.jpg"
expect(image.attachment).to be_attached
expect(image.attachment.filename).to eq "clippy.jpg"
end
end

View File

@@ -1,7 +1,7 @@
require "rails_helper"
describe LocalCensusRecords::Import do
let(:base_files_path) { %w[spec fixtures files local_census_records import] }
let(:base_files_path) { "local_census_records/import/" }
let(:import) { build(:local_census_records_import) }
describe "Validations" do
@@ -17,7 +17,7 @@ describe LocalCensusRecords::Import do
context "When file extension" do
it "is wrong it should not be valid" do
file = Rack::Test::UploadedFile.new("spec/fixtures/files/clippy.gif")
file = fixture_file_upload("clippy.gif")
import = build(:local_census_records_import, file: file)
expect(import).not_to be_valid
@@ -25,7 +25,7 @@ describe LocalCensusRecords::Import do
it "is csv it should be valid" do
path = base_files_path << "valid.csv"
file = Rack::Test::UploadedFile.new(Rails.root.join(*path))
file = fixture_file_upload(path)
import = build(:local_census_records_import, file: file)
expect(import).to be_valid
@@ -35,7 +35,7 @@ describe LocalCensusRecords::Import do
context "When file headers" do
it "are all missing it should not be valid" do
path = base_files_path << "valid-without-headers.csv"
file = Rack::Test::UploadedFile.new(Rails.root.join(*path))
file = fixture_file_upload(path)
import = build(:local_census_records_import, file: file)
expect(import).not_to be_valid
@@ -64,7 +64,7 @@ describe LocalCensusRecords::Import do
it "Add invalid local census records to invalid_records array" do
path = base_files_path << "invalid.csv"
file = Rack::Test::UploadedFile.new(Rails.root.join(*path))
file = fixture_file_upload(path)
import.file = file
import.save!

View File

@@ -1,22 +1,19 @@
require "rails_helper"
describe SiteCustomization::Image do
it "stores images with both Paperclip and Active Storage" do
it "stores images with Active Storage" do
image = create(:site_customization_image, name: "map",
image: File.new("spec/fixtures/files/custom_map.jpg"))
image: fixture_file_upload("custom_map.jpg"))
expect(image.image).to exist
expect(image.image_file_name).to eq "custom_map.jpg"
expect(image.storage_image).to be_attached
expect(image.storage_image.filename).to eq "custom_map.jpg"
expect(image.image).to be_attached
expect(image.image.filename).to eq "custom_map.jpg"
end
describe "logo" do
it "is valid with a 260x80 image" do
image = build(:site_customization_image,
name: "logo_header",
image: File.new("spec/fixtures/files/logo_header-260x80.png"))
image: fixture_file_upload("logo_header-260x80.png"))
expect(image).to be_valid
end
@@ -24,7 +21,7 @@ describe SiteCustomization::Image do
it "is valid with a 223x80 image" do
image = build(:site_customization_image,
name: "logo_header",
image: File.new("spec/fixtures/files/logo_header.png"))
image: fixture_file_upload("logo_header.png"))
expect(image).to be_valid
end
@@ -32,7 +29,7 @@ describe SiteCustomization::Image do
it "is not valid with a 400x80 image" do
image = build(:site_customization_image,
name: "logo_header",
image: File.new("spec/fixtures/files/logo_email_custom.png"))
image: fixture_file_upload("logo_email_custom.png"))
expect(image).not_to be_valid
end

View File

@@ -7,21 +7,21 @@ shared_examples "acts as imageable" do |imageable_factory|
describe "file extension" do
it "is not valid with '.png' extension" do
image.attachment = File.new("spec/fixtures/files/clippy.png")
image.attachment = fixture_file_upload("clippy.png")
expect(image).not_to be_valid
expect(image.errors[:attachment].size).to eq(1)
end
it "is not valid with '.gif' extension" do
image.attachment = File.new("spec/fixtures/files/clippy.gif")
image.attachment = fixture_file_upload("clippy.gif")
expect(image).not_to be_valid
expect(image.errors[:attachment].size).to eq(1)
end
it "is valid with '.jpg' extension" do
image.attachment = File.new("spec/fixtures/files/clippy.jpg")
image.attachment = fixture_file_upload("clippy.jpg")
expect(image).to be_valid
end
@@ -33,7 +33,7 @@ shared_examples "acts as imageable" do |imageable_factory|
end
it "is not valid when image dimmensions are smaller than 475X475" do
image.attachment = File.new("spec/fixtures/files/logo_header.jpg")
image.attachment = fixture_file_upload("logo_header.jpg")
expect(image).not_to be_valid
end

View File

@@ -22,14 +22,14 @@ shared_examples "document validations" do |documentable_factory|
it "is valid for all accepted content types" do
acceptedcontenttypes.each do |content_type|
extension = content_type.split("/").last
document.attachment = File.new("spec/fixtures/files/empty.#{extension}")
document.attachment = fixture_file_upload("empty.#{extension}")
expect(document).to be_valid
end
end
it "is not valid for attachments larger than documentable max_file_size definition" do
allow(document).to receive(:attachment_file_size).and_return(maxfilesize.megabytes + 1.byte)
allow(document.attachment).to receive(:byte_size).and_return(maxfilesize.megabytes + 1.byte)
max_size_error_message = "must be in between 0 Bytes and #{maxfilesize} MB"
expect(document).not_to be_valid

View File

@@ -21,7 +21,7 @@ shared_examples "image validations" do |imageable_factory|
it "is 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}")
image.attachment = fixture_file_upload("clippy.#{extension}")
expect(image).to be_valid
end
@@ -30,7 +30,7 @@ shared_examples "image validations" do |imageable_factory|
it "is not 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}")
image.attachment = fixture_file_upload("clippy.#{extension}")
expect(image).not_to be_valid
end
@@ -38,7 +38,7 @@ shared_examples "image validations" do |imageable_factory|
it "is not valid for attachments larger than imageable max_file_size definition" do
larger_size = Setting["uploads.images.max_size"].to_i.megabytes + 1.byte
allow(image).to receive(:attachment_file_size).and_return(larger_size)
allow(image.attachment).to receive(:byte_size).and_return(larger_size)
expect(image).not_to be_valid
expect(image.errors[:attachment]).to include "must be in between 0 Bytes and 1 MB"

View File

@@ -51,7 +51,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
do_login_for user_to_login
visit send(path, arguments)
documentable.class.max_documents_allowed.times.each do
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
documentable_attach_new_file(file_fixture("empty.pdf"))
end
expect(page).to have_css ".max-documents-notice"
@@ -77,7 +77,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
click_link "Add new document"
within "#nested-documents" do
attach_file "Choose document", Rails.root.join("spec/fixtures/files/empty.pdf")
attach_file "Choose document", file_fixture("empty.pdf")
expect(page).to have_css ".loading-bar.complete"
end
@@ -90,7 +90,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
documentable_attach_new_file(file_fixture("empty.pdf"))
expect_document_has_title(0, "empty.pdf")
end
@@ -104,7 +104,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
within "#nested-documents" do
input = find("input[name$='[title]']")
fill_in input[:id], with: "My Title"
attach_file "Choose document", Rails.root.join("spec/fixtures/files/empty.pdf")
attach_file "Choose document", file_fixture("empty.pdf")
expect(page).to have_css ".loading-bar.complete"
end
@@ -116,7 +116,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
documentable_attach_new_file(file_fixture("empty.pdf"))
expect(page).to have_css ".loading-bar.complete"
end
@@ -125,10 +125,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(
Rails.root.join("spec/fixtures/files/logo_header.gif"),
false
)
documentable_attach_new_file(file_fixture("logo_header.gif"), false)
expect(page).to have_css ".loading-bar.errors"
end
@@ -137,21 +134,25 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
click_link "Add new document"
expect_document_has_cached_attachment(0, ".pdf")
cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden)
expect(cached_attachment_field.value).to be_empty
attach_file "Choose document", file_fixture("empty.pdf")
expect(page).to have_css(".loading-bar.complete")
expect(cached_attachment_field.value).not_to be_empty
end
scenario "Should not update document cached_attachment field after invalid file upload" do
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(
Rails.root.join("spec/fixtures/files/logo_header.gif"),
false
)
documentable_attach_new_file(file_fixture("logo_header.gif"), false)
expect_document_has_cached_attachment(0, "")
cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden)
expect(cached_attachment_field.value).to be_empty
end
scenario "Should show document errors after documentable submit with
@@ -171,7 +172,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
documentable_attach_new_file(file_fixture("empty.pdf"))
click_link "Remove document"
expect(page).not_to have_css("#nested-documents .document")
@@ -194,7 +195,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
documentable_attach_new_file(file_fixture("empty.pdf"))
click_on submit_button
expect(page).to have_content documentable_success_notice
@@ -208,7 +209,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/empty.pdf"))
documentable_attach_new_file(file_fixture("empty.pdf"))
click_on submit_button
documentable_redirected_to_resource_show_or_navigate_to
@@ -232,7 +233,7 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
send(fill_resource_method_name) if fill_resource_method_name
%w[clippy empty logo].take(documentable.class.max_documents_allowed).each do |filename|
documentable_attach_new_file(Rails.root.join("spec/fixtures/files/#{filename}.pdf"))
documentable_attach_new_file(file_fixture("#{filename}.pdf"))
end
click_on submit_button
@@ -279,6 +280,26 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
expect(page).not_to have_css ".document"
end
scenario "Same attachment URL after editing the title" do
do_login_for user_to_login
visit send(path, arguments)
documentable_attach_new_file(file_fixture("empty.pdf"))
within_fieldset("Documents") { fill_in "Title", with: "Original" }
click_button submit_button
expect(page).to have_content documentable_success_notice
original_url = find_link("Download file")[:href]
visit send(path, arguments)
within_fieldset("Documents") { fill_in "Title", with: "Updated" }
click_button submit_button
expect(page).to have_content documentable_success_notice
expect(find_link("Download file")[:href]).to eq original_url
end
end
describe "When allow attached documents setting is disabled" do
@@ -330,14 +351,6 @@ def expect_document_has_title(index, title)
end
end
def expect_document_has_cached_attachment(index, extension)
document = all(".document")[index]
within document do
expect(find("input[name$='[cached_attachment]']", visible: :hidden).value).to end_with(extension)
end
end
def documentable_fill_new_valid_proposal
fill_in_new_proposal_title with: "Proposal title #{rand(9999)}"
fill_in "Proposal summary", with: "Proposal summary"

View File

@@ -38,7 +38,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
visit send(path, arguments)
click_link "Add image"
attach_file "Choose image", Rails.root.join("spec/fixtures/files/clippy.jpg")
attach_file "Choose image", file_fixture("clippy.jpg")
expect(page).to have_selector ".file-name", text: "clippy.jpg"
end
@@ -47,7 +47,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
expect_image_has_title("clippy.jpg")
end
@@ -59,7 +59,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
click_link "Add image"
input_title = find(".image input[name$='[title]']")
fill_in input_title[:id], with: "Title"
attach_file "Choose image", Rails.root.join("spec/fixtures/files/clippy.jpg")
attach_file "Choose image", file_fixture("clippy.jpg")
if has_many_images
expect(find("input[id$='_title']").value).to eq "Title"
@@ -72,7 +72,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
expect(page).to have_selector ".loading-bar.complete"
end
@@ -81,7 +81,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/logo_header.png"), false)
imageable_attach_new_file(file_fixture("logo_header.png"), false)
expect(page).to have_selector ".loading-bar.errors"
end
@@ -90,18 +90,26 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
click_link "Add image"
expect_image_has_cached_attachment(".jpg")
cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden)
expect(cached_attachment_field.value).to be_empty
attach_file "Choose image", file_fixture("clippy.jpg")
expect(page).to have_css(".loading-bar.complete")
expect(cached_attachment_field.value).not_to be_empty
end
scenario "Should not update image cached_attachment field after invalid file upload" do
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/logo_header.png"), false)
imageable_attach_new_file(file_fixture("logo_header.png"), false)
expect_image_has_cached_attachment("")
cached_attachment_field = find("input[name$='[cached_attachment]']", visible: :hidden)
expect(cached_attachment_field.value).to be_empty
end
scenario "Should show nested image errors after invalid form submit" do
@@ -120,11 +128,24 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
end
end
scenario "Render image preview after sending the form with validation errors" do
skip "Question answers behave differently" if imageable.is_a?(Poll::Question::Answer)
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(file_fixture("clippy.jpg"))
within_fieldset("Descriptive image") { fill_in "Title", with: "" }
click_on submit_button
expect(page).to have_content "can't be blank"
expect(page).to have_css "img[src$='clippy.jpg']"
end
scenario "Should remove nested image after valid file upload and click on remove button" do
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
within "#nested-image .image" do
click_link "Remove image"
@@ -151,7 +172,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
expect(page).to have_selector ".loading-bar.complete"
@@ -165,7 +186,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
expect(page).to have_selector ".loading-bar.complete"
@@ -180,6 +201,22 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
end
end
scenario "Different URLs for different images" do
do_login_for user
visit send(path, arguments)
imageable_attach_new_file(file_fixture("clippy.jpg"))
original_src = find(:fieldset, "Descriptive image").find("img")[:src]
click_link "Remove image"
imageable_attach_new_file(file_fixture("custom_map.jpg"))
updated_src = find(:fieldset, "Descriptive image").find("img")[:src]
expect(updated_src).not_to eq original_src
end
if path.include? "edit"
scenario "show persisted image" do
create(:image, imageable: imageable)
@@ -268,16 +305,6 @@ def expect_image_has_title(title)
end
end
def expect_image_has_cached_attachment(extension)
within "#nested-image" do
image = find(".image")
within image do
expect(find("input[name$='[cached_attachment]']", visible: :hidden).value).to end_with(extension)
end
end
end
def show_caption_for?(imageable_factory_name)
imageable_factory_name != "budget"
end

View File

@@ -9,6 +9,7 @@ Dir["./spec/shared/**/*.rb"].sort.each { |f| require f }
RSpec.configure do |config|
config.use_transactional_fixtures = true
config.fixture_path = "spec/fixtures/files"
config.filter_run_when_matching :focus
config.include RequestSpecHelper, type: :request

View File

@@ -5,15 +5,15 @@ module RemoteCensusMock
include DocumentParser
def mock_valid_remote_census_response
mock_remote_census_response(File.read("spec/fixtures/files/remote_census_api/valid.xml"))
mock_remote_census_response(File.read(file_fixture("remote_census_api/valid.xml")))
end
def mock_invalid_remote_census_response
mock_remote_census_response(File.read("spec/fixtures/files/remote_census_api/invalid.xml"))
mock_remote_census_response(File.read(file_fixture("remote_census_api/invalid.xml")))
end
def mock_invalid_signature_sheet_remote_census_response
xml = File.read("spec/fixtures/files/remote_census_api/invalid.xml")
xml = File.read(file_fixture("remote_census_api/invalid.xml"))
Signature.new.document_types.each do |document_type|
get_document_number_variants(document_type, "12345678Z").each do

View File

@@ -46,7 +46,7 @@ describe "Admin budget phases" do
scenario "shows successful notice when updating the phase with a valid image" do
visit edit_admin_budget_budget_phase_path(budget, budget.current_phase)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
click_on "Save changes"

View File

@@ -175,7 +175,7 @@ describe "Admin collaborative legislation", :admin do
fill_in "End", with: base_date + 5.days
end
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
click_button "Create process"

View File

@@ -1,7 +1,7 @@
require "rails_helper"
describe "Imports", :admin do
let(:base_files_path) { %w[spec fixtures files local_census_records import] }
let(:base_files_path) { "local_census_records/import/" }
describe "New" do
scenario "Should show import form" do
@@ -17,7 +17,7 @@ describe "Imports", :admin do
scenario "Should show success notice after successful import" do
within "form#new_local_census_records_import" do
path = base_files_path << "valid.csv"
file = File.join(Rails.root, *path)
file = file_fixture(path)
attach_file("local_census_records_import_file", file)
click_button "Save"
end
@@ -35,8 +35,7 @@ describe "Imports", :admin do
scenario "Should show alert when file is not supported" do
within "form#new_local_census_records_import" do
path = ["spec", "fixtures", "files", "clippy.jpg"]
file = File.join(Rails.root, *path)
file = file_fixture("clippy.jpg")
attach_file("local_census_records_import_file", file)
click_button "Save"
end
@@ -47,7 +46,7 @@ describe "Imports", :admin do
scenario "Should show successfully created local census records at created group" do
within "form#new_local_census_records_import" do
path = base_files_path << "valid.csv"
file = File.join(Rails.root, *path)
file = file_fixture(path)
attach_file("local_census_records_import_file", file)
click_button "Save"
end
@@ -59,7 +58,7 @@ describe "Imports", :admin do
scenario "Should show invalid local census records at errored group" do
within "form#new_local_census_records_import" do
path = base_files_path << "invalid.csv"
file = File.join(Rails.root, *path)
file = file_fixture(path)
attach_file("local_census_records_import_file", file)
click_button "Save"
end
@@ -71,7 +70,7 @@ describe "Imports", :admin do
scenario "Should show error messages inside cells at errored group" do
within "form#new_local_census_records_import" do
path = base_files_path << "invalid.csv"
file = File.join(Rails.root, *path)
file = file_fixture(path)
attach_file("local_census_records_import_file", file)
click_button "Save"
end

View File

@@ -38,7 +38,7 @@ describe "Images", :admin do
expect(page).not_to have_content("clippy.jpg")
visit new_admin_answer_image_path(answer)
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
click_button "Save image"
expect(page).to have_css("img[title='clippy.jpg']")

View File

@@ -18,12 +18,12 @@ describe "Documents", :admin do
1.times { create(:document) }
document = Document.first
attachment = document.attachment
url = polymorphic_path(document.attachment)
visit admin_site_customization_documents_path
expect(page).to have_content "There are 3 documents"
expect(page).to have_link document.title, href: attachment.url
expect(page).to have_link document.title, href: url
end
scenario "Index (empty)" do
@@ -54,7 +54,7 @@ describe "Documents", :admin do
scenario "Create" do
visit new_admin_site_customization_document_path
attach_file("document_attachment", "#{Rails.root}/spec/fixtures/files/logo.pdf")
attach_file("document_attachment", file_fixture("logo.pdf"))
click_button "Upload"
expect(page).to have_content "Document uploaded succesfully"

View File

@@ -10,7 +10,7 @@ describe "Admin custom images", :admin do
end
within("tr#image_logo_header") do
attach_file "site_customization_image_image", "spec/fixtures/files/logo_header.png"
attach_file "site_customization_image_image", file_fixture("logo_header.png")
click_button "Update"
end
@@ -22,7 +22,7 @@ describe "Admin custom images", :admin do
visit admin_site_customization_images_path
within("tr#image_map") do
attach_file "site_customization_image_image", "spec/fixtures/files/custom_map.jpg"
attach_file "site_customization_image_image", file_fixture("custom_map.jpg")
click_button "Update"
end
@@ -37,7 +37,7 @@ describe "Admin custom images", :admin do
visit admin_site_customization_images_path
within("tr#image_map") do
attach_file "site_customization_image_image", "spec/fixtures/files/custom_map.jpg"
attach_file "site_customization_image_image", file_fixture("custom_map.jpg")
click_button "Update"
end
@@ -60,13 +60,24 @@ describe "Admin custom images", :admin do
end
end
scenario "Custom apple touch icon is replaced on front views" do
create(:site_customization_image,
name: "apple-touch-icon-200",
image: fixture_file_upload("apple-touch-icon-custom-200.png"))
visit root_path
expect(page).not_to have_css("link[href*='apple-touch-icon-200']", visible: :all)
expect(page).to have_css("link[href*='apple-touch-icon-custom-200']", visible: :hidden)
end
scenario "Image is replaced on admin newsletters" do
newsletter = create(:newsletter, segment_recipient: "all_users")
visit admin_site_customization_images_path
within("tr#image_logo_email") do
attach_file "site_customization_image_image", "spec/fixtures/files/logo_email_custom.png"
attach_file "site_customization_image_image", file_fixture("logo_email_custom.png")
click_button "Update"
end
@@ -81,7 +92,7 @@ describe "Admin custom images", :admin do
visit admin_site_customization_images_path
within("tr#image_social_media_icon") do
attach_file "site_customization_image_image", "spec/fixtures/files/logo_header.png"
attach_file "site_customization_image_image", file_fixture("logo_header.png")
click_button "Update"
end
@@ -93,7 +104,7 @@ describe "Admin custom images", :admin do
visit admin_site_customization_images_path
within("tr#image_social_media_icon") do
attach_file "site_customization_image_image", "spec/fixtures/files/social_media_icon.png"
attach_file "site_customization_image_image", file_fixture("social_media_icon.png")
click_button "Update"
end

View File

@@ -251,7 +251,7 @@ describe "Cards", :admin do
def attach_image_to_card
click_link "Add image"
attach_file "Choose image", Rails.root.join("spec/fixtures/files/clippy.jpg")
attach_file "Choose image", file_fixture("clippy.jpg")
expect(page).to have_field("widget_card_image_attributes_title", with: "clippy.jpg")
end

View File

@@ -33,7 +33,7 @@ describe "CKEditor" do
click_link "Upload"
within_frame(1) do
attach_file "Send it to the Server", Rails.root.join("spec/fixtures/files/clippy.jpg")
attach_file "Send it to the Server", file_fixture("clippy.jpg")
end
click_link "Send it to the Server"

View File

@@ -146,7 +146,7 @@ describe "Legislation Proposals" do
fill_in "Proposal title", with: "Legislation proposal with image"
fill_in "Proposal summary", with: "Including an image on a legislation proposal"
imageable_attach_new_file(Rails.root.join("spec/fixtures/files/clippy.jpg"))
imageable_attach_new_file(file_fixture("clippy.jpg"))
check "legislation_proposal_terms_of_service"
click_button "Create proposal"