Merge pull request #1446 from kreuzwerker/feature/scenario-deletion

Allow user to delete the scenarios agents with it
This commit is contained in:
Dominik Sander 2016-04-24 10:28:51 +02:00
commit ea95a9d6c3
9 changed files with 117 additions and 4 deletions

View file

@ -97,7 +97,7 @@ class ScenariosController < ApplicationController
def destroy
@scenario = current_user.scenarios.find(params[:id])
@scenario.destroy
@scenario.destroy_with_mode(params[:mode])
respond_to do |format|
format.html { redirect_to scenarios_path }

View file

@ -16,7 +16,25 @@ class Scenario < ActiveRecord::Base
validate :agents_are_owned
protected
def destroy_with_mode(mode)
case mode
when 'all_agents'
Agent.destroy(agents.pluck(:id))
when 'unique_agents'
Agent.destroy(unique_agent_ids)
end
destroy
end
private
def unique_agent_ids
agents.joins(:scenario_memberships)
.group('scenario_memberships.agent_id')
.having('count(scenario_memberships.agent_id) = 1')
.pluck('scenario_memberships.agent_id')
end
def agents_are_owned
errors.add(:agents, "must be owned by you") unless agents.all? {|s| s.user == user }

View file

@ -0,0 +1,46 @@
<div id="confirm-scenario-deletion-<%= scenario.id %>" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<%= form_for(scenario, url: scenario_path(scenario), method: :delete) do |f| %>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h4 class="modal-title">
<% if @scenario && @scenario == scenario %>
How do you want to delete this Scenario?
<% else %>
How do you want to delete the Scenario '<%= scenario.name %>'?
<% end %>
</h4>
</div>
<div class="modal-body">
<div class="radio">
<%= label_tag do %>
<%= radio_button_tag :mode, '', true %>
<h4><span class="label label-success">Scenario only</span></h4>
Only delete the Scenerio, keep the Agents.
<% end %>
</div>
<div class="radio">
<%= label_tag do %>
<%= radio_button_tag :mode, :unique_agents %>
<h4><span class="label label-warning">Scenario and unique Agents</span></h4>
Also deletes Agents that are used in this Scenario only.
<% end %>
</div>
<div class="radio">
<%= label_tag do %>
<%= radio_button_tag :mode, :all_agents %>
<h4><span class="label label-danger">Scenario and all included Agents</span></h4>
Deletes Scenario and all included Agents, even if they are used in different Scenarios.
<% end %>
</div>
</div>
<div class="modal-footer">
<%= f.button 'Abort', class: 'btn btn-default', 'data-dismiss' => 'modal' %>
<%= f.submit 'Delete', class: 'btn btn-danger' %>
</div>
<% end %>
</div>
</div>
</div>

View file

@ -31,8 +31,9 @@
<%= link_to 'Show', scenario, class: "btn btn-default" %>
<%= link_to 'Edit', edit_scenario_path(scenario), class: "btn btn-default" %>
<%= link_to 'Share', share_scenario_path(scenario), class: "btn btn-default" %>
<%= link_to 'Delete', scenario_path(scenario), method: :delete, data: { confirm: "This will remove the '#{scenario.name}' Scenerio from all Agents and delete it. Are you sure?" }, class: "btn btn-default" %>
<%= link_to 'Delete', '#', data: { toggle: 'modal', target: "#confirm-scenario-deletion-#{scenario.id}"}, class: "btn btn-default" %>
</div>
<%= render 'scenarios/confirm_deletion_modal', scenario: scenario %>
</td>
</tr>
<% end %>

View file

@ -23,8 +23,9 @@
<%= link_to icon_tag('glyphicon-refresh') + ' Update', new_scenario_imports_path(url: @scenario.source_url), class: "btn btn-default" %>
<% end %>
<%= link_to icon_tag('glyphicon-share-alt') + ' Share', share_scenario_path(@scenario), class: "btn btn-default" %>
<%= link_to icon_tag('glyphicon-trash') + ' Delete', scenario_path(@scenario), method: :delete, data: { confirm: "This will remove the '#{@scenario.name}' Scenerio from all Agents and delete it. Are you sure?" }, class: "btn btn-default" %>
<%= link_to icon_tag('glyphicon-trash') + ' Delete', '#', data: { toggle: 'modal', target: "#confirm-scenario-deletion-#{@scenario.id}"}, class: "btn btn-default" %>
</div>
</div>
</div>
</div>
<%= render 'scenarios/confirm_deletion_modal', scenario: @scenario %>

View file

@ -150,5 +150,11 @@ describe ScenariosController do
delete :destroy, :id => scenarios(:jane_weather).to_param
}.to raise_error(ActiveRecord::RecordNotFound)
end
it "passes the mode to the model" do
expect {
delete :destroy, id: scenarios(:bob_weather).to_param, mode: 'all_agents'
}.to change(Agent, :count).by(-2)
end
end
end

View file

@ -6,6 +6,10 @@ jane_rain_notifier_agent_scenario_membership:
agent: jane_rain_notifier_agent
scenario: jane_weather
jane_rain_notifier_agent_scenario_membership_duplicate:
agent: jane_weather_agent
scenario: jane_weather_duplicate
bob_weather_agent_scenario_membership:
agent: bob_weather_agent
scenario: bob_weather

View file

@ -5,6 +5,12 @@ jane_weather:
public: false
guid: random-guid-generated-by-bob
jane_weather_duplicate:
name: Jane's duplicated, incomplete weather alert Scenario
user: jane
public: false
guid: random-guid-generated-by-jane2
bob_weather:
name: Bob's weather alert Scenario
user: bob

View file

@ -64,4 +64,35 @@ describe Scenario do
}.to change { users(:bob).reload.scenario_count }.by(-1)
end
end
context '#unique_agents' do
it "equals agents when no agents are shared" do
agent_ids = scenarios(:bob_weather).agents.map(&:id).sort
unique_agent_ids = scenarios(:bob_weather).send(:unique_agent_ids).sort
expect(agent_ids).to eq(unique_agent_ids)
end
it "includes only agents that are not present in two scnearios" do
unique_agent_ids = scenarios(:jane_weather).send(:unique_agent_ids)
expect(unique_agent_ids).to eq([agents(:jane_rain_notifier_agent).id])
end
it "returns no agents when all are also used in a different scenario" do
expect(scenarios(:jane_weather_duplicate).send(:unique_agent_ids)).to eq([])
end
end
context '#destroy_with_mode' do
it "only destroys the scenario when no mode is passed" do
expect { scenarios(:jane_weather).destroy_with_mode('') }.not_to change(Agent, :count)
end
it "only destroys unique agents when 'unique_agents' is passed" do
expect { scenarios(:jane_weather).destroy_with_mode('unique_agents') }.to change(Agent, :count).by(-1)
end
it "destroys all agents when 'all_agents' is passed" do
expect { scenarios(:jane_weather).destroy_with_mode('all_agents') }.to change(Agent, :count).by(-2)
end
end
end