diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 67d006483..4e1a84896 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -64,6 +64,7 @@ //= require flaggable //= require documentable //= require imageable +//= require direct_uploads //= require tree_navigator //= require custom //= require tag_autocomplete diff --git a/app/assets/javascripts/direct_uploads.js.coffee b/app/assets/javascripts/direct_uploads.js.coffee new file mode 100644 index 000000000..f83ae0bf2 --- /dev/null +++ b/app/assets/javascripts/direct_uploads.js.coffee @@ -0,0 +1,98 @@ +App.DirectUploads = + + progressBarTemplate: '
' + + buildData: (e, data) -> + wrapper = $(e.target).closest('.direct-upload') + data.wrapper = wrapper + data.preview = $(wrapper).find('.image-preview') + data.progressBar = $(wrapper).find('.progress-bar-placeholder').html(App.DirectUploads.progressBarTemplate) + data.errorContainer = $(wrapper).find('.attachment-errors') + data.fileNameContainer = $(wrapper).find('p.file-name') + data.destroyAttachmentLinkContainer = $(wrapper).find('.action-remove') + data.addAttachmentLabel = $(wrapper).find('.action-add label') + data.cachedAttachmentField = $(wrapper).find("#" + $(e.target).data('cached-attachment-input-field')) + data.titleField = $(wrapper).find("#" + $(e.target).data('title-input-field')) + $(wrapper).find('.progress-bar-placeholder').css('display', 'block') + return data + + remove_cached_attachment: (e, data) -> + e.preventDefault() + e.stopPropagation() + $.ajax + type: "POST" + url: e.target.href + dataType: "json" + data: {"_method":"delete"} + complete: -> + console.log data + $(data.cachedAttachmentField).val("") + $(data.addAttachmentLabel).show() + $(data.destroyAttachmentLinkContainer).find('a.delete').remove() + $(data.fileNameContainer).text('') + $(data.fileNameContainer).hide() + $(data.errorContainer).find('small.error').remove() + $(data.progressBar).find('.loading-bar').removeClass('complete errors uploading').css('width', "0px").css('display', "none") + $(data.wrapper).find(".image-preview").remove() + $(data.preview).html('') + + initialize: -> + + $('.action-remove a.delete').on 'click', (e) -> + data = App.DirectUploads.buildData(e, []) + App.DirectUploads.remove_cached_attachment(e, data) + $(data.wrapper).find('small.error').remove() + $(data.wrapper).find('label.error').removeClass('error') + + $('input.direct_upload_attachment[type=file]').fileupload + + paramName: "attachment" + + formData: null + + add: (e, data) -> + data = App.DirectUploads.buildData(e, data) + data.submit() + + change: (e, data) -> + $.each data.files, (index, file) -> + $(e.target).closest('.direct-upload').find('p.file-name').text(file.name) + $(e.target).closest('.direct-upload').find('p.file-name').show() + + fail: (e, data) -> + $(data.cachedAttachmentField).val("") + $(data.progressBar).find('.loading-bar').addClass('errors') + $(data.errorContainer).find('small.error').remove() + $(data.errorContainer).append('' + data.jqXHR.responseJSON.errors + '') + $(data.fileNameContainer).text('') + $(data.fileNameContainer).hide() + $(data.destroyAttachmentLinkContainer).find("a.delete").remove() + $(data.addAttachmentLabel).show() + $(data.wrapper).find(".image-preview").remove() + + done: (e, data) -> + $(data.cachedAttachmentField).val(data.result.cached_attachment) + if $(data.titleField).val() == "" + $(data.titleField).val(data.result.filename) + $(data.progressBar).find('.loading-bar').addClass('complete') + $(data.fileNameContainer).text(data.result.filename) + $(data.fileNameContainer).show() + $(data.errorContainer).find('small.error').remove() + $(data.destroyAttachmentLinkContainer).html(data.result.destroy_link) + data.destroyAttachmentLinkContainer = $(data.wrapper).find('.action-remove') + $(data.addAttachmentLabel).hide() + if data.result.is_image + image = '
' + if $('.image-preview').length > 0 + $('.image-preview').replaceWith(image) + else + $(image).insertBefore($(data.wrapper).find(".attachment-actions")) + + $(data.destroyAttachmentLinkContainer).on 'click', (e) -> + App.DirectUploads.remove_cached_attachment(e, data) + + + progress: (e, data) -> + progress = parseInt(data.loaded / data.total * 100, 10) + $(data.progressBar).find('.loading-bar').css 'width', progress + '%' + return \ No newline at end of file diff --git a/app/assets/javascripts/documentable.js.coffee b/app/assets/javascripts/documentable.js.coffee index 4c354e5a6..78126be43 100644 --- a/app/assets/javascripts/documentable.js.coffee +++ b/app/assets/javascripts/documentable.js.coffee @@ -8,7 +8,7 @@ App.Documentable = $('input.js-document-attachment[type=file]').fileupload - paramName: "document[attachment]" + paramName: "direct_upload[attachment]" formData: null @@ -20,7 +20,7 @@ App.Documentable = data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('
') $(wrapper).find('.progress-bar-placeholder').css('display','block') data.formData = { - "document[title]": $(wrapper).find('input.document-title').val() || data.files[0].name + "direct_upload[title]": $(wrapper).find('inputdirect_upload-title').val() || data.files[0].name "index": index, "nested_document": is_nested_document } diff --git a/app/assets/stylesheets/documentable.scss b/app/assets/stylesheets/documentable.scss index 70629bb27..e16b8cbf9 100644 --- a/app/assets/stylesheets/documentable.scss +++ b/app/assets/stylesheets/documentable.scss @@ -28,7 +28,8 @@ background-color: $light-gray; } - .js-document-attachment { + .js-document-attachment, + input.direct_upload_attachment[type=file] { display: none; } diff --git a/app/assets/stylesheets/imageable.scss b/app/assets/stylesheets/imageable.scss index c65bf425b..036eb8038 100644 --- a/app/assets/stylesheets/imageable.scss +++ b/app/assets/stylesheets/imageable.scss @@ -29,7 +29,8 @@ background-color: $light-gray; } - input.image_ajax_attachment[type=file]{ + input.image_ajax_attachment[type=file], + input.direct_upload_attachment[type=file] { display: none; } diff --git a/app/controllers/direct_uploads_controller.rb b/app/controllers/direct_uploads_controller.rb index e6a8c139a..0411e411e 100644 --- a/app/controllers/direct_uploads_controller.rb +++ b/app/controllers/direct_uploads_controller.rb @@ -1,34 +1,53 @@ class DirectUploadsController < ApplicationController + include DirectUploadsHelper + include ActionView::Helpers::UrlHelper + before_action :authenticate_user! - def destroy_upload - @document = Document.new(cached_attachment: params[:path]) - @document.set_attachment_from_cached_attachment - @document.cached_attachment = nil - @document.documentable = @documentable + load_and_authorize_resource except: :create + skip_authorization_check only: :create - if @document.attachment.destroy - flash.now[:notice] = t "documents.actions.destroy.notice" + helper_method :render_destroy_upload_link + + # It should return cached attachment path or attachment errors + def create + @direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user, attachment: params[:attachment])) + + if @direct_upload.valid? + @direct_upload.save_attachment + @direct_upload.relation.set_cached_attachment_from_attachment(URI(request.url)) + render json: { cached_attachment: @direct_upload.relation.cached_attachment, + filename: @direct_upload.relation.attachment.original_filename, + destroy_link: render_destroy_upload_link(@direct_upload).html_safe, + attachment_url: @direct_upload.relation.attachment.url, + is_image: Image::ACCEPTED_CONTENT_TYPE.include?(@direct_upload.relation.attachment_content_type) + } else - flash.now[:alert] = t "documents.actions.destroy.alert" + @direct_upload.destroy_attachment + render json: { errors: @direct_upload.errors[:attachment].join(", ") }, + status: 422 end - render :destroy end - def upload - @document = Document.new(document_params.merge(user: current_user)) - @document.documentable = @documentable - @document.valid? + def destroy + @direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user) ) - if @document.valid? - @document.attachment.save - @document.set_cached_attachment_from_attachment(URI(request.url)) + @direct_upload.relation.set_attachment_from_cached_attachment + + if @direct_upload.destroy_attachment + render json: :ok else - @document.attachment.destroy + render json: :error end end private + def direct_upload_params + params.require(:direct_upload) + .permit(:resource, :resource_type, :resource_id, :resource_relation, + :attachment, :cached_attachment, attachment_attributes: []) + end + def set_attachment_container_resource @container_resource = params[:resource_type] end diff --git a/app/helpers/direct_uploads_helper.rb b/app/helpers/direct_uploads_helper.rb new file mode 100644 index 000000000..65196bcd6 --- /dev/null +++ b/app/helpers/direct_uploads_helper.rb @@ -0,0 +1,15 @@ +module DirectUploadsHelper + + def render_destroy_upload_link(direct_upload) + link_to t('documents.form.delete_button'), + direct_upload_destroy_url("direct_upload[resource_type]": direct_upload.resource_type, + "direct_upload[resource_id]": direct_upload.resource_id, + "direct_upload[resource_relation]": direct_upload.resource_relation, + "direct_upload[cached_attachment]": direct_upload.relation.cached_attachment, + format: :json), + method: :delete, + remote: true, + class: "delete float-right" + end + +end \ No newline at end of file diff --git a/app/helpers/documents_helper.rb b/app/helpers/documents_helper.rb index 638ef902f..0e1778f5d 100644 --- a/app/helpers/documents_helper.rb +++ b/app/helpers/documents_helper.rb @@ -1,5 +1,10 @@ module DocumentsHelper + def document_note(document) + t "documents.new.#{document.documentable.class.name.parameterize.underscore}.note", + title: document.documentable.title + end + def document_attachment_file_name(document) document.attachment_file_name end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index ba2f4070d..5f0c849e1 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -75,6 +75,7 @@ module Abilities can [:create, :destroy], Document can [:create, :destroy], Image + can [:create, :destroy], DirectUpload end end end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 8c339ec5a..a2e722451 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -43,6 +43,8 @@ module Abilities can [:create, :destroy, :new], Image, imageable: { author_id: user.id } can [:new_nested, :upload, :destroy_upload], Image + can [:create, :destroy], DirectUpload + unless user.organization? can :vote, Debate can :vote, Comment diff --git a/app/models/direct_upload.rb b/app/models/direct_upload.rb index b57618432..bc7c135ce 100644 --- a/app/models/direct_upload.rb +++ b/app/models/direct_upload.rb @@ -1,27 +1,53 @@ class DirectUpload include ActiveModel::Validations + include ActiveModel::Conversion + extend ActiveModel::Naming - attr_accessor :resource, :resource_type, :resource_id, :resource_relation, - :attachment, :cached_attachment + attr_accessor :resource, :resource_type, :resource_id, + :relation, :resource_relation, + :attachment, :cached_attachment, :user validates_presence_of :attachment, :resource_type, :resource_relation validate :parent_resource_attachment_validations, if: -> { attachment.present? && resource_type.present? && resource_relation.present? } + def save_attachment + @relation.attachment.save + end + + def destroy_attachment + @relation.attachment.destroy + end + + def persisted? + false + end + + def initialize(attributes = {}) + attributes.each do |name, value| + send("#{name}=", value) + end + + if @resource_type.present? + @resource = @resource_type.constantize.find_or_initialize_by(id: @resource_id) + end + + if @resource.class.reflections[@resource_relation].macro == :has_one + @relation = @resource.send("build_#{resource_relation}", attachment: @attachment, cached_attachment: @cached_attachment) + else + @relation = @resource.send(resource_relation).build(attachment: @attachment, cached_attachment: @cached_attachment) + end + + @relation.user = user + end + + private + def parent_resource_attachment_validations - # Proposal or Budget::Investment - resource = resource_type.constantize.find_or_initialize_by(id: resource_id) + @relation.valid? - # 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] + if @relation.errors.has_key? :attachment + errors[:attachment] = @relation.errors[:attachment] end end diff --git a/app/views/direct_uploads/_attachment.html.erb b/app/views/direct_uploads/_attachment.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb index 591503758..06137b5d3 100644 --- a/app/views/documents/_form.html.erb +++ b/app/views/documents/_form.html.erb @@ -4,14 +4,57 @@ documentable_id: @document.documentable_id, from: params[:from] ), - html: { multipart: true, class: "documentable"}, - data: { direct_upload_url: upload_documents_url(documentable_type: @document.documentable_type, documentable_id: @document.documentable_id) } do |f| %> + html: { multipart: true, class: "documentable" } do |f| %> <%= render 'shared/errors', resource: @document %> -
+
- <%= render 'plain_fields', document: @document %> + <%= f.hidden_field :cached_attachment %> + +
+ <%= f.text_field :title %> +
+ +
+
+ <%= f.label :attachment, t("documents.form.attachment_label"), class: 'button hollow' %> + <%= f.file_field :attachment, + accept: accepted_content_types_extensions(@document.documentable.class), + label: false, + class: 'js-document-attachment', + data: { + url: direct_uploads_url("direct_upload[resource_type]": @document.documentable_type, + "direct_upload[resource_id]": @document.documentable_id, + "direct_upload[resource_relation]": "documents"), + cached_attachment_input_field: "document_cached_attachment", + title_input_field: "document_title" + } %> + +
+
+ <% if @document.cached_attachment.present? %> + <%= link_to t('documents.form.delete_button'), + direct_upload_destroy_url("direct_upload[resource_type]": @document.documentable_type, + "direct_upload[resource_id]": @document.documentable_id, + "direct_upload[resource_relation]": "documents", + "direct_upload[cached_attachment]": @document.cached_attachment), + method: :delete, + remote: true, + class: "delete float-right" %> + <% end %> +
+
+ +
+

+ <%= document_attachment_file_name(@document) %> +

+
+ +
+
+
<%= f.submit(t("documents.form.submit_button"), class: "button expanded") %> diff --git a/app/views/documents/_plain_fields.html.erb b/app/views/documents/_plain_fields.html.erb deleted file mode 100644 index a4e9b7e0b..000000000 --- a/app/views/documents/_plain_fields.html.erb +++ /dev/null @@ -1,53 +0,0 @@ -
- -
- <%= label_tag :document_title, t("activerecord.attributes.document.title") %> - <%= text_field_tag :document_title, - document.errors.has_key?(:attachment) ? "" : document.title, - name: "document[title]", - class: "document-title" %> - <% if document.errors.has_key?(:title) %> - <%= document.errors[:title].join(", ") %> - <% end %> -
- -
- <%= hidden_field_tag :cached_attachment, document.cached_attachment, name: "document[cached_attachment]" %> - <%= file_field_tag :attachment, - accept: accepted_content_types_extensions(document.documentable.class), - label: false, - class: 'js-document-attachment', - data: { - url: upload_documents_url(documentable_type: document.documentable_type, documentable_id: document.documentable_id), - cached_attachment_input_field: "document_cached_attachment", - multiple: false, - nested_document: false - }, - id: "document_attachment", - name: "document[attachment]" %> - - <% if document.cached_attachment.blank? %> - <%= label_tag :document_attachment, t("documents.form.attachment_label"), class: 'button hollow' %> - <% else %> - <%= link_to t('documents.form.delete_button'), - destroy_upload_documents_path(path: document.cached_attachment, - nested_document: false, - documentable_type: document.documentable_type, - documentable_id: document.documentable_id), - method: :delete, - remote: true, - class: "delete float-right" %> - <% end %> - - <% if document.errors.has_key?(:attachment) %> -
-
- <%= document_errors_on_attachment(document) %> -
-
- <% end %> -

<%= document_attachment_file_name(document) %>

-
-
- -
diff --git a/app/views/documents/new.html.erb b/app/views/documents/new.html.erb index be300450e..482d8c404 100644 --- a/app/views/documents/new.html.erb +++ b/app/views/documents/new.html.erb @@ -3,6 +3,7 @@
<%= back_link_to params[:from] %>

<%= t("documents.new.title") %>

+

<%= document_note(@document) %>

<%= render "documents/form", form_url: documents_url %>
diff --git a/app/views/images/_form.html.erb b/app/views/images/_form.html.erb index 666eaf5eb..d50815957 100644 --- a/app/views/images/_form.html.erb +++ b/app/views/images/_form.html.erb @@ -4,17 +4,63 @@ imageable_id: @image.imageable_id, from: params[:from] ), - html: { multipart: true, class: "imageable"}, - data: { direct_upload_url: upload_images_url(imageable_type: @image.imageable_type, imageable_id: @image.imageable_id) } do |f| %> + html: { multipart: true, class: "imageable" } do |f| %> <%= render 'shared/errors', resource: @image %> -
+
- <%= render 'plain_fields', image: @image %> + <%= f.hidden_field :cached_attachment %> + +
+ <%= f.text_field :title, placeholder: t("images.new.form.title_placeholder") %> +
+ + <%= render_image(@image, :thumb, false) if @image.attachment.exists? %> + +
+
+ <%= f.label :attachment, t("images.form.attachment_label"), class: 'button hollow' %> + <%= f.file_field :attachment, + accept: imageable_accepted_content_types_extensions, + label: false, + class: 'direct_upload_attachment', + data: { + url: direct_uploads_url("direct_upload[resource_type]": @image.imageable_type, + "direct_upload[resource_id]": @image.imageable_id, + "direct_upload[resource_relation]": "image"), + cached_attachment_input_field: "image_cached_attachment", + title_input_field: "image_title", + multiple: false + } %> +
+
+ <% if @image.cached_attachment.present? %> + <%= link_to t('images.form.delete_button'), + direct_upload_destroy_url("direct_upload[resource_type]": @image.imageable_type, + "direct_upload[resource_id]": @image.imageable_id, + "direct_upload[resource_relation]": "image", + "direct_upload[cached_attachment]": @image.cached_attachment), + method: :delete, + remote: true, + class: "delete float-right" %> + <% end %> +
+
+ +
+

+ <%= image_attachment_file_name(@image) %> +

+
+ +
+
+
<%= f.submit(t("images.form.submit_button"), class: "button expanded") %>
+
<% end %> diff --git a/app/views/images/_image.html.erb b/app/views/images/_image.html.erb index da1f66295..ca7a95867 100644 --- a/app/views/images/_image.html.erb +++ b/app/views/images/_image.html.erb @@ -1,19 +1,17 @@ -
-
-
- <%= image_tag image.attachment.url(version), - class: image_class(image), - alt: image.title %> - <% if show_caption %> -
- <%= image.title %> -
- <% end %> -
- +
+
+ <%= image_tag image.attachment.url(version), + class: image_class(image), + alt: image.title %> <% if show_caption %> -
+
+ <%= image.title %> +
<% end %> +
+ + <% if show_caption %> +
+ <% end %> -
\ No newline at end of file diff --git a/app/views/images/_plain_fields.html.erb b/app/views/images/_plain_fields.html.erb deleted file mode 100644 index c18ec0b4d..000000000 --- a/app/views/images/_plain_fields.html.erb +++ /dev/null @@ -1,52 +0,0 @@ -
- -
- <%= label_tag :image_title, t("activerecord.attributes.image.title") %> - <%= text_field_tag :image_title, image.title, placeholder: t("images.new.form.title_placeholder"), name: "image[title]", class: "image-title" %> - <% if image.errors.has_key?(:title) %> - <%= image.errors[:title].join(", ") %> - <% end %> -
- -
- <%= render_image(image, :thumb, false) if image.attachment.exists? %> - - <%= hidden_field_tag :cached_attachment, image.cached_attachment, name: "image[cached_attachment]" %> - <%= file_field_tag :attachment, - accept: imageable_accepted_content_types_extensions, - label: false, - class: 'image_ajax_attachment', - data: { - url: upload_images_url(imageable_type: image.imageable_type, imageable_id: image.imageable_id), - cached_attachment_input_field: "image_cached_attachment", - multiple: false, - nested_image: false - }, - id: "image_attachment", - name: "image[attachment]" %> - - <% if image.cached_attachment.blank? %> - <%= label_tag :image_attachment, t("images.form.attachment_label"), class: 'button hollow' %> - <% else %> - <%= link_to t('images.form.delete_button'), - destroy_upload_images_path(path: image.cached_attachment, - nested_image: false, - imageable_type: image.imageable_type, - imageable_id: image.imageable_id), - method: :delete, - remote: true, - class: "delete float-right" %> - <% end %> - - <% if image.errors.has_key?(:attachment) %> -
-
- <%= image_errors_on_attachment(image) %> -
-
- <% end %> -

<%= image_attachment_file_name(image) %>

-
-
- -
diff --git a/config/locales/en/documents.yml b/config/locales/en/documents.yml index d2485df4c..0b36dc79d 100644 --- a/config/locales/en/documents.yml +++ b/config/locales/en/documents.yml @@ -4,6 +4,7 @@ en: no_documents: Don't have uploaded documents upload_document: Upload document max_documents_allowed_reached_html: You have reached the maximum number of documents allowed! You have to delete one before you can upload another. + form: title: Documents attachment_label: Choose document @@ -11,8 +12,13 @@ en: delete_button: Remove document note: "You can upload up to a maximum of %{max_documents_allowed} documents of following content types: %{accepted_content_types}, up to %{max_file_size} MB per file." add_new_document: Add new document + new: title: Upload document + budget_investment: + note: 'Add new document to your investment project: %{title}' + proposal: + note: 'Add new document to your proposal: %{title}' recommendations_title: File upload tips recommendation_one_html: You can upload up to a maximum of %{max_documents_allowed} documents. recommendation_two_html: You can upload %{accepted_content_types} files. diff --git a/config/locales/es/documents.yml b/config/locales/es/documents.yml index a0b646ecc..e418b2e3b 100644 --- a/config/locales/es/documents.yml +++ b/config/locales/es/documents.yml @@ -4,6 +4,7 @@ es: no_documents: No hay documentos subidos upload_document: Subir documento max_documents_allowed_reached_html: ¡Has alcanzado el número máximo de documentos permitidos! Tienes que eliminar uno antes de poder subir otro. + form: title: Documentos attachment_label: Selecciona un documento @@ -11,12 +12,18 @@ es: delete_button: Eliminar documento note: "Puedes subir hasta un máximo de %{max_documents_allowed} documentos en los formatos: %{accepted_content_types}, y de hasta %{max_file_size} MB por archivo." add_new_document: Añadir nuevo documento + new: title: Subir un documento + budget_investment: + note: 'Añade un documento la propuesta de inversión: %{title}.' + proposal: + note: 'Añade un documento a la propuesta: %{title}.' recommendations_title: Consejos para subir archivos recommendation_one_html: Puedes subir hasta un máximo de %{max_documents_allowed} documentos recommendation_two_html: Sólo puedes subir archivos %{accepted_content_types}. recommendation_three_html: Puedes subir archivos de hasta %{max_file_size} MB + actions: create: notice: "El documento se ha creado correctamente." diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 9f52ccc38..4b1ebe2ba 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -181,6 +181,7 @@ es: signature_sheet: la hoja de firmas document: el documento topic: Tema + image: Imagen geozones: none: Toda la ciudad all: Todos los ámbitos de actuación diff --git a/config/routes.rb b/config/routes.rb index b8289bae4..3d92db80d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -101,21 +101,16 @@ Rails.application.routes.draw do resources :follows, only: [:create, :destroy] resources :documents, only: [:new, :create, :destroy] do - collection do - get :new_nested - delete :destroy_upload - post :upload - end + get :new_nested, on: :collection end resources :images, only: [:new, :create, :destroy] do - collection do - get :new_nested - delete :destroy_upload - post :upload - end + get :new_nested, on: :collection end + resources :direct_uploads, only: [:create] + delete "direct_uploads/destroy", to: "direct_uploads#destroy", as: :direct_upload_destroy + resources :stats, only: [:index] resources :legacy_legislations, only: [:show], path: 'legislations' diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 23bed5690..52b26a78f 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -474,7 +474,7 @@ feature 'Budget Investments' do "Create Investment", "Budget Investment created successfully." - it_behaves_like "documentable", "budget_investment", "budget_investment_path", {"budget_id": "budget_id", "id": "id"} + it_behaves_like "documentable", "budget_investment", "budget_investment_path", { "budget_id": "budget_id", "id": "id" } it_behaves_like "nested documentable", "budget_investment", diff --git a/spec/shared/features/documentable.rb b/spec/shared/features/documentable.rb index aef4e33c8..839c38c1d 100644 --- a/spec/shared/features/documentable.rb +++ b/spec/shared/features/documentable.rb @@ -213,14 +213,24 @@ shared_examples "documentable" do |documentable_factory_name, documentable_path, expect(page).to have_selector ".loading-bar.errors" end - scenario "Should update document title with attachment original file name after file selection if no title defined by user", :js do + scenario "Should update document title with attachment original file name after valid upload if no title defined by user", :js do login_as documentable.author visit new_document_path(documentable_type: documentable.class.name, documentable_id: documentable.id) attach_document("spec/fixtures/files/empty.pdf", true) - expect(page).to have_css("input[name='document[title]'][value='empty.pdf']") + expect(find("input#document_title").value).to eq("empty.pdf") + end + + scenario "Should update document title with attachment original file name after invalid upload if no title defined by user", :js do + login_as documentable.author + visit new_document_path(documentable_type: documentable.class.name, + documentable_id: documentable.id) + + attach_document("spec/fixtures/files/logo_header.png", false) + + expect(find("input#document_title").value).to be_empty end scenario "Should not update document title with attachment original file name after file selection when title already defined by user", :js do @@ -429,8 +439,8 @@ end def attach_document(path, success = true) attach_file :document_attachment, path, make_visible: true if success - have_css ".loading-bar.complete" + expect(page).to have_css ".loading-bar.complete" else - have_css ".loading-bar.errors" + expect(page).to have_css ".loading-bar.errors" end end \ No newline at end of file diff --git a/spec/shared/features/imageable.rb b/spec/shared/features/imageable.rb index 09526b02d..c4f3156bf 100644 --- a/spec/shared/features/imageable.rb +++ b/spec/shared/features/imageable.rb @@ -127,7 +127,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/logo_header.png", make_visible: true + attach_image("spec/fixtures/files/logo_header.png", false) expect(page).to have_css "small.error" end @@ -147,9 +147,8 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/clippy.png", make_visible: true + attach_image("spec/fixtures/files/logo_header.png", false) - expect(page).to have_css ".loading-bar.errors" expect(page).not_to have_content "clippy.png" end @@ -158,7 +157,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true + attach_image("spec/fixtures/files/clippy.jpg", true) expect(page).to have_css("figure img") expect(page).not_to have_css("figure figcaption") @@ -169,7 +168,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true + attach_image("spec/fixtures/files/clippy.jpg", true) expect(page).to have_selector ".loading-bar.complete" end @@ -179,7 +178,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/logo_header.png", make_visible: true + attach_image("spec/fixtures/files/logo_header.png", false) expect(page).to have_selector ".loading-bar.errors" end @@ -189,9 +188,9 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true + attach_image("spec/fixtures/files/clippy.jpg") - expect(page).to have_css("input[name='image[title]'][value='clippy.jpg']", visible: false) + expect(find('input#image_title').value).to eq('clippy.jpg') end scenario "Should not update image title with attachment original file name after valid image upload when title already defined by user", :js do @@ -200,10 +199,9 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl imageable_id: imageable.id) fill_in :image_title, with: "My custom title" - attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true + attach_image("spec/fixtures/files/clippy.jpg") - expect(page).to have_selector ".loading-bar.complete" - expect(page).to have_css("input[name='image[title]'][value='My custom title']", visible: false) + expect(find('input#image_title').value).to eq('My custom title') end scenario "Should update image cached_attachment field after valid file upload", :js do @@ -211,7 +209,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/clippy.jpg", make_visible: true + attach_image("spec/fixtures/files/clippy.jpg", true) expect(page).to have_css("input[name='image[cached_attachment]'][value$='clippy.jpg']", visible: false) end @@ -221,7 +219,7 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl visit new_image_path(imageable_type: imageable.class.name, imageable_id: imageable.id) - attach_file :image_attachment, "spec/fixtures/files/logo_header.png", make_visible: true + attach_image("spec/fixtures/files/logo_header.png", false) expect(page).to have_selector ".loading-bar.errors" expect(find("input[name='image[cached_attachment]']", visible: false).value).to eq("") @@ -342,3 +340,12 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl end end + +def attach_image(path, success = true) + attach_file :image_attachment, path, make_visible: true + if success + expect(page).to have_css ".loading-bar.complete" + else + expect(page).to have_css ".loading-bar.errors" + end +end