merges master and fix conflicts

This commit is contained in:
kikito
2015-08-28 13:23:30 +02:00
62 changed files with 869 additions and 516 deletions

View File

@@ -164,6 +164,11 @@ body.admin {
font-size: rem-calc(12);
}
.ignored {
color: $text-medium;
font-size: rem-calc(12);
}
.rejected {
color: $delete;
}

View File

@@ -187,7 +187,7 @@ h1, h2, h3, h4, h5, h6 {
// - - - - - - - - - - - - - - - - - - - - - - - - -
header {
background: url('home_header_bg.jpg');
background: image-url('home_header_bg.jpg');
background-position: 50% 50%;
background-size: cover;
min-height: rem-calc(480);
@@ -217,6 +217,12 @@ header {
margin: 0;
}
p {
color: white;
font-size: rem-calc(18);
line-height: $line-height;
}
.button {
color: white;
font-family: inherit;
@@ -431,6 +437,11 @@ footer {
.logo {
@include logo;
a {
line-height: rem-calc(36);
padding-left: 0;
}
}
h4 {
@@ -446,6 +457,16 @@ footer {
opacity: .5;
}
}
.footer-description {
a {
text-decoration: underline;
&:hover {
color: rgba(255,255,255,.6);
}
}
}
}
.subfooter {
@@ -566,7 +587,7 @@ form.locale-form {
position: relative;
select {
background-image: url("language_select.png");
background-image: image-url("language_select.png");
&.js-locale-switcher {
background-color: transparent;

View File

@@ -1,13 +1,35 @@
class Admin::CommentsController < Admin::BaseController
before_filter :set_valid_filters, only: :index
before_filter :parse_filter, only: :index
before_filter :load_comment, only: [:confirm_hide, :restore]
def index
@comments = Comment.only_hidden.page(params[:page])
@comments = Comment.only_hidden.send(@filter).page(params[:page])
end
def confirm_hide
@comment.confirm_hide
redirect_to request.query_parameters.merge(action: :index)
end
def restore
@comment = Comment.with_hidden.find(params[:id])
@comment.restore
redirect_to admin_comments_path, notice: t('admin.comments.restore.success')
redirect_to request.query_parameters.merge(action: :index)
end
private
def load_comment
@comment = Comment.with_hidden.find(params[:id])
end
def set_valid_filters
@valid_filters = %w{all with_confirmed_hide}
end
def parse_filter
@filter = params[:filter]
@filter = 'all' unless @valid_filters.include?(@filter)
end
end

View File

@@ -1,16 +1,36 @@
class Admin::DebatesController < Admin::BaseController
before_filter :set_valid_filters, only: :index
before_filter :parse_filter, only: :index
before_filter :load_debate, only: [:confirm_hide, :restore]
def index
@debates = Debate.only_hidden.page(params[:page])
@debates = Debate.only_hidden.send(@filter).page(params[:page])
end
def show
@debate = Debate.with_hidden.find(params[:id])
def confirm_hide
@debate.confirm_hide
redirect_to request.query_parameters.merge(action: :index)
end
def restore
@debate = Debate.with_hidden.find(params[:id])
@debate.restore
redirect_to admin_debates_path, notice: t('admin.debates.restore.success')
redirect_to request.query_parameters.merge(action: :index)
end
private
def load_debate
@debate = Debate.with_hidden.find(params[:id])
end
def set_valid_filters
@valid_filters = %w{all with_confirmed_hide}
end
def parse_filter
@filter = params[:filter]
@filter = 'all' unless @valid_filters.include?(@filter)
end
end

View File

@@ -1,25 +1,42 @@
class Admin::UsersController < Admin::BaseController
before_filter :set_valid_filters, only: :index
before_filter :parse_filter, only: :index
before_filter :load_user, only: [:confirm_hide, :restore]
def index
@users = User.only_hidden.page(params[:page])
@users = User.only_hidden.send(@filter).page(params[:page])
end
def show
@user = User.with_hidden.find(params[:id])
@debates = Debate.where(author_id: @user.id).with_hidden.page(params[:page])
@comments = Comment.where(user_id: @user.id).with_hidden.page(params[:page])
@debates = @user.debates.with_hidden.page(params[:page])
@comments = @user.comments.with_hidden.page(params[:page])
end
def confirm_hide
@user.confirm_hide
redirect_to request.query_parameters.merge(action: :index)
end
def restore
user = User.with_hidden.find(params[:id])
if hidden_at = user.hidden_at
debates_ids = Debate.only_hidden.where(author_id: user.id).where("debates.hidden_at > ?", hidden_at).pluck(:id)
comments_ids = Comment.only_hidden.where(user_id: user.id).where("comments.hidden_at > ?", hidden_at).pluck(:id)
user.restore
Debate.restore_all debates_ids
Comment.restore_all comments_ids
end
redirect_to admin_users_path, notice: t('admin.users.restore.success')
@user.restore
redirect_to request.query_parameters.merge(action: :index)
end
private
def load_user
@user = User.with_hidden.find(params[:id])
end
def set_valid_filters
@valid_filters = %w{all with_confirmed_hide}
end
def parse_filter
@filter = params[:filter]
@filter = 'all' unless @valid_filters.include?(@filter)
end
end

View File

@@ -22,14 +22,14 @@ class CommentsController < ApplicationController
respond_with @comment
end
def flag_as_inappropiate
InappropiateFlag.flag!(current_user, @comment)
respond_with @comment, template: 'comments/_refresh_flag_as_inappropiate_actions'
def flag
Flag.flag!(current_user, @comment)
respond_with @comment, template: 'comments/_refresh_flag_actions'
end
def undo_flag_as_inappropiate
InappropiateFlag.unflag!(current_user, @comment)
respond_with @comment, template: 'comments/_refresh_flag_as_inappropiate_actions'
def unflag
Flag.unflag!(current_user, @comment)
respond_with @comment, template: 'comments/_refresh_flag_actions'
end
private

View File

@@ -52,14 +52,14 @@ class DebatesController < ApplicationController
set_debate_votes(@debate)
end
def flag_as_inappropiate
InappropiateFlag.flag!(current_user, @debate)
respond_with @debate, template: 'debates/_refresh_flag_as_inappropiate_actions'
def flag
Flag.flag!(current_user, @debate)
respond_with @debate, template: 'debates/_refresh_flag_actions'
end
def undo_flag_as_inappropiate
InappropiateFlag.unflag!(current_user, @debate)
respond_with @debate, template: 'debates/_refresh_flag_as_inappropiate_actions'
def unflag
Flag.unflag!(current_user, @debate)
respond_with @debate, template: 'debates/_refresh_flag_actions'
end
private

View File

@@ -19,19 +19,19 @@ class Moderation::CommentsController < Moderation::BaseController
redirect_to request.query_parameters.merge(action: :index)
end
def archive
@comment.archive
def ignore_flag
@comment.ignore_flag
redirect_to request.query_parameters.merge(action: :index)
end
private
def load_comments
@comments = Comment.accessible_by(current_ability, :hide).flagged_as_inappropiate.sorted_for_moderation.includes(:commentable)
@comments = Comment.accessible_by(current_ability, :hide).flagged.sorted_for_moderation.includes(:commentable)
end
def set_valid_filters
@valid_filters = %w{all pending archived}
@valid_filters = %w{all pending_flag_review with_ignored_flag}
end
def parse_filter

View File

@@ -19,19 +19,19 @@ class Moderation::DebatesController < Moderation::BaseController
redirect_to request.query_parameters.merge(action: :index)
end
def archive
@debate.archive
def ignore_flag
@debate.ignore_flag
redirect_to request.query_parameters.merge(action: :index)
end
private
def load_debates
@debates = Debate.accessible_by(current_ability, :hide).flagged_as_inappropiate.sorted_for_moderation
@debates = Debate.accessible_by(current_ability, :hide).flagged.sorted_for_moderation
end
def set_valid_filters
@valid_filters = %w{all pending archived}
@valid_filters = %w{all pending_flag_review with_ignored_flag}
end
def parse_filter

View File

@@ -22,20 +22,20 @@ class Ability
can :create, Comment
can :create, Debate
can :flag_as_inappropiate, Comment do |comment|
comment.author_id != user.id && !InappropiateFlag.flagged?(user, comment)
can :flag, Comment do |comment|
comment.author_id != user.id && !Flag.flagged?(user, comment)
end
can :undo_flag_as_inappropiate, Comment do |comment|
comment.author_id != user.id && InappropiateFlag.flagged?(user, comment)
can :unflag, Comment do |comment|
comment.author_id != user.id && Flag.flagged?(user, comment)
end
can :flag_as_inappropiate, Debate do |debate|
debate.author_id != user.id && !InappropiateFlag.flagged?(user, debate)
can :flag, Debate do |debate|
debate.author_id != user.id && !Flag.flagged?(user, debate)
end
can :undo_flag_as_inappropiate, Debate do |debate|
debate.author_id != user.id && InappropiateFlag.flagged?(user, debate)
can :unflag, Debate do |debate|
debate.author_id != user.id && Flag.flagged?(user, debate)
end
unless user.organization?
@@ -53,14 +53,14 @@ class Ability
can :hide, Comment, hidden_at: nil
cannot :hide, Comment, user_id: user.id
can :archive, Comment, archived_at: nil, hidden_at: nil
cannot :archive, Comment, user_id: user.id
can :ignore_flag, Comment, ignored_flag_at: nil, hidden_at: nil
cannot :ignore_flag, Comment, user_id: user.id
can :hide, Debate, hidden_at: nil
cannot :hide, Debate, author_id: user.id
can :archive, Debate, archived_at: nil, hidden_at: nil
cannot :archive, Debate, author_id: user.id
can :ignore_flag, Debate, ignored_flag_at: nil, hidden_at: nil
cannot :ignore_flag, Debate, author_id: user.id
can :hide, User
cannot :hide, User, id: user.id
@@ -72,8 +72,23 @@ class Ability
if user.administrator?
can :restore, Comment
cannot :restore, Comment, hidden_at: nil
can :restore, Debate
cannot :restore, Debate, hidden_at: nil
can :restore, User
cannot :restore, User, hidden_at: nil
can :confirm_hide, Comment
cannot :confirm_hide, Comment, hidden_at: nil
can :confirm_hide, Debate
cannot :confirm_hide, Debate, hidden_at: nil
can :confirm_hide, User
cannot :confirm_hide, User, hidden_at: nil
can :comment_as_administrator, [Debate, Comment]
end
end

View File

@@ -1,7 +1,7 @@
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
include ActsAsParanoidAliases
acts_as_votable
attr_accessor :as_moderator, :as_administrator
@@ -12,14 +12,14 @@ class Comment < ActiveRecord::Base
belongs_to :commentable, polymorphic: true, counter_cache: true
belongs_to :user, -> { with_hidden }
has_many :inappropiate_flags, :as => :flaggable
has_many :flags, :as => :flaggable
scope :recent, -> { order(id: :desc) }
scope :sorted_for_moderation, -> { order(inappropiate_flags_count: :desc, updated_at: :desc) }
scope :pending, -> { where(archived_at: nil, hidden_at: nil) }
scope :archived, -> { where("archived_at IS NOT NULL AND hidden_at IS NULL") }
scope :flagged_as_inappropiate, -> { where("inappropiate_flags_count > 0") }
scope :sorted_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
scope :with_ignored_flag, -> { where("ignored_flag_at IS NOT NULL AND hidden_at IS NULL") }
scope :flagged, -> { where("flags_count > 0") }
scope :for_render, -> { with_hidden.includes(user: :organization) }
@@ -65,8 +65,12 @@ class Comment < ActiveRecord::Base
hidden? || user.hidden?
end
def archived?
archived_at.present?
def ignored_flag?
ignored_flag_at.present?
end
def ignore_flag
update(ignored_flag_at: Time.now)
end
def as_administrator?
@@ -77,10 +81,6 @@ class Comment < ActiveRecord::Base
moderator_id.present?
end
def archive
update(archived_at: Time.now)
end
# TODO: faking counter cache since there is a bug with acts_as_nested_set :counter_cache
# Remove when https://github.com/collectiveidea/awesome_nested_set/issues/294 is fixed
# and reset counters using

View File

@@ -1,6 +1,5 @@
require 'numeric'
class Debate < ActiveRecord::Base
include ActsAsParanoidAliases
default_scope { order(created_at: :desc) }
apply_simple_captcha
@@ -10,9 +9,10 @@ class Debate < ActiveRecord::Base
acts_as_commentable
acts_as_taggable
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
has_many :inappropiate_flags, :as => :flaggable
has_many :flags, :as => :flaggable
validates :title, presence: true
validates :description, presence: true
@@ -23,10 +23,10 @@ class Debate < ActiveRecord::Base
before_validation :sanitize_description
before_validation :sanitize_tag_list
scope :sorted_for_moderation, -> { order(inappropiate_flags_count: :desc, updated_at: :desc) }
scope :pending, -> { where(archived_at: nil, hidden_at: nil) }
scope :archived, -> { where("archived_at IS NOT NULL AND hidden_at IS NULL") }
scope :flagged_as_inappropiate, -> { where("inappropiate_flags_count > 0") }
scope :sorted_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
scope :with_ignored_flag, -> { where("ignored_flag_at IS NOT NULL AND hidden_at IS NULL") }
scope :flagged, -> { where("flags_count > 0") }
scope :for_render, -> { includes(:tags) }
scope :sort_by_total_votes, -> { reorder(cached_votes_total: :desc) }
scope :sort_by_likes , -> { reorder(cached_votes_up: :desc) }
@@ -79,12 +79,12 @@ class Debate < ActiveRecord::Base
count < 0 ? 0 : count
end
def archived?
archived_at.present?
def ignored_flag?
ignored_flag_at.present?
end
def archive
update(archived_at: Time.now)
def ignore_flag
update(ignored_flag_at: Time.now)
end
protected

View File

@@ -1,7 +1,7 @@
class InappropiateFlag < ActiveRecord::Base
class Flag < ActiveRecord::Base
belongs_to :user
belongs_to :flaggable, polymorphic: true, counter_cache: true, touch: :flagged_as_inappropiate_at
belongs_to :flaggable, polymorphic: true, counter_cache: true
scope(:by_user_and_flaggable, lambda do |user, flaggable|
where(user_id: user.id,
@@ -12,13 +12,13 @@ class InappropiateFlag < ActiveRecord::Base
class AlreadyFlaggedError < StandardError
def initialize
super "The flaggable was already flagged as inappropiate by this user"
super "The flaggable was already flagged by this user"
end
end
class NotFlaggedError < StandardError
def initialize
super "The flaggable was not flagged as inappropiate by this user"
super "The flaggable was not flagged by this user"
end
end

View File

@@ -1,6 +1,9 @@
class User < ActiveRecord::Base
<<<<<<< HEAD
include ActsAsParanoidAliases
include Verification
=======
>>>>>>> master
OMNIAUTH_EMAIL_PREFIX = 'omniauth@participacion'
OMNIAUTH_EMAIL_REGEX = /\A#{OMNIAUTH_EMAIL_PREFIX}/
@@ -11,13 +14,16 @@ class User < ActiveRecord::Base
acts_as_voter
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
has_one :address
has_one :administrator
has_one :moderator
has_one :organization
has_many :inappropiate_flags
has_many :flags
has_many :identities, dependent: :destroy
has_many :debates, -> { with_hidden }, foreign_key: :author_id
has_many :comments, -> { with_hidden }
validates :username, presence: true, unless: :organization?
validates :official_level, inclusion: {in: 0..5}
@@ -116,4 +122,5 @@ class User < ActiveRecord::Base
!!(email && email !~ OMNIAUTH_EMAIL_REGEX) ||
!!(unconfirmed_email && unconfirmed_email !~ OMNIAUTH_EMAIL_REGEX)
end
end

View File

@@ -1,13 +1,17 @@
<h2><%= t("admin.comments.index.title") %></h2>
<!-- Filters for pending and archived comments (example on "/admin/organizations/index.html.erb")-->
<dl class="sub-nav">
<dt><%= t("admin.comments.index.filter") %>:</dt>
<dd class="active"><%= t("admin.comments.filters.all") %></dd>
<dd><%= t("admin.comments.filters.pending") %></dd>
<dd><%= t("admin.comments.filters.archived") %></dd>
<% @valid_filters.each do |filter| %>
<% if @filter == filter %>
<dd class="active"><%= t("admin.comments.index.filters.#{filter}") %></dd>
<% else %>
<dd><%= link_to t("admin.comments.index.filters.#{filter}"),
admin_comments_path(filter: filter) %></dd>
<% end %>
<% end %>
</dl>
<!-- Filters for pending and archived comments (example on "/admin/organizations/index.html.erb")-->
<h3><%= page_entries_info @comments %></h3>
@@ -17,17 +21,19 @@
<div class="row">
<div class="small-12 medium-8 column">
<%= comment.body %>
<!-- Link to debate of this comment -->
<%= link_to t("admin.comments.index.show_debate"), "#" %>
<!-- /. Link to debate of this comment -->
<%= link_to comment.commentable.title, comment.commentable %>
</div>
<div class="small-6 medium-4 column text-right">
<!-- Link to archive this comment -->
<%= link_to t("admin.actions.archive"), "#", class: "button radius tiny warning" %>
<!-- /. Link to archive this comment -->
<%= link_to t("admin.actions.restore"), restore_admin_comment_path(comment),
method: :put, data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny success" %>
<%= link_to t("admin.actions.restore"),
restore_admin_comment_path(comment, request.query_parameters),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny success right" %>
<%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_comment_path(comment, request.query_parameters),
method: :put,
class: "button radius tiny warning right" %>
</div>
</div>
</li>

View File

@@ -1,28 +1,35 @@
<h2><%= t("admin.debates.index.title") %></h2>
<!-- Filters for pending and archived debates (example on "/admin/organizations/index.html.erb")-->
<dl class="sub-nav">
<dt><%= t("admin.debates.index.filter") %>:</dt>
<dd class="active"><%= t("admin.debates.filters.all") %></dd>
<dd><%= t("admin.debates.filters.pending") %></dd>
<dd><%= t("admin.debates.filters.archived") %></dd>
<% @valid_filters.each do |filter| %>
<% if @filter == filter %>
<dd class="active"><%= t("admin.debates.index.filters.#{filter}") %></dd>
<% else %>
<dd><%= link_to t("admin.debates.index.filters.#{filter}"),
admin_debates_path(filter: filter) %></dd>
<% end %>
<% end %>
</dl>
<!-- Filters for pending and archived debates (example on "/admin/organizations/index.html.erb")-->
<h3><%= page_entries_info @debates %></h3>
<ul class="admin-list">
<% @debates.each do |debate| %>
<li id="<%= dom_id(debate) %>">
<%= link_to debate.title, admin_debate_path(debate) %>
<%= link_to debate.title, debate_path(debate) %>
<%= link_to t("admin.actions.restore"), restore_admin_debate_path(debate),
method: :put, data: { confirm: t("admin.actions.confirm") },
<%= link_to t("admin.actions.restore"),
restore_admin_debate_path(debate, request.query_parameters),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny success right" %>
<!-- Link to archive this debate -->
<%= link_to t("admin.actions.archive"), "#", class: "button radius tiny warning right" %>
<!-- /. Link to archive this debate -->
<%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_debate_path(debate, request.query_parameters),
method: :put,
class: "button radius tiny warning right" %>
</li>
<% end %>
</ul>

View File

@@ -1,12 +0,0 @@
<h2><%= t("admin.debates.index.title") %></h2>
<h3><%= @debate.title %></h3>
<div><%= @debate.description %></div>
<%= link_to t("admin.debates.show.back"), admin_debates_path,
class: "button radius small secondary" %>
<%= link_to t("admin.actions.restore"), restore_admin_debate_path(@debate),
method: :put, data: { confirm: t("admin.actions.confirm") },
class: "button radius small success" %>

View File

@@ -1,5 +1,18 @@
<h2><%= t("admin.users.index.title") %></h2>
<dl class="sub-nav">
<dt><%= t("admin.users.index.filter") %>:</dt>
<% @valid_filters.each do |filter| %>
<% if @filter == filter %>
<dd class="active"><%= t("admin.users.index.filters.#{filter}") %></dd>
<% else %>
<dd><%= link_to t("admin.users.index.filters.#{filter}"),
admin_users_path(filter: filter) %></dd>
<% end %>
<% end %>
</dl>
<h3><%= page_entries_info @users %></h3>
<ul class="admin-list">
@@ -7,8 +20,16 @@
<li>
<%= link_to user.name, admin_user_path(user) %>
<%= link_to t("admin.users.index.restore"), restore_admin_user_path(user),
method: :put, data: { confirm: t('admin.actions.confirm') }, class: "button radius tiny right" %>
<%= link_to t("admin.actions.restore"),
restore_admin_user_path(user, request.query_parameters),
method: :put,
data: { confirm: t("admin.actions.confirm") },
class: "button radius tiny success right" %>
<%= link_to t("admin.actions.confirm_hide"),
confirm_hide_admin_user_path(user, request.query_parameters),
method: :put,
class: "button radius tiny warning right" %>
</li>
<% end %>
</ul>

View File

@@ -6,8 +6,6 @@
<strong><%= t("admin.users.show.hidden_at") %></strong> <%= @user.hidden_at %>
</p>
<p>
<%= link_to t("admin.users.show.restore"), restore_admin_user_path(@user),
method: :put, data: { confirm: t('admin.actions.confirm') }, class: "button radius tiny" %>
<%= link_to t("admin.users.show.back"), admin_users_path,
class: "button radius tiny secondary" %>
</p>
@@ -19,7 +17,7 @@
<ul class="admin-list">
<% @debates.each do |debate| %>
<li>
<%= link_to debate.title, admin_debate_path(debate) %>
<%= link_to debate.title, debate_path(debate) %>
</li>
<% end %>
</ul>

View File

@@ -1,5 +1,5 @@
<span class="js-flag-as-inappropiate-actions">
<%= render 'comments/flag_as_inappropiate_actions', comment: comment %>
<span class="js-flag-actions">
<%= render 'comments/flag_actions', comment: comment %>
</span>
<span class='js-moderation-actions'>

View File

@@ -1,23 +1,23 @@
<% if can? :flag_as_inappropiate, comment %>
<% if can? :flag, comment %>
<span class="divider">&nbsp;|&nbsp;</span>
<a id="flag-expand-comment-<%= comment.id %>" data-dropdown="flag-drop-comment-<%= comment.id %>" aria-controls="flag-drop-comment-<%= comment.id %>" aria-expanded="false" title="<%= t('shared.flag_as_inappropiate') %>">
<a id="flag-expand-comment-<%= comment.id %>" data-dropdown="flag-drop-comment-<%= comment.id %>" aria-controls="flag-drop-comment-<%= comment.id %>" aria-expanded="false" title="<%= t('shared.flag') %>">
&nbsp;<i class="icon-flag flag-disable"></i>&nbsp;&nbsp;
</a>
<ul id="flag-drop-comment-<%= comment.id %>" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
<li>
<%= link_to t("shared.flag_as_inappropiate"), flag_as_inappropiate_comment_path(comment), method: :put, remote: true, id: "flag-comment-#{comment.id}" %>
<%= link_to t("shared.flag"), flag_comment_path(comment), method: :put, remote: true, id: "flag-comment-#{comment.id}" %>
</li>
</ul>
<% end %>
<% if can? :undo_flag_as_inappropiate, comment %>
<% if can? :unflag, comment %>
<span class="divider">&nbsp;|&nbsp;</span>
<a id="unflag-expand-comment-<%= comment.id %>" data-dropdown="unflag-drop-comment-<%= comment.id %>" aria-controls="unflag-drop-comment-<%= comment.id %>" aria-expanded="false" title="<%= t('shared.undo_flag_as_inappropiate') %>">
<a id="unflag-expand-comment-<%= comment.id %>" data-dropdown="unflag-drop-comment-<%= comment.id %>" aria-controls="unflag-drop-comment-<%= comment.id %>" aria-expanded="false" title="<%= t('shared.unflag') %>">
&nbsp;<i class="icon-flag flag-active"></i>&nbsp;&nbsp;
</a>
<ul id="unflag-drop-comment-<%= comment.id %>" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
<li>
<%= link_to t("shared.undo_flag_as_inappropiate"), undo_flag_as_inappropiate_comment_path(comment), method: :put, remote: true, id: "unflag-comment-#{comment.id}" %>
<%= link_to t("shared.unflag"), unflag_comment_path(comment), method: :put, remote: true, id: "unflag-comment-#{comment.id}" %>
</li>
</ul>
<% end %>

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@comment) %> .js-flag-actions").html('<%= j render("comments/flag_actions", comment: @comment) %>');

View File

@@ -1 +0,0 @@
$("#<%= dom_id(@comment) %> .js-flag-as-inappropiate-actions").html('<%= j render("comments/flag_as_inappropiate_actions", comment: @comment) %>');

View File

@@ -1,21 +1,21 @@
<% if can? :flag_as_inappropiate, debate %>
<a id="flag-expand-debate-<%= debate.id %>" data-dropdown="flag-drop-debate-<%= debate.id %>" aria-controls="flag-drop-debate-<%= debate.id %>" aria-expanded="false" title="<%= t('shared.flag_as_inappropiate') %>">
<% if can? :flag, debate %>
<a id="flag-expand-debate-<%= debate.id %>" data-dropdown="flag-drop-debate-<%= debate.id %>" aria-controls="flag-drop-debate-<%= debate.id %>" aria-expanded="false" title="<%= t('shared.flag') %>">
&nbsp;<i class="icon-flag flag-disable"></i>&nbsp;&nbsp;
</a>
<ul id="flag-drop-debate-<%= debate.id %>" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
<li>
<%= link_to t('shared.flag_as_inappropiate'), flag_as_inappropiate_debate_path(debate), method: :put, remote: true, id: "flag-debate-#{ debate.id }" %>
<%= link_to t('shared.flag'), flag_debate_path(debate), method: :put, remote: true, id: "flag-debate-#{ debate.id }" %>
</li>
</ul>
<% end %>
<% if can? :undo_flag_as_inappropiate, debate %>
<a id="unflag-expand-debate-<%= debate.id %>" data-dropdown="unflag-drop-debate-<%= debate.id %>" aria-controls="unflag-drop-debate-<%= debate.id %>" aria-expanded="false" title="<%= t('shared.undo_flag_as_inappropiate') %>">
<% if can? :unflag, debate %>
<a id="unflag-expand-debate-<%= debate.id %>" data-dropdown="unflag-drop-debate-<%= debate.id %>" aria-controls="unflag-drop-debate-<%= debate.id %>" aria-expanded="false" title="<%= t('shared.unflag') %>">
&nbsp;<i class="icon-flag flag-active"></i>&nbsp;&nbsp;
</a>
<ul id="unflag-drop-debate-<%= debate.id %>" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
<li>
<%= link_to t('shared.undo_flag_as_inappropiate'), undo_flag_as_inappropiate_debate_path(debate), method: :put, remote: true, id: "unflag-debate-#{ debate.id }" %>
<%= link_to t('shared.unflag'), unflag_debate_path(debate), method: :put, remote: true, id: "unflag-debate-#{ debate.id }" %>
</li>
</ul>
<% end %>

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@debate) %> .js-flag-actions").html('<%= j render("debates/flag_actions", debate: @debate) %>');

View File

@@ -1 +0,0 @@
$("#<%= dom_id(@debate) %> .js-flag-as-inappropiate-actions").html('<%= j render("debates/flag_as_inappropiate_actions", debate: @debate) %>');

View File

@@ -16,6 +16,8 @@
<li><%= t("debates.new.recommendation_one") %></li>
<li><%= t("debates.new.recommendation_two") %></li>
<li><%= t("debates.new.recommendation_three") %></li>
<li><%= t("debates.new.recommendation_four") %></li>
<li><%= t("debates.new.recommendation_five") %></li>
</ul>
</div>
</div>

View File

@@ -42,8 +42,8 @@
<i class="icon-comments"></i>&nbsp;
<%= link_to t("debates.show.comments", count: @debate.comments_count), "#comments" %>
<span class="bullet">&nbsp;&bullet;&nbsp;</span>
<span class="js-flag-as-inappropiate-actions">
<%= render 'debates/flag_as_inappropiate_actions', debate: @debate %>
<span class="js-flag-actions">
<%= render 'debates/flag_actions', debate: @debate %>
</span>
</div>

View File

@@ -23,14 +23,4 @@
</section>
</nav>
</div>
<% if home_page? %>
<div class="row home-page">
<div class="small-12 column text-center">
<h1><%= t("layouts.header.open_city") %></h1>
<h2><%= t("layouts.header.open_city_slogan") %></h2>
<%= link_to t("layouts.header.see_all_debates"), debates_path, class: 'button radius' %>
</div>
</div>
<% end %>
</header>

View File

@@ -1,36 +1,35 @@
<footer>
<div class="row-full">
<div class="row">
<div class="small-12 column">
<div class="right">
<%= link_to "Enlace 1", "#", class: "link" %> | <%= link_to "Enlace 2", "#", class: "link" %>
<div class="small-12 medium-4 column">
<div class="logo">
<%= link_to t("layouts.header.open_gov", open: "<strong>#{t('layouts.header.open')}</strong>").html_safe %>
</div>
<div class="logo left">
<%= link_to root_path do %>
<%= image_tag('logo_madrid_white.png', class: 'left', size: '96x96') %>
<%= t("layouts.header.open_gov", open: "<strong>#{t('layouts.header.open')}</strong>").html_safe %>
<% end %>
<p class="footer-description">
<%= t("layouts.footer.description",
open_source: link_to(t('layouts.footer.open_source'), t('layouts.footer.open_source_url'), target: 'blank'),
github_url: link_to(t('layouts.footer.github_url'), t('layouts.footer.github_url'), target: 'blank')).html_safe
%>
</p>
</div>
<div class="small-12 medium-8 column">
<div class="small-12 medium-4 column">
<h4><%= t("layouts.footer.participation_title") %></h4>
<p><%= t("layouts.footer.participation_text") %></p>
</div>
</div>
<div class="small-12 medium-3 column clear">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
<div class="small-12 medium-4 column">
<h4><%= t("layouts.footer.transparency_title") %></h4>
<p><%= t("layouts.footer.transparency_text") %></p>
</div>
<div class="small-12 medium-3 column">
<h4>Lorem ipsum dolor</h4>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<div class="small-12 medium-3 column">
<h4>Ut enim ad minim</h4>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
</div>
<div class="small-12 medium-3 column">
<h4>Duis aute irure</h4>
<p>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<div class="small-12 medium-4 column">
<h4><%= t("layouts.footer.open_data_title") %></h4>
<p><%= t("layouts.footer.open_data_text") %></p>
</div>
</div>
</div>

View File

@@ -4,8 +4,8 @@
<%= render "shared/locale_switcher" %>
<div class="external-links">
<%= link_to t("layouts.header.participation"), root_path, class: "selected" %>&nbsp;|
<%= link_to t("layouts.header.external_link_transparency"), "#" %>&nbsp;|
<%= link_to t("layouts.header.external_link_opendata"), "#" %>
<%= link_to t("layouts.header.external_link_transparency"), t("layouts.header.external_link_transparency_url"), target: "_blank" %>&nbsp;|
<%= link_to t("layouts.header.external_link_opendata"), t("layouts.header.external_link_opendata_url"), target: "_blank" %>
</div>
</div>
</section>
@@ -50,8 +50,10 @@
<% if home_page? %>
<div class="row home-page">
<div class="small-12 column text-center">
<h1><%= t("layouts.header.open_city") %></h1>
<h2><%= t("layouts.header.open_city_slogan") %></h2>
<h1><%= t("layouts.header.open_city_title") %></h1>
<p><%= t("layouts.header.open_city_slogan") %></p>
<p><%= t("layouts.header.open_city_text") %></p>
<p><%= t("layouts.header.open_city_soon") %></p>
<%= link_to t("layouts.header.see_all_debates"), debates_path, class: "button radius" %>
</div>
</div>

View File

@@ -35,18 +35,18 @@
<span class="date"><%= l comment.updated_at.to_date %></span>
</td>
<td><%= comment.body %></td>
<td class="text-center"><%= comment.inappropiate_flags_count %></td>
<td class="text-center"><%= comment.flags_count %></td>
<td>
<%= link_to t("moderation.comments.index.hide"), hide_in_moderation_screen_moderation_comment_path(comment, request.query_parameters), method: :put, class: "delete" %>
</td>
<% if can? :archive, comment %>
<% if can? :ignore_flag, comment %>
<td>
<%= link_to t("moderation.comments.index.archive"), archive_moderation_comment_path(comment, request.query_parameters), method: :put, class: "button radius tiny warning" %>
<%= link_to t("moderation.comments.index.ignore_flag"), ignore_flag_moderation_comment_path(comment, request.query_parameters), method: :put, class: "button radius tiny warning" %>
</td>
<% end %>
<% if comment.archived? %>
<td class="archived">
<%= t("moderation.comments.index.archived") %>
<% if comment.ignored_flag? %>
<td class="ignored">
<%= t("moderation.comments.index.ignored_flag") %>
</td>
<% end %>
</tr>

View File

@@ -34,18 +34,18 @@
<br>
<%= debate.description %>
</td>
<td class="text-center"><%= debate.inappropiate_flags_count %></td>
<td class="text-center"><%= debate.flags_count %></td>
<td>
<%= link_to t("moderation.debates.index.hide"), hide_in_moderation_screen_moderation_debate_path(debate, request.query_parameters), method: :put, class: "delete" %>
</td>
<% if can? :archive, debate %>
<% if can? :ignore_flag, debate %>
<td>
<%= link_to t("moderation.debates.index.archive"), archive_moderation_debate_path(debate, request.query_parameters), method: :put, class: "button radius tiny warning" %>
<%= link_to t("moderation.debates.index.ignore_flag"), ignore_flag_moderation_debate_path(debate, request.query_parameters), method: :put, class: "button radius tiny warning" %>
</td>
<% end %>
<% if debate.archived? %>
<td class="archived">
<%= t("moderation.debates.index.archived") %>
<% if debate.ignored_flag? %>
<td class="ignored">
<%= t("moderation.debates.index.ignored_flag") %>
</td>
<% end %>
</tr>

View File

@@ -9,3 +9,4 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
Rails.application.config.assets.precompile += %w( ckeditor/* )

View File

@@ -36,7 +36,7 @@ en:
hide_author: Ban author
restore: Restore
confirm: 'Are you sure?'
archive: Archive
confirm_hide: Confirm
tags:
index:
title: 'Debate topics'
@@ -48,39 +48,30 @@ en:
comments:
index:
title: Hidden comments
show_debate: Show debate
filter: Filter
restore:
success: The comment has been restored
filters:
all: All
pending: Pending
archived: Archived
filters:
all: All
with_confirmed_hide: Confirmed
debates:
index:
title: Hidden debates
filter: Filter
show:
back: Back
restore:
success: The debate has been restored
filters:
all: All
pending: Pending
archived: Archived
filters:
all: All
with_confirmed_hide: Confirmed
users:
index:
title: Banned users
restore: Restore user
filter: Filter
filters:
all: All
with_confirmed_hide: Confirmed
show:
title: "User activity from %{user}"
restore: Restore user
back: Back
email: "Email:"
registered_at: "Registered at:"
hidden_at: "Hidden at:"
restore:
success: The user has been restored
officials:
level_0: Level 0
level_1: Level 1

View File

@@ -36,7 +36,7 @@ es:
hide_author: Bloquear al autor
restore: Volver a mostrar
confirm: '¿Estás seguro?'
archive: Archivar
confirm_hide: Confirmar
tags:
index:
title: 'Temas de debate'
@@ -48,39 +48,30 @@ es:
comments:
index:
title: Comentarios ocultos
show_debate: Ver debate
filter: Filtro
restore:
success: El comentario ha sido permitido
filters:
all: Todos
pending: Pendientes
archived: Archivados
filter: Firar
filters:
all: Todos
with_confirmed_hide: Confirmados
debates:
index:
title: Debates ocultos
filter: Filtro
show:
back: Volver
restore:
success: El debate ha sido permitido
filters:
all: Todos
pending: Pendientes
archived: Archivados
filters:
all: Todos
with_confirmed_hide: Confirmados
users:
index:
title: Usuarios bloqueados
restore: Restaurar usuario
filter: Filro
filters:
all: Todos
with_confirmed_hide: Confirmados
show:
title: "Actividad del usuario %{user}"
restore: Restaurar usuario
back: Volver
email: "Email:"
registered_at: "Fecha de alta:"
hidden_at: "Bloqueado:"
restore:
success: El usuario y sus contenidos han sido restaurados
officials:
level_0: Nivel 0
level_1: Nivel 1

View File

@@ -3,14 +3,24 @@ en:
layouts:
header:
external_link_transparency: Transparency
external_link_transparency_url: "http://www.madrid.es/portales/munimadrid/es/Inicio/El-Ayuntamiento/Transparencia?vgnextfmt=default&vgnextchannel=20fd850769797310VgnVCM2000000c205a0aRCRD"
external_link_opendata: Open data
external_link_opendata_url: "http://datos.madrid.es"
external_link_blog: Blog
open_gov: "%{open} government"
open: "Open"
participation: Participation
menu: Menu
open_city: We are opening Madrid
open_city_slogan: So the citizens can decide what kind of city they want.
open_city_title: "The city you want, it will be the city you want."
open_city_slogan:
"Start listening to Madrid.
For that we open this digital Puerta del Sol, where all the locals can meet to discuss and share everything we want.
Also a place where you can talk directly with all the employees of the City of Madrid, from the Mayor to any officer."
open_city_text:
"Here every voice has its place, and are citizens, and no one in their name, they decide to vote debates what issues are
most important of every time. Officials have individual users with whom you may participate in the debates, and evaluated,
the same level as everyone else. Because the Madrid City Council works for its citizens, and must respond to them."
open_city_soon: "And soon... we opened the section of citizen proposals."
see_all_debates: See all debates
my_account_link: My account
locale: "Site language:"
@@ -21,7 +31,20 @@ en:
debates: Debates
initiatives: Initiatives
footer:
description:
"The city you want, it will be the city you want. Get more information here on this page.
This Open Government Portal is %{open_source}, and code is in %{github_url}.
Madrid, for the whole world."
open_source: "software libre AGPLv3"
open_source_url: "http://www.gnu.org/licenses/agpl-3.0.html"
github_url: "https://github.com/ayuntamientomadrid"
copyright: "Ayuntamiento de Madrid, 2015. All rights reserved"
participation_title: "Participation"
participation_text: Decide what should be the city of Madrid you want.
transparency_title: Transparency
transparency_text: Get any information on the City of Madrid.
open_data_title: Open Data
open_data_text: All City Council data are yours
form:
error: error
errors: errors
@@ -92,9 +115,11 @@ en:
publish_new: Publish new debate
back_link: Back
recommendations_title: Tips for creating a debate
recommendation_one: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
recommendation_two: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
recommendation_three: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
recommendation_one: "On the Internet it is easy to say things you would not dare to say face to face. The tone of what you say you will be matched by a similar tone in the answers."
recommendation_two: "Do not write the title of the debate or whole sentences in capital. On the Internet this is considered shouting. And nobody likes to scream."
recommendation_three: "Any discussion or comment that involves an illegal act will be eliminated, also intending to sabotage the debate spaces, everything else is permitted."
recommendation_four: "The harsh criticism are very welcome. This is a space of thought but we recommend preserving the elegance and intelligence. The world is better with them present."
recommendation_five: "Enjoy this space, voices that fill it, it is yours too."
comments:
form:
leave_comment: Write a comment
@@ -137,8 +162,8 @@ en:
shared:
tags_cloud:
tags: Topics
flag_as_inappropiate: Flag as inappropriate
undo_flag_as_inappropiate: Undo flag
flag: Flag as inappropriate
unflag: Undo flag
collective: Collective
mailer:
comment:

View File

@@ -3,14 +3,24 @@ es:
layouts:
header:
external_link_transparency: Transparencia
external_link_transparency_url: "http://www.madrid.es/portales/munimadrid/es/Inicio/El-Ayuntamiento/Transparencia?vgnextfmt=default&vgnextchannel=20fd850769797310VgnVCM2000000c205a0aRCRD"
external_link_opendata: Datos abiertos
external_link_opendata_url: "http://datos.madrid.es"
external_link_blog: Blog
open_gov: "Gobierno %{open}"
open: "abierto"
participation: Participación
menu: Menú
open_city: Estamos abriendo Madrid
open_city_slogan: Para que todos los madrileños decidamos que ciudad queremos tener.
open_city_title: "La ciudad que quieres, será la ciudad que quieras."
open_city_slogan:
"Empecemos escuchando qué tiene que decir Madrid.
Para ello abrimos esta Puerta del Sol digital, donde todos los madrileños podemos encontrarnos para debatir y compartir todo lo que queramos.
También un espacio donde poder hablar directamente con todos los trabajadores del Ayuntamiento de Madrid, desde la Alcaldesa hasta cualquier funcionario."
open_city_text:
"Aquí cualquier voz tiene su espacio, y son los ciudadanos, y nadie en su nombre, los que deciden votando los debates cuáles son los temas
más importantes de cada momento. Los funcionarios tienen usuarios propios con los que podrán participar en los debates, y ser evaluados,
al mismo nivel que todos los demás. Porque el Ayuntamiento de Madrid trabaja para sus ciudadanos, y ante ellos debe responder."
open_city_soon: "Y muy pronto... abrimos la sección de propuestas ciudadanas."
see_all_debates: Ver todos los debates
my_account_link: Mi cuenta
locale: "Idioma de la página:"
@@ -21,7 +31,20 @@ es:
debates: Debates
initiatives: Iniciativas
footer:
description:
"La ciudad que quieres, será la ciudad que quieras. Obtén aquí más información sobre esta página.
Este Portal de Gobierno Abierto es %{open_source}, y su código se encuentra en %{github_url}.
De Madrid, para el mundo entero."
open_source: "software libre AGPLv3"
open_source_url: "http://www.gnu.org/licenses/agpl-3.0.html"
github_url: "https://github.com/ayuntamientomadrid"
copyright: "Ayuntamiento de Madrid, %{year}. Todos los derechos reservados"
participation_title: "Participación"
participation_text: "Decide cómo debe ser la ciudad de Madrid que quieres."
transparency_title: Transparencia
transparency_text: "Obtén cualquier información sobre el Ayuntamiento de Madrid."
open_data_title: Datos Abiertos
open_data_text: Todos los datos del Ayuntamiento son tuyos
form:
error: error
errors: errores
@@ -92,9 +115,11 @@ es:
publish_new: Publicar debate nuevo
back_link: Volver
recommendations_title: Recomendaciones para crear un debate
recommendation_one: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
recommendation_two: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
recommendation_three: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore"
recommendation_one: "En internet es fácil decir cosas que uno no se atrevería a decir cara a cara. El tono de lo que digas será correspondido con un tono similar en las respuestas."
recommendation_two: "No escribas el título del debate o frases enteras en mayúsculas. En internet eso se considera gritar. Y a nadie le gusta que le griten."
recommendation_three: "Cualquier debate o comentario que implique una acción ilegal será eliminado, también los que tengan la intención de sabotear los espacios de debate, todo lo demás está permitido."
recommendation_four: "Las críticas despiadadas son muy bienvenidas. Este es un espacio de pensamiento. Pero te recomendamos conservar la elegancia y la inteligencia. El mundo es mejor con ellas presentes."
recommendation_five: "Disfruta de este espacio, de las voces que lo llenan, también es tuyo."
comments:
form:
leave_comment: Deja tu comentario
@@ -137,8 +162,8 @@ es:
shared:
tags_cloud:
tags: Temas
flag_as_inappropiate: Denunciar como inapropiado
undo_flag_as_inappropiate: Deshacer denuncia
flag: Denunciar como inapropiado
unflag: Deshacer denuncia
collective: Colectivo
mailer:
comment:

View File

@@ -16,13 +16,13 @@ en:
commentable: Root
comment: Comment
hide: Hide
archive: Archive
archived: Archived
ignore_flag: Ignore
ignored_flag: Ignored
filter: Filter
filters:
all: All
pending: Pending
archived: Archived
pending_flag_review: Pending
with_ignored_flag: Ignored
debates:
index:
title: Debates flagged as inappropriate
@@ -33,10 +33,10 @@ en:
description: Description
actions: Actions
hide: Hide
archive: Archive
archived: Archived
ignore_flag: Ignore
ignored_flag: Ignored
filter: Filter
filters:
all: All
pending: Pending
archived: Archived
pending_flag_review: Pending
with_ignored_flag: Ignored

View File

@@ -16,13 +16,13 @@ es:
commentable: Raíz
comment: Comentario
hide: Ocultar
archive: Archivar
archived: Archivado
ignore_flag: Ignorar
ignored_flag: Ignorado
filter: Filtrar
filters:
all: Todos
pending: Pendientes
archived: Archivados
pending_flag_review: Pendientes
with_ignored_flag: Ignorados
debates:
index:
title: Debates denunciados como inapropiados
@@ -33,10 +33,10 @@ es:
description: Descripción
actions: Acciones
hide: Ocultar
archive: Archivar
archived: Archivado
ignore_flag: Ignorar
ignored_flag: Ignorado
filter: Filtrar
filters:
all: Todos
pending: Pendientes
archived: Archivados
pending_flag_review: Pendientes
with_ignored_flag: Ignorados

View File

@@ -28,15 +28,15 @@ Rails.application.routes.draw do
resources :debates do
member do
post :vote
put :flag_as_inappropiate
put :undo_flag_as_inappropiate
put :flag
put :unflag
end
resources :comments, only: :create, shallow: true do
member do
post :vote
put :flag_as_inappropiate
put :undo_flag_as_inappropiate
put :flag
put :unflag
end
end
end
@@ -61,15 +61,24 @@ Rails.application.routes.draw do
end
resources :users, only: [:index, :show] do
member { put :restore }
member do
put :restore
put :confirm_hide
end
end
resources :debates, only: [:index, :show] do
member { put :restore }
resources :debates, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :comments, only: :index do
member { put :restore }
member do
put :restore
put :confirm_hide
end
end
resources :tags, only: [:index, :create, :update, :destroy]
@@ -91,7 +100,7 @@ Rails.application.routes.draw do
member do
put :hide
put :hide_in_moderation_screen
put :archive
put :ignore_flag
end
end
@@ -99,7 +108,7 @@ Rails.application.routes.draw do
member do
put :hide
put :hide_in_moderation_screen
put :archive
put :ignore_flag
end
end
end

View File

@@ -0,0 +1,5 @@
class RenameInappropiateFlagsAsFlags < ActiveRecord::Migration
def change
rename_table :inappropiate_flags, :flags
end
end

View File

@@ -0,0 +1,6 @@
class RenameArchivedAtToIgnoredFlagAtInCommentsAndDebates < ActiveRecord::Migration
def change
rename_column :comments, :archived_at, :ignored_flag_at
rename_column :debates, :archived_at, :ignored_flag_at
end
end

View File

@@ -0,0 +1,6 @@
class AddConfirmedHideAtToCommentsAndDebates < ActiveRecord::Migration
def change
add_column :debates, :confirmed_hide_at, :datetime
add_column :comments, :confirmed_hide_at, :datetime
end
end

View File

@@ -0,0 +1,6 @@
class RenameInappropiateFlagsCountToFlagsCountInDebatesAndComments < ActiveRecord::Migration
def change
rename_column :debates, :inappropiate_flags_count, :flags_count
rename_column :comments, :inappropiate_flags_count, :flags_count
end
end

View File

@@ -0,0 +1,6 @@
class RemoveFlaggedAsInappropiateAtFromCommentsAndDebates < ActiveRecord::Migration
def change
remove_column :debates, :flagged_as_inappropiate_at
remove_column :comments, :flagged_as_inappropiate_at
end
end

View File

@@ -0,0 +1,5 @@
class AddConfirmedHideAtToUsers < ActiveRecord::Migration
def change
add_column :users, :confirmed_hide_at, :datetime
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150826182010) do
ActiveRecord::Schema.define(version: 20150828085718) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -61,22 +61,22 @@ ActiveRecord::Schema.define(version: 20150826182010) do
t.string "title"
t.text "body"
t.string "subject"
t.integer "user_id", null: false
t.integer "user_id", null: false
t.integer "parent_id"
t.integer "lft"
t.integer "rgt"
t.datetime "created_at"
t.datetime "updated_at"
t.datetime "hidden_at"
t.integer "children_count", default: 0
t.datetime "flagged_as_inappropiate_at"
t.integer "inappropiate_flags_count", default: 0
t.datetime "archived_at"
t.integer "children_count", default: 0
t.integer "flags_count", default: 0
t.datetime "ignored_flag_at"
t.integer "moderator_id"
t.integer "administrator_id"
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_up", default: 0
t.integer "cached_votes_down", default: 0
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_up", default: 0
t.integer "cached_votes_down", default: 0
t.datetime "confirmed_hide_at"
end
add_index "comments", ["cached_votes_down"], name: "index_comments_on_cached_votes_down", using: :btree
@@ -87,20 +87,20 @@ ActiveRecord::Schema.define(version: 20150826182010) do
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
create_table "debates", force: :cascade do |t|
t.string "title", limit: 80
t.string "title", limit: 80
t.text "description"
t.integer "author_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "visit_id"
t.datetime "hidden_at"
t.datetime "flagged_as_inappropiate_at"
t.integer "inappropiate_flags_count", default: 0
t.datetime "archived_at"
t.integer "flags_count", default: 0
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_up", default: 0
t.integer "cached_votes_down", default: 0
t.integer "comments_count", default: 0
t.datetime "ignored_flag_at"
t.integer "comments_count", default: 0
t.datetime "confirmed_hide_at"
end
add_index "debates", ["cached_votes_down"], name: "index_debates_on_cached_votes_down", using: :btree
@@ -108,6 +108,18 @@ ActiveRecord::Schema.define(version: 20150826182010) do
add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree
add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree
create_table "flags", force: :cascade do |t|
t.integer "user_id"
t.string "flaggable_type"
t.integer "flaggable_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "flags", ["flaggable_type", "flaggable_id"], name: "index_flags_on_flaggable_type_and_flaggable_id", using: :btree
add_index "flags", ["user_id", "flaggable_type", "flaggable_id"], name: "access_inappropiate_flags", using: :btree
add_index "flags", ["user_id"], name: "index_flags_on_user_id", using: :btree
create_table "identities", force: :cascade do |t|
t.integer "user_id"
t.string "provider"
@@ -118,18 +130,6 @@ ActiveRecord::Schema.define(version: 20150826182010) do
add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree
create_table "inappropiate_flags", force: :cascade do |t|
t.integer "user_id"
t.string "flaggable_type"
t.integer "flaggable_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "inappropiate_flags", ["flaggable_type", "flaggable_id"], name: "index_inappropiate_flags_on_flaggable_type_and_flaggable_id", using: :btree
add_index "inappropiate_flags", ["user_id", "flaggable_type", "flaggable_id"], name: "access_inappropiate_flags", using: :btree
add_index "inappropiate_flags", ["user_id"], name: "index_inappropiate_flags_on_user_id", using: :btree
create_table "moderators", force: :cascade do |t|
t.integer "user_id"
end
@@ -216,6 +216,7 @@ ActiveRecord::Schema.define(version: 20150826182010) do
t.string "unconfirmed_phone"
t.string "confirmed_phone"
t.datetime "letter_requested_at"
t.datetime "confirmed_hide_at"
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
@@ -278,8 +279,8 @@ ActiveRecord::Schema.define(version: 20150826182010) do
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 "flags", "users"
add_foreign_key "identities", "users"
add_foreign_key "inappropiate_flags", "users"
add_foreign_key "moderators", "users"
add_foreign_key "organizations", "users"
end

View File

@@ -14,9 +14,26 @@ module ActsAsParanoidAliases
def after_hide
end
def confirmed_hide?
confirmed_hide_at.present?
end
def confirm_hide
update_attribute(:confirmed_hide_at, Time.now)
end
def restore(opts={})
super(opts)
update_attribute(:confirmed_hide_at, nil)
end
end
module ClassMethods
def with_confirmed_hide
where("confirmed_hide_at IS NOT NULL")
end
def with_hidden
with_deleted
end
@@ -35,9 +52,5 @@ module ActsAsParanoidAliases
only_hidden.where(id: ids).update_all(hidden_at: nil)
end
end
end
module ActsAsParanoid
include ActsAsParanoidAliases
end

View File

@@ -4,6 +4,14 @@ FactoryGirl.define do
sequence(:email) { |n| "manuela#{n}@madrid.es" }
password 'judgmentday'
confirmed_at { Time.now }
trait :hidden do
hidden_at Time.now
end
trait :with_confirmed_hide do
confirmed_hide_at Time.now
end
end
factory :identity do
@@ -49,13 +57,17 @@ FactoryGirl.define do
hidden_at Time.now
end
trait :archived do
archived_at Time.now
trait :with_ignored_flag do
ignored_flag_at Time.now
end
trait :flagged_as_inappropiate do
trait :with_confirmed_hide do
confirmed_hide_at Time.now
end
trait :flagged do
after :create do |debate|
InappropiateFlag.flag!(FactoryGirl.create(:user), debate)
Flag.flag!(FactoryGirl.create(:user), debate)
end
end
end
@@ -78,13 +90,17 @@ FactoryGirl.define do
hidden_at Time.now
end
trait :archived do
archived_at Time.now
trait :with_ignored_flag do
ignored_flag_at Time.now
end
trait :flagged_as_inappropiate do
trait :with_confirmed_hide do
confirmed_hide_at Time.now
end
trait :flagged do
after :create do |debate|
InappropiateFlag.flag!(FactoryGirl.create(:user), debate)
Flag.flag!(FactoryGirl.create(:user), debate)
end
end
end

View File

@@ -2,27 +2,71 @@ require 'rails_helper'
feature 'Admin comments' do
scenario 'Restore', :js do
citizen = create(:user)
background do
admin = create(:administrator)
debate = create(:debate)
comment = create(:comment, :hidden, commentable: debate, body: 'Not really SPAM')
login_as(admin.user)
end
scenario 'Restore', :js do
comment = create(:comment, :hidden, body: 'Not really SPAM')
visit admin_comments_path
within("#comment_#{comment.id}") do
first(:link, "Restore").click
end
click_link 'Restore'
expect(page).to have_content 'The comment has been restored'
expect(page).to_not have_content(comment.body)
login_as(citizen)
visit debate_path(debate)
expect(comment.reload).to_not be_hidden
end
expect(page).to have_css('.comment', count: 1)
expect(page).to have_content('Not really SPAM')
scenario 'Confirm hide' do
comment = create(:comment, :hidden, body: 'SPAM')
visit admin_comments_path
click_link 'Confirm'
expect(page).to have_content(comment.body)
expect(page).to have_content('Confirmed')
expect(comment.reload).to be_confirmed_hide
end
scenario "Current filter is properly highlighted" do
visit admin_comments_path
expect(page).to_not have_link('All')
expect(page).to have_link('Confirmed')
visit admin_comments_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Confirmed')
visit admin_comments_path(filter: 'with_confirmed_hide')
expect(page).to have_link('All')
expect(page).to_not have_link('Confirmed')
end
scenario "Filtering comments" do
create(:comment, :hidden, body: "Unconfirmed comment")
create(:comment, :hidden, :with_confirmed_hide, body: "Confirmed comment")
visit admin_comments_path(filter: 'all')
expect(page).to have_content('Unconfirmed comment')
expect(page).to have_content('Confirmed comment')
visit admin_comments_path(filter: 'with_confirmed_hide')
expect(page).to_not have_content('Unconfirmed comment')
expect(page).to have_content('Confirmed comment')
end
scenario "Action links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:comment, :hidden, :with_confirmed_hide) }
visit admin_comments_path(filter: 'with_confirmed_hide', page: 2)
click_on('Restore', match: :first, exact: true)
expect(current_url).to include('filter=with_confirmed_hide')
expect(current_url).to include('page=2')
end
end

View File

@@ -2,22 +2,71 @@ require 'rails_helper'
feature 'Admin debates' do
scenario 'Restore', :js do
citizen = create(:user)
background do
admin = create(:administrator)
debate = create(:debate, :hidden)
login_as(admin.user)
visit admin_debate_path(debate)
end
scenario 'Restore' do
debate = create(:debate, :hidden)
visit admin_debates_path
click_link 'Restore'
expect(page).to have_content 'The debate has been restored'
expect(page).to_not have_content(debate.title)
login_as(citizen)
visit debates_path
expect(page).to have_css('.debate', count: 1)
expect(debate.reload).to_not be_hidden
end
scenario 'Confirm hide' do
debate = create(:debate, :hidden)
visit admin_debates_path
click_link 'Confirm'
expect(page).to have_content(debate.title)
expect(page).to have_content('Confirmed')
expect(debate.reload).to be_confirmed_hide
end
scenario "Current filter is properly highlighted" do
visit admin_debates_path
expect(page).to_not have_link('All')
expect(page).to have_link('Confirmed')
visit admin_debates_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Confirmed')
visit admin_debates_path(filter: 'with_confirmed_hide')
expect(page).to have_link('All')
expect(page).to_not have_link('Confirmed')
end
scenario "Filtering debates" do
create(:debate, :hidden, title: "Unconfirmed debate")
create(:debate, :hidden, :with_confirmed_hide, title: "Confirmed debate")
visit admin_debates_path(filter: 'all')
expect(page).to have_content('Unconfirmed debate')
expect(page).to have_content('Confirmed debate')
visit admin_debates_path(filter: 'with_confirmed_hide')
expect(page).to_not have_content('Unconfirmed debate')
expect(page).to have_content('Confirmed debate')
end
scenario "Action links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:debate, :hidden, :with_confirmed_hide) }
visit admin_debates_path(filter: 'with_confirmed_hide', page: 2)
click_on('Restore', match: :first, exact: true)
expect(current_url).to include('filter=with_confirmed_hide')
expect(current_url).to include('page=2')
end
end

View File

@@ -119,11 +119,8 @@ feature 'Admin::Organizations' do
click_on('Verify', match: :first)
uri = URI.parse(current_url)
query_params = Rack::Utils.parse_nested_query(uri.query).symbolize_keys
expect(query_params[:filter]).to eq('pending')
expect(query_params[:page]).to eq('2')
expect(current_url).to include('filter=pending')
expect(current_url).to include('page=2')
end
end

View File

@@ -2,60 +2,20 @@ require 'rails_helper'
feature 'Admin users' do
scenario 'Restore hidden user' do
citizen = create(:user)
background do
admin = create(:administrator)
create(:moderator, user: admin.user)
debate_previously_hidden = create(:debate, :hidden, author: citizen)
debate = create(:debate, author: citizen)
comment_previously_hidden = create(:comment, :hidden, user: citizen, commentable: debate, body: "You have the manners of a beggar")
comment = create(:comment, user: citizen, commentable: debate, body: 'Not Spam')
login_as(admin.user)
visit debate_path(debate)
within("#debate_#{debate.id}") do
click_link 'Ban author'
end
visit debates_path
expect(page).to_not have_content(debate.title)
expect(page).to_not have_content(debate_previously_hidden)
click_link "Administration"
click_link "Hidden users"
click_link "Restore user"
visit debates_path
expect(page).to have_content(debate.title)
expect(page).to_not have_content(debate_previously_hidden)
visit debate_path(debate)
expect(page).to have_content(comment.body)
expect(page).to_not have_content(comment_previously_hidden.body)
end
scenario 'Show user activity' do
citizen = create(:user)
admin = create(:administrator)
create(:moderator, user: admin.user)
user = create(:user, :hidden)
debate1 = create(:debate, :hidden, author: citizen)
debate2 = create(:debate, author: citizen)
comment1 = create(:comment, :hidden, user: citizen, commentable: debate2, body: "You have the manners of a beggar")
comment2 = create(:comment, user: citizen, commentable: debate2, body: 'Not Spam')
debate1 = create(:debate, :hidden, author: user)
debate2 = create(:debate, author: user)
comment1 = create(:comment, :hidden, user: user, commentable: debate2, body: "You have the manners of a beggar")
comment2 = create(:comment, user: user, commentable: debate2, body: 'Not Spam')
login_as(admin.user)
visit debate_path(debate2)
within("#debate_#{debate2.id}") do
click_link 'Ban author'
end
click_link "Administration"
click_link "Hidden users"
click_link citizen.name
visit admin_user_path(user)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
@@ -63,4 +23,66 @@ feature 'Admin users' do
expect(page).to have_content(comment2.body)
end
scenario 'Restore' do
user = create(:user, :hidden)
visit admin_users_path
click_link 'Restore'
expect(page).to_not have_content(user.username)
expect(user.reload).to_not be_hidden
end
scenario 'Confirm hide' do
user = create(:user, :hidden)
visit admin_users_path
click_link 'Confirm'
expect(page).to have_content(user.username)
expect(page).to have_content('Confirmed')
expect(user.reload).to be_confirmed_hide
end
scenario "Current filter is properly highlighted" do
visit admin_users_path
expect(page).to_not have_link('All')
expect(page).to have_link('Confirmed')
visit admin_users_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Confirmed')
visit admin_users_path(filter: 'with_confirmed_hide')
expect(page).to have_link('All')
expect(page).to_not have_link('Confirmed')
end
scenario "Filtering users" do
create(:user, :hidden, username: "Unconfirmed")
create(:user, :hidden, :with_confirmed_hide, username: "Confirmed user")
visit admin_users_path(filter: 'all')
expect(page).to have_content('Unconfirmed')
expect(page).to have_content('Confirmed user')
visit admin_users_path(filter: 'with_confirmed_hide')
expect(page).to_not have_content('Unconfirmed')
expect(page).to have_content('Confirmed user')
end
scenario "Action links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:user, :hidden, :with_confirmed_hide) }
visit admin_users_path(filter: 'with_confirmed_hide', page: 2)
click_on('Restore', match: :first, exact: true)
expect(current_url).to include('filter=with_confirmed_hide')
expect(current_url).to include('page=2')
end
end

View File

@@ -148,14 +148,14 @@ feature 'Comments' do
expect(page).to have_css("#unflag-expand-comment-#{comment.id}")
end
expect(InappropiateFlag.flagged?(user, comment)).to be
expect(Flag.flagged?(user, comment)).to be
end
scenario "Undoing flagging as inappropriate", :js do
user = create(:user)
debate = create(:debate)
comment = create(:comment, commentable: debate)
InappropiateFlag.flag!(user, comment)
Flag.flag!(user, comment)
login_as(user)
visit debate_path(debate)
@@ -167,7 +167,7 @@ feature 'Comments' do
expect(page).to have_css("#flag-expand-comment-#{comment.id}")
end
expect(InappropiateFlag.flagged?(user, comment)).to_not be
expect(Flag.flagged?(user, comment)).to_not be
end
feature "Moderators" do

View File

@@ -315,7 +315,7 @@ feature 'Debates' do
end
end
scenario "Flagging as inappropiate", :js do
scenario "Flagging", :js do
user = create(:user)
debate = create(:debate)
@@ -329,13 +329,13 @@ feature 'Debates' do
expect(page).to have_css("#unflag-expand-debate-#{debate.id}")
end
expect(InappropiateFlag.flagged?(user, debate)).to be
expect(Flag.flagged?(user, debate)).to be
end
scenario "Undoing flagging as inappropiate", :js do
scenario "Unflagging", :js do
user = create(:user)
debate = create(:debate)
InappropiateFlag.flag!(user, debate)
Flag.flag!(user, debate)
login_as(user)
visit debate_path(debate)
@@ -347,7 +347,7 @@ feature 'Debates' do
expect(page).to have_css("#flag-expand-debate-#{debate.id}")
end
expect(InappropiateFlag.flagged?(user, debate)).to_not be
expect(Flag.flagged?(user, debate)).to_not be
end
feature 'Debate index order filters', :js do

View File

@@ -6,7 +6,7 @@ feature 'Localization' do
visit root_path(locale: :es)
visit root_path(locale: :klingon)
expect(page).to have_text('Estamos abriendo Madrid')
expect(page).to have_text('La ciudad que quieres, será la ciudad que quieras.')
end
scenario 'Available locales appear in the locale switcher' do

View File

@@ -104,65 +104,62 @@ feature 'Moderate Comments' do
visit moderation_comments_path
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
expect(page).to have_link('Archived')
expect(page).to have_link('Ignored')
visit moderation_comments_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
expect(page).to have_link('Archived')
expect(page).to have_link('Ignored')
visit moderation_comments_path(filter: 'pending')
visit moderation_comments_path(filter: 'pending_flag_review')
expect(page).to have_link('All')
expect(page).to_not have_link('Pending')
expect(page).to have_link('Archived')
expect(page).to have_link('Ignored')
visit moderation_comments_path(filter: 'archived')
visit moderation_comments_path(filter: 'with_ignored_flag')
expect(page).to have_link('All')
expect(page).to have_link('Pending')
expect(page).to_not have_link('Archived')
expect(page).to_not have_link('Ignored')
end
scenario "Filtering comments" do
create(:comment, :flagged_as_inappropiate, body: "Pending comment")
create(:comment, :flagged_as_inappropiate, :hidden, body: "Hidden comment")
create(:comment, :flagged_as_inappropiate, :archived, body: "Archived comment")
create(:comment, :flagged, body: "Pending comment")
create(:comment, :flagged, :hidden, body: "Hidden comment")
create(:comment, :flagged, :with_ignored_flag, body: "Ignored comment")
visit moderation_comments_path(filter: 'all')
expect(page).to have_content('Pending comment')
expect(page).to_not have_content('Hidden comment')
expect(page).to have_content('Archived comment')
expect(page).to have_content('Ignored comment')
visit moderation_comments_path(filter: 'pending')
visit moderation_comments_path(filter: 'pending_flag_review')
expect(page).to have_content('Pending comment')
expect(page).to_not have_content('Hidden comment')
expect(page).to_not have_content('Archived comment')
expect(page).to_not have_content('Ignored comment')
visit moderation_comments_path(filter: 'archived')
visit moderation_comments_path(filter: 'with_ignored_flag')
expect(page).to_not have_content('Pending comment')
expect(page).to_not have_content('Hidden comment')
expect(page).to have_content('Archived comment')
expect(page).to have_content('Ignored comment')
end
scenario "Reviewing links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:comment, :flagged_as_inappropiate) }
(per_page + 2).times { create(:comment, :flagged) }
visit moderation_comments_path(filter: 'pending', page: 2)
visit moderation_comments_path(filter: 'pending_flag_review', page: 2)
click_link('Archive', match: :first, exact: true)
click_link('Ignore', match: :first, exact: true)
uri = URI.parse(current_url)
query_params = Rack::Utils.parse_nested_query(uri.query).symbolize_keys
expect(query_params[:filter]).to eq('pending')
expect(query_params[:page]).to eq('2')
expect(current_url).to include('filter=pending_flag_review')
expect(current_url).to include('page=2')
end
feature 'A flagged comment exists' do
background do
debate = create(:debate, title: 'Democracy')
@comment = create(:comment, :flagged_as_inappropiate, commentable: debate, body: 'spammy spam')
@comment = create(:comment, :flagged, commentable: debate, body: 'spammy spam')
visit moderation_comments_path
end
@@ -172,7 +169,7 @@ feature 'Moderate Comments' do
expect(page).to have_content('spammy spam')
expect(page).to have_content('1')
expect(page).to have_link('Hide')
expect(page).to have_link('Archive')
expect(page).to have_link('Ignore')
end
end
@@ -187,18 +184,18 @@ feature 'Moderate Comments' do
expect(@comment.reload).to be_hidden
end
scenario 'Marking the comment as archived' do
scenario 'Marking the comment as ignored' do
within("#comment_#{@comment.id}") do
click_link('Archive')
click_link('Ignore')
end
expect(current_path).to eq(moderation_comments_path)
within("#comment_#{@comment.id}") do
expect(page).to have_content('Archived')
expect(page).to have_content('Ignored')
end
expect(@comment.reload).to be_archived
expect(@comment.reload).to be_ignored_flag
end
end
end

View File

@@ -47,64 +47,61 @@ feature 'Moderate debates' do
visit moderation_debates_path
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
expect(page).to have_link('Archived')
expect(page).to have_link('Ignored')
visit moderation_debates_path(filter: 'all')
expect(page).to_not have_link('All')
expect(page).to have_link('Pending')
expect(page).to have_link('Archived')
expect(page).to have_link('Ignored')
visit moderation_debates_path(filter: 'pending')
visit moderation_debates_path(filter: 'pending_flag_review')
expect(page).to have_link('All')
expect(page).to_not have_link('Pending')
expect(page).to have_link('Archived')
expect(page).to have_link('Ignored')
visit moderation_debates_path(filter: 'archived')
visit moderation_debates_path(filter: 'with_ignored_flag')
expect(page).to have_link('All')
expect(page).to have_link('Pending')
expect(page).to_not have_link('Archived')
expect(page).to_not have_link('Ignored')
end
scenario "Filtering debates" do
create(:debate, :flagged_as_inappropiate, title: "Pending debate")
create(:debate, :flagged_as_inappropiate, :hidden, title: "Hidden debate")
create(:debate, :flagged_as_inappropiate, :archived, title: "Archived debate")
create(:debate, :flagged, title: "Pending debate")
create(:debate, :flagged, :hidden, title: "Hidden debate")
create(:debate, :flagged, :with_ignored_flag, title: "Ignored debate")
visit moderation_debates_path(filter: 'all')
expect(page).to have_content('Pending debate')
expect(page).to_not have_content('Hidden debate')
expect(page).to have_content('Archived debate')
expect(page).to have_content('Ignored debate')
visit moderation_debates_path(filter: 'pending')
visit moderation_debates_path(filter: 'pending_flag_review')
expect(page).to have_content('Pending debate')
expect(page).to_not have_content('Hidden debate')
expect(page).to_not have_content('Archived debate')
expect(page).to_not have_content('Ignored debate')
visit moderation_debates_path(filter: 'archived')
visit moderation_debates_path(filter: 'with_ignored_flag')
expect(page).to_not have_content('Pending debate')
expect(page).to_not have_content('Hidden debate')
expect(page).to have_content('Archived debate')
expect(page).to have_content('Ignored debate')
end
scenario "Reviewing links remember the pagination setting and the filter" do
per_page = Kaminari.config.default_per_page
(per_page + 2).times { create(:debate, :flagged_as_inappropiate) }
(per_page + 2).times { create(:debate, :flagged) }
visit moderation_debates_path(filter: 'pending', page: 2)
visit moderation_debates_path(filter: 'pending_flag_review', page: 2)
click_link('Archive', match: :first, exact: true)
click_link('Ignore', match: :first, exact: true)
uri = URI.parse(current_url)
query_params = Rack::Utils.parse_nested_query(uri.query).symbolize_keys
expect(query_params[:filter]).to eq('pending')
expect(query_params[:page]).to eq('2')
expect(current_url).to include('filter=pending_flag_review')
expect(current_url).to include('page=2')
end
feature 'A flagged debate exists' do
background do
@debate = create(:debate, :flagged_as_inappropiate, title: 'spammy spam', description: 'buy buy buy')
@debate = create(:debate, :flagged, title: 'spammy spam', description: 'buy buy buy')
visit moderation_debates_path
end
@@ -114,7 +111,7 @@ feature 'Moderate debates' do
expect(page).to have_content('buy buy buy')
expect(page).to have_content('1')
expect(page).to have_link('Hide')
expect(page).to have_link('Archive')
expect(page).to have_link('Ignore')
end
end
@@ -129,18 +126,18 @@ feature 'Moderate debates' do
expect(@debate.reload).to be_hidden
end
scenario 'Marking the debate as archived' do
scenario 'Marking the debate as ignored' do
within("#debate_#{@debate.id}") do
click_link('Archive')
click_link('Ignore')
end
expect(current_path).to eq(moderation_debates_path)
within("#debate_#{@debate.id}") do
expect(page).to have_content('Archived')
expect(page).to have_content('Ignored')
end
expect(@debate.reload).to be_archived
expect(@debate.reload).to be_ignored_flag
end
end
end

View File

@@ -2,7 +2,7 @@ require 'rails_helper'
describe 'Paranoid methods' do
describe '#hide_all' do
describe '.hide_all' do
it 'hides all instances in the id list' do
debate1 = create(:debate)
debate2 = create(:debate)
@@ -17,7 +17,7 @@ describe 'Paranoid methods' do
end
end
describe '#restore_all' do
describe '.restore_all' do
it 'restores all instances in the id list' do
debate1 = create(:debate)
debate2 = create(:debate)
@@ -34,4 +34,14 @@ describe 'Paranoid methods' do
end
end
describe '#restore' do
it 'resets the confirmed_hide_at attribute' do
debate = create(:debate, :hidden, :with_confirmed_hide)
debate.restore
expect(debate.reload.confirmed_hide?).to_not be
end
end
end

View File

@@ -31,38 +31,38 @@ describe Ability do
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) }
it { should be_able_to(:flag_as_inappropiate, comment) }
it { should_not be_able_to(:undo_flag_as_inappropiate, comment) }
describe 'flagging content' do
it { should be_able_to(:flag, debate) }
it { should_not be_able_to(:unflag, debate) }
it { should be_able_to(:flag, comment) }
it { should_not be_able_to(:unflag, comment) }
describe "own comments" do
let(:own_comment) { create(:comment, author: user) }
it { should_not be_able_to(:flag_as_inappropiate, own_comment) }
it { should_not be_able_to(:undo_flag_as_inappropiate, own_comment) }
it { should_not be_able_to(:flag, own_comment) }
it { should_not be_able_to(:unflag, own_comment) }
end
describe "own debates" do
let(:own_debate) { create(:debate, author: user) }
it { should_not be_able_to(:flag_as_inappropiate, own_debate) }
it { should_not be_able_to(:undo_flag_as_inappropiate, own_debate) }
it { should_not be_able_to(:flag, own_debate) }
it { should_not be_able_to(:unflag, own_debate) }
end
describe "already-flagged comments" do
before(:each) { InappropiateFlag.flag!(user, comment) }
before(:each) { Flag.flag!(user, comment) }
it { should_not be_able_to(:flag_as_inappropiate, comment) }
it { should be_able_to(:undo_flag_as_inappropiate, comment) }
it { should_not be_able_to(:flag, comment) }
it { should be_able_to(:unflag, comment) }
end
describe "already-flagged debates" do
before(:each) { InappropiateFlag.flag!(user, debate) }
before(:each) { Flag.flag!(user, debate) }
it { should_not be_able_to(:flag_as_inappropiate, debate) }
it { should be_able_to(:undo_flag_as_inappropiate, debate) }
it { should_not be_able_to(:flag, debate) }
it { should be_able_to(:unflag, debate) }
end
end
@@ -131,8 +131,8 @@ describe Ability do
let(:own_debate) { create(:debate, author: user) }
let(:hidden_comment) { create(:comment, :hidden) }
let(:hidden_debate) { create(:debate, :hidden) }
let(:archived_comment) { create(:comment, :archived) }
let(:archived_debate) { create(:debate, :archived) }
let(:ignored_comment) { create(:comment, :with_ignored_flag) }
let(:ignored_debate) { create(:debate, :with_ignored_flag) }
it { should be_able_to(:hide, comment) }
it { should be_able_to(:hide_in_moderation_screen, comment) }
@@ -144,15 +144,15 @@ describe Ability do
it { should_not be_able_to(:hide, hidden_debate) }
it { should_not be_able_to(:hide, own_debate) }
it { should be_able_to(:archive, comment) }
it { should_not be_able_to(:archive, hidden_comment) }
it { should_not be_able_to(:archive, archived_comment) }
it { should_not be_able_to(:archive, own_comment) }
it { should be_able_to(:ignore_flag, comment) }
it { should_not be_able_to(:ignore_flag, hidden_comment) }
it { should_not be_able_to(:ignore_flag, ignored_comment) }
it { should_not be_able_to(:ignore_flag, own_comment) }
it { should be_able_to(:archive, debate) }
it { should_not be_able_to(:archive, hidden_debate) }
it { should_not be_able_to(:archive, archived_debate) }
it { should_not be_able_to(:archive, own_debate) }
it { should be_able_to(:ignore_flag, debate) }
it { should_not be_able_to(:ignore_flag, hidden_debate) }
it { should_not be_able_to(:ignore_flag, ignored_debate) }
it { should_not be_able_to(:ignore_flag, own_debate) }
it { should_not be_able_to(:hide, user) }
it { should be_able_to(:hide, other_user) }
@@ -169,15 +169,34 @@ describe Ability do
describe "Administrator" do
let(:user) { create(:user) }
before { create(:administrator, user: user) }
let(:other_user) { create(:user) }
let(:other_user) { create(:user) }
let(:hidden_user) { create(:user, :hidden) }
let(:hidden_debate) { create(:debate, :hidden) }
let(:hidden_comment) { create(:comment, :hidden) }
let(:own_debate) { create(:debate, author: user)}
let(:own_comment) { create(:comment, author: 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(:restore, comment) }
it { should be_able_to(:restore, debate) }
it { should be_able_to(:restore, other_user) }
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(:restore, hidden_comment) }
it { should be_able_to(:restore, hidden_debate) }
it { should be_able_to(:restore, hidden_user) }
it { should_not be_able_to(:confirm_hide, comment) }
it { should_not be_able_to(:confirm_hide, debate) }
it { should_not be_able_to(:confirm_hide, other_user) }
it { should be_able_to(:confirm_hide, hidden_comment) }
it { should be_able_to(:confirm_hide, hidden_debate) }
it { should be_able_to(:confirm_hide, hidden_user) }
it { should be_able_to(:comment_as_administrator, debate) }
it { should_not be_able_to(:comment_as_moderator, debate) }

View File

@@ -1,6 +1,6 @@
require 'rails_helper'
describe InappropiateFlag do
describe Flag do
let(:user) { create(:user) }
let(:comment) { create(:comment) }
@@ -8,43 +8,35 @@ describe InappropiateFlag do
describe '.flag!' do
it 'creates a flag when there is none' do
expect { described_class.flag!(user, comment) }.to change{ InappropiateFlag.count }.by(1)
expect(InappropiateFlag.last.user).to eq(user)
expect(InappropiateFlag.last.flaggable).to eq(comment)
expect { described_class.flag!(user, comment) }.to change{ Flag.count }.by(1)
expect(Flag.last.user).to eq(user)
expect(Flag.last.flaggable).to eq(comment)
end
it 'raises an error if the flag has already been created' do
described_class.flag!(user, comment)
expect { described_class.flag!(user, comment) }.to raise_error(InappropiateFlag::AlreadyFlaggedError)
expect { described_class.flag!(user, comment) }.to raise_error(Flag::AlreadyFlaggedError)
end
it 'increases the flag count' do
expect { described_class.flag!(user, comment) }.to change{ comment.reload.inappropiate_flags_count }.by(1)
end
it 'updates the flagged_as date' do
expect { described_class.flag!(user, comment) }.to change{ comment.reload.flagged_as_inappropiate_at }
expect { described_class.flag!(user, comment) }.to change{ comment.reload.flags_count }.by(1)
end
end
describe '.unflag!' do
it 'raises an error if the flag does not exist' do
expect { described_class.unflag!(user, comment) }.to raise_error(InappropiateFlag::NotFlaggedError)
expect { described_class.unflag!(user, comment) }.to raise_error(Flag::NotFlaggedError)
end
describe 'when the flag already exists' do
before(:each) { described_class.flag!(user, comment) }
it 'removes an existing flag' do
expect { described_class.unflag!(user, comment) }.to change{ InappropiateFlag.count }.by(-1)
expect { described_class.unflag!(user, comment) }.to change{ Flag.count }.by(-1)
end
it 'decreases the flag count' do
expect { described_class.unflag!(user, comment) }.to change{ comment.reload.inappropiate_flags_count }.by(-1)
end
it 'does not update the flagged_as date' do
expect { described_class.unflag!(user, comment) }.to_not change{ comment.flagged_as_inappropiate_at }
expect { described_class.unflag!(user, comment) }.to change{ comment.reload.flags_count }.by(-1)
end
end