diff --git a/Gemfile b/Gemfile index a4e9b0e20..aeca43f64 100644 --- a/Gemfile +++ b/Gemfile @@ -34,6 +34,7 @@ gem 'cancancan' gem 'social-share-button' gem 'initialjs-rails' gem 'unicorn' +gem 'paranoia' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console diff --git a/Gemfile.lock b/Gemfile.lock index 2bcab8ad0..92b372edc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -179,6 +179,8 @@ GEM nokogiri (1.6.6.2) mini_portile (~> 0.6.0) orm_adapter (0.5.0) + paranoia (2.1.3) + activerecord (~> 4.0) pg (0.18.2) poltergeist (1.6.0) capybara (~> 2.1) @@ -331,6 +333,7 @@ DEPENDENCIES kaminari launchy letter_opener_web (~> 1.2.0) + paranoia pg poltergeist quiet_assets diff --git a/app/assets/javascripts/comments.js.coffee b/app/assets/javascripts/comments.js.coffee index 377fa4d1a..8a9ebe0b1 100644 --- a/app/assets/javascripts/comments.js.coffee +++ b/app/assets/javascripts/comments.js.coffee @@ -1,8 +1,11 @@ App.Comments = - add_response: (parent_id, response_html) -> + add_comment: (parent_id, response_html) -> $(response_html).insertAfter($("#js-comment-form-#{parent_id}")) + add_reply: (parent_id, response_html) -> + $("##{parent_id} .comment-children:first").prepend($(response_html)) + display_error: (field_with_errors, error_html) -> $(error_html).insertAfter($("#{field_with_errors}")) diff --git a/app/assets/javascripts/moderator_comment.js.coffee b/app/assets/javascripts/moderator_comment.js.coffee new file mode 100644 index 000000000..7cc680169 --- /dev/null +++ b/app/assets/javascripts/moderator_comment.js.coffee @@ -0,0 +1,7 @@ +App.ModeratorComments = + + add_class_faded: (id) -> + $("##{id} .comment-body:first").addClass("faded") + + hide_moderator_actions: (id) -> + $("##{id} #moderator-comment-actions:first").hide() \ No newline at end of file diff --git a/app/assets/javascripts/moderator_debates.js.coffee b/app/assets/javascripts/moderator_debates.js.coffee new file mode 100644 index 000000000..802504ec2 --- /dev/null +++ b/app/assets/javascripts/moderator_debates.js.coffee @@ -0,0 +1,8 @@ +App.ModeratorDebates = + + add_class_faded: (id) -> + $("##{id}").addClass("faded") + $("#comments").addClass("faded") + + hide_moderator_actions: (id) -> + $("##{id} #moderator-debate-actions:first").hide() \ No newline at end of file diff --git a/app/assets/stylesheets/debates.scss b/app/assets/stylesheets/debates.scss index f242e8757..afc99b75a 100644 --- a/app/assets/stylesheets/debates.scss +++ b/app/assets/stylesheets/debates.scss @@ -571,4 +571,9 @@ } } } + +} + +.faded { + opacity: 0.4; } diff --git a/app/assets/stylesheets/participacion.scss b/app/assets/stylesheets/participacion.scss index 6e5ad3d7b..710fb8c6d 100644 --- a/app/assets/stylesheets/participacion.scss +++ b/app/assets/stylesheets/participacion.scss @@ -134,7 +134,7 @@ header { min-height: rem-calc(480); &.results { - min-height: rem-calc(192); + min-height: rem-calc(216); } h1 { @@ -276,6 +276,35 @@ header { } } +.subnavigation { + background: white; + border-bottom: 1px solid white; + clear: both; + + a { + color: $link; + font-size: rem-calc(14); + font-weight: bold; + + &.active { + color: $text; + + &:after { + bottom: -17px; + left: 50%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + border-top-color: #fff; + border-width: 8px; + margin-left: -8px; + } + } + } +} + // 05. Footer // - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 81ec67996..7a812104b 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -1,6 +1,5 @@ class Admin::BaseController < ApplicationController layout 'admin' - before_action :authenticate_user! skip_authorization_check diff --git a/app/controllers/admin/comments_controller.rb b/app/controllers/admin/comments_controller.rb new file mode 100644 index 000000000..4c385b5d4 --- /dev/null +++ b/app/controllers/admin/comments_controller.rb @@ -0,0 +1,13 @@ +class Admin::CommentsController < Admin::BaseController + + def index + @comments = Comment.only_hidden + end + + def restore + @comment = Comment.with_hidden.find(params[:id]) + @comment.restore + redirect_to admin_comments_path, notice: t('admin.comments.restore.success') + end + +end \ No newline at end of file diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 870d7ef55..f7aa5c440 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -1,5 +1,4 @@ class Admin::DashboardController < Admin::BaseController - layout 'admin' def index end diff --git a/app/controllers/admin/debates_controller.rb b/app/controllers/admin/debates_controller.rb new file mode 100644 index 000000000..a37744f71 --- /dev/null +++ b/app/controllers/admin/debates_controller.rb @@ -0,0 +1,16 @@ +class Admin::DebatesController < Admin::BaseController + + def index + @debates = Debate.only_hidden + end + + def show + @debate = Debate.with_hidden.find(params[:id]) + end + + def restore + @debate = Debate.with_hidden.find(params[:id]) + @debate.restore + redirect_to admin_debates_path, notice: t('admin.debates.restore.success') + end +end \ No newline at end of file diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 71de112a9..a10d80da9 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -2,6 +2,7 @@ class CommentsController < ApplicationController before_action :authenticate_user! before_action :build_comment, only: :create before_action :parent, only: :create + load_and_authorize_resource respond_to :html, :js @@ -50,4 +51,5 @@ class CommentsController < ApplicationController def email_on_comment_reply? reply? && parent.author.email_on_comment_reply? end + end diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb index 0816245c7..eeb82825a 100644 --- a/app/controllers/debates_controller.rb +++ b/app/controllers/debates_controller.rb @@ -1,6 +1,8 @@ class DebatesController < ApplicationController before_action :authenticate_user!, except: [:index, :show] + load_and_authorize_resource + respond_to :html, :js def index @debates = Debate.search(params) @@ -9,6 +11,7 @@ class DebatesController < ApplicationController def show set_debate_votes(@debate) + @comments = @debate.root_comments.with_hidden.recent end def new @@ -46,7 +49,6 @@ class DebatesController < ApplicationController set_debate_votes(@debate) end - private def debate_params diff --git a/app/controllers/moderation/comments_controller.rb b/app/controllers/moderation/comments_controller.rb new file mode 100644 index 000000000..c250fc460 --- /dev/null +++ b/app/controllers/moderation/comments_controller.rb @@ -0,0 +1,8 @@ +class Moderation::CommentsController < Moderation::BaseController + + def hide + @comment = Comment.find(params[:id]) + @comment.hide + end + +end \ No newline at end of file diff --git a/app/controllers/moderation/dashboard_controller.rb b/app/controllers/moderation/dashboard_controller.rb index 86196af37..ceaddd6f4 100644 --- a/app/controllers/moderation/dashboard_controller.rb +++ b/app/controllers/moderation/dashboard_controller.rb @@ -1,5 +1,4 @@ class Moderation::DashboardController < Moderation::BaseController - layout 'admin' def index end diff --git a/app/controllers/moderation/debates_controller.rb b/app/controllers/moderation/debates_controller.rb new file mode 100644 index 000000000..cb5599092 --- /dev/null +++ b/app/controllers/moderation/debates_controller.rb @@ -0,0 +1,7 @@ +class Moderation::DebatesController < Moderation::BaseController + + def hide + @debate = Debate.find(params[:id]) + @debate.hide + end +end \ No newline at end of file diff --git a/app/helpers/abilities_helper.rb b/app/helpers/abilities_helper.rb new file mode 100644 index 000000000..462af0479 --- /dev/null +++ b/app/helpers/abilities_helper.rb @@ -0,0 +1,7 @@ +module AbilitiesHelper + + def moderator? + current_user.try(:moderator?) + end + +end \ No newline at end of file diff --git a/app/models/ability.rb b/app/models/ability.rb index 0d1a518bf..8dcb319e3 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -27,8 +27,12 @@ class Ability can(:verify, Organization){ |o| !o.verified? } can(:reject, Organization){ |o| !o.rejected? } - elsif user.administrator? + can :hide, Comment + can :hide, Debate + elsif user.administrator? + can :restore, Comment + can :restore, Debate end end end diff --git a/app/models/comment.rb b/app/models/comment.rb index b8182b04f..f8a43c222 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,5 +1,8 @@ class Comment < ActiveRecord::Base + include ActsAsParanoidAliases acts_as_nested_set scope: [:commentable_id, :commentable_type], counter_cache: :children_count + + acts_as_paranoid column: :hidden_at acts_as_votable validates :body, presence: true diff --git a/app/models/debate.rb b/app/models/debate.rb index b0d022c51..e029ffdd4 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -1,5 +1,6 @@ require 'numeric' class Debate < ActiveRecord::Base + include ActsAsParanoidAliases default_scope { order('created_at DESC') } apply_simple_captcha @@ -8,6 +9,7 @@ class Debate < ActiveRecord::Base acts_as_votable acts_as_commentable acts_as_taggable + acts_as_paranoid column: :hidden_at belongs_to :author, class_name: 'User', foreign_key: 'author_id' diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 007dd966f..a6a05ab32 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -1,6 +1,6 @@ -
+ diff --git a/app/views/admin/comments/index.html.erb b/app/views/admin/comments/index.html.erb new file mode 100644 index 000000000..1555fda0c --- /dev/null +++ b/app/views/admin/comments/index.html.erb @@ -0,0 +1,14 @@ +<%= notice %>
diff --git a/app/views/moderation/comments/hide.js.erb b/app/views/moderation/comments/hide.js.erb new file mode 100644 index 000000000..4583aff53 --- /dev/null +++ b/app/views/moderation/comments/hide.js.erb @@ -0,0 +1,3 @@ +var comment_id = '<%= dom_id(@comment) %>'; +App.ModeratorComments.add_class_faded(comment_id); +App.ModeratorComments.hide_moderator_actions(comment_id); \ No newline at end of file diff --git a/app/views/moderation/debates/hide.js.erb b/app/views/moderation/debates/hide.js.erb new file mode 100644 index 000000000..1502feb08 --- /dev/null +++ b/app/views/moderation/debates/hide.js.erb @@ -0,0 +1,3 @@ +var debate_id = '<%= dom_id(@debate) %>'; +App.ModeratorDebates.add_class_faded(debate_id); +App.ModeratorDebates.hide_moderator_actions(debate_id); \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index e455f417a..03ca5bc4d 100644 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -1,11 +1,13 @@ en: admin: - menu: - tags: Tags - organizations: Organizations dashboard: index: title: Administration + menu: + debate_topics: Debate topics + hidden_debates: Hidden debates + hidden_comments: Hidden comments + organizations: Organizations organizations: index: title: Organizations @@ -19,6 +21,10 @@ en: pending: Pending verified: Verified rejected: Rejected + actions: + hide: Hide + restore: Restore + confirm: 'Are you sure?' tags: index: title: 'Debate topics' @@ -27,4 +33,13 @@ en: name: placeholder: 'Write a topic' destroy: Delete Tag - + comments: + index: + title: Hidden comments + restore: + success: The comment has been restored + debates: + index: + title: Hidden debates + restore: + success: The debate has been restored diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 0813a1931..370933b22 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -1,11 +1,13 @@ es: admin: - menu: - tags: Temas de debate - organizations: Organizaciones dashboard: index: title: Administración + menu: + debate_topics: Temas de debate + hidden_debates: Debates ocultos + hidden_comments: Comentarios ocultos + organizations: Organizaciones organizations: index: title: Organizaciones @@ -19,6 +21,10 @@ es: pending: Pendientes verified: Verificadas rejected: Rechazadas + actions: + hide: Ocultar + restore: Permitir + confirm: '¿Estás seguro?' tags: index: title: 'Temas de debate' @@ -27,3 +33,13 @@ es: name: placeholder: 'Escribe el nombre del tema' destroy: Elimina la etiqueta + comments: + index: + title: Comentarios ocultos + restore: + success: El comentario ha sido permitido + debates: + index: + title: Debates ocultos + restore: + success: El debate ha sido permitido diff --git a/config/locales/en.yml b/config/locales/en.yml index e5d6882c5..4cd62d7bf 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -15,6 +15,10 @@ en: language: Site language administration: Administration moderation: Moderation + welcome: Welcome + news: News + debates: Debates + initiatives: Initiatives footer: copyright: "Ayuntamiento de Madrid, 2015. All rights reserved" form: @@ -38,6 +42,7 @@ en: one: 1 vote other: "%{count} votes" comment: + deleted: This comment has been deleted responses: zero: No Responses one: 1 Response diff --git a/config/locales/es.yml b/config/locales/es.yml index ea68e07f8..a93143bdd 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -15,6 +15,10 @@ es: language: Idioma de la página administration: Administar moderation: Moderar + welcome: Portada + news: Novedades + debates: Debates + initiatives: Iniciativas footer: copyright: "Ayuntamiento de Madrid, %{year}. Todos los derechos reservados" form: @@ -38,6 +42,7 @@ es: one: 1 voto other: "%{count} votos" comment: + deleted: Este comentario ha sido eliminado responses: zero: Sin respuestas one: 1 Respuesta diff --git a/config/routes.rb b/config/routes.rb index 34fa752e1..fa4e848a6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,14 +13,10 @@ Rails.application.routes.draw do root 'welcome#index' resources :debates do - member do - post :vote - end + member { post :vote } resources :comments, only: :create, shallow: true do - member do - post :vote - end + member { post :vote } end end @@ -35,11 +31,27 @@ Rails.application.routes.draw do end end + resources :debates, only: [:index, :show] do + member { put :restore } + end + + resources :comments, only: :index do + member { put :restore } + end + resources :tags, only: [:index, :create, :update, :destroy] end namespace :moderation do root to: "dashboard#index" + + resources :debates, only: [] do + member { put :hide } + end + + resources :comments, only: [:index] do + member { put :hide } + end end # Example of regular route: diff --git a/db/migrate/20150810201448_add_hidden_at_to_comments.rb b/db/migrate/20150810201448_add_hidden_at_to_comments.rb new file mode 100644 index 000000000..55d652087 --- /dev/null +++ b/db/migrate/20150810201448_add_hidden_at_to_comments.rb @@ -0,0 +1,6 @@ +class AddHiddenAtToComments < ActiveRecord::Migration + def change + add_column :comments, :hidden_at, :datetime + add_index :comments, :hidden_at + end +end diff --git a/db/migrate/20150811145628_add_hidden_at_to_debates.rb b/db/migrate/20150811145628_add_hidden_at_to_debates.rb new file mode 100644 index 000000000..5fbb29532 --- /dev/null +++ b/db/migrate/20150811145628_add_hidden_at_to_debates.rb @@ -0,0 +1,6 @@ +class AddHiddenAtToDebates < ActiveRecord::Migration + def change + add_column :debates, :hidden_at, :datetime + add_index :debates, :hidden_at + end +end diff --git a/db/schema.rb b/db/schema.rb index e0ca3ab78..2879e876b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,7 +12,6 @@ # It's strongly recommended that you check this file into your version control system. ActiveRecord::Schema.define(version: 20150815154430) do - # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -35,9 +34,11 @@ ActiveRecord::Schema.define(version: 20150815154430) do t.datetime "created_at" t.datetime "updated_at" t.integer "children_count", default: 0 + t.datetime "hidden_at" end add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree + add_index "comments", ["hidden_at"], name: "index_comments_on_hidden_at", using: :btree add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree create_table "debates", force: :cascade do |t| @@ -46,8 +47,11 @@ ActiveRecord::Schema.define(version: 20150815154430) do t.integer "author_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.datetime "hidden_at" end + add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree + create_table "moderators", force: :cascade do |t| t.integer "user_id" end diff --git a/lib/acts_as_paranoid_aliases.rb b/lib/acts_as_paranoid_aliases.rb new file mode 100644 index 000000000..066ce3e29 --- /dev/null +++ b/lib/acts_as_paranoid_aliases.rb @@ -0,0 +1,29 @@ +module ActsAsParanoidAliases + + def self.included(base) + base.extend(ClassMethods) + + def hide + update_attribute(:hidden_at, Time.now) + end + + def hidden? + deleted? + end + end + + module ClassMethods + def with_hidden + with_deleted + end + + def only_hidden + only_deleted + end + end + +end + +module ActsAsParanoid + include ActsAsParanoidAliases +end \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb index 6bf82bbaa..2d0dd2c8f 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -13,6 +13,10 @@ FactoryGirl.define do description 'Debate description' terms_of_service '1' association :author, factory: :user + + trait :hidden do + hidden_at Time.now + end end factory :vote do @@ -25,6 +29,10 @@ FactoryGirl.define do association :commentable, factory: :debate user body 'Comment body' + + trait :hidden do + hidden_at Time.now + end end factory :administrator do diff --git a/spec/features/admin/comments_spec.rb b/spec/features/admin/comments_spec.rb new file mode 100644 index 000000000..6e4a0d53d --- /dev/null +++ b/spec/features/admin/comments_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +feature 'Admin comments' do + + scenario 'Restore', :js do + citizen = create(:user) + admin = create(:administrator) + + debate = create(:debate) + comment = create(:comment, :hidden, commentable: debate, body: 'Not really SPAM') + + login_as(admin.user) + visit admin_comments_path + + within("#comment_#{comment.id}") do + first(:link, "Restore").click + end + + expect(page).to have_content 'The comment has been restored' + + login_as(citizen) + visit debate_path(debate) + + expect(page).to have_css('.comment', count: 1) + expect(page).to have_content('Not really SPAM') + end + +end \ No newline at end of file diff --git a/spec/features/admin/debates_spec.rb b/spec/features/admin/debates_spec.rb new file mode 100644 index 000000000..50859816e --- /dev/null +++ b/spec/features/admin/debates_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +feature 'Admin debates' do + + scenario 'Restore', :js do + citizen = create(:user) + admin = create(:administrator) + + debate = create(:debate, :hidden) + + login_as(admin.user) + visit admin_debate_path(debate) + + click_link 'Restore' + + expect(page).to have_content 'The debate has been restored' + + login_as(citizen) + visit debates_path + + expect(page).to have_css('.debate', count: 1) + end +end diff --git a/spec/features/comments_spec.rb b/spec/features/comments_spec.rb index 27a7ac1cd..b1f311be5 100644 --- a/spec/features/comments_spec.rb +++ b/spec/features/comments_spec.rb @@ -77,7 +77,7 @@ feature 'Comments' do click_button 'Publish reply' end - within("#comment-#{comment.id}") do + within "#comment_#{comment.id}" do expect(page).to have_content 'It will be done next week.' end diff --git a/spec/features/moderation/comments_spec.rb b/spec/features/moderation/comments_spec.rb new file mode 100644 index 000000000..099946d82 --- /dev/null +++ b/spec/features/moderation/comments_spec.rb @@ -0,0 +1,72 @@ +require 'rails_helper' + +feature 'Moderate Comments' do + + scenario 'Hide', :js do + citizen = create(:user) + moderator = create(:moderator) + + debate = create(:debate) + comment = create(:comment, commentable: debate, body: 'SPAM') + + login_as(moderator.user) + visit debate_path(debate) + + within("#comment_#{comment.id}") do + click_link 'Hide' + expect(page).to have_css('.comment .faded') + end + + login_as(citizen) + visit debate_path(debate) + + expect(page).to have_css('.comment', count: 1) + expect(page).to have_content('This comment has been deleted') + expect(page).to_not have_content('SPAM') + end + + scenario 'Children visible', :js do + citizen = create(:user) + moderator = create(:moderator) + + debate = create(:debate) + comment = create(:comment, commentable: debate, body: 'SPAM') + reply = create(:comment, commentable: debate, body: 'Acceptable reply', parent_id: comment.id) + + login_as(moderator.user) + visit debate_path(debate) + + within("#comment_#{comment.id}") do + first(:link, "Hide").click + expect(page).to have_css('.comment .faded') + end + + login_as(citizen) + visit debate_path(debate) + + expect(page).to have_css('.comment', count: 2) + expect(page).to have_content('This comment has been deleted') + expect(page).to_not have_content('SPAM') + + expect(page).to have_content('Acceptable reply') + end + + scenario 'Moderator actions' do + citizen = create(:user) + moderator = create(:moderator) + + debate = create(:debate) + comment = create(:comment, commentable: debate) + + login_as(moderator.user) + visit debate_path(debate) + + expect(page).to have_css("#moderator-comment-actions") + + login_as(citizen) + visit debate_path(debate) + + expect(page).to_not have_css("#moderator-comment-actions") + end + +end \ No newline at end of file diff --git a/spec/features/moderation/debates_spec.rb b/spec/features/moderation/debates_spec.rb new file mode 100644 index 000000000..388044a72 --- /dev/null +++ b/spec/features/moderation/debates_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +feature 'Moderate debates' do + + scenario 'Hide', :js do + citizen = create(:user) + moderator = create(:moderator) + + debate = create(:debate) + + login_as(moderator.user) + visit debate_path(debate) + + within("#debate_#{debate.id}") do + click_link 'Hide' + end + + login_as(citizen) + visit debates_path + + expect(page).to have_css('.debate', count: 0) + end + +end \ No newline at end of file diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 0cc6edcc8..20a3456d4 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -4,6 +4,7 @@ require 'cancan/matchers' describe Ability do subject(:ability) { Ability.new(user) } let(:debate) { Debate.new } + let(:comment) { create(:comment) } describe "Non-logged in user" do let(:user) { nil } @@ -84,6 +85,12 @@ describe Ability do it { should_not be_able_to(:reject, rejected_organization) } it { should be_able_to( :verify, rejected_organization) } end + + it { should be_able_to(:hide, comment) } + it { should be_able_to(:hide, debate) } + + it { should_not be_able_to(:restore, comment) } + it { should_not be_able_to(:restore, debate) } end describe "Administrator" do @@ -94,5 +101,7 @@ describe Ability do it { should be_able_to(:show, debate) } it { should be_able_to(:vote, debate) } + it { should be_able_to(:restore, comment) } + it { should be_able_to(:restore, debate) } end end
<%= comment.body %>
+ <%= avatar_image(comment.user, size: 32, class: 'left') %> - - <%= render 'comments/votes', comment: comment %> - +<%= comment.body %>
-- <%= t("debates.comment.responses", count: comment.children_count) %> - <% if user_signed_in? %> - | - <%= render 'comments/form', {parent: comment, toggeable: true} %> - <% end %> -
-+ <%= t("debates.comment.responses", count: comment.children_count) %> + + <% if user_signed_in? %> + | + <%= link_to(comment_link_text(comment), "", + class: "js-add-comment-link", data: {'id': dom_id(comment)}) %> + + <% if moderator? %> + <%= render 'comments/actions', comment: comment %> + <% end %> + + <%= render 'comments/form', {parent: comment, toggeable: true} %> + <% end %> +
+