Add sdg manager section to admin

Allow a user to become an sdg manager
This commit is contained in:
taitus
2020-11-25 18:57:19 +01:00
committed by Javi Martín
parent fb5965fe63
commit 9fe24aec9d
24 changed files with 301 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
module Admin::Header
extend ActiveSupport::Concern
def header(options: {})
provide(:title) do
title
end
tag.h2 options do
title
end
end
end

View File

@@ -0,0 +1,38 @@
<%= header %>
<%= render "admin/shared/user_search", url: admin_sdg_managers_path %>
<div id="sdg_managers">
<% if users.any? %>
<h3 class="margin"><%= page_entries_info users %></h3>
<table>
<thead>
<th scope="col"><%= SDG::Manager.human_attribute_name(:name) %></th>
<th scope="col"><%= SDG::Manager.human_attribute_name(:email) %></th>
<th scope="col"><%= t("admin.shared.actions") %></th>
</thead>
<tbody>
<% users.each do |user| %>
<tr>
<td>
<%= user.name %>
</td>
<td>
<%= user.email %>
</td>
<td>
<%= render Admin::Roles::TableActionsComponent.new(user.sdg_manager || user.build_sdg_manager) %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= paginate users %>
<% else %>
<div class="callout primary">
<%= t("admin.sdg_managers.index.no_sdg_managers") %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,15 @@
class Admin::SDG::Managers::IndexComponent < ApplicationComponent
include Admin::Header
attr_reader :users
def initialize(users)
@users = users
end
private
def title
SDG::Manager.model_name.human(count: 2).upcase_first
end
end

View File

@@ -0,0 +1,23 @@
class Admin::SDG::ManagersController < Admin::BaseController
load_and_authorize_resource instance_name: :sdg_manager, class: "SDG::Manager"
def index
if params[:search]
@users = User.accessible_by(current_ability).search(params[:search]).page(params[:page])
else
@users = User.accessible_by(current_ability).sdg_managers.page(params[:page])
end
end
def create
@sdg_manager.user_id = params[:user_id]
@sdg_manager.save!
redirect_to admin_sdg_managers_path
end
def destroy
@sdg_manager.destroy!
redirect_to admin_sdg_managers_path
end
end

View File

@@ -56,6 +56,7 @@ module Abilities
can [:search, :create, :index, :destroy], ::Moderator
can [:search, :show, :edit, :update, :create, :index, :destroy, :summary], ::Valuator
can [:search, :create, :index, :destroy], ::Manager
can [:create, :read, :destroy], ::SDG::Manager
can [:search, :index], ::User
can :manage, Dashboard::Action

View File

@@ -95,6 +95,7 @@ class User < ApplicationRecord
scope :administrators, -> { joins(:administrator) }
scope :moderators, -> { joins(:moderator) }
scope :organizations, -> { joins(:organization) }
scope :sdg_managers, -> { joins(:sdg_manager) }
scope :officials, -> { where("official_level > 0") }
scope :male, -> { where(gender: "male") }
scope :female, -> { where(gender: "female") }

View File

@@ -0,0 +1 @@
<%= render Admin::SDG::Managers::IndexComponent.new(@users) %>

View File

@@ -4,6 +4,9 @@ en:
results_enabled: "Show results"
stats_enabled: "Show stats"
advanced_stats_enabled: "Show advanced stats"
name: Name
email: Email
description: Description
activerecord:
models:
activity:
@@ -78,6 +81,9 @@ en:
sdg/local_target:
one: "local target"
other: "local targets"
sdg/manager:
one: "SDG manager"
other: "SDG managers"
sdg/target:
one: "target"
other: "targets"

View File

@@ -621,6 +621,12 @@ en:
add: Add
search:
title: "Managers: User search"
sdg_managers:
index:
no_sdg_managers: There are no users.
sdg/managers:
sdg/manager:
add: Add
menu:
activity: Moderator activity
admin: Admin menu
@@ -637,6 +643,7 @@ en:
hidden_users: Hidden users
administrators: Administrators
managers: Managers
sdg_managers: SDG Managers
moderators: Moderators
messaging_users: Messages to users
newsletters: Newsletters

View File

@@ -4,6 +4,9 @@ es:
results_enabled: "Mostrar resultados"
stats_enabled: "Mostrar estadísticas"
advanced_stats_enabled: "Mostrar estadísticas avanzadas"
name: Nombre
email: Email
description: Descripción
activerecord:
models:
activity:
@@ -78,6 +81,9 @@ es:
sdg/local_target:
one: "meta localizada"
other: "metas localizadas"
sdg/manager:
one: "gestor ODS"
other: "gestores ODS"
sdg/target:
one: "meta"
other: "metas"

View File

@@ -620,6 +620,12 @@ es:
add: Añadir como gestor
search:
title: "Gestores: Búsqueda de usuarios"
sdg_managers:
index:
no_sdg_managers: No hay usuarios.
sdg/managers:
sdg/manager:
add: Añadir como gestor ODS
menu:
activity: Actividad de moderadores
admin: Menú de administración
@@ -636,6 +642,7 @@ es:
hidden_users: Usuarios bloqueados
administrators: Administradores
managers: Gestores
sdg_managers: Gestores ODS
moderators: Moderadores
messaging_users: Mensajes a usuarios
newsletters: Newsletters

View File

@@ -113,6 +113,10 @@ namespace :admin do
get :search, on: :collection
end
namespace :sdg do
resources :managers, only: [:index, :create, :destroy]
end
resources :administrators, only: [:index, :create, :destroy, :edit, :update] do
get :search, on: :collection
end

View File

@@ -109,4 +109,8 @@ describe Abilities::Administrator do
it { should be_able_to(:read, SDG::Goal) }
it { should be_able_to(:read, SDG::Target) }
it { should be_able_to(:read, SDG::Manager) }
it { should be_able_to(:create, SDG::Manager) }
it { should be_able_to(:destroy, SDG::Manager) }
end

View File

@@ -307,4 +307,8 @@ describe Abilities::Common do
it { should_not be_able_to(:read, SDG::Goal) }
it { should_not be_able_to(:read, SDG::Target) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }
it { should_not be_able_to(:delete, SDG::Manager) }
end

View File

@@ -55,4 +55,8 @@ describe Abilities::Everyone do
it { should_not be_able_to(:read, SDG::Goal) }
it { should_not be_able_to(:read, SDG::Target) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }
it { should_not be_able_to(:delete, SDG::Manager) }
end

View File

@@ -111,4 +111,8 @@ describe Abilities::Moderator do
it { should_not be_able_to(:read, SDG::Goal) }
it { should_not be_able_to(:read, SDG::Target) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }
it { should_not be_able_to(:delete, SDG::Manager) }
end

View File

@@ -25,4 +25,8 @@ describe "Abilities::Organization" do
it { should_not be_able_to(:read, SDG::Goal) }
it { should_not be_able_to(:read, SDG::Target) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }
it { should_not be_able_to(:delete, SDG::Manager) }
end

View File

@@ -9,4 +9,8 @@ describe "Abilities::SDG::Manager" do
it { should be_able_to(:read, SDG::Goal) }
it { should be_able_to(:read, SDG::Target) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }
it { should_not be_able_to(:delete, SDG::Manager) }
end

View File

@@ -42,4 +42,8 @@ describe Abilities::Valuator do
it { should_not be_able_to(:read, SDG::Goal) }
it { should_not be_able_to(:read, SDG::Target) }
it { should_not be_able_to(:read, SDG::Manager) }
it { should_not be_able_to(:create, SDG::Manager) }
it { should_not be_able_to(:delete, SDG::Manager) }
end

View File

@@ -0,0 +1,96 @@
require "rails_helper"
describe "Admin SDG managers", :js do
let!(:user) { create(:user) }
let!(:sdg_manager) { create(:sdg_manager) }
before do
login_as(create(:administrator).user)
visit admin_sdg_managers_path
end
scenario "Index" do
expect(page).to have_content sdg_manager.name
expect(page).to have_content sdg_manager.email
expect(page).not_to have_content user.name
end
scenario "Create SDG Manager" do
fill_in "search", with: user.email
click_button "Search"
expect(page).to have_content user.name
click_link "Add"
within("#sdg_managers") do
expect(page).to have_content user.name
end
end
scenario "Delete SDG Manager" do
accept_confirm { click_link "Delete" }
within("#sdg_managers") do
expect(page).not_to have_content sdg_manager.name
end
end
context "Search" do
let(:user) { create(:user, username: "Taylor Swift", email: "taylor@swift.com") }
let(:user2) { create(:user, username: "Stephanie Corneliussen", email: "steph@mrrobot.com") }
let!(:sdg_manager1) { create(:sdg_manager, user: user) }
let!(:sdg_manager2) { create(:sdg_manager, user: user2) }
before do
visit admin_sdg_managers_path
end
scenario "returns no results if search term is empty" do
expect(page).to have_content(sdg_manager1.name)
expect(page).to have_content(sdg_manager2.name)
fill_in "search", with: " "
click_button "Search"
expect(page).to have_content("SDG managers")
expect(page).to have_content("There are no users.")
expect(page).not_to have_content(sdg_manager1.name)
expect(page).not_to have_content(sdg_manager2.name)
end
scenario "search by name" do
expect(page).to have_content(sdg_manager1.name)
expect(page).to have_content(sdg_manager2.name)
fill_in "search", with: "Taylor"
click_button "Search"
expect(page).to have_content("SDG managers")
expect(page).to have_content(sdg_manager1.name)
expect(page).not_to have_content(sdg_manager2.name)
end
scenario "search by email" do
expect(page).to have_content(sdg_manager1.email)
expect(page).to have_content(sdg_manager2.email)
fill_in "search", with: sdg_manager2.email
click_button "Search"
expect(page).to have_content("SDG managers")
expect(page).to have_content(sdg_manager2.email)
expect(page).not_to have_content(sdg_manager1.email)
end
scenario "Delete after searching" do
fill_in "Search user by name or email", with: sdg_manager2.email
click_button "Search"
accept_confirm { click_link "Delete" }
expect(page).to have_content(sdg_manager1.email)
expect(page).not_to have_content(sdg_manager2.email)
end
end
end

View File

@@ -42,6 +42,16 @@ describe "Admin" do
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as SDG manager is not authorized", :js do
create(:sdg_manager, user: user)
login_as(user)
visit admin_root_path
expect(page).not_to have_current_path(admin_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as poll officer is not authorized" do
login_as(create(:poll_officer).user)
visit admin_root_path
@@ -59,12 +69,15 @@ describe "Admin" do
end
scenario "Admin access links", :admin do
Setting["feature.sdg"] = true
visit root_path
expect(page).to have_link("Administration")
expect(page).to have_link("Moderation")
expect(page).to have_link("Valuation")
expect(page).to have_link("Management")
expect(page).to have_link("SDG content")
end
scenario "Admin dashboard", :admin do

View File

@@ -43,6 +43,21 @@ describe "Moderation" do
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as SDG manager is not authorized", :js do
create(:sdg_manager, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Moderation")
visit moderation_root_path
expect(page).not_to have_current_path(moderation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as poll officer is not authorized" do
create(:poll_officer, user: user)

View File

@@ -42,6 +42,20 @@ describe "Poll Officing" do
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as SDG manager is not authorized", :js do
create(:sdg_manager, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Polling officers")
visit officing_root_path
expect(page).not_to have_current_path(officing_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as a valuator is not authorized" do
create(:valuator, user: user)
login_as(user)

View File

@@ -42,6 +42,19 @@ describe "Valuation" do
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as SDG manager is not authorized" do
create(:sdg_manager, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario "Access as poll officer is not authorized" do
create(:poll_officer, user: user)
login_as(user)