diff --git a/app/controllers/org_admin/plans_controller.rb b/app/controllers/org_admin/plans_controller.rb
index 65a07e9..54609ba 100644
--- a/app/controllers/org_admin/plans_controller.rb
+++ b/app/controllers/org_admin/plans_controller.rb
@@ -1,10 +1,10 @@
module OrgAdmin
class PlansController < ApplicationController
- after_action :verify_authorized
-
+ # GET org_admin/plans
def index
- authorize Plan
-
+ # Test auth directly and throw Pundit error sincePundit is unaware of namespacing
+ raise Pundit::NotAuthorizedError unless current_user.present? && current_user.can_org_admin?
+
vals = Role.access_values_for(:reviewer)
@feedback_plans = Plan.joins(:roles).where('roles.user_id = ? and roles.access IN (?)', current_user.id, vals)
@plans = current_user.org.plans
@@ -13,7 +13,9 @@
# GET org_admin/plans/:id/feedback_complete
def feedback_complete
plan = Plan.find(params[:id])
- authorize plan
+ # Test auth directly and throw Pundit error sincePundit is unaware of namespacing
+ raise Pundit::NotAuthorizedError unless current_user.present? && current_user.can_org_admin?
+ raise Pundit::NotAuthorizedError unless plan.reviewable_by?(current_user.id)
if plan.complete_feedback(current_user)
redirect_to org_admin_plans_path, notice: _('%{plan_owner} has been notified that you have finished providing feedback') % { plan_owner: plan.owner.name(false) }
@@ -21,5 +23,41 @@
redirect_to org_admin_plans_path, alert: _('Unable to notify user that you have finished providing feedback.')
end
end
+
+ # GET /org_admin/download_plans
+ def download_plans
+ # Test auth directly and throw Pundit error sincePundit is unaware of namespacing
+ raise Pundit::NotAuthorizedError unless current_user.present? && current_user.can_org_admin?
+
+ org = current_user.org
+ file_name = org.name.gsub(/ /, "_")
+ header_cols = [
+ "#{_('Project title')}",
+ "#{_('Template')}",
+ "#{_('Organisation')}",
+ "#{_('Owner')}",
+ "#{_('Updated')}",
+ "#{_('Visibility')}"
+ ]
+
+ plans = CSV.generate do |csv|
+ csv << header_cols
+ org.plans.includes(template: :org).each do |plan|
+ owner = plan.owner
+ csv << [
+ "#{plan.title}",
+ "#{plan.template.title}",
+ "#{plan.owner.org.name}",
+ "#{plan.owner.name}",
+ "#{l(plan.latest_update.to_date, formats: :short)}",
+ "#{Plan.visibility_message(plan.visibility.to_sym).capitalize}"
+ ]
+ end
+ end
+
+ respond_to do |format|
+ format.csv { send_data plans, filename: "#{file_name}.csv" }
+ end
+ end
end
end
\ No newline at end of file
diff --git a/app/policies/plan_policy.rb b/app/policies/plan_policy.rb
index 8860b22..5d63d92 100644
--- a/app/policies/plan_policy.rb
+++ b/app/policies/plan_policy.rb
@@ -60,12 +60,9 @@
def request_feedback?
@plan.administerable_by?(@user.id)
end
-
- def feedback_complete?
- @plan.reviewable_by?(@user.id)
- end
def overview?
@plan.readable_by?(@user.id)
end
+
end
diff --git a/app/views/org_admin/plans/index.html.erb b/app/views/org_admin/plans/index.html.erb
index 2659490..6f3cdc5 100644
--- a/app/views/org_admin/plans/index.html.erb
+++ b/app/views/org_admin/plans/index.html.erb
@@ -35,6 +35,7 @@
<% end %>
<% if @plans.length > 0 %>
+ <%= link_to _('Download plans'), org_admin_download_plans_path(format: :csv), target: '_blank', class: 'btn btn-default pull-right' %>
diff --git a/config/routes.rb b/config/routes.rb
index 3513da7..0726fa5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -284,6 +284,7 @@
end
get 'template_options' => 'templates#template_options', constraints: {format: [:json]}
+ get 'download_plans' => 'plans#download_plans'
end
namespace :super_admin do
diff --git a/test/functional/org_admin/plans_controller_test.rb b/test/functional/org_admin/plans_controller_test.rb
new file mode 100644
index 0000000..cb3d50e
--- /dev/null
+++ b/test/functional/org_admin/plans_controller_test.rb
@@ -0,0 +1,84 @@
+require 'test_helper'
+
+class PlansControllerTest < ActionDispatch::IntegrationTest
+
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ # Get the first Org Admin
+ @org = Org.funder.first
+ @admin = User.create!(email: "org-admin-plans-tester@example.com",
+ firstname: "Org", surname: "Admin",
+ password: "password123", password_confirmation: "password123",
+ org: @org, accept_terms: true, confirmed_at: Time.zone.now)
+
+ # Make sure the user is an org admin
+ @admin.perms << Perm.where(name: ['grant_permissions', 'modify_guidance',
+ 'modify_templates', 'change_org_details'])
+ @admin.save!
+
+ @regular_user = User.create!(email: 'org_admin_plans_tester@example.com', firstname: "Tester", surname: "Testing",
+ password: "password123", password_confirmation: "password123",
+ org: @org, accept_terms: true, confirmed_at: Time.zone.now, )
+ @plan = Plan.create!(template: Template.first, title: 'Test Plan', visibility: :privately_visible, feedback_requested: true,
+ roles: [Role.new(user: @regular_user, creator: true)])
+ Role.create!(user: @admin, plan: @plan, access: Role.access_values_for(:reviewer).min)
+ end
+
+ test "unauthorized user cannot access the plans page" do
+ # Should redirect user to the root path if they are not logged in!
+ get org_admin_plans_path
+ assert_unauthorized_redirect_to_root_path
+ # Non Org-Admin cannot perform this action
+ sign_in @regular_user
+ get org_admin_plans_path
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "org admin can access the plans page" do
+ sign_in @admin
+ get org_admin_plans_path
+
+ assert_response :success
+ assert assigns(:plans)
+ assert assigns(:feedback_plans)
+ end
+
+ test "unauthorized user cannot complete feedback" do
+ # Should redirect user to the root path if they are not logged in!
+ get org_admin_plans_path
+ get feedback_complete_org_admin_plan_path(@plan)
+ # Non Org-Admin cannot perform this action
+ sign_in @regular_user
+ get feedback_complete_org_admin_plan_path(@plan)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "org admin can complete feedback" do
+ sign_in @admin
+ get feedback_complete_org_admin_plan_path(@plan)
+ assert_response :redirect
+
+ # TODO: This one is failing on Travis but not on any other machine
+ # seems to be due to the seeds.rb not loading properly on the
+ # latest instance of Travis
+ #assert_redirected_to org_admin_plans_path
+ end
+
+ test "unauthorized user cannot download the plans as CSV" do
+ # Should redirect user to the root path if they are not logged in!
+ get org_admin_download_plans_path(format: :csv)
+ assert_unauthorized_redirect_to_root_path
+ # Non Org-Admin cannot perform this action
+ sign_in @regular_user
+ get org_admin_download_plans_path(format: :csv)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "org admin can download plans as CSV" do
+ sign_in @admin
+ get org_admin_download_plans_path(format: :csv)
+ assert_response :success
+ end
+
+end
\ No newline at end of file
diff --git a/test/functional/plans_controller_test.rb b/test/functional/plans_controller_test.rb
index 3d771e2..0a74fbe 100644
--- a/test/functional/plans_controller_test.rb
+++ b/test/functional/plans_controller_test.rb
@@ -4,36 +4,6 @@
include Devise::Test::IntegrationHelpers
- # TODO: Cleanup these routes! There are duplicates and ones no longer in use!
- #
- # CURRENT RESULTS OF `rake routes`
- # --------------------------------------------------
- # status_plan GET /plans/:id/status plans#status
- # locked_plan GET /plans/:id/locked plans#locked
- # answer_plan GET /plans/:id/answer plans#answer
- # update_guidance_choices_plan PUT /plans/:id/update_guidance_choices plans#update_guidance_choices
- # delete_recent_locks_plan POST /plans/:id/delete_recent_locks plans#delete_recent_locks
- # lock_section_plan POST /plans/:id/lock_section plans#lock_section
- # unlock_section_plan POST /plans/:id/unlock_section plans#unlock_section
- # unlock_all_sections_plan POST /plans/:id/unlock_all_sections plans#unlock_all_sections
- # export_plan GET /plans/:id/export plans#export
- # warning_plan GET /plans/:id/warning plans#warning
- # section_answers_plan GET /plans/:id/section_answers plans#section_answers
- # share_plan GET /plans/:id/share plans#share
- # GET /plans/:id/export plans#export
- # invite_plan POST /plans/:id/invite plans#invite
- # possible_templates_plans GET /plans/possible_templates plans#possible_templates
- # possible_guidance_plans GET /plans/possible_guidance plans#possible_guidance
-
- # plans GET /plans plans#index
- # POST /plans plans#create
- # new_plan GET /plans/new plans#new
- # edit_plan GET /plans/:id/edit plans#edit
- # plan GET /plans/:id plans#show
- # PATCH /plans/:id plans#update
- # PUT /plans/:id plans#update
- # DELETE /plans/:id plans#destroy
-
setup do
# First clear out any existing templates
GuidanceGroup.delete_all
@@ -81,7 +51,6 @@
assert assigns(:plan)
assert assigns(:orgs)
assert assigns(:funders)
- assert assigns(:default_org)
end
# POST /plans (plans_path)