- <%= form_for(Poll::Question::Answer.new, url: admin_answer_documents_path(answer)) do |f| %>
- <%= render "shared/errors", resource: answer %>
+ <% if can?(:update, @answer) %>
+ <%= form_for(Poll::Question::Answer.new, url: admin_answer_documents_path(answer)) do |f| %>
+ <%= render "shared/errors", resource: answer %>
-
- <%= f.submit(class: "button expanded", value: t("shared.save")) %>
+
+ <%= f.submit(class: "button expanded", value: t("shared.save")) %>
+
+ <% end %>
+ <% else %>
+
+ <%= t("admin.questions.no_edit") %>
<% end %>
@@ -33,17 +39,7 @@
<%= link_to document.title, document.attachment %>
- <%= render Admin::TableActionsComponent.new(document,
- actions: [:destroy],
- destroy_path: document_path(document)
- ) do |actions| %>
- <%= actions.action(:download,
- text: t("documents.buttons.download_document"),
- path: document.attachment,
- target: "_blank",
- rel: "nofollow") %>
-
- <% end %>
+ <%= render Admin::Poll::Questions::Answers::Documents::TableActionsComponent.new(document) %>
|
<% end %>
diff --git a/app/components/admin/poll/questions/answers/documents/index_component.rb b/app/components/admin/poll/questions/answers/documents/index_component.rb
index ca72d4f98..5a46f05da 100644
--- a/app/components/admin/poll/questions/answers/documents/index_component.rb
+++ b/app/components/admin/poll/questions/answers/documents/index_component.rb
@@ -1,5 +1,6 @@
class Admin::Poll::Questions::Answers::Documents::IndexComponent < ApplicationComponent
attr_reader :answer
+ delegate :can?, to: :helpers
def initialize(answer)
@answer = answer
diff --git a/app/components/admin/poll/questions/answers/documents/table_actions_component.html.erb b/app/components/admin/poll/questions/answers/documents/table_actions_component.html.erb
new file mode 100644
index 000000000..f2406512e
--- /dev/null
+++ b/app/components/admin/poll/questions/answers/documents/table_actions_component.html.erb
@@ -0,0 +1,9 @@
+<%= render Admin::TableActionsComponent.new(document,
+ actions: actions,
+ destroy_path: document_path(document)) do |table_actions| %>
+ <%= table_actions.action(:download,
+ text: t("documents.buttons.download_document"),
+ path: document.attachment,
+ target: "_blank",
+ rel: "nofollow") %>
+<% end %>
diff --git a/app/components/admin/poll/questions/answers/documents/table_actions_component.rb b/app/components/admin/poll/questions/answers/documents/table_actions_component.rb
new file mode 100644
index 000000000..38b7a7c08
--- /dev/null
+++ b/app/components/admin/poll/questions/answers/documents/table_actions_component.rb
@@ -0,0 +1,14 @@
+class Admin::Poll::Questions::Answers::Documents::TableActionsComponent < ApplicationComponent
+ attr_reader :document
+ delegate :can?, to: :helpers
+
+ def initialize(document)
+ @document = document
+ end
+
+ private
+
+ def actions
+ [:destroy].select { |action| can?(action, document) }
+ end
+end
diff --git a/app/controllers/admin/poll/questions/answers/documents_controller.rb b/app/controllers/admin/poll/questions/answers/documents_controller.rb
index 3210896d6..eeea65aa6 100644
--- a/app/controllers/admin/poll/questions/answers/documents_controller.rb
+++ b/app/controllers/admin/poll/questions/answers/documents_controller.rb
@@ -8,6 +8,7 @@ class Admin::Poll::Questions::Answers::DocumentsController < Admin::Poll::BaseCo
def create
@answer.attributes = documents_params
+ authorize! :update, @answer
if @answer.save
redirect_to admin_answer_documents_path(@answer),
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 3c94e802e..f6e2bb038 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -124,7 +124,9 @@ module Abilities
cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation, ::Legislation::Proposal]
can [:create], Document
- can [:destroy], Document, documentable_type: "Poll::Question::Answer"
+ can [:destroy], Document do |document|
+ document.documentable_type == "Poll::Question::Answer" && can?(:update, document.documentable)
+ end
can [:create, :destroy], DirectUpload
can [:deliver], Newsletter, hidden_at: nil
diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb
index 264b98521..2da9a057d 100644
--- a/app/models/abilities/common.rb
+++ b/app/models/abilities/common.rb
@@ -71,7 +71,7 @@ module Abilities
can [:create, :destroy], Follow, user_id: user.id
can [:destroy], Document do |document|
- document.documentable&.author_id == user.id
+ document.documentable_type != "Poll::Question::Answer" && document.documentable&.author_id == user.id
end
can [:destroy], Image do |image|
diff --git a/spec/components/admin/poll/questions/answers/documents/index_component_spec.rb b/spec/components/admin/poll/questions/answers/documents/index_component_spec.rb
new file mode 100644
index 000000000..053c37ce5
--- /dev/null
+++ b/spec/components/admin/poll/questions/answers/documents/index_component_spec.rb
@@ -0,0 +1,19 @@
+require "rails_helper"
+
+describe Admin::Poll::Questions::Answers::Documents::IndexComponent do
+ before { sign_in(create(:administrator).user) }
+ let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) }
+ let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) }
+
+ it "displays the 'Add new document' link when the poll has not started" do
+ render_inline Admin::Poll::Questions::Answers::Documents::IndexComponent.new(future_answer)
+
+ expect(page).to have_link "Add new document"
+ end
+
+ it "does not display the 'Add new document' link when the poll has started" do
+ render_inline Admin::Poll::Questions::Answers::Documents::IndexComponent.new(current_answer)
+
+ expect(page).not_to have_link "Add new document"
+ end
+end
diff --git a/spec/components/admin/poll/questions/answers/documents/table_actions_component_spec.rb b/spec/components/admin/poll/questions/answers/documents/table_actions_component_spec.rb
new file mode 100644
index 000000000..2d2261aea
--- /dev/null
+++ b/spec/components/admin/poll/questions/answers/documents/table_actions_component_spec.rb
@@ -0,0 +1,27 @@
+require "rails_helper"
+
+describe Admin::Poll::Questions::Answers::Documents::TableActionsComponent, controller: Admin::BaseController do
+ before { sign_in(create(:administrator).user) }
+ let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) }
+ let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) }
+
+ it "displays the destroy action when the poll has not started" do
+ document = create(:document, documentable: future_answer)
+
+ render_inline Admin::Poll::Questions::Answers::Documents::TableActionsComponent.new(document)
+
+ expect(page).to have_link "Download file"
+ expect(page).to have_button "Delete"
+ expect(page).not_to have_link "Edit"
+ end
+
+ it "does not display the destroy action when the poll has started" do
+ document = create(:document, documentable: current_answer)
+
+ render_inline Admin::Poll::Questions::Answers::Documents::TableActionsComponent.new(document)
+
+ expect(page).to have_link "Download file"
+ expect(page).not_to have_button "Delete"
+ expect(page).not_to have_link "Edit"
+ end
+end
diff --git a/spec/controllers/admin/poll/questions/answers/documents_controller_spec.rb b/spec/controllers/admin/poll/questions/answers/documents_controller_spec.rb
new file mode 100644
index 000000000..84e02f0f6
--- /dev/null
+++ b/spec/controllers/admin/poll/questions/answers/documents_controller_spec.rb
@@ -0,0 +1,35 @@
+require "rails_helper"
+
+describe Admin::Poll::Questions::Answers::DocumentsController, :admin do
+ let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) }
+ let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) }
+
+ describe "POST create" do
+ let(:answer_attributes) do
+ {
+ documents_attributes: {
+ "0" => {
+ attachment: fixture_file_upload("clippy.pdf"),
+ title: "Title",
+ user_id: User.last.id
+ }
+ }
+ }
+ end
+
+ it "is not possible for an already started poll" do
+ post :create, params: { poll_question_answer: answer_attributes, answer_id: current_answer }
+
+ expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Answer."
+ expect(Document.count).to eq 0
+ end
+
+ it "is possible for a not started poll" do
+ post :create, params: { poll_question_answer: answer_attributes, answer_id: future_answer }
+
+ expect(response).to redirect_to admin_answer_documents_path(future_answer)
+ expect(flash[:notice]).to eq "Document uploaded successfully"
+ expect(Document.count).to eq 1
+ end
+ end
+end
diff --git a/spec/controllers/documents_controller_spec.rb b/spec/controllers/documents_controller_spec.rb
new file mode 100644
index 000000000..9b0977034
--- /dev/null
+++ b/spec/controllers/documents_controller_spec.rb
@@ -0,0 +1,28 @@
+require "rails_helper"
+
+describe DocumentsController do
+ describe "DELETE destroy" do
+ context "Poll answers administration", :admin do
+ let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) }
+ let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) }
+
+ it "is not possible for an already started poll" do
+ document = create(:document, documentable: current_answer)
+ delete :destroy, params: { id: document }
+
+ expect(flash[:alert]).to eq "You do not have permission to carry out the action 'destroy' on Document."
+ expect(Document.count).to eq 1
+ end
+
+ it "is possible for a not started poll" do
+ document = create(:document, documentable: future_answer)
+ request.env["HTTP_REFERER"] = admin_answer_documents_path(future_answer)
+ delete :destroy, params: { id: document }
+
+ expect(response).to redirect_to admin_answer_documents_path(future_answer)
+ expect(flash[:notice]).to eq "Document was deleted successfully."
+ expect(Document.count).to eq 0
+ end
+ end
+ end
+end
diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb
index 2eebf28a1..4579aa4c8 100644
--- a/spec/models/abilities/administrator_spec.rb
+++ b/spec/models/abilities/administrator_spec.rb
@@ -26,6 +26,8 @@ describe Abilities::Administrator do
let(:future_poll_answer_video) { create(:poll_answer_video, answer: future_poll_question_answer) }
let(:current_poll_answer_image) { build(:image, imageable: current_poll_question_answer) }
let(:future_poll_answer_image) { build(:image, imageable: future_poll_question_answer) }
+ let(:current_poll_answer_document) { build(:document, documentable: current_poll_question_answer) }
+ let(:future_poll_answer_document) { build(:document, documentable: future_poll_question_answer) }
let(:past_process) { create(:legislation_process, :past) }
let(:past_draft_process) { create(:legislation_process, :past, :not_published) }
@@ -145,6 +147,9 @@ describe Abilities::Administrator do
it { should be_able_to(:destroy, future_poll_answer_image) }
it { should_not be_able_to(:destroy, current_poll_answer_image) }
+ it { should be_able_to(:destroy, future_poll_answer_document) }
+ it { should_not be_able_to(:destroy, current_poll_answer_document) }
+
it { is_expected.to be_able_to :manage, Dashboard::AdministratorTask }
it { is_expected.to be_able_to :manage, dashboard_administrator_task }
diff --git a/spec/system/admin/poll/questions/answers/documents/documents_spec.rb b/spec/system/admin/poll/questions/answers/documents/documents_spec.rb
index 8a3b3e356..d4439e5bb 100644
--- a/spec/system/admin/poll/questions/answers/documents/documents_spec.rb
+++ b/spec/system/admin/poll/questions/answers/documents/documents_spec.rb
@@ -1,6 +1,8 @@
require "rails_helper"
describe "Documents", :admin do
+ let(:future_poll) { create(:poll, :future) }
+
context "Index" do
scenario "Answer with no documents" do
answer = create(:poll_question_answer)
@@ -23,7 +25,7 @@ describe "Documents", :admin do
end
scenario "Create document for answer" do
- answer = create(:poll_question_answer)
+ answer = create(:poll_question_answer, poll: future_poll)
visit admin_answer_documents_path(answer)
@@ -35,7 +37,7 @@ describe "Documents", :admin do
end
scenario "Remove document from answer" do
- answer = create(:poll_question_answer)
+ answer = create(:poll_question_answer, poll: future_poll)
document = create(:document, documentable: answer)
visit admin_answer_documents_path(answer)
@@ -45,6 +47,7 @@ describe "Documents", :admin do
click_button "Delete"
end
+ expect(page).to have_content "Document was deleted successfully."
expect(page).not_to have_content(document.title)
end
end