diff --git a/app/assets/javascripts/documentable.js.coffee b/app/assets/javascripts/documentable.js.coffee
index cf5e3cad1..4dfc9024c 100644
--- a/app/assets/javascripts/documentable.js.coffee
+++ b/app/assets/javascripts/documentable.js.coffee
@@ -6,8 +6,11 @@ App.Documentable =
App.Documentable.initializeDirectUploadInput(input)
if $(nested_document).closest('#nested-documents').find('.document').length >= $('#nested-documents').data('max-documents-allowed')
- $('#max-documents-notice').removeClass('hide')
- $('#new_document_link').addClass('hide')
+ App.Documentable.lockUploads()
+
+ inputFiles = $('.js-document-attachment')
+ $.each inputFiles, (index, input) ->
+ App.Documentable.initializeDirectUploadInput(input)
initializeDirectUploadInput: (input) ->
@@ -108,6 +111,14 @@ App.Documentable =
errors = '' + data.jqXHR.responseJSON.errors + ''
$(data.errorContainer).append(errors)
+ lockUploads: ->
+ $('#max-documents-notice').removeClass('hide')
+ $('#new_document_link').addClass('hide')
+
+ unlockUploads: ->
+ $('#max-documents-notice').addClass('hide')
+ $('#new_document_link').removeClass('hide')
+
doDeleteCachedAttachmentRequest: (url, data) ->
$.ajax
type: "POST"
@@ -122,8 +133,7 @@ App.Documentable =
App.Documentable.clearInputErrors(data)
App.Documentable.clearProgressBar(data)
- $('#new_document_link').removeClass('hide')
- $('#max-documents-notice').addClass('hide')
+ App.Documentable.unlockUploads()
$(data.wrapper).find(".attachment-actions").addClass('small-12').removeClass('small-6 float-right')
$(data.wrapper).find(".attachment-actions .action-remove").addClass('small-3').removeClass('small-12')
@@ -136,8 +146,7 @@ App.Documentable =
$(remove_document_link).on 'click', (e) ->
e.preventDefault()
$(wrapper).remove()
- $('#new_document_link').removeClass('hide')
- $('#max-documents-notice').addClass('hide')
+ App.Documentable.unlockUploads()
initializeRemoveCachedDocumentLink: (input, data) ->
wrapper = $(input).closest(".direct-upload")
@@ -149,3 +158,5 @@ App.Documentable =
destroyNestedDocument: (id) ->
$('#' + id).remove()
+ if $('#nested-documents .document').length < $('#nested-documents').data('max-documents-allowed')
+ App.Documentable.unlockUploads()
diff --git a/app/assets/javascripts/imageable.js.coffee b/app/assets/javascripts/imageable.js.coffee
index 608eb9b1b..2f4e4c791 100644
--- a/app/assets/javascripts/imageable.js.coffee
+++ b/app/assets/javascripts/imageable.js.coffee
@@ -1,12 +1,16 @@
App.Imageable =
initialize: ->
- inputFiles = $('input.js-document-attachment[type=file]')
+ $('#nested-image').on 'cocoon:after-insert', (e, nested_image) ->
+ input = $(nested_image).find('.js-image-attachment')
+ App.Imageable.initializeDirectUploadInput(input)
+ inputFiles = $('.js-image-attachment')
$.each inputFiles, (index, input) ->
App.Imageable.initializeDirectUploadInput(input)
- $("#new_image_link").on 'click', -> $(this).hide()
+ $("#new_image_link").on 'click', ->
+ $(this).addClass('hide')
initializeDirectUploadInput: (input) ->
@@ -52,8 +56,8 @@ App.Imageable =
$(data.addAttachmentLabel).hide()
$(data.wrapper).find(".attachment-actions").removeClass('small-12').addClass('small-6 float-right')
$(data.wrapper).find(".attachment-actions .action-remove").removeClass('small-3').addClass('small-12')
-
App.Imageable.setPreview(data)
+
destroyAttachmentLink = $(data.result.destroy_link)
$(data.destroyAttachmentLinkContainer).html(destroyAttachmentLink)
$(destroyAttachmentLink).on 'click', (e) ->
@@ -80,8 +84,8 @@ App.Imageable =
data.fileNameContainer = $(wrapper).find('p.file-name')
data.destroyAttachmentLinkContainer = $(wrapper).find('.action-remove')
data.addAttachmentLabel = $(wrapper).find('.action-add label')
- data.cachedAttachmentField = $(wrapper).find("#" + $(input).data('cached-attachment-input-field'))
- data.titleField = $(wrapper).find("#" + $(input).data('title-input-field'))
+ data.cachedAttachmentField = $(wrapper).find("input[name$='[cached_attachment]']")
+ data.titleField = $(wrapper).find("input[name$='[title]']")
$(wrapper).find('.progress-bar-placeholder').css('display', 'block')
return data
@@ -114,7 +118,6 @@ App.Imageable =
$(data.errorContainer).append(errors)
setPreview: (data) ->
- console.log 'App.Imageable.setPreview'
image_preview = '

'
if $(data.preview).length > 0
$(data.preview).replaceWith(image_preview)
@@ -122,13 +125,6 @@ App.Imageable =
$(image_preview).insertBefore($(data.wrapper).find(".attachment-actions"))
data.preview = $(data.wrapper).find('.image-preview')
- watchRemoveImagebutton: (wrapper) ->
- remove_image_button = $(wrapper).find('a.delete[href="#"]')
- $(remove_image_button).on 'click', (e) ->
- e.preventDefault()
- $(wrapper).remove()
- $('#new_image_link').show()
-
doDeleteCachedAttachmentRequest: (url, data) ->
$.ajax
type: "POST"
@@ -144,9 +140,10 @@ App.Imageable =
App.Imageable.clearProgressBar(data)
App.Imageable.clearPreview(data)
+ $('#new_image_link').removeClass('hide')
+
if $(data.input).data('nested-image') == true
$(data.wrapper).remove()
- $('#new_image_link').show()
else
$(data.destroyAttachmentLinkContainer).find('a.delete').remove()
@@ -156,7 +153,7 @@ App.Imageable =
$(remove_image_link).on 'click', (e) ->
e.preventDefault()
$(wrapper).remove()
- $('#new_image_link').show()
+ $('#new_image_link').removeClass('hide')
initializeRemoveCachedImageLink: (input, data) ->
wrapper = $(input).closest(".direct-upload")
@@ -166,37 +163,6 @@ App.Imageable =
e.stopPropagation()
App.Imageable.doDeleteCachedAttachmentRequest(this.href, data)
- new: (nested_field) ->
- nested_field = $(nested_field)
- $(".images-list").append(nested_field)
- input = nested_field.find("input[type='file']")
- @initializeDirectUploadInput(input)
- $("#new_image_link").hide()
-
destroyNestedImage: (id, notice) ->
$('#' + id).remove()
- $("#new_image_link").show()
- @updateNotice(notice)
-
- replacePlainImage: (id, notice, plain_image) ->
- $('#' + id).replaceWith(plain_image)
- @updateNotice(notice)
- @initialize()
-
- updateNotice: (notice) ->
- if $('[data-alert]').length > 0
- $('[data-alert]').replaceWith(notice)
- else
- $("body").append(notice)
-
- updateNewImageButton: (link) ->
- if $('.image').length >= $('.images').data('max-images')
- $('#new_image_link').hide()
- $('.max-images-notice').removeClass('hide')
- $('.max-images-notice').show()
- else if $('#new_image_link').length > 0
- $('#new_image_link').replaceWith(link)
- $('.max-images-notice').hide()
- else
- $('.max-images-notice').hide()
- $(link).insertBefore('.images hr:last')
+ $("#new_image_link").removeClass('hide')
diff --git a/app/assets/stylesheets/mixins.scss b/app/assets/stylesheets/mixins.scss
index 102401d80..58de36b74 100644
--- a/app/assets/stylesheets/mixins.scss
+++ b/app/assets/stylesheets/mixins.scss
@@ -77,7 +77,8 @@
margin-bottom: 0;
}
}
- .js-document-attachment{
+ input.js-document-attachment,
+ input.js-image-attachment{
display: none;
}
}
diff --git a/app/controllers/images_controller.rb b/app/controllers/images_controller.rb
index 870570ed7..5af4dcf60 100644
--- a/app/controllers/images_controller.rb
+++ b/app/controllers/images_controller.rb
@@ -1,7 +1,7 @@
class ImagesController < ApplicationController
before_action :authenticate_user!
before_filter :find_imageable, except: :destroy
- before_filter :prepare_new_image, only: [:new, :new_nested]
+ before_filter :prepare_new_image, only: [:new]
before_filter :prepare_image_for_creation, only: :create
load_and_authorize_resource
@@ -9,9 +9,6 @@ class ImagesController < ApplicationController
def new
end
- def new_nested
- end
-
def create
recover_attachments_from_cache
diff --git a/app/helpers/documents_helper.rb b/app/helpers/documents_helper.rb
index 8ead51f8c..ba816ff5f 100644
--- a/app/helpers/documents_helper.rb
+++ b/app/helpers/documents_helper.rb
@@ -46,23 +46,19 @@ module DocumentsHelper
end
def render_attachment(builder, document)
- html = builder.file_field :attachment,
- label: false,
- accept: accepted_content_types_extensions(document.documentable_type.constantize),
- class: 'js-document-attachment',
- data: {
- url: document_direct_upload_url(document),
- nested_document: true
- }
- if document.attachment.blank? && document.cached_attachment.blank?
- klass = document.errors[:attachment].any? ? "error" : ""
- html += builder.label :attachment, t("documents.upload_document"), class: "button hollow"
- if document.errors[:attachment].any?
- html += content_tag :small, class: "error" do
- document_errors_on_attachment(document)
- end
- end
- end
+ klass = document.errors[:attachment].any? ? "error" : ""
+ klass = document.persisted? ? " hide" : ""
+ html = builder.label :attachment,
+ t("documents.upload_document"),
+ class: "button hollow #{klass}"
+ html += builder.file_field :attachment,
+ label: false,
+ accept: accepted_content_types_extensions(document.documentable_type.constantize),
+ class: 'js-document-attachment',
+ data: {
+ url: document_direct_upload_url(document),
+ nested_document: true
+ }
html
end
diff --git a/app/helpers/images_helper.rb b/app/helpers/images_helper.rb
index 9596f1a82..8b9d15be6 100644
--- a/app/helpers/images_helper.rb
+++ b/app/helpers/images_helper.rb
@@ -31,22 +31,8 @@ module ImagesHelper
bytes / Numeric::MEGABYTE
end
- def image_nested_field_name(image, field)
- parent = image.imageable_type.parameterize.underscore
- "#{parent.parameterize}[image_attributes]#{field}"
- end
-
- def image_nested_field_id(image, field)
- parent = image.imageable_type.parameterize.underscore
- "#{parent.parameterize}_image_attributes_#{field}"
- end
-
- def image_nested_field_wrapper_id
- "nested_image"
- end
-
def image_class(image)
- image.persisted? ? "image" : "cached-image"
+ image.persisted? ? "persisted-image" : "cached-image"
end
def render_destroy_image_link(image)
@@ -59,10 +45,10 @@ module ImagesHelper
class: "delete remove-image"
elsif !image.persisted? && image.cached_attachment.present?
link_to t('images.form.delete_button'),
- destroy_upload_images_path(path: image.cached_attachment,
- nested_image: true,
- imageable_type: image.imageable_type,
- imageable_id: image.imageable_id),
+ 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 remove-cached-attachment"
@@ -73,30 +59,21 @@ module ImagesHelper
end
end
- def render_image_attachment(image)
- html = file_field_tag :attachment,
- accept: imageable_accepted_content_types_extensions,
- class: 'js-document-attachment',
- data: {
- url: image_direct_upload_url(image),
- cached_attachment_input_field: image_nested_field_id(image, :cached_attachment),
- title_input_field: image_nested_field_id(image, :title),
- multiple: false,
- nested_image: true
- },
- name: image_nested_field_name(image, :attachment),
- id: image_nested_field_id(image, :attachment)
- if image.attachment.blank? && image.cached_attachment.blank?
- klass = image.errors[:attachment].any? ? "error" : ""
- html += label_tag image_nested_field_id(image, :attachment),
- t("images.form.attachment_label"),
- class: "button hollow #{klass}"
- if image.errors[:attachment].any?
- html += content_tag :small, class: "error" do
- image_errors_on_attachment(image)
- end
- end
- end
+ def render_image_attachment(builder, imageable, image)
+ klass = image.errors[:attachment].any? ? "error" : ""
+ klass = image.persisted? ? " hide" : ""
+ html = builder.label :attachment,
+ t("images.form.attachment_label"),
+ class: "button hollow #{klass}"
+ html += builder.file_field :attachment,
+ label: false,
+ accept: imageable_accepted_content_types_extensions,
+ class: 'js-image-attachment',
+ data: {
+ url: image_direct_upload_url(imageable),
+ nested_image: true
+ }
+
html
end
@@ -107,9 +84,9 @@ module ImagesHelper
show_caption: show_caption }
end
- def image_direct_upload_url(image)
- direct_uploads_url("direct_upload[resource_type]": image.imageable_type,
- "direct_upload[resource_id]": image.imageable_id,
+ def image_direct_upload_url(imageable)
+ direct_uploads_url("direct_upload[resource_type]": imageable.class.name,
+ "direct_upload[resource_id]": imageable.id,
"direct_upload[resource_relation]": "image")
end
diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb
index da34dd65b..b4248c3b6 100644
--- a/app/models/abilities/common.rb
+++ b/app/models/abilities/common.rb
@@ -38,10 +38,8 @@ module Abilities
can [:create, :destroy], Follow
can [:create, :destroy, :new], Document, documentable: { author_id: user.id }
- can [:upload, :destroy_upload], Document
can [:create, :destroy, :new], Image, imageable: { author_id: user.id }
- can [:new_nested, :upload, :destroy_upload], Image
can [:create, :destroy], DirectUpload
diff --git a/app/models/concerns/imageable.rb b/app/models/concerns/imageable.rb
index 04a4ba3a3..a2a2f537d 100644
--- a/app/models/concerns/imageable.rb
+++ b/app/models/concerns/imageable.rb
@@ -5,7 +5,7 @@ module Imageable
included do
has_one :image, as: :imageable, dependent: :destroy
- accepts_nested_attributes_for :image, allow_destroy: true
+ accepts_nested_attributes_for :image, allow_destroy: true, update_only: true
def image_url(style)
image.attachment.url(style) if image && image.attachment.exists?
diff --git a/app/views/budgets/investments/_form.html.erb b/app/views/budgets/investments/_form.html.erb
index 300635e5d..0d0bdd7f1 100644
--- a/app/views/budgets/investments/_form.html.erb
+++ b/app/views/budgets/investments/_form.html.erb
@@ -22,7 +22,7 @@
- <%= render 'images/nested_images', imageable: @investment %>
+ <%= render 'images/nested_image', imageable: @investment, f: f %>
diff --git a/app/views/documents/_nested_documents.html.erb b/app/views/documents/_nested_documents.html.erb
index a186a7f95..ecbe46ce7 100644
--- a/app/views/documents/_nested_documents.html.erb
+++ b/app/views/documents/_nested_documents.html.erb
@@ -10,13 +10,8 @@
<%= link_to_add_association t('documents.form.add_new_document'), f, :documents,
partial: "documents/document_fields",
- render_options: {
- locals: {
- document: Document.new(documentable: documentable)
- },
- },
id: "new_document_link",
- class: "button hollow",
+ class: "button hollow #{"hide" if documentable.documents.count >= documentable.class.max_documents_allowed}",
data: {
association_insertion_node: "#nested-documents",
association_insertion_method: "append"
diff --git a/app/views/images/_form.html.erb b/app/views/images/_form.html.erb
index b44940f94..8f8cd6995 100644
--- a/app/views/images/_form.html.erb
+++ b/app/views/images/_form.html.erb
@@ -24,7 +24,7 @@
<%= f.file_field :attachment,
accept: imageable_accepted_content_types_extensions,
label: false,
- class: 'js-document-attachment',
+ class: 'js-image-attachment',
data: {
url: direct_uploads_url("direct_upload[resource_type]": @image.imageable_type,
"direct_upload[resource_id]": @image.imageable_id,
diff --git a/app/views/images/_image_fields.html.erb b/app/views/images/_image_fields.html.erb
new file mode 100644
index 000000000..43a79a2c2
--- /dev/null
+++ b/app/views/images/_image_fields.html.erb
@@ -0,0 +1,31 @@
+
+ <%= f.hidden_field :id %>
+ <%= f.hidden_field :user_id, value: current_user.id %>
+ <%= f.hidden_field :cached_attachment %>
+
+
+ <%= f.text_field :title, placeholder: t("images.new.form.title_placeholder") %>
+
+
+ <%= render_image(f.object, :thumb, false) if f.object.attachment.exists? %>
+
+
+
+ <%= render_image_attachment(f, imageable, f.object) %>
+
+
+ <%= render_destroy_image_link(f.object) %>
+
+
+
+
+
+ <%= image_attachment_file_name(f.object) %>
+
+
+
+
+
+
diff --git a/app/views/images/_nested_fields.html.erb b/app/views/images/_nested_fields.html.erb
deleted file mode 100644
index 73afa44ee..000000000
--- a/app/views/images/_nested_fields.html.erb
+++ /dev/null
@@ -1,51 +0,0 @@
-
- <%= hidden_field_tag :id,
- image.id,
- name: image_nested_field_name(image, :id),
- id: image_nested_field_id(image, :id) if image.persisted? %>
- <%= hidden_field_tag :user_id,
- current_user.id,
- name: image_nested_field_name(image, :user_id),
- id: image_nested_field_id(image, :user_id) %>
- <%= hidden_field_tag :cached_attachment,
- image.cached_attachment,
- name: image_nested_field_name(image, :cached_attachment),
- id: image_nested_field_id(image, :cached_attachment) %>
-
-
- <%= label_tag :title,
- t("activerecord.attributes.image.title"),
- class: image.errors[:title].any? ? "error" : "" %>
-
- <%= text_field_tag :title,
- image.title,
- placeholder: t("images.new.form.title_placeholder"),
- name: image_nested_field_name(image, :title),
- id: image_nested_field_id(image, :title),
- class: image.errors[:title].any? ? "error" : "" %>
- <% if image.errors[:title].any? %>
- <%= image.errors[:title].join(", ") %>
- <% end %>
-
-
- <%= render_image(image, :thumb, false) if image.attachment.exists? %>
-
-
-
- <%= render_image_attachment(image) %>
-
-
- <%= render_destroy_image_link(image) %>
-
-
-
-
-
- <%= image_attachment_file_name(image) %>
-
-
-
-
-
diff --git a/app/views/images/_nested_image.html.erb b/app/views/images/_nested_image.html.erb
new file mode 100644
index 000000000..a981dd190
--- /dev/null
+++ b/app/views/images/_nested_image.html.erb
@@ -0,0 +1,25 @@
+
+ <%= f.label :image, t("images.form.title") %>
+
<%= imageables_note(imageable) %>
+
+
+ <%= f.fields_for :image do |image_builder| %>
+ <%= render 'images/image_fields', f: image_builder, imageable: imageable %>
+ <% end %>
+
+
+
+<%= link_to_add_association t('images.form.add_new_image'), f, :image,
+ force_non_association_create: true,
+ partial: "images/image_fields",
+ id: "new_image_link",
+ class: "button hollow #{"hide" if imageable.image.present?}",
+ render_options: {
+ locals: { imageable: imageable }
+ },
+ data: {
+ association_insertion_node: "#nested-image",
+ association_insertion_method: "append"
+ } %>
+
+
diff --git a/app/views/images/_nested_images.html.erb b/app/views/images/_nested_images.html.erb
deleted file mode 100644
index 31c8ba417..000000000
--- a/app/views/images/_nested_images.html.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-
- <%= label_tag :image, t("images.form.title") %>
-
<%= imageables_note(imageable) %>
-
- <%= render 'images/nested_fields', image: imageable.image, index: 0 if imageable.image.present? %>
-
-
-<% if imageable.image.blank? %>
- <%= link_to t("images.form.add_new_image"),
- new_nested_images_path(imageable_type: imageable.class.name, index: 0),
- remote: true,
- id: "new_image_link",
- class: "button hollow" %>
-<% end %>
-
-
diff --git a/app/views/images/destroy.js.erb b/app/views/images/destroy.js.erb
index fddb55300..0fdac4b76 100644
--- a/app/views/images/destroy.js.erb
+++ b/app/views/images/destroy.js.erb
@@ -1,7 +1 @@
-App.Imageable.destroyNestedImage("<%= image_nested_field_wrapper_id %>", "<%= j render('layouts/flash') %>")
-<% new_image_link = link_to t("images.form.add_new_image"),
- new_nested_images_path(imageable_type: @image.imageable_type),
- remote: true,
- id: "new_image_link",
- class: "button hollow" %>
-App.Imageable.updateNewImageButton("<%= j new_image_link %>")
+App.Imageable.destroyNestedImage("<%= dom_id(@image) %>")
\ No newline at end of file
diff --git a/app/views/images/new_nested.js.erb b/app/views/images/new_nested.js.erb
deleted file mode 100644
index 00c00b132..000000000
--- a/app/views/images/new_nested.js.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-App.Imageable.new("<%= j render('images/nested_fields', image: @image) %>")
-App.DirectUploads.initializeDirectUpload($('#nested_image input.direct_upload_attachment[type=file]'))
\ No newline at end of file
diff --git a/app/views/images/upload.js.erb b/app/views/images/upload.js.erb
deleted file mode 100644
index 9177a35cd..000000000
--- a/app/views/images/upload.js.erb
+++ /dev/null
@@ -1,12 +0,0 @@
-<% if params[:nested_image] == "true" %>
-
- App.Imageable.uploadNestedImage("<%= image_nested_field_wrapper_id %>",
- "<%= j render('images/nested_fields', image: @image) %>",
- <%= @image.cached_attachment.present? %>)
-<% else %>
-
- App.Imageable.uploadPlainImage("plain_image_fields",
- "<%= j render('images/plain_fields', image: @image) %>",
- <%= @image.cached_attachment.present? %>)
-
-<% end %>
\ No newline at end of file
diff --git a/app/views/proposals/_form.html.erb b/app/views/proposals/_form.html.erb
index 16855cc03..df1e096e9 100644
--- a/app/views/proposals/_form.html.erb
+++ b/app/views/proposals/_form.html.erb
@@ -47,7 +47,7 @@
- <%= render 'images/nested_images', imageable: @proposal %>
+ <%= render 'images/nested_image', imageable: @proposal, f: f %>
diff --git a/config/routes.rb b/config/routes.rb
index 8be1a8a7a..14a8faf19 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -102,9 +102,7 @@ Rails.application.routes.draw do
resources :documents, only: [:new, :create, :destroy]
- resources :images, only: [:new, :create, :destroy] do
- get :new_nested, on: :collection
- end
+ resources :images, only: [:new, :create, :destroy]
resources :direct_uploads, only: [:create]
delete "direct_uploads/destroy", to: "direct_uploads#destroy", as: :direct_upload_destroy
diff --git a/spec/shared/features/imageable.rb b/spec/shared/features/imageable.rb
index 3030869d3..a6e5ae4ae 100644
--- a/spec/shared/features/imageable.rb
+++ b/spec/shared/features/imageable.rb
@@ -159,6 +159,8 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
attach_image("spec/fixtures/files/clippy.jpg", true)
+ expect(page).to have_selector ".loading-bar.complete"
+
expect(page).to have_css("figure img")
expect(page).not_to have_css("figure figcaption")
end
@@ -342,7 +344,9 @@ shared_examples "imageable" do |imageable_factory_name, imageable_path, imageabl
end
def attach_image(path, success = true)
- attach_file :image_attachment, path, make_visible: true
+ image = find(".image")
+ image_input = image.find("input[type=file]", visible: false)
+ attach_file image_input[:id], path, make_visible: true
if success
expect(page).to have_css ".loading-bar.complete"
else
diff --git a/spec/shared/features/nested_documentable.rb b/spec/shared/features/nested_documentable.rb
index 09c706d1f..cadc7d2da 100644
--- a/spec/shared/features/nested_documentable.rb
+++ b/spec/shared/features/nested_documentable.rb
@@ -195,21 +195,28 @@ shared_examples "nested documentable" do |documentable_factory_name, path, docum
end
scenario "Should show resource with new document after successful creation with maximum allowed uploaded files", :js do
- skip "weird behavior"
- # page.driver.resize_window 1200, 2500
+ skip "due to weird behaviour"
+ page.driver.resize_window 1200, 2500
login_as user
visit send(path, arguments)
send(fill_resource_method_name) if fill_resource_method_name
- documentable.class.max_documents_allowed.times.each do |index|
- documentable_attach_new_file(documentable_factory_name, index , "spec/fixtures/files/empty.pdf")
- end
+ click_link "Add new document"
+ click_link "Add new document"
+ click_link "Add new document"
+ documents = all(".document")
+ documents.each_with_index do |document, index|
+ document_input = document.find("input[type=file]", visible: false)
+ attach_file(document_input[:id], "spec/fixtures/files/empty.pdf", make_visible: true)
+ within all(".document")[index] do
+ expect(page).to have_css ".loading-bar.complete"
+ end
+ end
click_on submit_button
documentable_redirected_to_resource_show_or_navigate_to
- save_screenshot
expect(page).to have_content "Documents (#{documentable.class.max_documents_allowed})"
end
@@ -223,6 +230,26 @@ shared_examples "nested documentable" do |documentable_factory_name, path, docum
expect(page).to have_css ".document", count: 1
end
+ scenario "Should not show add document button when documentable has reached maximum of documents allowed", :js do
+ login_as user
+ create_list(:document, documentable.class.max_documents_allowed, documentable: documentable)
+ visit send(path, arguments)
+
+ expect(page).to have_css "#new_document_link", visible: false
+ end
+
+ scenario "Should show add document button after destroy one document", :js do
+ login_as user
+ create_list(:document, documentable.class.max_documents_allowed, documentable: documentable)
+ visit send(path, arguments)
+ last_document = all("#nested-documents .document").last
+ within last_document do
+ click_on "Remove document"
+ end
+
+ expect(page).to have_css "#new_document_link", visible: true
+ end
+
scenario "Should remove nested field after remove document", :js do
login_as user
create(:document, documentable: documentable)
diff --git a/spec/shared/features/nested_imageable.rb b/spec/shared/features/nested_imageable.rb
index ebbe4f9a2..242686bd6 100644
--- a/spec/shared/features/nested_imageable.rb
+++ b/spec/shared/features/nested_imageable.rb
@@ -27,16 +27,24 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
expect(page).to have_selector "#new_image_link", visible: true
end
+ scenario "Should hide new image link after add one image" do
+ login_as user
+ visit send(path, arguments)
+
+ click_on "Add image"
+
+ expect(page).to have_selector "#new_image_link", visible: true
+ end
+
scenario "Should update nested image file name after choosing any file", :js do
login_as user
visit send(path, arguments)
click_link "Add image"
- # next line is to force capybara to wait for ajax response and new DOM elements rendering
- find("input[name='#{imageable_factory_name}[image_attributes]attachment']", visible: false)
- attach_file("#{imageable_factory_name}[image_attributes]attachment", "spec/fixtures/files/empty.pdf", make_visible: true)
+ image_input = find(".image").find("input[type=file]", visible: false)
+ attach_file(image_input[:id], "spec/fixtures/files/clippy.jpg", make_visible: true)
- expect(page).to have_selector ".file-name", text: "empty.pdf"
+ expect(page).to have_selector ".file-name", text: "clippy.jpg"
end
scenario "Should update nested image file title with file name after choosing a file when no title defined", :js do
@@ -45,7 +53,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
imageable_attach_new_file(imageable_factory_name, "spec/fixtures/files/clippy.jpg")
- expect(find("##{imageable_factory_name}_image_attributes_title").value).to eq("clippy.jpg")
+ expect_image_has_title("clippy.jpg")
end
scenario "Should not update nested image file title with file name after choosing a file when title already defined", :js do
@@ -53,10 +61,10 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
visit send(path, arguments)
click_link "Add image"
- fill_in "#{imageable_factory_name}[image_attributes]title", with: "Title"
- attach_file("#{imageable_factory_name}[image_attributes]attachment", "spec/fixtures/files/empty.pdf", make_visible: true)
- # force capybara to wait for AJAX response to ensure new input has correct value after direct upload
- have_css(".loading-bar.complete")
+ input_title = find(".image input[name$='[title]']")
+ fill_in input_title[:id], with: "Title"
+ image_input = find(".image").find("input[type=file]", visible: false)
+ attach_file(image_input[:id], "spec/fixtures/files/clippy.jpg", make_visible: true)
expect(find("##{imageable_factory_name}_image_attributes_title").value).to eq "Title"
end
@@ -85,7 +93,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
imageable_attach_new_file(imageable_factory_name, "spec/fixtures/files/clippy.jpg")
- expect(page).to have_selector("input[name='#{imageable_factory_name}[image_attributes]cached_attachment'][value$='.jpg']", visible: false)
+ expect_image_has_cached_attachment(".jpg")
end
scenario "Should not update image cached_attachment field after unvalid file upload", :js do
@@ -94,7 +102,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
imageable_attach_new_file(imageable_factory_name, "spec/fixtures/files/logo_header.png", false)
- expect(find("input[name='#{imageable_factory_name}[image_attributes]cached_attachment']", visible: false).value).to eq ""
+ expect_image_has_cached_attachment("")
end
scenario "Should show nested image errors after unvalid form submit", :js do
@@ -102,34 +110,23 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
visit send(path, arguments)
click_link "Add image"
- find("input[id$='_image_attributes_title']") # force to wait for ajax response new DOM elements
click_on submit_button
- expect(page).to have_css("#nested_image .error")
+ within "#nested-image .image" do
+ expect(page).to have_content("can't be blank", count: 2)
+ end
end
- scenario "Should delete image after valid file upload and click on remove button", :js do
+ scenario "Should remove nested image after valid file upload and click on remove button", :js do
login_as user
visit send(path, arguments)
imageable_attach_new_file(imageable_factory_name, "spec/fixtures/files/clippy.jpg")
- within "#nested_image" do
+ within "#nested-image .image" do
click_link "Remove image"
end
- expect(page).not_to have_selector("#nested_image")
- end
-
- scenario "Should delete image after valid file upload and click on remove button", :js do
- login_as user
- visit send(path, arguments)
-
- imageable_attach_new_file(imageable_factory_name, "spec/fixtures/files/clippy.jpg")
- within "#nested_image" do
- click_link "Remove image"
- end
-
- expect(page).not_to have_css "#nested_image"
+ expect(page).not_to have_selector("#nested-image .image")
end
scenario "Should show successful notice when resource filled correctly without any nested images", :js do
@@ -162,10 +159,48 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
click_on submit_button
imageable_redirected_to_resource_show_or_navigate_to
- expect(page).to have_selector "figure .image"
+ expect(page).to have_selector "figure img"
expect(page).to have_selector "figure figcaption"
end
+ if path.include? "edit"
+
+ scenario "Should show persisted image" do
+ login_as user
+ create(:image, imageable: imageable)
+ visit send(path, arguments)
+
+ expect(page).to have_css ".image", count: 1
+ end
+
+ scenario "Should not show add image button when image already exists", :js do
+ login_as user
+ create(:image, imageable: imageable)
+ visit send(path, arguments)
+
+ expect(page).to have_css "a#new_image_link", visible: false
+ end
+
+ scenario "Should remove nested field after remove image", :js do
+ login_as user
+ create(:image, imageable: imageable)
+ visit send(path, arguments)
+ click_on "Remove image"
+
+ expect(page).not_to have_css ".image"
+ end
+
+ scenario "Should show add image button after remove image", :js do
+ login_as user
+ create(:image, imageable: imageable)
+ visit send(path, arguments)
+ click_on "Remove image"
+
+ expect(page).to have_css "a#new_image_link", visible: true
+ end
+
+ end
+
end
end
@@ -179,14 +214,17 @@ end
def imageable_attach_new_file(imageable_factory_name, path, success = true)
click_link "Add image"
- # next line is to force capybara to wait for ajax response and new DOM elements rendering
- find("input[name='#{imageable_factory_name}[image_attributes]attachment']", visible: false)
- attach_file("#{imageable_factory_name}[image_attributes]attachment", path, make_visible: true)
- # next line is to force capybara to wait for ajax response and new DOM elements rendering
- if success
- expect(page).to have_css(".loading-bar.complete")
- else
- expect(page).to have_css(".loading-bar.errors")
+ within "#nested-image" do
+ image = find(".image")
+ image_input = image.find("input[type=file]", visible: false)
+ attach_file(image_input[:id], path, make_visible: true)
+ within image do
+ if success
+ expect(page).to have_css(".loading-bar.complete")
+ else
+ expect(page).to have_css(".loading-bar.errors")
+ end
+ end
end
end
@@ -202,4 +240,22 @@ def imageable_fill_new_valid_budget_investment
fill_in :budget_investment_title, with: "Budget investment title"
fill_in_ckeditor "budget_investment_description", with: "Budget investment description"
check :budget_investment_terms_of_service
+end
+
+def expect_image_has_title(title)
+ image = find(".image")
+
+ within image do
+ expect(find("input[name$='[title]']").value).to eq 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: false).value).to end_with(extension)
+ end
+ end
end
\ No newline at end of file