paging for flag list
corrected reload behavior on flag list refactored post actions ... extracted flag queries
This commit is contained in:
parent
22bcb7d412
commit
a9393e4a7a
14 changed files with 261 additions and 216 deletions
app
assets
javascripts/admin
controllers
models
routes
templates
views
stylesheets/application
controllers/admin
models
lib
spec
|
@ -78,6 +78,16 @@ Discourse.AdminFlagsController = Ember.ArrayController.extend({
|
||||||
|
|
||||||
@property adminActiveFlagsView
|
@property adminActiveFlagsView
|
||||||
**/
|
**/
|
||||||
adminActiveFlagsView: Em.computed.equal('query', 'active')
|
adminActiveFlagsView: Em.computed.equal('query', 'active'),
|
||||||
|
|
||||||
|
loadMore: function(){
|
||||||
|
var flags = this.get('model');
|
||||||
|
return Discourse.FlaggedPost.findAll(this.get('query'),flags.length+1).then(function(data){
|
||||||
|
if(data.length===0){
|
||||||
|
flags.set('allLoaded',true);
|
||||||
|
}
|
||||||
|
flags.addObjects(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -103,10 +103,13 @@ Discourse.FlaggedPost = Discourse.Post.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
Discourse.FlaggedPost.reopenClass({
|
Discourse.FlaggedPost.reopenClass({
|
||||||
findAll: function(filter) {
|
findAll: function(filter, offset) {
|
||||||
|
|
||||||
|
offset = offset || 0;
|
||||||
|
|
||||||
var result = Em.A();
|
var result = Em.A();
|
||||||
result.set('loading', true);
|
result.set('loading', true);
|
||||||
Discourse.ajax('/admin/flags/' + filter + '.json').then(function(data) {
|
return Discourse.ajax('/admin/flags/' + filter + '.json?offset=' + offset).then(function(data) {
|
||||||
var userLookup = {};
|
var userLookup = {};
|
||||||
_.each(data.users,function(user) {
|
_.each(data.users,function(user) {
|
||||||
userLookup[user.id] = Discourse.AdminUser.create(user);
|
userLookup[user.id] = Discourse.AdminUser.create(user);
|
||||||
|
@ -117,8 +120,8 @@ Discourse.FlaggedPost.reopenClass({
|
||||||
result.pushObject(f);
|
result.pushObject(f);
|
||||||
});
|
});
|
||||||
result.set('loading', false);
|
result.set('loading', false);
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
/**
|
|
||||||
Handles routes related to viewing active flags.
|
|
||||||
|
|
||||||
@class AdminFlagsActiveRoute
|
|
||||||
@extends Discourse.Route
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.AdminFlagsActiveRoute = Discourse.Route.extend({
|
|
||||||
|
|
||||||
model: function() {
|
|
||||||
return Discourse.FlaggedPost.findAll('active');
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
|
||||||
var adminFlagsController = this.controllerFor('adminFlags');
|
|
||||||
adminFlagsController.set('content', model);
|
|
||||||
adminFlagsController.set('query', 'active');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
/**
|
|
||||||
Handles routes related to viewing old flags.
|
|
||||||
|
|
||||||
@class AdminFlagsOldRoute
|
|
||||||
@extends Discourse.Route
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
Discourse.AdminFlagsOldRoute = Discourse.Route.extend({
|
|
||||||
|
|
||||||
model: function() {
|
|
||||||
return Discourse.FlaggedPost.findAll('old');
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController: function(controller, model) {
|
|
||||||
var adminFlagsController = this.controllerFor('adminFlags');
|
|
||||||
adminFlagsController.set('content', model);
|
|
||||||
adminFlagsController.set('query', 'old');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,30 @@
|
||||||
/**
|
Discourse.AdminFlagsIndexRoute = Discourse.Route.extend({
|
||||||
Handles routes related to viewing flags.
|
|
||||||
|
|
||||||
@class AdminFlagsRoute
|
|
||||||
@extends Discourse.Route
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
|
|
||||||
Discourse.AdminFlagsRoute = Discourse.Route.extend({
|
|
||||||
redirect: function() {
|
redirect: function() {
|
||||||
this.transitionTo('adminFlags.active');
|
this.transitionTo('adminFlags.active');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Discourse.AdminFlagsRouteType = Discourse.Route.extend({
|
||||||
|
model: function() {
|
||||||
|
return Discourse.FlaggedPost.findAll(this.get('filter'));
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController: function(controller, model) {
|
||||||
|
var adminFlagsController = this.controllerFor('adminFlags');
|
||||||
|
adminFlagsController.set('content', model);
|
||||||
|
adminFlagsController.set('query', this.get('filter'));
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Discourse.AdminFlagsActiveRoute = Discourse.AdminFlagsRouteType.extend({
|
||||||
|
filter: 'active'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Discourse.AdminFlagsOldRoute = Discourse.AdminFlagsRouteType.extend({
|
||||||
|
filter: 'old'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ Discourse.Route.buildRoutes(function() {
|
||||||
this.resource('adminReports', { path: '/reports/:type' });
|
this.resource('adminReports', { path: '/reports/:type' });
|
||||||
|
|
||||||
this.resource('adminFlags', { path: '/flags' }, function() {
|
this.resource('adminFlags', { path: '/flags' }, function() {
|
||||||
|
this.route('index', { path: '/' });
|
||||||
this.route('active', { path: '/active' });
|
this.route('active', { path: '/active' });
|
||||||
this.route('old', { path: '/old' });
|
this.route('old', { path: '/old' });
|
||||||
});
|
});
|
||||||
|
|
|
@ -85,6 +85,10 @@
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{{#if view.loading}}
|
||||||
|
<div class='admin-loading'>{{i18n loading}}</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>{{i18n admin.flags.no_results}}</p>
|
<p>{{i18n admin.flags.no_results}}</p>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
13
app/assets/javascripts/admin/views/admin_flags_view.js
Normal file
13
app/assets/javascripts/admin/views/admin_flags_view.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
Discourse.AdminFlagsView = Discourse.View.extend(Discourse.LoadMore, {
|
||||||
|
loading: false,
|
||||||
|
eyelineSelector: '.admin-flags tbody tr',
|
||||||
|
loadMore: function() {
|
||||||
|
var view = this;
|
||||||
|
if(this.get("loading") || this.get("model.allLoaded")) { return; }
|
||||||
|
this.set("loading", true);
|
||||||
|
this.get("controller").loadMore().then(function(){
|
||||||
|
view.set("loading", false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
|
@ -272,22 +272,23 @@
|
||||||
|
|
||||||
#topic-list-bottom {
|
#topic-list-bottom {
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
.topics-loading {
|
}
|
||||||
width: 200px;
|
|
||||||
margin: 0 auto;
|
.topics-loading {
|
||||||
padding: 10px 0 10px 43px;
|
width: 200px;
|
||||||
color: $white;
|
margin: 0 auto;
|
||||||
font-size: 18px;
|
padding: 10px 0 10px 43px;
|
||||||
line-height: 25px;
|
color: $white;
|
||||||
background: {
|
font-size: 18px;
|
||||||
color: $black;
|
line-height: 25px;
|
||||||
image: image-url("spinner_96_w.gif");
|
background: {
|
||||||
repeat: no-repeat;
|
color: $black;
|
||||||
position: 10px 50%;
|
image: image-url("spinner_96_w.gif");
|
||||||
size: 25px;
|
repeat: no-repeat;
|
||||||
};
|
position: 10px 50%;
|
||||||
@include border-radius-all(12px);
|
size: 25px;
|
||||||
}
|
};
|
||||||
|
@include border-radius-all(12px);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Misc. stuff
|
// Misc. stuff
|
||||||
|
@ -335,4 +336,4 @@
|
||||||
image: image-url("posted.png");
|
image: image-url("posted.png");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
require 'flag_query'
|
||||||
|
|
||||||
class Admin::FlagsController < Admin::AdminController
|
class Admin::FlagsController < Admin::AdminController
|
||||||
def index
|
def index
|
||||||
# we may get out of sync, fix it here
|
# we may get out of sync, fix it here
|
||||||
PostAction.update_flagged_posts_count
|
PostAction.update_flagged_posts_count
|
||||||
posts, users = PostAction.flagged_posts_report(params[:filter])
|
posts, users = FlagQuery.flagged_posts_report(params[:filter], params[:offset].to_i, 10)
|
||||||
|
|
||||||
if posts.blank?
|
if posts.blank?
|
||||||
render json: {users: [], posts: []}
|
render json: {users: [], posts: []}
|
||||||
|
|
|
@ -91,51 +91,52 @@ class PostAction < ActiveRecord::Base
|
||||||
update_flagged_posts_count
|
update_flagged_posts_count
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.act(user, post, post_action_type_id, opts={})
|
def self.create_message_for_post_action(user, post, post_action_type_id, opts)
|
||||||
begin
|
post_action_type = PostActionType.types[post_action_type_id]
|
||||||
title, target_usernames, target_group_names, subtype, body = nil
|
|
||||||
|
|
||||||
if opts[:message]
|
return unless opts[:message] && [:notify_moderators, :notify_user].include?(post_action_type)
|
||||||
[:notify_moderators, :notify_user].each do |k|
|
|
||||||
if post_action_type_id == PostActionType.types[k]
|
|
||||||
if k == :notify_moderators
|
|
||||||
target_group_names = target_moderators
|
|
||||||
else
|
|
||||||
target_usernames = post.user.username
|
|
||||||
end
|
|
||||||
title = I18n.t("post_action_types.#{k}.email_title",
|
|
||||||
title: post.topic.title)
|
|
||||||
body = I18n.t("post_action_types.#{k}.email_body",
|
|
||||||
message: opts[:message],
|
|
||||||
link: "#{Discourse.base_url}#{post.url}")
|
|
||||||
subtype = k == :notify_moderators ? TopicSubtype.notify_moderators : TopicSubtype.notify_user
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
related_post_id = nil
|
target_group_names, target_usernames = nil
|
||||||
if target_usernames.present? || target_group_names.present?
|
|
||||||
related_post_id = PostCreator.new(user,
|
|
||||||
target_usernames: target_usernames,
|
|
||||||
target_group_names: target_group_names,
|
|
||||||
archetype: Archetype.private_message,
|
|
||||||
subtype: subtype,
|
|
||||||
title: title,
|
|
||||||
raw: body
|
|
||||||
).create.id
|
|
||||||
end
|
|
||||||
|
|
||||||
create( post_id: post.id,
|
if post_action_type == :notify_moderators
|
||||||
user_id: user.id,
|
target_group_names = target_moderators
|
||||||
post_action_type_id: post_action_type_id,
|
else
|
||||||
message: opts[:message],
|
target_usernames = post.user.username
|
||||||
staff_took_action: opts[:take_action] || false,
|
|
||||||
related_post_id: related_post_id )
|
|
||||||
rescue ActiveRecord::RecordNotUnique
|
|
||||||
# can happen despite being .create
|
|
||||||
# since already bookmarked
|
|
||||||
true
|
|
||||||
end
|
end
|
||||||
|
title = I18n.t("post_action_types.#{post_action_type}.email_title",
|
||||||
|
title: post.topic.title)
|
||||||
|
body = I18n.t("post_action_types.#{post_action_type}.email_body",
|
||||||
|
message: opts[:message],
|
||||||
|
link: "#{Discourse.base_url}#{post.url}")
|
||||||
|
|
||||||
|
subtype = post_action_type == :notify_moderators ? TopicSubtype.notify_moderators : TopicSubtype.notify_user
|
||||||
|
|
||||||
|
if target_usernames.present? || target_group_names.present?
|
||||||
|
PostCreator.new(user,
|
||||||
|
target_usernames: target_usernames,
|
||||||
|
target_group_names: target_group_names,
|
||||||
|
archetype: Archetype.private_message,
|
||||||
|
subtype: subtype,
|
||||||
|
title: title,
|
||||||
|
raw: body
|
||||||
|
).create.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.act(user, post, post_action_type_id, opts={})
|
||||||
|
|
||||||
|
related_post_id = create_message_for_post_action(user,post,post_action_type_id,opts)
|
||||||
|
|
||||||
|
create( post_id: post.id,
|
||||||
|
user_id: user.id,
|
||||||
|
post_action_type_id: post_action_type_id,
|
||||||
|
message: opts[:message],
|
||||||
|
staff_took_action: opts[:take_action] || false,
|
||||||
|
related_post_id: related_post_id )
|
||||||
|
rescue ActiveRecord::RecordNotUnique
|
||||||
|
# can happen despite being .create
|
||||||
|
# since already bookmarked
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.remove_act(user, post, post_action_type_id)
|
def self.remove_act(user, post, post_action_type_id)
|
||||||
|
@ -298,90 +299,8 @@ class PostAction < ActiveRecord::Base
|
||||||
Post.hidden_reasons[:flag_threshold_reached]
|
Post.hidden_reasons[:flag_threshold_reached]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.flagged_posts_report(filter)
|
|
||||||
|
|
||||||
actions = flagged_post_actions(filter)
|
|
||||||
|
|
||||||
post_ids = actions.limit(300).pluck(:post_id).uniq
|
|
||||||
return nil if post_ids.blank?
|
|
||||||
|
|
||||||
posts = SqlBuilder.new("SELECT p.id, t.title, p.cooked, p.user_id,
|
|
||||||
p.topic_id, p.post_number, p.hidden, t.visible topic_visible,
|
|
||||||
p.deleted_at, t.deleted_at topic_deleted_at
|
|
||||||
FROM posts p
|
|
||||||
JOIN topics t ON t.id = p.topic_id
|
|
||||||
WHERE p.id in (:post_ids)").map_exec(OpenStruct, post_ids: post_ids)
|
|
||||||
|
|
||||||
post_lookup = {}
|
|
||||||
users = Set.new
|
|
||||||
|
|
||||||
posts.each do |p|
|
|
||||||
users << p.user_id
|
|
||||||
p.excerpt = Post.excerpt(p.cooked)
|
|
||||||
p.topic_slug = Slug.for(p.title)
|
|
||||||
post_lookup[p.id] = p
|
|
||||||
end
|
|
||||||
|
|
||||||
# maintain order
|
|
||||||
posts = post_ids.map{|id| post_lookup[id]}
|
|
||||||
|
|
||||||
post_actions = actions.where(:post_id => post_ids)
|
|
||||||
# TODO this is so far from optimal, it should not be
|
|
||||||
# selecting all the columns but the includes stops working
|
|
||||||
# with the code below
|
|
||||||
#
|
|
||||||
# .select('post_actions.id,
|
|
||||||
# post_actions.user_id,
|
|
||||||
# post_action_type_id,
|
|
||||||
# post_actions.created_at,
|
|
||||||
# post_actions.post_id,
|
|
||||||
# post_actions.message')
|
|
||||||
# .to_a
|
|
||||||
|
|
||||||
post_actions.each do |pa|
|
|
||||||
post = post_lookup[pa.post_id]
|
|
||||||
post.post_actions ||= []
|
|
||||||
action = pa.attributes
|
|
||||||
action[:name_key] = PostActionType.types.key(pa.post_action_type_id)
|
|
||||||
if (pa.related_post && pa.related_post.topic)
|
|
||||||
action.merge!(topic_id: pa.related_post.topic_id,
|
|
||||||
slug: pa.related_post.topic.slug,
|
|
||||||
permalink: pa.related_post.topic.url)
|
|
||||||
end
|
|
||||||
post.post_actions << action
|
|
||||||
users << pa.user_id
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO add serializer so we can skip this
|
|
||||||
posts.map!(&:marshal_dump)
|
|
||||||
[posts, User.where(id: users.to_a).to_a]
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def self.flagged_post_actions(filter)
|
|
||||||
post_actions = PostAction
|
|
||||||
.includes({:related_post => :topic})
|
|
||||||
.where(post_action_type_id: PostActionType.notify_flag_type_ids)
|
|
||||||
.joins(:post => :topic)
|
|
||||||
.order('post_actions.created_at DESC')
|
|
||||||
|
|
||||||
if filter == 'old'
|
|
||||||
post_actions
|
|
||||||
.with_deleted
|
|
||||||
.where('post_actions.deleted_at IS NOT NULL OR
|
|
||||||
defer = true OR
|
|
||||||
topics.deleted_at IS NOT NULL OR
|
|
||||||
posts.deleted_at IS NOT NULL')
|
|
||||||
else
|
|
||||||
post_actions
|
|
||||||
.where('defer IS NULL OR
|
|
||||||
defer = false')
|
|
||||||
.where('posts.deleted_at IS NULL AND
|
|
||||||
topics.deleted_at IS NULL')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.target_moderators
|
def self.target_moderators
|
||||||
Group[:moderators].name
|
Group[:moderators].name
|
||||||
end
|
end
|
||||||
|
|
97
lib/flag_query.rb
Normal file
97
lib/flag_query.rb
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
module FlagQuery
|
||||||
|
def self.flagged_posts_report(filter, offset = 0, per_page = 25)
|
||||||
|
|
||||||
|
actions = flagged_post_actions(filter)
|
||||||
|
|
||||||
|
post_ids = actions
|
||||||
|
.limit(per_page)
|
||||||
|
.offset(offset)
|
||||||
|
.group(:post_id)
|
||||||
|
.order('min(post_actions.created_at) DESC')
|
||||||
|
.pluck(:post_id).uniq
|
||||||
|
|
||||||
|
return nil if post_ids.blank?
|
||||||
|
|
||||||
|
actions = actions
|
||||||
|
.order('post_actions.created_at DESC')
|
||||||
|
.includes({:related_post => :topic})
|
||||||
|
|
||||||
|
posts = SqlBuilder.new("SELECT p.id, t.title, p.cooked, p.user_id,
|
||||||
|
p.topic_id, p.post_number, p.hidden, t.visible topic_visible,
|
||||||
|
p.deleted_at, t.deleted_at topic_deleted_at
|
||||||
|
FROM posts p
|
||||||
|
JOIN topics t ON t.id = p.topic_id
|
||||||
|
WHERE p.id in (:post_ids)").map_exec(OpenStruct, post_ids: post_ids)
|
||||||
|
|
||||||
|
post_lookup = {}
|
||||||
|
users = Set.new
|
||||||
|
|
||||||
|
posts.each do |p|
|
||||||
|
users << p.user_id
|
||||||
|
p.excerpt = Post.excerpt(p.cooked)
|
||||||
|
p.topic_slug = Slug.for(p.title)
|
||||||
|
post_lookup[p.id] = p
|
||||||
|
end
|
||||||
|
|
||||||
|
# maintain order
|
||||||
|
posts = post_ids.map{|id| post_lookup[id]}
|
||||||
|
|
||||||
|
post_actions = actions.where(:post_id => post_ids)
|
||||||
|
|
||||||
|
post_actions.each do |pa|
|
||||||
|
post = post_lookup[pa.post_id]
|
||||||
|
post.post_actions ||= []
|
||||||
|
action = pa.attributes
|
||||||
|
action[:name_key] = PostActionType.types.key(pa.post_action_type_id)
|
||||||
|
if (pa.related_post && pa.related_post.topic)
|
||||||
|
action.merge!(topic_id: pa.related_post.topic_id,
|
||||||
|
slug: pa.related_post.topic.slug,
|
||||||
|
permalink: pa.related_post.topic.url)
|
||||||
|
end
|
||||||
|
post.post_actions << action
|
||||||
|
users << pa.user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO add serializer so we can skip this
|
||||||
|
posts.map!(&:marshal_dump)
|
||||||
|
[posts, User.where(id: users.to_a).to_a]
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def self.flagged_post_ids(filter, offset, limit)
|
||||||
|
sql = <<SQL
|
||||||
|
|
||||||
|
SELECT p.id from posts p
|
||||||
|
JOIN topics t ON t.id = p.topic_id
|
||||||
|
WHERE p.id IN (
|
||||||
|
SELECT post_id from post_actions
|
||||||
|
WHERE
|
||||||
|
)
|
||||||
|
/*offset*/
|
||||||
|
/*limit*/
|
||||||
|
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.flagged_post_actions(filter)
|
||||||
|
post_actions = PostAction
|
||||||
|
.where(post_action_type_id: PostActionType.notify_flag_type_ids)
|
||||||
|
.joins(:post => :topic)
|
||||||
|
|
||||||
|
if filter == 'old'
|
||||||
|
post_actions
|
||||||
|
.with_deleted
|
||||||
|
.where('post_actions.deleted_at IS NOT NULL OR
|
||||||
|
defer = true OR
|
||||||
|
topics.deleted_at IS NOT NULL OR
|
||||||
|
posts.deleted_at IS NOT NULL')
|
||||||
|
else
|
||||||
|
post_actions
|
||||||
|
.where('defer IS NULL OR
|
||||||
|
defer = false')
|
||||||
|
.where('posts.deleted_at IS NULL AND
|
||||||
|
topics.deleted_at IS NULL')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
40
spec/components/flag_query_spec.rb
Normal file
40
spec/components/flag_query_spec.rb
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require_dependency 'flag_query'
|
||||||
|
|
||||||
|
describe FlagQuery do
|
||||||
|
|
||||||
|
let(:codinghorror) { Fabricate(:coding_horror) }
|
||||||
|
|
||||||
|
describe "flagged_posts_report" do
|
||||||
|
it "operates correctly" do
|
||||||
|
post = create_post
|
||||||
|
post2 = create_post
|
||||||
|
|
||||||
|
user2 = Fabricate(:user)
|
||||||
|
user3 = Fabricate(:user)
|
||||||
|
|
||||||
|
PostAction.act(codinghorror, post, PostActionType.types[:spam])
|
||||||
|
PostAction.act(user2, post, PostActionType.types[:spam])
|
||||||
|
mod_message = PostAction.act(user3, post, PostActionType.types[:notify_moderators], message: "this is a 10")
|
||||||
|
|
||||||
|
PostAction.act(codinghorror, post2, PostActionType.types[:spam])
|
||||||
|
PostAction.act(user2, post2, PostActionType.types[:spam])
|
||||||
|
|
||||||
|
posts, users = FlagQuery.flagged_posts_report("")
|
||||||
|
posts.count.should == 2
|
||||||
|
first = posts.first
|
||||||
|
|
||||||
|
users.count.should == 5
|
||||||
|
first[:post_actions].count.should == 2
|
||||||
|
|
||||||
|
second = posts[1]
|
||||||
|
|
||||||
|
second[:post_actions].count.should == 3
|
||||||
|
second[:post_actions].first[:permalink].should == mod_message.related_post.topic.url
|
||||||
|
|
||||||
|
posts, users = FlagQuery.flagged_posts_report("",offset=1)
|
||||||
|
posts.count.should == 1
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -12,21 +12,6 @@ describe PostAction do
|
||||||
let(:post) { Fabricate(:post) }
|
let(:post) { Fabricate(:post) }
|
||||||
let(:bookmark) { PostAction.new(user_id: post.user_id, post_action_type_id: PostActionType.types[:bookmark] , post_id: post.id) }
|
let(:bookmark) { PostAction.new(user_id: post.user_id, post_action_type_id: PostActionType.types[:bookmark] , post_id: post.id) }
|
||||||
|
|
||||||
describe "flagged_posts_report" do
|
|
||||||
it "operates correctly" do
|
|
||||||
post = create_post
|
|
||||||
PostAction.act(codinghorror, post, PostActionType.types[:spam])
|
|
||||||
mod_message = PostAction.act(Fabricate(:user), post, PostActionType.types[:notify_moderators], message: "this is a 10")
|
|
||||||
|
|
||||||
posts, users = PostAction.flagged_posts_report("")
|
|
||||||
posts.count.should == 1
|
|
||||||
first = posts.first
|
|
||||||
|
|
||||||
users.count.should == 3
|
|
||||||
first[:post_actions].count.should == 2
|
|
||||||
first[:post_actions].first[:permalink].should == mod_message.related_post.topic.url
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "messaging" do
|
describe "messaging" do
|
||||||
|
|
||||||
|
|
Reference in a new issue