diff --git a/app/components/admin/poll/questions/answers/videos/table_actions_component.html.erb b/app/components/admin/poll/questions/answers/videos/table_actions_component.html.erb
new file mode 100644
index 000000000..f799eae21
--- /dev/null
+++ b/app/components/admin/poll/questions/answers/videos/table_actions_component.html.erb
@@ -0,0 +1 @@
+<%= render Admin::TableActionsComponent.new(video, actions: actions) %>
diff --git a/app/components/admin/poll/questions/answers/videos/table_actions_component.rb b/app/components/admin/poll/questions/answers/videos/table_actions_component.rb
new file mode 100644
index 000000000..935cd5c80
--- /dev/null
+++ b/app/components/admin/poll/questions/answers/videos/table_actions_component.rb
@@ -0,0 +1,14 @@
+class Admin::Poll::Questions::Answers::Videos::TableActionsComponent < ApplicationComponent
+ attr_reader :video
+ delegate :can?, to: :helpers
+
+ def initialize(video)
+ @video = video
+ end
+
+ private
+
+ def actions
+ [:edit, :destroy].select { |action| can?(action, video) }
+ end
+end
diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb
index 07f26a649..ee323ef80 100644
--- a/app/models/abilities/administrator.rb
+++ b/app/models/abilities/administrator.rb
@@ -99,7 +99,10 @@ module Abilities
can [:create, :update, :destroy], Poll::Question::Answer do |answer|
can?(:update, answer.question)
end
- can :manage, Poll::Question::Answer::Video
+ can :read, Poll::Question::Answer::Video
+ can [:create, :update, :destroy], Poll::Question::Answer::Video do |video|
+ can?(:update, video.answer)
+ end
can [:create, :destroy], Image do |image|
image.imageable_type == "Poll::Question::Answer"
end
diff --git a/app/views/admin/poll/questions/answers/videos/index.html.erb b/app/views/admin/poll/questions/answers/videos/index.html.erb
index bd436d88a..c9e82498a 100644
--- a/app/views/admin/poll/questions/answers/videos/index.html.erb
+++ b/app/views/admin/poll/questions/answers/videos/index.html.erb
@@ -6,9 +6,15 @@
<%= t("admin.answers.videos.index.title") %>
-<%= link_to t("admin.answers.videos.index.add_video"),
- new_admin_answer_video_path(@answer),
- class: "button success float-right" %>
+<% if can?(:create, Poll::Question::Answer.new(question: @answer.question)) %>
+ <%= link_to t("admin.answers.videos.index.add_video"),
+ new_admin_answer_video_path(@answer),
+ class: "button success float-right" %>
+<% else %>
+
+ <%= t("admin.questions.no_edit") %>
+
+<% end %>
@@ -27,7 +33,7 @@
<%= video.title %> |
<%= link_to video.url, video.url %> |
- <%= render Admin::TableActionsComponent.new(video) %>
+ <%= render Admin::Poll::Questions::Answers::Videos::TableActionsComponent.new(video) %>
|
<% end %>
diff --git a/spec/components/admin/poll/questions/answers/videos/table_actions_component_spec.rb b/spec/components/admin/poll/questions/answers/videos/table_actions_component_spec.rb
new file mode 100644
index 000000000..e8449103d
--- /dev/null
+++ b/spec/components/admin/poll/questions/answers/videos/table_actions_component_spec.rb
@@ -0,0 +1,23 @@
+require "rails_helper"
+
+describe Admin::Poll::Questions::Answers::Videos::TableActionsComponent, controller: Admin::BaseController do
+ before { sign_in(create(:administrator).user) }
+
+ it "displays the edit and destroy actions when the poll has not started" do
+ video = create(:poll_answer_video, poll: create(:poll, :future))
+
+ render_inline Admin::Poll::Questions::Answers::Videos::TableActionsComponent.new(video)
+
+ expect(page).to have_link "Edit"
+ expect(page).to have_button "Delete"
+ end
+
+ it "does not display the edit and destroy actions when the poll has started" do
+ video = create(:poll_answer_video, poll: create(:poll))
+
+ render_inline Admin::Poll::Questions::Answers::Videos::TableActionsComponent.new(video)
+
+ expect(page).not_to have_link "Edit"
+ expect(page).not_to have_button "Delete"
+ end
+end
diff --git a/spec/controllers/admin/poll/questions/answers/videos_controller_spec.rb b/spec/controllers/admin/poll/questions/answers/videos_controller_spec.rb
new file mode 100644
index 000000000..65c5dc1f8
--- /dev/null
+++ b/spec/controllers/admin/poll/questions/answers/videos_controller_spec.rb
@@ -0,0 +1,87 @@
+require "rails_helper"
+
+describe Admin::Poll::Questions::Answers::VideosController, :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
+ it "is not possible for an already started poll" do
+ post :create, params: {
+ poll_question_answer_video: {
+ title: "Video from started poll",
+ url: "https://www.youtube.com/watch?v=-JMf43st-1A"
+ },
+ answer_id: current_answer
+ }
+
+ expect(flash[:alert]).to eq "You do not have permission to carry out the action 'create' on Video."
+ expect(Poll::Question::Answer::Video.count).to eq 0
+ end
+
+ it "is possible for a not started poll" do
+ post :create, params: {
+ poll_question_answer_video: {
+ title: "Video from not started poll",
+ url: "https://www.youtube.com/watch?v=-JMf43st-1A"
+ },
+ answer_id: future_answer
+ }
+
+ expect(response).to redirect_to admin_answer_videos_path(future_answer)
+ expect(flash[:notice]).to eq "Video created successfully"
+ expect(Poll::Question::Answer::Video.count).to eq 1
+ end
+ end
+
+ describe "PATCH update" do
+ it "is not possible for an already started poll" do
+ current_video = create(:poll_answer_video, answer: current_answer, title: "Sample title")
+
+ patch :update, params: {
+ poll_question_answer_video: {
+ title: "New title"
+ },
+ id: current_video,
+ answer_id: current_answer
+ }
+
+ expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Video."
+ expect(current_video.reload.title).to eq "Sample title"
+ end
+
+ it "is possible for a not started poll" do
+ future_video = create(:poll_answer_video, answer: future_answer)
+
+ patch :update, params: {
+ poll_question_answer_video: {
+ title: "New title"
+ },
+ id: future_video,
+ answer_id: future_answer
+ }
+
+ expect(response).to redirect_to admin_answer_videos_path(future_answer)
+ expect(flash[:notice]).to eq "Changes saved"
+ expect(future_video.reload.title).to eq "New title"
+ end
+ end
+
+ describe "DELETE destroy" do
+ it "is not possible for an already started poll" do
+ current_video = create(:poll_answer_video, answer: current_answer)
+ delete :destroy, params: { answer_id: current_answer, id: current_video }
+
+ expect(flash[:alert]).to eq "You do not have permission to carry out the action 'destroy' on Video."
+ expect(Poll::Question::Answer::Video.count).to eq 1
+ end
+
+ it "is possible for a not started poll" do
+ future_video = create(:poll_answer_video, answer: future_answer)
+ delete :destroy, params: { answer_id: future_answer, id: future_video }
+
+ expect(response).to redirect_to admin_answer_videos_path(future_answer)
+ expect(flash[:notice]).to eq "Answer video deleted successfully."
+ expect(Poll::Question::Answer::Video.count).to eq 0
+ end
+ end
+end
diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb
index 853fcee82..289407fd4 100644
--- a/spec/models/abilities/administrator_spec.rb
+++ b/spec/models/abilities/administrator_spec.rb
@@ -22,6 +22,8 @@ describe Abilities::Administrator do
let(:future_poll_question) { create(:poll_question, poll: future_poll) }
let(:current_poll_question_answer) { create(:poll_question_answer) }
let(:future_poll_question_answer) { create(:poll_question_answer, poll: future_poll) }
+ let(:current_poll_answer_video) { create(:poll_answer_video, answer: current_poll_question_answer) }
+ let(:future_poll_answer_video) { create(:poll_answer_video, answer: future_poll_question_answer) }
let(:answer_image) { build(:image, imageable: current_poll_question_answer) }
let(:past_process) { create(:legislation_process, :past) }
@@ -132,7 +134,12 @@ describe Abilities::Administrator do
it { should_not be_able_to(:update, current_poll_question_answer) }
it { should_not be_able_to(:destroy, current_poll_question_answer) }
- it { should be_able_to(:manage, Poll::Question::Answer::Video) }
+ it { should be_able_to(:create, future_poll_answer_video) }
+ it { should be_able_to(:update, future_poll_answer_video) }
+ it { should be_able_to(:destroy, future_poll_answer_video) }
+ it { should_not be_able_to(:create, current_poll_answer_video) }
+ it { should_not be_able_to(:update, current_poll_answer_video) }
+ it { should_not be_able_to(:destroy, current_poll_answer_video) }
it { should be_able_to(:create, answer_image) }
it { should be_able_to(:destroy, answer_image) }
diff --git a/spec/system/admin/poll/questions/answers/videos/videos_spec.rb b/spec/system/admin/poll/questions/answers/videos/videos_spec.rb
index b4d2cdfab..67278fbdd 100644
--- a/spec/system/admin/poll/questions/answers/videos/videos_spec.rb
+++ b/spec/system/admin/poll/questions/answers/videos/videos_spec.rb
@@ -1,55 +1,72 @@
require "rails_helper"
describe "Videos", :admin do
- let!(:question) { create(:poll_question) }
- let!(:answer) { create(:poll_question_answer, question: question) }
+ let(:future_poll) { create(:poll, :future) }
+ let(:current_poll) { create(:poll) }
let(:title) { "'Magical' by Junko Ohashi" }
let(:url) { "https://www.youtube.com/watch?v=-JMf43st-1A" }
- scenario "Create" do
- visit admin_question_path(question)
+ describe "Create" do
+ scenario "Is possible for a not started poll" do
+ question = create(:poll_question, poll: future_poll)
+ answer = create(:poll_question_answer, question: question)
- within("#poll_question_answer_#{answer.id}") do
- click_link "Video list"
+ visit admin_question_path(question)
+
+ within("#poll_question_answer_#{answer.id}") do
+ click_link "Video list"
+ end
+ click_link "Add video"
+
+ fill_in "Title", with: title
+ fill_in "External video", with: url
+
+ click_button "Save"
+
+ expect(page).to have_content "Video created successfully"
+ expect(page).to have_content title
+ expect(page).to have_content url
end
- click_link "Add video"
- fill_in "Title", with: title
- fill_in "External video", with: url
+ scenario "Is not possible for an already started poll" do
+ answer = create(:poll_question_answer, poll: current_poll)
- click_button "Save"
+ visit admin_answer_videos_path(answer)
- expect(page).to have_content title
- expect(page).to have_content url
+ expect(page).not_to have_link "Add video"
+ expect(page).to have_content "Once the poll has started it will not be possible to create, edit or"
+ end
end
scenario "Update" do
- video = create(:poll_answer_video, answer: answer)
+ video = create(:poll_answer_video, poll: future_poll)
- visit edit_admin_answer_video_path(answer, video)
+ visit edit_admin_answer_video_path(video.answer, video)
- expect(page).to have_link "Go back", href: admin_answer_videos_path(answer)
+ expect(page).to have_link "Go back", href: admin_answer_videos_path(video.answer)
fill_in "Title", with: title
fill_in "External video", with: url
click_button "Save"
+ expect(page).to have_content "Changes saved"
expect(page).to have_content title
expect(page).to have_content url
end
scenario "Destroy" do
- video = create(:poll_answer_video, answer: answer)
+ video = create(:poll_answer_video, poll: future_poll)
- visit admin_answer_videos_path(answer)
+ visit admin_answer_videos_path(video.answer)
- within("#poll_question_answer_video_#{video.id}") do
+ within("tr", text: video.title) do
accept_confirm("Are you sure? This action will delete \"#{video.title}\" and can't be undone.") do
click_button "Delete"
end
end
expect(page).to have_content "Answer video deleted successfully."
+ expect(page).not_to have_content video.title
end
end