Merge pull request #116 from AyuntamientoMadrid/admin-77
Administrator and Moderator basic interface
This commit is contained in:
1
Gemfile
1
Gemfile
@@ -28,6 +28,7 @@ gem 'foundation-rails'
|
|||||||
gem 'acts_as_votable'
|
gem 'acts_as_votable'
|
||||||
gem "recaptcha", require: "recaptcha/rails"
|
gem "recaptcha", require: "recaptcha/rails"
|
||||||
gem 'ckeditor'
|
gem 'ckeditor'
|
||||||
|
gem 'cancancan'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ GEM
|
|||||||
builder (3.2.2)
|
builder (3.2.2)
|
||||||
byebug (5.0.0)
|
byebug (5.0.0)
|
||||||
columnize (= 0.9.0)
|
columnize (= 0.9.0)
|
||||||
|
cancancan (1.12.0)
|
||||||
capistrano (3.4.0)
|
capistrano (3.4.0)
|
||||||
i18n
|
i18n
|
||||||
rake (>= 10.0.0)
|
rake (>= 10.0.0)
|
||||||
@@ -290,6 +291,7 @@ DEPENDENCIES
|
|||||||
acts_as_commentable_with_threading
|
acts_as_commentable_with_threading
|
||||||
acts_as_votable
|
acts_as_votable
|
||||||
byebug
|
byebug
|
||||||
|
cancancan
|
||||||
capistrano (= 3.4.0)
|
capistrano (= 3.4.0)
|
||||||
capistrano-bundler (= 1.1.4)
|
capistrano-bundler (= 1.1.4)
|
||||||
capistrano-passenger
|
capistrano-passenger
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ class AccountController < ApplicationController
|
|||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
load_and_authorize_resource class: "User"
|
||||||
|
|
||||||
def show
|
def show
|
||||||
end
|
end
|
||||||
|
|||||||
13
app/controllers/admin/base_controller.rb
Normal file
13
app/controllers/admin/base_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class Admin::BaseController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
skip_authorization_check
|
||||||
|
before_action :verify_administrator
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def verify_administrator
|
||||||
|
raise CanCan::AccessDenied unless current_user.try(:administrator?)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
6
app/controllers/admin/dashboard_controller.rb
Normal file
6
app/controllers/admin/dashboard_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class Admin::DashboardController < Admin::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
require "application_responder"
|
require "application_responder"
|
||||||
|
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
|
check_authorization unless: :devise_controller?
|
||||||
|
|
||||||
self.responder = ApplicationResponder
|
self.responder = ApplicationResponder
|
||||||
respond_to :html
|
respond_to :html
|
||||||
|
|
||||||
@@ -11,6 +14,10 @@ class ApplicationController < ActionController::Base
|
|||||||
# For APIs, you may want to use :null_session instead.
|
# For APIs, you may want to use :null_session instead.
|
||||||
protect_from_forgery with: :exception
|
protect_from_forgery with: :exception
|
||||||
|
|
||||||
|
rescue_from CanCan::AccessDenied do |exception|
|
||||||
|
redirect_to main_app.root_url, alert: exception.message
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_locale
|
def set_locale
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
class CommentsController < ApplicationController
|
class CommentsController < ApplicationController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_debate, :set_parent, only: :create
|
before_action :build_comment, only: :create
|
||||||
|
load_and_authorize_resource
|
||||||
respond_to :html, :js
|
respond_to :html, :js
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@comment = Comment.build(@debate, current_user, params[:comment][:body])
|
|
||||||
@comment.save!
|
@comment.save!
|
||||||
@comment.move_to_child_of(@parent) if reply?
|
@comment.move_to_child_of(parent) if reply?
|
||||||
|
|
||||||
Mailer.comment(@comment).deliver_now if email_on_debate_comment?
|
Mailer.comment(@comment).deliver_now if email_on_debate_comment?
|
||||||
Mailer.reply(@comment).deliver_now if email_on_comment_reply?
|
Mailer.reply(@comment).deliver_now if email_on_comment_reply?
|
||||||
@@ -15,7 +15,6 @@ class CommentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def vote
|
def vote
|
||||||
@comment = Comment.find(params[:id])
|
|
||||||
@comment.vote_by(voter: current_user, vote: params[:value])
|
@comment.vote_by(voter: current_user, vote: params[:value])
|
||||||
respond_with @comment
|
respond_with @comment
|
||||||
end
|
end
|
||||||
@@ -25,16 +24,20 @@ class CommentsController < ApplicationController
|
|||||||
params.require(:comments).permit(:commentable_type, :commentable_id, :body)
|
params.require(:comments).permit(:commentable_type, :commentable_id, :body)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_debate
|
def build_comment
|
||||||
@debate = Debate.find(params[:debate_id])
|
@comment = Comment.build(debate, current_user, params[:comment][:body])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_parent
|
def debate
|
||||||
@parent = Comment.find_parent(params[:comment])
|
@debate ||= Debate.find(params[:debate_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def parent
|
||||||
|
@parent ||= Comment.find_parent(params[:comment])
|
||||||
end
|
end
|
||||||
|
|
||||||
def reply?
|
def reply?
|
||||||
@parent.class == Comment
|
parent.class == Comment
|
||||||
end
|
end
|
||||||
|
|
||||||
def email_on_debate_comment?
|
def email_on_debate_comment?
|
||||||
@@ -42,6 +45,6 @@ class CommentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def email_on_comment_reply?
|
def email_on_comment_reply?
|
||||||
reply? && @parent.author.email_on_comment_reply?
|
reply? && parent.author.email_on_comment_reply?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
class DebatesController < ApplicationController
|
class DebatesController < ApplicationController
|
||||||
include RecaptchaHelper
|
include RecaptchaHelper
|
||||||
before_action :set_debate, only: [:show, :edit, :update, :vote]
|
|
||||||
before_action :authenticate_user!, except: [:index, :show]
|
before_action :authenticate_user!, except: [:index, :show]
|
||||||
before_action :validate_ownership, only: [:edit, :update]
|
load_and_authorize_resource
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if params[:tag]
|
if params[:tag]
|
||||||
@@ -56,10 +55,6 @@ class DebatesController < ApplicationController
|
|||||||
params.require(:debate).permit(:title, :description, :tag_list, :terms_of_service)
|
params.require(:debate).permit(:title, :description, :tag_list, :terms_of_service)
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate_ownership
|
|
||||||
raise ActiveRecord::RecordNotFound unless @debate.editable_by?(current_user)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_voted_values(debates_ids)
|
def set_voted_values(debates_ids)
|
||||||
@voted_values = current_user ? current_user.votes_on_debates(debates_ids) : {}
|
@voted_values = current_user ? current_user.votes_on_debates(debates_ids) : {}
|
||||||
end
|
end
|
||||||
|
|||||||
13
app/controllers/moderation/base_controller.rb
Normal file
13
app/controllers/moderation/base_controller.rb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
class Moderation::BaseController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
skip_authorization_check
|
||||||
|
before_action :verify_moderator
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def verify_moderator
|
||||||
|
raise CanCan::AccessDenied unless current_user.try(:moderator?) || current_user.try(:administrator?)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
6
app/controllers/moderation/dashboard_controller.rb
Normal file
6
app/controllers/moderation/dashboard_controller.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class Moderation::DashboardController < Moderation::BaseController
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
26
app/models/ability.rb
Normal file
26
app/models/ability.rb
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
class Ability
|
||||||
|
include CanCan::Ability
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
# Not logged in users
|
||||||
|
can :read, Debate
|
||||||
|
|
||||||
|
if user # logged-in users
|
||||||
|
can [:read, :update], User, id: user.id
|
||||||
|
|
||||||
|
can [:read, :create, :vote], Debate
|
||||||
|
can :update, Debate do |debate|
|
||||||
|
debate.editable_by?(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
can [:create, :vote], Comment
|
||||||
|
|
||||||
|
if user.moderator? or user.administrator?
|
||||||
|
|
||||||
|
elsif user.administrator?
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
6
app/models/administrator.rb
Normal file
6
app/models/administrator.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class Administrator < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
delegate :name, :email, to: :user
|
||||||
|
|
||||||
|
validates :user_id, presence: true, uniqueness: true
|
||||||
|
end
|
||||||
6
app/models/moderator.rb
Normal file
6
app/models/moderator.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class Moderator < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
delegate :name, :email, to: :user
|
||||||
|
|
||||||
|
validates :user_id, presence: true, uniqueness: true
|
||||||
|
end
|
||||||
@@ -19,4 +19,12 @@ class User < ActiveRecord::Base
|
|||||||
voted = votes.where("votable_type = ? AND votable_id IN (?)", "Debate", debates_ids)
|
voted = votes.where("votable_type = ? AND votable_id IN (?)", "Debate", debates_ids)
|
||||||
voted.each_with_object({}){ |v,_| _[v.votable_id] = v.vote_flag }
|
voted.each_with_object({}){ |v,_| _[v.votable_id] = v.vote_flag }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def administrator?
|
||||||
|
@is_administrator ||= Administrator.where(user_id: id).exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
def moderator?
|
||||||
|
@is_moderator ||= Moderator.where(user_id: id).exists?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
1
app/views/admin/dashboard/index.html.erb
Normal file
1
app/views/admin/dashboard/index.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<h1><%= t("admin.dashboard.index.title") %></h1>
|
||||||
1
app/views/moderation/dashboard/index.html.erb
Normal file
1
app/views/moderation/dashboard/index.html.erb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<h1><%= t("moderation.dashboard.index.title") %></h1>
|
||||||
@@ -85,6 +85,8 @@ search:
|
|||||||
# ignore_missing:
|
# ignore_missing:
|
||||||
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
|
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
|
||||||
# - '{devise,simple_form}.*'
|
# - '{devise,simple_form}.*'
|
||||||
|
ignore_missing:
|
||||||
|
- 'unauthorized.*'
|
||||||
|
|
||||||
## Consider these keys used:
|
## Consider these keys used:
|
||||||
ignore_unused:
|
ignore_unused:
|
||||||
@@ -93,6 +95,8 @@ ignore_unused:
|
|||||||
# - 'simple_form.{yes,no}'
|
# - 'simple_form.{yes,no}'
|
||||||
# - 'simple_form.{placeholders,hints,labels}.*'
|
# - 'simple_form.{placeholders,hints,labels}.*'
|
||||||
# - 'simple_form.{error_notification,required}.:'
|
# - 'simple_form.{error_notification,required}.:'
|
||||||
|
ignore_unused:
|
||||||
|
- 'unauthorized.*'
|
||||||
|
|
||||||
## Exclude these keys from the `i18n-tasks eq-base' report:
|
## Exclude these keys from the `i18n-tasks eq-base' report:
|
||||||
# ignore_eq_base:
|
# ignore_eq_base:
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ en:
|
|||||||
create_debate: Create a debate
|
create_debate: Create a debate
|
||||||
my_account_link: My account
|
my_account_link: My account
|
||||||
language: Site language
|
language: Site language
|
||||||
|
admin:
|
||||||
|
dashboard:
|
||||||
|
index:
|
||||||
|
title: Administration
|
||||||
|
moderation:
|
||||||
|
dashboard:
|
||||||
|
index:
|
||||||
|
title: Moderation
|
||||||
debates:
|
debates:
|
||||||
index:
|
index:
|
||||||
create_debate: Create a debate
|
create_debate: Create a debate
|
||||||
@@ -81,3 +89,7 @@ en:
|
|||||||
subject: Someone has commented on your debate
|
subject: Someone has commented on your debate
|
||||||
reply:
|
reply:
|
||||||
subject: Someone has replied to your comment
|
subject: Someone has replied to your comment
|
||||||
|
unauthorized:
|
||||||
|
default: "You are not authorized to access this page."
|
||||||
|
manage:
|
||||||
|
all: "You are not authorized to %{action} %{subject}."
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ es:
|
|||||||
create_debate: Crea un debate
|
create_debate: Crea un debate
|
||||||
my_account_link: Mi cuenta
|
my_account_link: Mi cuenta
|
||||||
language: Idioma de la página
|
language: Idioma de la página
|
||||||
|
admin:
|
||||||
|
dashboard:
|
||||||
|
index:
|
||||||
|
title: Administración
|
||||||
|
moderation:
|
||||||
|
dashboard:
|
||||||
|
index:
|
||||||
|
title: Moderación
|
||||||
debates:
|
debates:
|
||||||
index:
|
index:
|
||||||
create_debate: Crea un debate
|
create_debate: Crea un debate
|
||||||
@@ -81,3 +89,21 @@ es:
|
|||||||
subject: Alguien ha comentado en tu debate
|
subject: Alguien ha comentado en tu debate
|
||||||
reply:
|
reply:
|
||||||
subject: Alguien ha respondido a tu comentario
|
subject: Alguien ha respondido a tu comentario
|
||||||
|
unauthorized:
|
||||||
|
default: "No tienes permiso para acceder a esta página."
|
||||||
|
index:
|
||||||
|
all: "No tienes permiso para listar %{subject}"
|
||||||
|
show:
|
||||||
|
all: "No tienes permiso para ver %{subject}"
|
||||||
|
edit:
|
||||||
|
all: "No tienes permiso para editar %{subject}"
|
||||||
|
update:
|
||||||
|
all: "No tienes permiso para modificar %{subject}"
|
||||||
|
create:
|
||||||
|
all: "No tienes permiso para crear %{subject}"
|
||||||
|
delete:
|
||||||
|
all: "No tienes permiso para borrar %{subject}"
|
||||||
|
manage:
|
||||||
|
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,18 @@ Rails.application.routes.draw do
|
|||||||
post :vote
|
post :vote
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resource :account, controller: "account", only: [:show, :update]
|
resource :account, controller: "account", only: [:show, :update]
|
||||||
|
|
||||||
|
namespace :admin do
|
||||||
|
root to: "dashboard#index"
|
||||||
|
end
|
||||||
|
|
||||||
|
namespace :moderation do
|
||||||
|
root to: "dashboard#index"
|
||||||
|
end
|
||||||
|
|
||||||
# Example of regular route:
|
# Example of regular route:
|
||||||
# get 'products/:id' => 'catalog#view'
|
# get 'products/:id' => 'catalog#view'
|
||||||
|
|
||||||
|
|||||||
7
db/migrate/20150807140235_create_administrators.rb
Normal file
7
db/migrate/20150807140235_create_administrators.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class CreateAdministrators < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :administrators do |t|
|
||||||
|
t.belongs_to :user, index: true, foreign_key: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
7
db/migrate/20150807140346_create_moderators.rb
Normal file
7
db/migrate/20150807140346_create_moderators.rb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
class CreateModerators < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :moderators do |t|
|
||||||
|
t.belongs_to :user, index: true, foreign_key: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
16
db/schema.rb
16
db/schema.rb
@@ -11,11 +11,17 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20150806163142) do
|
ActiveRecord::Schema.define(version: 20150807140346) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
create_table "administrators", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "administrators", ["user_id"], name: "index_administrators_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "comments", force: :cascade do |t|
|
create_table "comments", force: :cascade do |t|
|
||||||
t.integer "commentable_id"
|
t.integer "commentable_id"
|
||||||
t.string "commentable_type"
|
t.string "commentable_type"
|
||||||
@@ -41,6 +47,12 @@ ActiveRecord::Schema.define(version: 20150806163142) do
|
|||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "moderators", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "moderators", ["user_id"], name: "index_moderators_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "taggings", force: :cascade do |t|
|
create_table "taggings", force: :cascade do |t|
|
||||||
t.integer "tag_id"
|
t.integer "tag_id"
|
||||||
t.integer "taggable_id"
|
t.integer "taggable_id"
|
||||||
@@ -105,4 +117,6 @@ ActiveRecord::Schema.define(version: 20150806163142) do
|
|||||||
add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree
|
add_index "votes", ["votable_id", "votable_type", "vote_scope"], name: "index_votes_on_votable_id_and_votable_type_and_vote_scope", using: :btree
|
||||||
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
|
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
|
||||||
|
|
||||||
|
add_foreign_key "administrators", "users"
|
||||||
|
add_foreign_key "moderators", "users"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -31,4 +31,12 @@ FactoryGirl.define do
|
|||||||
debate
|
debate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :administrator do
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :moderator do
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -10,6 +10,7 @@ feature 'Account' do
|
|||||||
login_as(@user)
|
login_as(@user)
|
||||||
visit root_path
|
visit root_path
|
||||||
click_link "My account"
|
click_link "My account"
|
||||||
|
expect(current_path).to eq(account_path)
|
||||||
|
|
||||||
expect(page).to have_selector("input[value='Manuela']")
|
expect(page).to have_selector("input[value='Manuela']")
|
||||||
expect(page).to have_selector("input[value='Colau']")
|
expect(page).to have_selector("input[value='Colau']")
|
||||||
|
|||||||
34
spec/features/admin_spec.rb
Normal file
34
spec/features/admin_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature 'Admin' do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
scenario 'Access as regular user is not authorized' do
|
||||||
|
login_as(user)
|
||||||
|
visit admin_root_path
|
||||||
|
|
||||||
|
expect(current_path).to eq(root_path)
|
||||||
|
expect(page).to have_content "not authorized"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Access as a moderator is not authorized' do
|
||||||
|
create(:moderator, user: user)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit admin_root_path
|
||||||
|
|
||||||
|
expect(current_path).to eq(root_path)
|
||||||
|
expect(page).to have_content "not authorized"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Access as an administrator is authorized' do
|
||||||
|
create(:administrator, user: user)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit admin_root_path
|
||||||
|
|
||||||
|
expect(current_path).to eq(admin_root_path)
|
||||||
|
expect(page).to_not have_content "not authorized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -98,9 +98,9 @@ feature 'Debates' do
|
|||||||
expect(debate).to be_editable
|
expect(debate).to be_editable
|
||||||
login_as(create(:user))
|
login_as(create(:user))
|
||||||
|
|
||||||
expect {
|
|
||||||
visit edit_debate_path(debate)
|
visit edit_debate_path(debate)
|
||||||
}.to raise_error ActiveRecord::RecordNotFound
|
expect(current_path).to eq(root_path)
|
||||||
|
expect(page).to have_content 'not authorized'
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'Update should not be posible if debate is not editable' do
|
scenario 'Update should not be posible if debate is not editable' do
|
||||||
@@ -109,17 +109,19 @@ feature 'Debates' do
|
|||||||
expect(debate).to_not be_editable
|
expect(debate).to_not be_editable
|
||||||
login_as(debate.author)
|
login_as(debate.author)
|
||||||
|
|
||||||
expect {
|
|
||||||
visit edit_debate_path(debate)
|
visit edit_debate_path(debate)
|
||||||
}.to raise_error ActiveRecord::RecordNotFound
|
edit_debate_path(debate)
|
||||||
|
expect(current_path).to eq(root_path)
|
||||||
|
expect(page).to have_content 'not authorized'
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'Update should be posible for the author of an editable debate' do
|
scenario 'Update should be posible for the author of an editable debate' do
|
||||||
debate = create(:debate)
|
debate = create(:debate)
|
||||||
login_as(debate.author)
|
login_as(debate.author)
|
||||||
|
|
||||||
visit debate_path(debate)
|
visit edit_debate_path(debate)
|
||||||
click_link 'Edit'
|
expect(current_path).to eq(edit_debate_path(debate))
|
||||||
|
|
||||||
fill_in 'debate_title', with: "End child poverty"
|
fill_in 'debate_title', with: "End child poverty"
|
||||||
fill_in 'debate_description', with: "Let's..."
|
fill_in 'debate_description', with: "Let's..."
|
||||||
|
|
||||||
|
|||||||
34
spec/features/moderation_spec.rb
Normal file
34
spec/features/moderation_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature 'Admin' do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
scenario 'Access as regular user is not authorized' do
|
||||||
|
login_as(user)
|
||||||
|
visit moderation_root_path
|
||||||
|
|
||||||
|
expect(current_path).to eq(root_path)
|
||||||
|
expect(page).to have_content "not authorized"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Access as a moderator is authorized' do
|
||||||
|
create(:moderator, user: user)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit moderation_root_path
|
||||||
|
|
||||||
|
expect(current_path).to eq(moderation_root_path)
|
||||||
|
expect(page).to_not have_content "not authorized"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Access as an administrator is authorized' do
|
||||||
|
create(:administrator, user: user)
|
||||||
|
|
||||||
|
login_as(user)
|
||||||
|
visit moderation_root_path
|
||||||
|
|
||||||
|
expect(current_path).to eq(moderation_root_path)
|
||||||
|
expect(page).to_not have_content "not authorized"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
67
spec/models/ability_spec.rb
Normal file
67
spec/models/ability_spec.rb
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
require 'cancan/matchers'
|
||||||
|
|
||||||
|
describe Ability do
|
||||||
|
subject(:ability) { Ability.new(user) }
|
||||||
|
let(:debate) { Debate.new }
|
||||||
|
|
||||||
|
describe "Non-logged in user" do
|
||||||
|
let(:user) { nil }
|
||||||
|
|
||||||
|
it { should be_able_to(:index, Debate) }
|
||||||
|
it { should be_able_to(:show, debate) }
|
||||||
|
it { should_not be_able_to(:edit, Debate) }
|
||||||
|
it { should_not be_able_to(:vote, Debate) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Citizen" do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
it { should be_able_to(:index, Debate) }
|
||||||
|
it { should be_able_to(:show, debate) }
|
||||||
|
it { should be_able_to(:vote, debate) }
|
||||||
|
|
||||||
|
it { should be_able_to(:show, user) }
|
||||||
|
it { should be_able_to(:edit, user) }
|
||||||
|
|
||||||
|
it { should be_able_to(:create, Comment) }
|
||||||
|
it { should be_able_to(:vote, Comment) }
|
||||||
|
|
||||||
|
describe "other users" do
|
||||||
|
let(:other_user) { create(:user) }
|
||||||
|
it { should_not be_able_to(:show, other_user) }
|
||||||
|
it { should_not be_able_to(:edit, other_user) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "editing debates" do
|
||||||
|
let(:own_debate) { create(:debate, author: user) }
|
||||||
|
let(:own_debate_non_editable) { create(:debate, author: user) }
|
||||||
|
|
||||||
|
before { allow(own_debate_non_editable).to receive(:editable?).and_return(false) }
|
||||||
|
|
||||||
|
it { should be_able_to(:edit, own_debate) }
|
||||||
|
it { should_not be_able_to(:edit, debate) } # Not his
|
||||||
|
it { should_not be_able_to(:edit, own_debate_non_editable) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Moderator" do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
before { create(:moderator, user: user) }
|
||||||
|
|
||||||
|
it { should be_able_to(:index, Debate) }
|
||||||
|
it { should be_able_to(:show, debate) }
|
||||||
|
it { should be_able_to(:vote, debate) }
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Administrator" do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
before { create(:administrator, user: user) }
|
||||||
|
|
||||||
|
it { should be_able_to(:index, Debate) }
|
||||||
|
it { should be_able_to(:show, debate) }
|
||||||
|
it { should be_able_to(:vote, debate) }
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -7,13 +7,13 @@ describe User do
|
|||||||
@user = create(:user)
|
@user = create(:user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return {} if no debate" do
|
it "returns {} if no debate" do
|
||||||
expect(@user.votes_on_debates()).to eq({})
|
expect(@user.votes_on_debates()).to eq({})
|
||||||
expect(@user.votes_on_debates([])).to eq({})
|
expect(@user.votes_on_debates([])).to eq({})
|
||||||
expect(@user.votes_on_debates([nil, nil])).to eq({})
|
expect(@user.votes_on_debates([nil, nil])).to eq({})
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should return a hash of debates ids and votes" do
|
it "returns a hash of debates ids and votes" do
|
||||||
debate1 = create(:debate)
|
debate1 = create(:debate)
|
||||||
debate2 = create(:debate)
|
debate2 = create(:debate)
|
||||||
debate3 = create(:debate)
|
debate3 = create(:debate)
|
||||||
@@ -87,4 +87,28 @@ describe User do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "administrator?" do
|
||||||
|
it "is false when the user is not an admin" do
|
||||||
|
expect(subject.administrator?).to be false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is true when the user is an admin" do
|
||||||
|
subject.save
|
||||||
|
create(:administrator, user: subject)
|
||||||
|
expect(subject.administrator?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "moderator?" do
|
||||||
|
it "is false when the user is not a moderator" do
|
||||||
|
expect(subject.moderator?).to be false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is true when the user is a moderator" do
|
||||||
|
subject.save
|
||||||
|
create(:moderator, user: subject)
|
||||||
|
expect(subject.moderator?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user