Merge pull request #234 from AyuntamientoMadrid/moderator_comments
Moderator/Administrator comments
This commit is contained in:
BIN
app/assets/images/admin_avatar.png
Normal file
BIN
app/assets/images/admin_avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/assets/images/moderator_avatar.png
Normal file
BIN
app/assets/images/moderator_avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@@ -249,6 +249,7 @@
|
||||
|
||||
.panel {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
margin-bottom: 0;
|
||||
min-height: rem-calc(192);
|
||||
padding: 0 rem-calc(12) rem-calc(2) rem-calc(12);
|
||||
@@ -567,6 +568,15 @@
|
||||
background: $comment-author;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
|
||||
&.is-admin {
|
||||
background: $comment-admin;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
|
||||
&.is-moderator {
|
||||
@extend .is-admin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -548,19 +548,19 @@ form {
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
input[type]:not([type=submit]):not([type=file]) {
|
||||
input[type]:not([type=submit]):not([type=file]):not([type=checkbox]) {
|
||||
background: $input-bg;
|
||||
height: rem-calc(48);
|
||||
margin-bottom: rem-calc(16);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
height: rem-calc(24) !important;
|
||||
margin: 0 !important;
|
||||
input[type="checkbox"] + label,
|
||||
input[type="radio"] + label {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
margin: rem-calc(12) 0;
|
||||
margin: rem-calc(12) 0 rem-calc(12) rem-calc(6);
|
||||
}
|
||||
|
||||
.note {
|
||||
@@ -579,8 +579,7 @@ form {
|
||||
font-size: rem-calc(14);
|
||||
font-weight: normal;
|
||||
line-height: $line-height;
|
||||
margin: 0 0 0 rem-calc(6);
|
||||
vertical-align: top;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.captcha {
|
||||
@@ -591,6 +590,10 @@ form {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.button.margin-top {
|
||||
margin-top: rem-calc(24);
|
||||
}
|
||||
}
|
||||
|
||||
// 09. Alerts
|
||||
@@ -689,11 +692,15 @@ form {
|
||||
}
|
||||
}
|
||||
|
||||
img.initialjs-avatar, img.avatar {
|
||||
img.admin-avatar, img.moderator-avatar {
|
||||
border-radius: rem-calc(1000);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img.initialjs-avatar {
|
||||
@extend .moderator-avatar;
|
||||
}
|
||||
|
||||
.author-deleted {
|
||||
background-color: rgba(255,255,255,.5);
|
||||
color: rgba(0,0,0,.4);
|
||||
|
||||
@@ -77,8 +77,9 @@ $author: #008CCF;
|
||||
$association: #C0392B;
|
||||
|
||||
$comment-author: rgba(45,144,248,.15);
|
||||
$comment-official: rgba(70,219,145,.3);
|
||||
$comment-level-5: rgba(255,241,204,1);
|
||||
$comment-admin: rgba(45,144,248,.15);
|
||||
$comment-official: rgba(70,219,145,.3);
|
||||
|
||||
// 06. Responsive
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
@@ -35,11 +35,20 @@ class CommentsController < ApplicationController
|
||||
private
|
||||
|
||||
def comment_params
|
||||
params.require(:comment).permit(:commentable_type, :commentable_id, :body)
|
||||
params.require(:comment).permit(:commentable_type, :commentable_id, :body, :as_moderator, :as_administrator)
|
||||
end
|
||||
|
||||
def build_comment
|
||||
@comment = Comment.build(debate, current_user, comment_params[:body])
|
||||
check_for_special_comments
|
||||
end
|
||||
|
||||
def check_for_special_comments
|
||||
if administrator_comment?
|
||||
@comment.administrator_id = current_user.administrator.id
|
||||
elsif moderator_comment?
|
||||
@comment.moderator_id = current_user.moderator.id
|
||||
end
|
||||
end
|
||||
|
||||
def debate
|
||||
@@ -62,4 +71,12 @@ class CommentsController < ApplicationController
|
||||
reply? && parent.author.email_on_comment_reply?
|
||||
end
|
||||
|
||||
def administrator_comment?
|
||||
["1", true].include?(comment_params[:as_administrator]) && can?(:comment_as_administrator, Debate)
|
||||
end
|
||||
|
||||
def moderator_comment?
|
||||
["1", true].include?(comment_params[:as_moderator]) && can?(:comment_as_moderator, Debate)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -66,10 +66,15 @@ class Ability
|
||||
cannot :hide, User, id: user.id
|
||||
end
|
||||
|
||||
if user.moderator?
|
||||
can :comment_as_moderator, [Debate, Comment]
|
||||
end
|
||||
|
||||
if user.administrator?
|
||||
can :restore, Comment
|
||||
can :restore, Debate
|
||||
can :restore, User
|
||||
can :comment_as_administrator, [Debate, Comment]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
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
|
||||
|
||||
attr_accessor :as_moderator, :as_administrator
|
||||
|
||||
validates :body, presence: true
|
||||
validates :user, presence: true
|
||||
|
||||
@@ -59,6 +60,14 @@ class Comment < ActiveRecord::Base
|
||||
reviewed_at.present?
|
||||
end
|
||||
|
||||
def as_administrator?
|
||||
administrator_id.present?
|
||||
end
|
||||
|
||||
def as_moderator?
|
||||
moderator_id.present?
|
||||
end
|
||||
|
||||
def mark_as_reviewed
|
||||
update(reviewed_at: Time.now)
|
||||
end
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
<%= t("debates.comment.deleted") %>
|
||||
<% else %>
|
||||
|
||||
<% if comment.as_administrator? %>
|
||||
<%= image_tag("admin_avatar.png", size: 32, class: "admin-avatar left") %>
|
||||
<% elsif comment.as_moderator? %>
|
||||
<%= image_tag("moderator_avatar.png", size: 32, class: "moderator-avatar left") %>
|
||||
<% else %>
|
||||
|
||||
<% if comment.user.organization? %>
|
||||
<%= image_tag("collective_avatar.png", size: 32, class: "avatar left") %>
|
||||
<% else %>
|
||||
@@ -14,9 +20,17 @@
|
||||
<i class="icon-deleted user-deleted"></i>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
|
||||
<div class="comment-body">
|
||||
<div class="comment-info">
|
||||
|
||||
<% if comment.as_administrator? %>
|
||||
<span class="user-name"><%= t("debates.comment.admin") %> #<%= comment.administrator_id%></span>
|
||||
<% elsif comment.as_moderator? %>
|
||||
<span class="user-name"><%= t("debates.comment.moderator") %> #<%= comment.moderator_id%></span>
|
||||
<% else %>
|
||||
|
||||
<% if comment.user.hidden? %>
|
||||
<span class="user-name"><%= t("debates.comment.user_deleted") %></span>
|
||||
<% else %>
|
||||
@@ -40,15 +54,21 @@
|
||||
<%= t("debates.comment.author") %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
|
||||
• <%= time_ago_in_words(comment.created_at) %>
|
||||
|
||||
<span class="right js-flag-as-inappropiate-actions">
|
||||
<%= render 'comments/flag_as_inappropiate_actions', comment: comment %>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<% if comment.user.official? && comment.user_id == @debate.author_id %>
|
||||
<% if comment.as_administrator? %>
|
||||
<p class="comment-user is-admin"><%= comment.body %></p>
|
||||
<% elsif comment.as_moderator? %>
|
||||
<p class="comment-user is-moderator"><%= comment.body %></p>
|
||||
<% elsif comment.user.official? && comment.user_id == @debate.author_id %>
|
||||
<p class="comment-user level-<%= comment.user.official_level %> is-author"><%= comment.body %></p>
|
||||
<% elsif comment.user.official? %>
|
||||
<p class="comment-user level-<%= comment.user.official_level %>"><%= comment.body %></p>
|
||||
@@ -81,6 +101,5 @@
|
||||
<div class="comment-children">
|
||||
<%= render comment.children.with_hidden.reorder('id DESC, lft') %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,6 +4,19 @@
|
||||
<%= f.hidden_field :commentable_type, value: parent.class %>
|
||||
<%= f.hidden_field :commentable_id, value: parent.id %>
|
||||
|
||||
<%= f.submit comment_button_text(parent), class: "button radius small" %>
|
||||
<%= f.submit comment_button_text(parent), class: "button radius small inline-block" %>
|
||||
|
||||
<% if can? :comment_as_moderator, @debate %>
|
||||
<div class="right">
|
||||
<%= f.check_box :as_moderator, label: false %>
|
||||
<%= f.label :as_moderator, t("comments.form.comment_as_moderator"), class: "checkbox" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if can? :comment_as_administrator, @debate %>
|
||||
<div class="right">
|
||||
<%= f.check_box :as_administrator, label: false %>
|
||||
<%= f.label :as_administrator, t("comments.form.comment_as_admin"), class: "checkbox" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -49,6 +49,8 @@ en:
|
||||
other: "%{count} votes"
|
||||
comment:
|
||||
author: Debate's author
|
||||
moderator: Moderator
|
||||
admin: Administrator
|
||||
deleted: This comment has been deleted
|
||||
user_deleted: Deleted user
|
||||
responses:
|
||||
@@ -95,6 +97,8 @@ en:
|
||||
comments:
|
||||
form:
|
||||
leave_comment: Write a comment
|
||||
comment_as_moderator: Comment as moderator
|
||||
comment_as_admin: Comment as administrator
|
||||
comments_helper:
|
||||
comment_link: Comment
|
||||
comment_button: Publish comment
|
||||
|
||||
@@ -49,6 +49,8 @@ es:
|
||||
other: "%{count} votos"
|
||||
comment:
|
||||
author: Autor del debate
|
||||
moderator: Moderador
|
||||
admin: Administrador
|
||||
deleted: Este comentario ha sido eliminado
|
||||
user_deleted: Usuario eliminado
|
||||
responses:
|
||||
@@ -95,6 +97,8 @@ es:
|
||||
comments:
|
||||
form:
|
||||
leave_comment: Deja tu comentario
|
||||
comment_as_moderator: Comentar como moderador
|
||||
comment_as_admin: Comentar como administrador
|
||||
comments_helper:
|
||||
comment_link: Comentar
|
||||
comment_button: Publicar comentario
|
||||
|
||||
5
db/migrate/20150824111844_add_moderator_id_to_comment.rb
Normal file
5
db/migrate/20150824111844_add_moderator_id_to_comment.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddModeratorIdToComment < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :comments, :moderator_id, :integer, default: nil
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddAdministratorIdToComment < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :comments, :administrator_id, :integer, default: nil
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150821180155) do
|
||||
ActiveRecord::Schema.define(version: 20150824113326) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -52,6 +52,8 @@ ActiveRecord::Schema.define(version: 20150821180155) do
|
||||
t.datetime "flagged_as_inappropiate_at"
|
||||
t.integer "inappropiate_flags_count", default: 0
|
||||
t.datetime "reviewed_at"
|
||||
t.integer "moderator_id"
|
||||
t.integer "administrator_id"
|
||||
end
|
||||
|
||||
add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree
|
||||
|
||||
@@ -168,4 +168,122 @@ feature 'Comments' do
|
||||
expect(InappropiateFlag.flagged?(user, comment)).to_not be
|
||||
end
|
||||
|
||||
feature "Moderators" do
|
||||
scenario "can create comment as a moderator", :js do
|
||||
moderator = create(:moderator)
|
||||
debate = create(:debate)
|
||||
|
||||
login_as(moderator.user)
|
||||
visit debate_path(debate)
|
||||
|
||||
fill_in "comment_body", with: "I am moderating!"
|
||||
check "comment_as_moderator"
|
||||
click_button "Publish comment"
|
||||
|
||||
within "#comments" do
|
||||
expect(page).to have_content "I am moderating!"
|
||||
expect(page).to have_content "Moderator ##{moderator.id}"
|
||||
expect(page).to have_css "p.is-moderator"
|
||||
expect(page).to have_css "img.moderator-avatar"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "can create reply as a moderator", :js do
|
||||
citizen = create(:user, username: "Ana")
|
||||
manuela = create(:user, username: "Manuela")
|
||||
moderator = create(:moderator, user: manuela)
|
||||
debate = create(:debate)
|
||||
comment = create(:comment, commentable: debate, user: citizen)
|
||||
|
||||
login_as(manuela)
|
||||
visit debate_path(debate)
|
||||
|
||||
click_link "Reply"
|
||||
|
||||
within "#js-comment-form-comment_#{comment.id}" do
|
||||
fill_in "comment_body", with: "I am moderating!"
|
||||
check "comment_as_moderator"
|
||||
click_button 'Publish reply'
|
||||
end
|
||||
|
||||
within "#comment_#{comment.id}" do
|
||||
expect(page).to have_content "I am moderating!"
|
||||
expect(page).to have_content "Moderator ##{moderator.id}"
|
||||
expect(page).to have_css "p.is-moderator"
|
||||
expect(page).to have_css "img.moderator-avatar"
|
||||
end
|
||||
|
||||
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
|
||||
end
|
||||
|
||||
scenario "can not comment as an administrator" do
|
||||
moderator = create(:moderator)
|
||||
debate = create(:debate)
|
||||
|
||||
login_as(moderator.user)
|
||||
visit debate_path(debate)
|
||||
|
||||
expect(page).to_not have_content "Comment as administrator"
|
||||
end
|
||||
end
|
||||
|
||||
feature "Administrators" do
|
||||
scenario "can create comment as an administrator", :js do
|
||||
admin = create(:administrator)
|
||||
debate = create(:debate)
|
||||
|
||||
login_as(admin.user)
|
||||
visit debate_path(debate)
|
||||
|
||||
fill_in "comment_body", with: "I am your Admin!"
|
||||
check "comment_as_administrator"
|
||||
click_button "Publish comment"
|
||||
|
||||
within "#comments" do
|
||||
expect(page).to have_content "I am your Admin!"
|
||||
expect(page).to have_content "Administrator ##{admin.id}"
|
||||
expect(page).to have_css "p.is-admin"
|
||||
expect(page).to have_css "img.admin-avatar"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "can create reply as an administrator", :js do
|
||||
citizen = create(:user, username: "Ana")
|
||||
manuela = create(:user, username: "Manuela")
|
||||
admin = create(:administrator, user: manuela)
|
||||
debate = create(:debate)
|
||||
comment = create(:comment, commentable: debate, user: citizen)
|
||||
|
||||
login_as(manuela)
|
||||
visit debate_path(debate)
|
||||
|
||||
click_link "Reply"
|
||||
|
||||
within "#js-comment-form-comment_#{comment.id}" do
|
||||
fill_in "comment_body", with: "Top of the world!"
|
||||
check "comment_as_administrator"
|
||||
click_button 'Publish reply'
|
||||
end
|
||||
|
||||
within "#comment_#{comment.id}" do
|
||||
expect(page).to have_content "Top of the world!"
|
||||
expect(page).to have_content "Administrator ##{admin.id}"
|
||||
expect(page).to have_css "p.is-admin"
|
||||
expect(page).to have_css "img.admin-avatar"
|
||||
end
|
||||
|
||||
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
|
||||
end
|
||||
|
||||
scenario "can not comment as a moderator" do
|
||||
admin = create(:administrator)
|
||||
debate = create(:debate)
|
||||
|
||||
login_as(admin.user)
|
||||
visit debate_path(debate)
|
||||
|
||||
expect(page).to_not have_content "Comment as moderator"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -22,13 +22,15 @@ describe Ability do
|
||||
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) }
|
||||
|
||||
it { should_not be_able_to(:comment_as_administrator, debate) }
|
||||
it { should_not be_able_to(:comment_as_moderator, debate) }
|
||||
|
||||
describe 'flagging content as inappropiate' do
|
||||
it { should be_able_to(:flag_as_inappropiate, debate) }
|
||||
it { should_not be_able_to(:undo_flag_as_inappropiate, debate) }
|
||||
@@ -158,6 +160,9 @@ describe Ability do
|
||||
it { should_not be_able_to(:restore, comment) }
|
||||
it { should_not be_able_to(:restore, debate) }
|
||||
it { should_not be_able_to(:restore, other_user) }
|
||||
|
||||
it { should be_able_to(:comment_as_moderator, debate) }
|
||||
it { should_not be_able_to(:comment_as_administrator, debate) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -173,5 +178,8 @@ describe Ability do
|
||||
it { should be_able_to(:restore, comment) }
|
||||
it { should be_able_to(:restore, debate) }
|
||||
it { should be_able_to(:restore, other_user) }
|
||||
|
||||
it { should be_able_to(:comment_as_administrator, debate) }
|
||||
it { should_not be_able_to(:comment_as_moderator, debate) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,4 +38,24 @@ describe Comment do
|
||||
expect { new_comment.destroy }.to change { comment.children_count }.from(1).to(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#as_administrator?" do
|
||||
it "should be true if comment has administrator_id, false otherway" do
|
||||
expect(comment).not_to be_as_administrator
|
||||
|
||||
comment.administrator_id = 33
|
||||
|
||||
expect(comment).to be_as_administrator
|
||||
end
|
||||
end
|
||||
|
||||
describe "#as_moderator?" do
|
||||
it "should be true if comment has moderator_id, false otherway" do
|
||||
expect(comment).not_to be_as_moderator
|
||||
|
||||
comment.moderator_id = 21
|
||||
|
||||
expect(comment).to be_as_moderator
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user