Merge pull request #4781 from Zauberstuhl/report_feature
It is now possible to report posts and comments
This commit is contained in:
commit
63c44d9f6b
47 changed files with 615 additions and 276 deletions
|
|
@ -49,7 +49,7 @@ Read more in [#4249](https://github.com/diaspora/diaspora/pull/4249) and [#4883]
|
||||||
* Redirect to the stream when switching the mobile publisher to desktop [#4806](https://github.com/diaspora/diaspora/issues/4806)
|
* Redirect to the stream when switching the mobile publisher to desktop [#4806](https://github.com/diaspora/diaspora/issues/4806)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* You can report a single post by clicking the correct icon in the controler section [#4517](https://github.com/diaspora/diaspora/pull/4517)
|
* You can report a single post or comment by clicking the correct icon in the controler section [#4517](https://github.com/diaspora/diaspora/pull/4517) [#4781](https://github.com/diaspora/diaspora/pull/4781)
|
||||||
* Add permalinks for comments [#4577](https://github.com/diaspora/diaspora/pull/4577)
|
* Add permalinks for comments [#4577](https://github.com/diaspora/diaspora/pull/4577)
|
||||||
* New menu for the mobile version [#4673](https://github.com/diaspora/diaspora/pull/4673)
|
* New menu for the mobile version [#4673](https://github.com/diaspora/diaspora/pull/4673)
|
||||||
* Added comment count to statistic to enable calculations of posts/comments ratios [#4799](https://github.com/diaspora/diaspora/pull/4799)
|
* Added comment count to statistic to enable calculations of posts/comments ratios [#4799](https://github.com/diaspora/diaspora/pull/4799)
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 173 B |
|
|
@ -1,3 +0,0 @@
|
||||||
app.models.PostReport = Backbone.Model.extend({
|
|
||||||
urlRoot: '/post_report'
|
|
||||||
});
|
|
||||||
4
app/assets/javascripts/app/models/report.js
Normal file
4
app/assets/javascripts/app/models/report.js
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
app.models.Report = Backbone.Model.extend({
|
||||||
|
urlRoot: '/report',
|
||||||
|
type: 'POST'
|
||||||
|
});
|
||||||
|
|
@ -81,6 +81,37 @@ app.views.Base = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
report: function(evt) {
|
||||||
|
if(evt) { evt.preventDefault(); }
|
||||||
|
var msg = prompt(Diaspora.I18n.t('report.prompt'), Diaspora.I18n.t('report.prompt_default'));
|
||||||
|
if (msg == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var data = {
|
||||||
|
report: {
|
||||||
|
item_id: this.model.id,
|
||||||
|
item_type: $(evt.currentTarget).data("type"),
|
||||||
|
text: msg
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var report = new app.models.Report();
|
||||||
|
report.save(data, {
|
||||||
|
success: function(model, response) {
|
||||||
|
Diaspora.page.flashMessages.render({
|
||||||
|
success: true,
|
||||||
|
notice: Diaspora.I18n.t('report.status.created')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function(model, response) {
|
||||||
|
Diaspora.page.flashMessages.render({
|
||||||
|
success: false,
|
||||||
|
notice: Diaspora.I18n.t('report.status.exists')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
destroyModel: function(evt) {
|
destroyModel: function(evt) {
|
||||||
evt && evt.preventDefault();
|
evt && evt.preventDefault();
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
@ -114,4 +145,4 @@ app.views.StaticContentView = app.views.Base.extend({
|
||||||
presenter : function(){
|
presenter : function(){
|
||||||
return this.data;
|
return this.data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ app.views.Comment = app.views.Content.extend({
|
||||||
|
|
||||||
events : function() {
|
events : function() {
|
||||||
return _.extend({}, app.views.Content.prototype.events, {
|
return _.extend({}, app.views.Content.prototype.events, {
|
||||||
"click .comment_delete": "destroyModel"
|
"click .comment_delete": "destroyModel",
|
||||||
|
"click .comment_report": "report"
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ app.views.Feedback = app.views.Base.extend({
|
||||||
events: {
|
events: {
|
||||||
"click *[rel='auth-required']" : "requireAuth",
|
"click *[rel='auth-required']" : "requireAuth",
|
||||||
"click .like" : "toggleLike",
|
"click .like" : "toggleLike",
|
||||||
"click .reshare" : "resharePost"
|
"click .reshare" : "resharePost",
|
||||||
|
"click .post_report" : "report"
|
||||||
},
|
},
|
||||||
|
|
||||||
tooltipSelector : ".label",
|
tooltipSelector : ".label",
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ app.views.StreamPost = app.views.Post.extend({
|
||||||
|
|
||||||
"click .remove_post": "destroyModel",
|
"click .remove_post": "destroyModel",
|
||||||
"click .hide_post": "hidePost",
|
"click .hide_post": "hidePost",
|
||||||
"click .post_report": "postReport",
|
"click .post_report": "report",
|
||||||
"click .block_user": "blockUser"
|
"click .block_user": "blockUser"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -108,21 +108,6 @@ app.views.StreamPost = app.views.Post.extend({
|
||||||
this.remove();
|
this.remove();
|
||||||
},
|
},
|
||||||
|
|
||||||
postReport : function(evt) {
|
|
||||||
if(evt) { evt.preventDefault(); }
|
|
||||||
var text = prompt(Diaspora.I18n.t('post_report_prompt'),
|
|
||||||
Diaspora.I18n.t('post_report_prompt_default'));
|
|
||||||
|
|
||||||
var postReport = new app.models.PostReport();
|
|
||||||
postReport.fetch({
|
|
||||||
data: {
|
|
||||||
post_id: this.model.id,
|
|
||||||
text: text
|
|
||||||
},
|
|
||||||
type: 'POST'
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
focusCommentTextarea: function(evt){
|
focusCommentTextarea: function(evt){
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
this.$(".new_comment_form_wrapper").removeClass("hidden");
|
this.$(".new_comment_form_wrapper").removeClass("hidden");
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
@import 'facebox'
|
@import 'facebox'
|
||||||
@import 'aspects'
|
@import 'aspects'
|
||||||
@import 'popover'
|
@import 'popover'
|
||||||
@import 'post_report'
|
|
||||||
@import 'stream_element'
|
@import 'stream_element'
|
||||||
|
@import 'report'
|
||||||
|
|
||||||
/* ====== media ====== */
|
/* ====== media ====== */
|
||||||
.media
|
.media
|
||||||
|
|
@ -211,10 +211,10 @@ ul.as-selections
|
||||||
:z-index 6
|
:z-index 6
|
||||||
:float right
|
:float right
|
||||||
|
|
||||||
.post_report
|
.post_report, .comment_report
|
||||||
:display inline-block
|
:display inline-block
|
||||||
|
|
||||||
.icons-postreport
|
.icons-report
|
||||||
:height 14px
|
:height 14px
|
||||||
:width 14px
|
:width 14px
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,18 @@
|
||||||
#post_report {
|
#reports {
|
||||||
padding-top: 2em;
|
padding-top: 2em;
|
||||||
span {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.content {
|
.content {
|
||||||
float: left;
|
float: left;
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.options {
|
.options {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
.clear {
|
.clear {
|
||||||
clear: both;
|
clear: both;
|
||||||
|
border-bottom: 1px solid #808080;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +61,9 @@
|
||||||
i.comment:hover {
|
i.comment:hover {
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
|
.post_report i.gray:hover {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
i.heart.gray:hover {
|
i.heart.gray:hover {
|
||||||
color: $red;
|
color: $red;
|
||||||
}
|
}
|
||||||
|
|
@ -204,6 +207,13 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
@include opacity(1);
|
@include opacity(1);
|
||||||
}
|
}
|
||||||
|
.comment_report {
|
||||||
|
display: inline-block;
|
||||||
|
.icons-report {
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
.delete {
|
.delete {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
.icons-deletelabel {
|
.icons-deletelabel {
|
||||||
|
|
|
||||||
|
|
@ -133,17 +133,17 @@
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
.comment_delete {
|
.comment_delete, .comment_report {
|
||||||
@include transition(opacity);
|
@include transition(opacity);
|
||||||
@include opacity(0);
|
@include opacity(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
.controls {
|
.controls {
|
||||||
.comment_delete {
|
.comment_delete, .comment_report {
|
||||||
@include opacity(0.3);
|
@include opacity(0.3);
|
||||||
}
|
}
|
||||||
.comment_delete:hover {
|
.comment_delete:hover, .comment_report:hover {
|
||||||
@include opacity(1);
|
@include opacity(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,17 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bd">
|
<div class="bd">
|
||||||
|
<div class="controls">
|
||||||
{{#if canRemove}}
|
{{#if canRemove}}
|
||||||
<div class="controls">
|
<a href="#" class="delete comment_delete" title="{{t "delete"}}">
|
||||||
<a href="#" class="delete comment_delete" title="{{t "delete"}}">
|
<div alt="Deletelabel" class="icons-deletelabel" />
|
||||||
<div alt="Deletelabel" class="icons-deletelabel" />
|
<a/>
|
||||||
<a/>
|
{{else}}
|
||||||
</div>
|
<a href="#" data-type="comment" class="comment_report" title="{{t "report.name"}}">
|
||||||
|
<div class="icons-report"/>
|
||||||
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{#with author}}
|
{{#with author}}
|
||||||
<a href="/people/{{guid}}" class="author author-name {{hovercardable this}}">
|
<a href="/people/{{guid}}" class="author author-name {{hovercardable this}}">
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,9 @@
|
||||||
</a>
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
<a href="#" rel="auth-required" data-type="post" class="post_report" title="{{t "report.name"}}">
|
||||||
|
<i class="entypo gray large">!</i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
{{#if loggedIn}}
|
{{#if loggedIn}}
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{{#unless authorIsCurrentUser}}
|
{{#unless authorIsCurrentUser}}
|
||||||
<a href="#" rel="nofollow" class="post_report" title="{{t "post_report"}}">
|
<a href="#" rel="nofollow" data-type="post" class="post_report" title="{{t "report.name"}}">
|
||||||
<div class="icons-postreport control_icon"/>
|
<div class="icons-report control_icon"/>
|
||||||
</a>
|
</a>
|
||||||
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
|
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
|
||||||
<div class="icons-ignoreuser control_icon"></div>
|
<div class="icons-ignoreuser control_icon"></div>
|
||||||
|
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
class PostReportController < ApplicationController
|
|
||||||
before_filter :authenticate_user!
|
|
||||||
before_filter :redirect_unless_admin, :except => [:create]
|
|
||||||
|
|
||||||
def index
|
|
||||||
@post_report = PostReport.where(reviewed: false).all
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
if PostReport.exists?(post_id: params[:id])
|
|
||||||
mark_as_reviewed
|
|
||||||
end
|
|
||||||
redirect_to :action => :index and return
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
if Post.exists?(params[:id])
|
|
||||||
delete_post
|
|
||||||
mark_as_reviewed
|
|
||||||
end
|
|
||||||
redirect_to :action => :index and return
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
username = current_user.username
|
|
||||||
unless PostReport.where(post_id: params[:post_id]).exists?(user_id: username)
|
|
||||||
post = PostReport.new(
|
|
||||||
:post_id => params[:post_id],
|
|
||||||
:user_id => username,
|
|
||||||
:text => params[:text])
|
|
||||||
result = post.save
|
|
||||||
status(( 200 if result ) || ( 422 if !result ))
|
|
||||||
else
|
|
||||||
status(409)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def delete_post
|
|
||||||
post = Post.find(params[:id])
|
|
||||||
current_user.retract(post)
|
|
||||||
flash[:notice] = I18n.t 'post_report.status.destroyed'
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_as_reviewed id = params[:id]
|
|
||||||
posts = PostReport.where(post_id: id)
|
|
||||||
posts.each do |post|
|
|
||||||
post.update_attributes(reviewed: true)
|
|
||||||
end
|
|
||||||
flash[:notice] = I18n.t 'post_report.status.marked'
|
|
||||||
end
|
|
||||||
|
|
||||||
def status(code)
|
|
||||||
if code == 200
|
|
||||||
flash[:notice] = I18n.t 'post_report.status.created'
|
|
||||||
else
|
|
||||||
flash[:error] = I18n.t 'post_report.status.failed'
|
|
||||||
end
|
|
||||||
render :nothing => true, :status => code
|
|
||||||
end
|
|
||||||
end
|
|
||||||
42
app/controllers/report_controller.rb
Normal file
42
app/controllers/report_controller.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
class ReportController < ApplicationController
|
||||||
|
before_filter :authenticate_user!
|
||||||
|
before_filter :redirect_unless_admin, :except => [:create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@reports = Report.where(reviewed: false).all
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if report = Report.where(id: params[:id]).first
|
||||||
|
report.mark_as_reviewed
|
||||||
|
end
|
||||||
|
redirect_to :action => :index
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if (report = Report.where(id: params[:id]).first) && report.destroy_reported_item
|
||||||
|
flash[:notice] = I18n.t 'report.status.destroyed'
|
||||||
|
else
|
||||||
|
flash[:error] = I18n.t 'report.status.failed'
|
||||||
|
end
|
||||||
|
redirect_to :action => :index
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
report = current_user.reports.new(report_params)
|
||||||
|
if report.save
|
||||||
|
render :json => true, :status => 200
|
||||||
|
else
|
||||||
|
render :nothing => true, :status => 409
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def report_params
|
||||||
|
params.require(:report).permit(:item_id, :item_type, :text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -179,6 +179,7 @@ class UsersController < ApplicationController
|
||||||
:remember_me,
|
:remember_me,
|
||||||
:getting_started,
|
:getting_started,
|
||||||
email_preferences: [
|
email_preferences: [
|
||||||
|
:someone_reported,
|
||||||
:also_commented,
|
:also_commented,
|
||||||
:mentioned,
|
:mentioned,
|
||||||
:comment_on_post,
|
:comment_on_post,
|
||||||
|
|
|
||||||
16
app/helpers/report_helper.rb
Normal file
16
app/helpers/report_helper.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Copyright (c) 2012, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
module ReportHelper
|
||||||
|
def report_content(id, type)
|
||||||
|
raw case type
|
||||||
|
when 'post'
|
||||||
|
t('report.post_label', title: link_to(post_page_title(Post.find_by_id(id)), post_path(id)))
|
||||||
|
when 'comment'
|
||||||
|
# comment_message is not html_safe. To prevent
|
||||||
|
# cross-site-scripting we have to escape html
|
||||||
|
t('report.comment_label', data: h(comment_message(Comment.find_by_id(id))))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
class PostReportMailer < ActionMailer::Base
|
|
||||||
default :from => AppConfig.mail.sender_address
|
|
||||||
|
|
||||||
def new_report
|
|
||||||
Role.admins.each do |role|
|
|
||||||
email = User.find_by_id(role.person_id).email
|
|
||||||
format(email).deliver
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def format(email)
|
|
||||||
mail(to: email, subject: I18n.t('notifier.post_report_email.subject')) do |format|
|
|
||||||
format.text { render 'post_report/post_report_email' }
|
|
||||||
format.html { render 'post_report/post_report_email' }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
26
app/mailers/report_mailer.rb
Normal file
26
app/mailers/report_mailer.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
class ReportMailer < ActionMailer::Base
|
||||||
|
default :from => AppConfig.mail.sender_address
|
||||||
|
|
||||||
|
def new_report(type, id)
|
||||||
|
resource = {
|
||||||
|
:url => report_index_url,
|
||||||
|
:type => I18n.t('notifier.report_email.type.' + type),
|
||||||
|
:id => id
|
||||||
|
}
|
||||||
|
Role.admins.each do |role|
|
||||||
|
user = User.find_by_id(role.person_id)
|
||||||
|
unless user.user_preferences.exists?(:email_type => :someone_reported)
|
||||||
|
resource[:email] = user.email
|
||||||
|
format(resource).deliver
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def format(resource)
|
||||||
|
mail(to: resource[:email], subject: I18n.t('notifier.report_email.subject', :type => resource[:type])) do |format|
|
||||||
|
format.html { render 'report/report_email', :locals => { :resource => resource } }
|
||||||
|
format.text { render 'report/report_email', :locals => { :resource => resource } }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
class PostReport < ActiveRecord::Base
|
|
||||||
validates :user_id, presence: true
|
|
||||||
validates :post_id, presence: true
|
|
||||||
|
|
||||||
belongs_to :user
|
|
||||||
belongs_to :post
|
|
||||||
|
|
||||||
has_many :post_reports
|
|
||||||
|
|
||||||
after_create :send_report_notification
|
|
||||||
|
|
||||||
def send_report_notification
|
|
||||||
Workers::Mail::PostReportWorker.perform_async
|
|
||||||
end
|
|
||||||
end
|
|
||||||
60
app/models/report.rb
Normal file
60
app/models/report.rb
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
class Report < ActiveRecord::Base
|
||||||
|
validates :user_id, presence: true
|
||||||
|
validates :item_id, presence: true
|
||||||
|
validates :item_type, presence: true, :inclusion => { :in => %w(post comment),
|
||||||
|
:message => 'Type should match `post` or `comment`!'}
|
||||||
|
validates :text, presence: true
|
||||||
|
|
||||||
|
validate :entry_does_not_exist, :on => :create
|
||||||
|
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :post
|
||||||
|
belongs_to :comment
|
||||||
|
|
||||||
|
after_commit :send_report_notification, :on => :create
|
||||||
|
|
||||||
|
def entry_does_not_exist
|
||||||
|
if Report.where(item_id: item_id, item_type: item_type).exists?(user_id: user_id)
|
||||||
|
errors[:base] << 'You cannot report the same post twice.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_reported_item
|
||||||
|
if item_type == 'post'
|
||||||
|
delete_post
|
||||||
|
elsif item_type == 'comment'
|
||||||
|
delete_comment
|
||||||
|
end
|
||||||
|
mark_as_reviewed
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_post
|
||||||
|
if post = Post.where(id: item_id).first
|
||||||
|
if post.author.local?
|
||||||
|
post.author.owner.retract(post)
|
||||||
|
else
|
||||||
|
post.destroy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_comment
|
||||||
|
if comment = Comment.where(id: item_id).first
|
||||||
|
if comment.author.local?
|
||||||
|
comment.author.owner.retract(comment)
|
||||||
|
elsif comment.parent.author.local?
|
||||||
|
comment.parent.author.owner.retract(comment)
|
||||||
|
else
|
||||||
|
comment.destroy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_as_reviewed
|
||||||
|
Report.where(item_id: item_id, item_type: item_type).update_all(reviewed: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_report_notification
|
||||||
|
Workers::Mail::ReportWorker.perform_async(self.item_type, self.item_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -69,6 +69,8 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
has_many :notifications, :foreign_key => :recipient_id
|
has_many :notifications, :foreign_key => :recipient_id
|
||||||
|
|
||||||
|
has_many :reports
|
||||||
|
|
||||||
before_save :guard_unconfirmed_email,
|
before_save :guard_unconfirmed_email,
|
||||||
:save_person!
|
:save_person!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ class UserPreference < ActiveRecord::Base
|
||||||
validate :must_be_valid_email_type
|
validate :must_be_valid_email_type
|
||||||
|
|
||||||
VALID_EMAIL_TYPES =
|
VALID_EMAIL_TYPES =
|
||||||
["mentioned",
|
["someone_reported",
|
||||||
|
"mentioned",
|
||||||
"comment_on_post",
|
"comment_on_post",
|
||||||
"private_message",
|
"private_message",
|
||||||
"started_sharing",
|
"started_sharing",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
%li= link_to t('.user_search'), user_search_path
|
%li= link_to t('.user_search'), user_search_path
|
||||||
%li= link_to t('.weekly_user_stats'), weekly_user_stats_path
|
%li= link_to t('.weekly_user_stats'), weekly_user_stats_path
|
||||||
%li= link_to t('.pod_stats'), pod_stats_path
|
%li= link_to t('.pod_stats'), pod_stats_path
|
||||||
%li= link_to t('.post_report'), post_report_index_path
|
%li= link_to t('.report'), report_index_path
|
||||||
%li= link_to t('.correlations'), correlations_path
|
%li= link_to t('.correlations'), correlations_path
|
||||||
%li= link_to t('.sidekiq_monitor'), sidekiq_path
|
%li= link_to t('.sidekiq_monitor'), sidekiq_path
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
.span-24
|
|
||||||
= render :partial => 'admins/admin_bar'
|
|
||||||
|
|
||||||
.span-24.last
|
|
||||||
%h1
|
|
||||||
= t('post_report.title')
|
|
||||||
%div#post_report
|
|
||||||
- @post_report.each do |report|
|
|
||||||
%div.content
|
|
||||||
%span
|
|
||||||
= raw t('post_report.post_label', title: link_to(post_page_title(Post.find_by_id(report.post_id)), post_path(report.post_id)))
|
|
||||||
%span
|
|
||||||
= raw t('post_report.reported_label', person: link_to(report.user_id, user_profile_path(report.user_id)))
|
|
||||||
%span
|
|
||||||
= t('post_report.reason_label', text: report.text)
|
|
||||||
%div.options
|
|
||||||
%span
|
|
||||||
= link_to t('post_report.review_link'), post_report_path(report.post_id), method: :put
|
|
||||||
%span
|
|
||||||
= link_to t('post_report.delete_link'), post_report_path(report.post_id), method: :delete
|
|
||||||
%div.clear
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
<%= t('notifier.post_report_email.body') %>
|
|
||||||
|
|
||||||
27
app/views/report/index.html.haml
Normal file
27
app/views/report/index.html.haml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
.span-24
|
||||||
|
= render :partial => 'admins/admin_bar'
|
||||||
|
|
||||||
|
.span-24.last
|
||||||
|
%h1
|
||||||
|
= t('report.title')
|
||||||
|
%div#reports
|
||||||
|
- @reports.each do |r|
|
||||||
|
- username = User.find_by_id(r.user_id).username
|
||||||
|
%div.content
|
||||||
|
%span
|
||||||
|
= report_content(r.item_id, r.item_type)
|
||||||
|
%span
|
||||||
|
= raw t('report.reported_label', person: link_to(username, user_profile_path(username)))
|
||||||
|
%span
|
||||||
|
= t('report.reason_label', text: r.text)
|
||||||
|
%div.options
|
||||||
|
%span
|
||||||
|
= button_to t('report.review_link'), report_path(r.id, :type => r.item_type),
|
||||||
|
:class => "button",
|
||||||
|
method: :put
|
||||||
|
%span
|
||||||
|
= button_to t('report.delete_link'), report_path(r.id, :type => r.item_type),
|
||||||
|
:data => { :confirm => t('report.confirm_deletion') },
|
||||||
|
:class => "button delete",
|
||||||
|
method: :delete
|
||||||
|
%div.clear
|
||||||
2
app/views/report/report_email.markerb
Normal file
2
app/views/report/report_email.markerb
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
<%= t('notifier.report_email.body', url: resource[:url], type: resource[:type], id: resource[:id]) %>
|
||||||
|
|
||||||
|
|
@ -125,11 +125,22 @@
|
||||||
|
|
||||||
= f.fields_for :email_preferences do |type|
|
= f.fields_for :email_preferences do |type|
|
||||||
#email_prefs
|
#email_prefs
|
||||||
|
- if current_user.admin?
|
||||||
|
%p.checkbox_select
|
||||||
|
= type.label :someone_reported, t('.someone_reported')
|
||||||
|
= type.check_box :someone_reported, {:checked => @email_prefs['someone_reported']}, false, true
|
||||||
|
|
||||||
|
%br
|
||||||
%p.checkbox_select
|
%p.checkbox_select
|
||||||
= type.label :started_sharing, t('.started_sharing')
|
= type.label :started_sharing, t('.started_sharing')
|
||||||
= type.check_box :started_sharing, {:checked => @email_prefs['started_sharing']}, false, true
|
= type.check_box :started_sharing, {:checked => @email_prefs['started_sharing']}, false, true
|
||||||
%br
|
%br
|
||||||
|
|
||||||
|
%p.checkbox_select
|
||||||
|
= type.label :also_commented, t('.also_commented')
|
||||||
|
= type.check_box :also_commented, {:checked => @email_prefs['also_commented']}, false, true
|
||||||
|
%br
|
||||||
|
|
||||||
%p.checkbox_select
|
%p.checkbox_select
|
||||||
= type.label :mentioned, t('.mentioned')
|
= type.label :mentioned, t('.mentioned')
|
||||||
= type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
|
= type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
|
||||||
|
|
|
||||||
|
|
@ -113,14 +113,25 @@
|
||||||
|
|
||||||
= f.fields_for :email_preferences do |type|
|
= f.fields_for :email_preferences do |type|
|
||||||
#email_prefs
|
#email_prefs
|
||||||
|
- if current_user.admin?
|
||||||
|
%p.checkbox_select
|
||||||
|
= type.label :someone_reported, t('.someone_reported')
|
||||||
|
= type.check_box :someone_reported, {:checked => @email_prefs['someone_reported']}, false, true
|
||||||
|
|
||||||
|
%br
|
||||||
%p.checkbox_select
|
%p.checkbox_select
|
||||||
= type.label :started_sharing, t('.started_sharing')
|
= type.label :started_sharing, t('.started_sharing')
|
||||||
= type.check_box :started_sharing, {:checked => @email_prefs['started_sharing']}, false, true
|
= type.check_box :started_sharing, {:checked => @email_prefs['started_sharing']}, false, true
|
||||||
%br
|
%br
|
||||||
|
|
||||||
%p.checkbox_select
|
%p.checkbox_select
|
||||||
= type.label :mentioned, t('.mentioned')
|
= type.label :also_commented, t('.also_commented')
|
||||||
= type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
|
= type.check_box :also_commented, {:checked => @email_prefs['also_commented']}, false, true
|
||||||
|
%br
|
||||||
|
|
||||||
|
%p.checkbox_select
|
||||||
|
= type.label :mentioned, t('.mentioned')
|
||||||
|
= type.check_box :mentioned, {:checked => @email_prefs['mentioned']}, false, true
|
||||||
%br
|
%br
|
||||||
|
|
||||||
%p.checkbox_select
|
%p.checkbox_select
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
module Workers
|
|
||||||
module Mail
|
|
||||||
class PostReportWorker < Base
|
|
||||||
sidekiq_options queue: :mail
|
|
||||||
|
|
||||||
def perform
|
|
||||||
PostReportMailer.new_report
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
12
app/workers/mail/report_worker.rb
Normal file
12
app/workers/mail/report_worker.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
module Workers
|
||||||
|
module Mail
|
||||||
|
class ReportWorker < Base
|
||||||
|
sidekiq_options queue: :mail
|
||||||
|
|
||||||
|
def perform(type, id)
|
||||||
|
ReportMailer.new_report(type, id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ en:
|
||||||
user_search: "User Search"
|
user_search: "User Search"
|
||||||
weekly_user_stats: "Weekly User Stats"
|
weekly_user_stats: "Weekly User Stats"
|
||||||
pod_stats: "Pod Stats"
|
pod_stats: "Pod Stats"
|
||||||
post_report: "Reported Posts"
|
report: "Reports"
|
||||||
correlations: "Correlations"
|
correlations: "Correlations"
|
||||||
sidekiq_monitor: "Sidekiq monitor"
|
sidekiq_monitor: "Sidekiq monitor"
|
||||||
correlations:
|
correlations:
|
||||||
|
|
@ -736,9 +736,26 @@ en:
|
||||||
confirm_email:
|
confirm_email:
|
||||||
subject: "Please activate your new email address %{unconfirmed_email}"
|
subject: "Please activate your new email address %{unconfirmed_email}"
|
||||||
click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:"
|
click_link: "To activate your new email address %{unconfirmed_email}, please follow this link:"
|
||||||
post_report_email:
|
report_email:
|
||||||
subject: "A new post was marked as offensive"
|
type:
|
||||||
body: "Please review as soon as possible!"
|
post: "post"
|
||||||
|
comment: "comment"
|
||||||
|
subject: "A new %{type} was marked as offensive"
|
||||||
|
body: |-
|
||||||
|
Hello,
|
||||||
|
|
||||||
|
the %{type} with ID %{id} was marked as offensive.
|
||||||
|
|
||||||
|
[%{url}][1]
|
||||||
|
|
||||||
|
Please review as soon as possible!
|
||||||
|
|
||||||
|
|
||||||
|
Cheers,
|
||||||
|
|
||||||
|
The diaspora* email robot!
|
||||||
|
|
||||||
|
[1]: %{url}
|
||||||
accept_invite: "Accept Your diaspora* invite!"
|
accept_invite: "Accept Your diaspora* invite!"
|
||||||
invited_you: "%{name} invited you to diaspora*"
|
invited_you: "%{name} invited you to diaspora*"
|
||||||
invite:
|
invite:
|
||||||
|
|
@ -868,13 +885,15 @@ en:
|
||||||
other: "%{count} photos by %{author}"
|
other: "%{count} photos by %{author}"
|
||||||
reshare_by: "Reshare by %{author}"
|
reshare_by: "Reshare by %{author}"
|
||||||
|
|
||||||
post_report:
|
report:
|
||||||
title: "Marked Reports Overview"
|
title: "Reports Overview"
|
||||||
post_label: "<b>Post</b>: %{title}"
|
post_label: "<b>Post</b>: %{title}"
|
||||||
|
comment_label: "<b>Comment</b>:<br>%{data}"
|
||||||
reported_label: "<b>Reported by</b> %{person}"
|
reported_label: "<b>Reported by</b> %{person}"
|
||||||
reason_label: "Reason: %{text}"
|
reason_label: "Reason: %{text}"
|
||||||
review_link: "Mark as reviewed"
|
review_link: "Mark as reviewed"
|
||||||
delete_link: "Delete post"
|
delete_link: "Delete item"
|
||||||
|
confirm_deletion: "Are you sure to delete the item?"
|
||||||
status:
|
status:
|
||||||
marked: "The report was marked as reviewed"
|
marked: "The report was marked as reviewed"
|
||||||
destroyed: "The post was destroyed"
|
destroyed: "The post was destroyed"
|
||||||
|
|
@ -1206,6 +1225,7 @@ en:
|
||||||
edit_account: "Edit account"
|
edit_account: "Edit account"
|
||||||
receive_email_notifications: "Receive email notifications when:"
|
receive_email_notifications: "Receive email notifications when:"
|
||||||
started_sharing: "someone starts sharing with you"
|
started_sharing: "someone starts sharing with you"
|
||||||
|
someone_reported: "someone sent a report"
|
||||||
mentioned: "you are mentioned in a post"
|
mentioned: "you are mentioned in a post"
|
||||||
liked: "someone likes your post"
|
liked: "someone likes your post"
|
||||||
reshared: "someone reshares your post"
|
reshared: "someone reshares your post"
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,15 @@
|
||||||
en:
|
en:
|
||||||
javascripts:
|
javascripts:
|
||||||
confirm_dialog: "Are you sure?"
|
confirm_dialog: "Are you sure?"
|
||||||
post_report_prompt: "Please enter a reason:"
|
|
||||||
post_report_prompt_default: "offensive content"
|
|
||||||
delete: "Delete"
|
delete: "Delete"
|
||||||
ignore: "Ignore"
|
ignore: "Ignore"
|
||||||
post_report: "Report"
|
report:
|
||||||
|
prompt: "Please enter a reason:"
|
||||||
|
prompt_default: "offensive content"
|
||||||
|
name: "Report"
|
||||||
|
status:
|
||||||
|
created: "The report was successfully created"
|
||||||
|
exists: "The report already exists"
|
||||||
ignore_user: "Ignore this user?"
|
ignore_user: "Ignore this user?"
|
||||||
and: "and"
|
and: "and"
|
||||||
comma: ","
|
comma: ","
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
require 'sidekiq/web'
|
require 'sidekiq/web'
|
||||||
|
|
||||||
Diaspora::Application.routes.draw do
|
Diaspora::Application.routes.draw do
|
||||||
resources :post_report, :except => [:edit]
|
resources :report, :except => [:edit, :new]
|
||||||
|
|
||||||
if Rails.env.production?
|
if Rails.env.production?
|
||||||
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
|
mount RailsAdmin::Engine => '/admin_panel', :as => 'rails_admin'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddPostTypeToPostReport < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :post_reports, :post_type, :string, :null => false, :after => :post_id, :default => 'post'
|
||||||
|
change_column_default :post_reports, :post_type, nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
class RenamePostReportToReport < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
rename_table :post_reports, :reports
|
||||||
|
end
|
||||||
|
def self.down
|
||||||
|
rename_table :reports, :post_reports
|
||||||
|
end
|
||||||
|
end
|
||||||
11
db/migrate/20140422134050_rename_post_columns_to_item.rb
Normal file
11
db/migrate/20140422134050_rename_post_columns_to_item.rb
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
class RenamePostColumnsToItem < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
rename_column :reports, :post_id, :item_id
|
||||||
|
rename_column :reports, :post_type, :item_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
rename_column :reports, :item_id, :post_id
|
||||||
|
rename_column :reports, :item_type, :post_type
|
||||||
|
end
|
||||||
|
end
|
||||||
12
db/migrate/20140422134627_change_user_id_type_to_integer.rb
Normal file
12
db/migrate/20140422134627_change_user_id_type_to_integer.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
class ChangeUserIdTypeToInteger < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
remove_column :reports, :user_id
|
||||||
|
add_column :reports, :user_id, :integer, :null => false, :default => 1
|
||||||
|
change_column_default :reports, :user_id, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :reports, :user_id
|
||||||
|
add_column :reports, :user_id, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
25
db/schema.rb
25
db/schema.rb
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20140308154022) do
|
ActiveRecord::Schema.define(:version => 20140422134627) do
|
||||||
|
|
||||||
create_table "account_deletions", :force => true do |t|
|
create_table "account_deletions", :force => true do |t|
|
||||||
t.string "diaspora_handle"
|
t.string "diaspora_handle"
|
||||||
|
|
@ -316,17 +316,6 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
|
||||||
|
|
||||||
add_index "polls", ["status_message_id"], :name => "index_polls_on_status_message_id"
|
add_index "polls", ["status_message_id"], :name => "index_polls_on_status_message_id"
|
||||||
|
|
||||||
create_table "post_reports", :force => true do |t|
|
|
||||||
t.integer "post_id", :null => false
|
|
||||||
t.string "user_id"
|
|
||||||
t.boolean "reviewed", :default => false
|
|
||||||
t.text "text"
|
|
||||||
t.datetime "created_at", :null => false
|
|
||||||
t.datetime "updated_at", :null => false
|
|
||||||
end
|
|
||||||
|
|
||||||
add_index "post_reports", ["post_id"], :name => "index_post_reports_on_post_id"
|
|
||||||
|
|
||||||
create_table "posts", :force => true do |t|
|
create_table "posts", :force => true do |t|
|
||||||
t.integer "author_id", :null => false
|
t.integer "author_id", :null => false
|
||||||
t.boolean "public", :default => false, :null => false
|
t.boolean "public", :default => false, :null => false
|
||||||
|
|
@ -410,6 +399,18 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
|
||||||
|
|
||||||
add_index "rails_admin_histories", ["item", "table", "month", "year"], :name => "index_rails_admin_histories"
|
add_index "rails_admin_histories", ["item", "table", "month", "year"], :name => "index_rails_admin_histories"
|
||||||
|
|
||||||
|
create_table "reports", :force => true do |t|
|
||||||
|
t.integer "item_id", :null => false
|
||||||
|
t.string "item_type", :null => false
|
||||||
|
t.boolean "reviewed", :default => false
|
||||||
|
t.text "text"
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
t.integer "user_id", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "reports", ["item_id"], :name => "index_post_reports_on_post_id"
|
||||||
|
|
||||||
create_table "roles", :force => true do |t|
|
create_table "roles", :force => true do |t|
|
||||||
t.integer "person_id"
|
t.integer "person_id"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class AccountDeleter
|
||||||
end
|
end
|
||||||
|
|
||||||
def ignored_ar_user_associations
|
def ignored_ar_user_associations
|
||||||
[:followed_tags, :invited_by, :contact_people, :aspect_memberships, :ignored_people, :conversation_visibilities, :conversations]
|
[:followed_tags, :invited_by, :contact_people, :aspect_memberships, :ignored_people, :conversation_visibilities, :conversations, :reports]
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_standard_user_associations
|
def delete_standard_user_associations
|
||||||
|
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe PostReportController do
|
|
||||||
before do
|
|
||||||
sign_in alice
|
|
||||||
@message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#index' do
|
|
||||||
context 'admin not signed in' do
|
|
||||||
it 'is behind redirect_unless_admin' do
|
|
||||||
get :index
|
|
||||||
response.should redirect_to stream_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'admin signed in' do
|
|
||||||
before do
|
|
||||||
Role.add_admin(alice.person)
|
|
||||||
end
|
|
||||||
it 'succeeds and renders index' do
|
|
||||||
get :index
|
|
||||||
response.should render_template('index')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#create' do
|
|
||||||
context 'report offensive content' do
|
|
||||||
it 'succeeds' do
|
|
||||||
put :create, :post_id => @message.id, :text => 'offensive content'
|
|
||||||
response.status.should == 200
|
|
||||||
PostReport.exists?(:post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#update' do
|
|
||||||
context 'mark report as user' do
|
|
||||||
it 'is behind redirect_unless_admin' do
|
|
||||||
put :update, :id => @message.id
|
|
||||||
response.should redirect_to stream_path
|
|
||||||
PostReport.where(:reviewed => false, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'mark report as admin' do
|
|
||||||
before do
|
|
||||||
Role.add_admin(alice.person)
|
|
||||||
end
|
|
||||||
it 'succeeds' do
|
|
||||||
put :update, :id => @message.id
|
|
||||||
response.status.should == 302
|
|
||||||
PostReport.where(:reviewed => true, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#destroy' do
|
|
||||||
context 'destroy post as user' do
|
|
||||||
it 'is behind redirect_unless_admin' do
|
|
||||||
delete :destroy, :id => @message.id
|
|
||||||
response.should redirect_to stream_path
|
|
||||||
PostReport.where(:reviewed => false, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'destroy post as admin' do
|
|
||||||
before do
|
|
||||||
Role.add_admin(alice.person)
|
|
||||||
end
|
|
||||||
it 'succeeds' do
|
|
||||||
delete :destroy, :id => @message.id
|
|
||||||
response.status.should == 302
|
|
||||||
PostReport.where(:reviewed => true, :post_id => @message.id).should be_true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
130
spec/controllers/report_controller_spec.rb
Normal file
130
spec/controllers/report_controller_spec.rb
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ReportController do
|
||||||
|
before do
|
||||||
|
sign_in alice
|
||||||
|
@message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id)
|
||||||
|
@comment = alice.comment!(@message, "flying pigs, everywhere")
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#index' do
|
||||||
|
context 'admin not signed in' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
get :index
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'admin signed in' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds and renders index' do
|
||||||
|
get :index
|
||||||
|
response.should render_template('index')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#create' do
|
||||||
|
let(:comment_hash) {
|
||||||
|
{:text =>"facebook, is that you?",
|
||||||
|
:item_id =>"#{@post.id}"}
|
||||||
|
}
|
||||||
|
|
||||||
|
context 'report offensive post' do
|
||||||
|
it 'succeeds' do
|
||||||
|
put :create, :report => { :item_id => @message.id, :item_type => 'post', :text => 'offensive content' }
|
||||||
|
response.status.should == 200
|
||||||
|
Report.exists?(:item_id => @message.id, :item_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'report offensive comment' do
|
||||||
|
it 'succeeds' do
|
||||||
|
put :create, :report => { :item_id => @comment.id, :item_type => 'comment', :text => 'offensive content' }
|
||||||
|
response.status.should == 200
|
||||||
|
Report.exists?(:item_id => @comment.id, :item_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#update' do
|
||||||
|
context 'mark post report as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
put :update, :id => @message.id, :type => 'post'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :item_id => @message.id, :item_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'mark comment report as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
put :update, :id => @comment.id, :type => 'comment'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :item_id => @comment.id, :item_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'mark post report as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
put :update, :id => @message.id, :type => 'post'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :item_id => @message.id, :item_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'mark comment report as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
put :update, :id => @comment.id, :type => 'comment'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :item_id => @comment.id, :item_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#destroy' do
|
||||||
|
context 'destroy post as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
delete :destroy, :id => @message.id, :type => 'post'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :item_id => @message.id, :item_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'destroy comment as user' do
|
||||||
|
it 'is behind redirect_unless_admin' do
|
||||||
|
delete :destroy, :id => @comment.id, :type => 'comment'
|
||||||
|
response.should redirect_to stream_path
|
||||||
|
Report.where(:reviewed => false, :item_id => @comment.id, :item_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'destroy post as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
delete :destroy, :id => @message.id, :type => 'post'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :item_id => @message.id, :item_type => 'post').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
context 'destroy comment as admin' do
|
||||||
|
before do
|
||||||
|
Role.add_admin(alice.person)
|
||||||
|
end
|
||||||
|
it 'succeeds' do
|
||||||
|
delete :destroy, :id => @comment.id, :type => 'comment'
|
||||||
|
response.status.should == 302
|
||||||
|
Report.where(:reviewed => true, :item_id => @comment.id, :item_type => 'comment').should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
26
spec/mailers/report_spec.rb
Normal file
26
spec/mailers/report_spec.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Report do
|
||||||
|
describe '#make_notification' do
|
||||||
|
before do
|
||||||
|
@user = bob
|
||||||
|
Role.add_admin(@user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should deliver successfully" do
|
||||||
|
expect {
|
||||||
|
ReportMailer.new_report('post', 666)
|
||||||
|
}.to_not raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be added to the delivery queue" do
|
||||||
|
expect {
|
||||||
|
ReportMailer.new_report('post', 666)
|
||||||
|
}.to change(ActionMailer::Base.deliveries, :size).by(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
79
spec/models/report_spec.rb
Normal file
79
spec/models/report_spec.rb
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Report do
|
||||||
|
before do
|
||||||
|
#:report => { :item_id => @message.id, :item_type => 'post', :text => 'offensive content' }
|
||||||
|
@user = bob
|
||||||
|
@bob_post = @user.post(:status_message, :text => "hello", :to => @user.aspects.first.id)
|
||||||
|
@bob_comment = @user.comment!(@bob_post, "welcome")
|
||||||
|
|
||||||
|
@valid_post_report = {
|
||||||
|
:item_id => @bob_post.id,
|
||||||
|
:item_type => 'post',
|
||||||
|
:text => 'offensive content'
|
||||||
|
}
|
||||||
|
@valid_comment_report = {
|
||||||
|
:item_id => @bob_comment.id,
|
||||||
|
:item_type => 'comment',
|
||||||
|
:text => 'offensive content'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#validation' do
|
||||||
|
it 'validates that post ID is required' do
|
||||||
|
@user.reports.build(:item_type => 'post', :text => 'blub').should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'validates that post type is required' do
|
||||||
|
@user.reports.build(:item_id => 666, :text => 'blub').should_not be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'validates that entry does not exist' do
|
||||||
|
@user.reports.build(@valid_post_report).should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'validates that entry does exist' do
|
||||||
|
@user.reports.create(@valid_post_report)
|
||||||
|
@user.reports.build(@valid_post_report).should_not be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#destroy_reported_item' do
|
||||||
|
before(:each) do
|
||||||
|
@post_report = @user.reports.create(@valid_post_report)
|
||||||
|
@comment_report = @user.reports.create(@valid_comment_report)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.post' do
|
||||||
|
it 'should destroy it' do
|
||||||
|
expect {
|
||||||
|
@post_report.destroy_reported_item
|
||||||
|
}.to change { Post.count }.by(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be marked' do
|
||||||
|
expect {
|
||||||
|
@post_report.destroy_reported_item
|
||||||
|
}.to change { Report.where(@valid_post_report).first.reviewed }.to(true).from(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.comment' do
|
||||||
|
it 'should destroy it' do
|
||||||
|
expect {
|
||||||
|
@comment_report.destroy_reported_item
|
||||||
|
}.to change { Comment.count }.by(-1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should be marked' do
|
||||||
|
expect {
|
||||||
|
@comment_report.destroy_reported_item
|
||||||
|
}.to change { Report.where(@valid_comment_report).first.reviewed }.to(true).from(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue