Added a link from the epics list to delete each epic. Checks were added
to ensure the epic does not have any dependant user stories.
Signed-off-by: Darryl L. Pierce <mcpierce(a)gmail.com>
---
app/controllers/epics_controller.rb | 21 ++++++++++++-
app/models/epic.rb | 5 +++
app/views/epics/destroy.html.erb | 2 -
app/views/epics/index.html.erb | 6 ++++
test/fixtures/epics.yml | 5 +++
test/functional/epics_controller_test.rb | 48 +++++++++++++++++++++++++++++-
6 files changed, 82 insertions(+), 5 deletions(-)
delete mode 100644 app/views/epics/destroy.html.erb
diff --git a/app/controllers/epics_controller.rb b/app/controllers/epics_controller.rb
index 55aadcb..2350e84 100644
--- a/app/controllers/epics_controller.rb
+++ b/app/controllers/epics_controller.rb
@@ -16,9 +16,9 @@
# +EpicsController+ allows users to work with +Epic+ stories.
class EpicsController < ApplicationController
- before_filter :authenticated, :only => [:new, :edit, :create, :update]
+ before_filter :authenticated, :only => [:new, :edit, :create, :update, :destroy]
before_filter :load_project
- before_filter :load_epic, :only => [:edit, :update]
+ before_filter :load_epic, :only => [:edit, :update, :destroy]
# GET /projects/1/epics
def index
@@ -100,7 +100,24 @@ class EpicsController < ApplicationController
end
end
+ # DELETE /projects/1/epics/1
def destroy
+ respond_to do |format|
+ if @epic.can_delete?(@user)
+ Epic.transaction do
+ if @epic.destroy
+ flash[:message] = "Epic was deleted."
+ format.html { redirect_to project_epics_path(@project) }
+ else
+ flash[:error] = "Unable to delete this epic."
+ format.html { redirect_to.project_epic_path(@project, @epic) }
+ end
+ end
+ else
+ flash[:message] = "You can not delete this epic."
+ format.html { redirect_to project_epic_path(@project, @epic) }
+ end
+ end
end
private
diff --git a/app/models/epic.rb b/app/models/epic.rb
index e6691d3..fe0bb5b 100644
--- a/app/models/epic.rb
+++ b/app/models/epic.rb
@@ -39,4 +39,9 @@ class Epic < ActiveRecord::Base
def selectable_title
"#{title} (#{priority})"
end
+
+ # Returns whether this epic can be deleted.
+ def can_delete?(user)
+ (user != nil) && (user.id == project.owner_id) &&
user_stories.empty?
+ end
end
diff --git a/app/views/epics/destroy.html.erb b/app/views/epics/destroy.html.erb
deleted file mode 100644
index 1cf72ac..0000000
--- a/app/views/epics/destroy.html.erb
+++ /dev/null
@@ -1,2 +0,0 @@
-<h1>Epics#destroy</h1>
-<p>Find me in app/views/epics/destroy.html.erb</p>
diff --git a/app/views/epics/index.html.erb b/app/views/epics/index.html.erb
index 9ff7974..7653c54 100644
--- a/app/views/epics/index.html.erb
+++ b/app/views/epics/index.html.erb
@@ -33,6 +33,12 @@
<%= link_to(image_tag("/images/icons/edit.png", :title => "Edit
this epic story..."),
edit_project_epic_path(@project, epic)) %>
<% end %>
+
+ <% if epic.can_delete?(@user) %>
+ <%= link_to image_tag("/images/icons/delete.png", :title => "Delete
this epic..."),
+ project_epic_path(@project, epic), :method => :delete,
+ :confirm => "Delete this epic? Are you sure?" %>
+ <% end %>
</td>
</tr>
<% end %>
diff --git a/test/fixtures/epics.yml b/test/fixtures/epics.yml
index 664454c..ee25170 100644
--- a/test/fixtures/epics.yml
+++ b/test/fixtures/epics.yml
@@ -7,3 +7,8 @@ login_epic:
project_id: <%= Fixtures.identify(:projxp) %>
priority: 2
title: Covers all login attempts.
+
+no_user_story_epic:
+ project_id: <%= Fixtures.identify(:projxp) %>
+ priority: 3
+ title: Has no user stories.
diff --git a/test/functional/epics_controller_test.rb
b/test/functional/epics_controller_test.rb
index c095704..9ea00e3 100644
--- a/test/functional/epics_controller_test.rb
+++ b/test/functional/epics_controller_test.rb
@@ -24,7 +24,7 @@ class EpicsControllerTest < ActionController::TestCase
def setup
@project = projects(:projxp)
@owner = @project.owner
- @epic = epics(:user_stories_epic)
+ @epic = epics(:no_user_story_epic)
raise "Epic is not in this project!" unless @epic.project_id ==
@project.id
@other_project = projects(:teatime)
@@ -223,4 +223,50 @@ class EpicsControllerTest < ActionController::TestCase
result = Epic.find_by_id((a)epic.id)
assert_equal "test", result.title, "Epic was not updated as
expected."
end
+
+ # Ensures that anonymous users cannot delete epics.
+ def test_destroy_as_anonymous
+ delete :destroy
+
+ assert_redirected_to login_path
+ end
+
+ # Ensures that valid project id is required.
+ def test_destroy_with_invalid_project
+ delete :destroy, { }, {:user_id => @owner.id}
+
+ assert_redirected_to error_path
+ end
+
+ # Ensures that a valid epic is required.
+ def test_destroy_with_invalid_epic
+ delete :destroy, {:project_id => @project.id}, {:user_id => @owner.id}
+
+ assert_redirected_to error_path
+ end
+
+ # Ensures that the epic and project must match.
+ def test_destroy_with_epic_project_mismatch
+ delete :destroy, {:project_id => @other_project.id, :id => @epic.id}, {:user_id
=> @owner.id}
+
+ assert_redirected_to error_path
+ end
+
+ # Ensures that epics cannot be deleted by non-owners.
+ def test_destroy_as_nonowner
+ delete :destroy, {:project_id => @project.id, :id => @epic.id}, {:user_id =>
@nonowner.id}
+
+ assert_redirected_to project_epic_path(@project, @epic)
+ result = Epic.find_by_id((a)epic.id)
+ assert result, "Epic should not have been deleted."
+ end
+
+ # Ensures that an epic can be deleted.
+ def test_destroy
+ delete :destroy, {:project_id => @project.id, :id => @epic.id}, {:user_id =>
@owner.id}
+
+ assert_redirected_to project_epics_path(@project)
+ result = Epic.find_by_id((a)epic.id)
+ assert_nil result, "Epic should have been deleted."
+ end
end
--
1.6.0.6