mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 09:36:19 -05:00
New Feature: Staff can choose to "Take Action" when flagging to immediately reach hiding
thresholds.
This commit is contained in:
parent
476ffcc627
commit
545dbfc07e
19 changed files with 194 additions and 135 deletions
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
Supports logic for flags in the modal
|
||||
|
||||
@class FlagActionTypeController
|
||||
@extends Discourse.ObjectController
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.FlagActionTypeController = Discourse.ObjectController.extend({
|
||||
needs: ['flag'],
|
||||
|
||||
message: Em.computed.alias('controllers.flag.message'),
|
||||
|
||||
customPlaceholder: function(){
|
||||
return Em.String.i18n("flagging.custom_placeholder_" + this.get('name_key'));
|
||||
}.property('name_key'),
|
||||
|
||||
formattedName: function(){
|
||||
return this.get('name').replace("{{username}}", this.get('controllers.flag.username'));
|
||||
}.property('name'),
|
||||
|
||||
selected: function() {
|
||||
return this.get('model') === this.get('controllers.flag.selected');
|
||||
}.property('controllers.flag.selected'),
|
||||
|
||||
showMessageInput: Em.computed.and('is_custom_flag', 'selected'),
|
||||
showDescription: Em.computed.not('showMessageInput'),
|
||||
|
||||
customMessageLengthClasses: function() {
|
||||
return (this.get('message.length') < Discourse.PostActionType.MIN_MESSAGE_LENGTH) ? "too-short" : "ok"
|
||||
}.property('message.length'),
|
||||
|
||||
customMessageLength: function() {
|
||||
var len = this.get('message.length') || 0;
|
||||
var minLen = Discourse.PostActionType.MIN_MESSAGE_LENGTH;
|
||||
if (len === 0) {
|
||||
return Em.String.i18n("flagging.custom_message.at_least", { n: minLen });
|
||||
} else if (len < minLen) {
|
||||
return Em.String.i18n("flagging.custom_message.more", { n: minLen - len });
|
||||
} else {
|
||||
return Em.String.i18n("flagging.custom_message.left", {
|
||||
n: Discourse.PostActionType.MAX_MESSAGE_LENGTH - len
|
||||
});
|
||||
}
|
||||
}.property('message.length')
|
||||
|
||||
});
|
||||
|
|
@ -9,70 +9,58 @@
|
|||
**/
|
||||
Discourse.FlagController = Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
|
||||
|
||||
// trick to bind user / post to flag
|
||||
boundFlags: function() {
|
||||
var _this = this;
|
||||
var original = this.get('flagsAvailable');
|
||||
if(original){
|
||||
return $.map(original, function(v){
|
||||
var b = Discourse.BoundPostActionType.create(v);
|
||||
b.set('post', _this.get('model'));
|
||||
return b;
|
||||
});
|
||||
}
|
||||
}.property('flagsAvailable.@each'),
|
||||
|
||||
changePostActionType: function(action) {
|
||||
if (this.get('postActionTypeId') === action.id) return false;
|
||||
|
||||
this.get('boundFlags').setEach('selected', false);
|
||||
action.set('selected', true);
|
||||
|
||||
this.set('postActionTypeId', action.id);
|
||||
this.set('isCustomFlag', action.is_custom_flag);
|
||||
this.set('selected', action);
|
||||
return false;
|
||||
},
|
||||
|
||||
showSubmit: function() {
|
||||
if (this.get('postActionTypeId')) {
|
||||
if (this.get('isCustomFlag')) {
|
||||
var m = this.get('selected.message');
|
||||
return m && m.length >= 10 && m.length <= 500;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
submitEnabled: function() {
|
||||
var selected = this.get('selected');
|
||||
if (!selected) return false;
|
||||
|
||||
if (selected.get('is_custom_flag')) {
|
||||
var len = this.get('message.length') || 0;
|
||||
return len >= Discourse.PostActionType.MIN_MESSAGE_LENGTH &&
|
||||
len <= Discourse.PostActionType.MAX_MESSAGE_LENGTH;
|
||||
}
|
||||
return false;
|
||||
}.property('isCustomFlag', 'selected.customMessageLength', 'postActionTypeId'),
|
||||
return true;
|
||||
}.property('selected.is_custom_flag', 'message.length'),
|
||||
|
||||
submitDisabled: Em.computed.not('submitEnabled'),
|
||||
|
||||
// Staff accounts can "take action"
|
||||
canTakeAction: function() {
|
||||
// We can only take actions on non-custom flags
|
||||
if (this.get('selected.is_custom_flag')) return false;
|
||||
return Discourse.User.current('staff');
|
||||
}.property('selected.is_custom_flag'),
|
||||
|
||||
submitText: function(){
|
||||
var action = this.get('selected');
|
||||
if (this.get('selected.is_custom_flag')) {
|
||||
return Em.String.i18n("flagging.notify_action");
|
||||
} else {
|
||||
return Em.String.i18n("flagging.action");
|
||||
}
|
||||
}.property('selected'),
|
||||
}.property('selected.is_custom_flag'),
|
||||
|
||||
createFlag: function() {
|
||||
var _this = this;
|
||||
takeAction: function() {
|
||||
this.createFlag({takeAction: true})
|
||||
this.set('hidden', true);
|
||||
},
|
||||
|
||||
var action = this.get('selected');
|
||||
var postAction = this.get('actionByName.' + (action.get('name_key')));
|
||||
createFlag: function(opts) {
|
||||
var flagController = this;
|
||||
var postAction = this.get('actionByName.' + this.get('selected.name_key'));
|
||||
var params = this.get('selected.is_custom_flag') ? {message: this.get('message')} : {}
|
||||
|
||||
var actionType = Discourse.Site.instance().postActionTypeById(this.get('postActionTypeId'));
|
||||
if (postAction) {
|
||||
postAction.act({
|
||||
message: action.get('message')
|
||||
}).then(function() {
|
||||
return $('#discourse-modal').modal('hide');
|
||||
}, function(errors) {
|
||||
return _this.displayErrors(errors);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
if (opts) params = $.extend(params, opts);
|
||||
|
||||
postAction.act(params).then(function() {
|
||||
flagController.closeModal();
|
||||
}, function(errors) {
|
||||
flagController.displayErrors(errors);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
**/
|
||||
Discourse.ModalController = Discourse.Controller.extend({
|
||||
|
||||
/**
|
||||
Close the modal.
|
||||
|
||||
@method closeModal
|
||||
**/
|
||||
closeModal: function() {
|
||||
// Currently uses jQuery to hide it.
|
||||
$('#discourse-modal').modal('hide');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,16 @@ Discourse.ModalFunctionality = Em.Mixin.create({
|
|||
message: message,
|
||||
messageClass: messageClass
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
Close the modal.
|
||||
|
||||
@method closeModal
|
||||
**/
|
||||
closeModal: function() {
|
||||
// Currently uses jQuery to hide it.
|
||||
this.get('controllers.modal').closeModal();
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -37,6 +37,8 @@ Discourse.ActionSummary = Discourse.Model.extend({
|
|||
|
||||
// Perform this action
|
||||
act: function(opts) {
|
||||
if (!opts) opts = {};
|
||||
|
||||
var action = this.get('actionType.name_key');
|
||||
|
||||
// Mark it as acted
|
||||
|
@ -63,7 +65,8 @@ Discourse.ActionSummary = Discourse.Model.extend({
|
|||
data: {
|
||||
id: this.get('post.id'),
|
||||
post_action_type_id: this.get('id'),
|
||||
message: (opts ? opts.message : void 0) || ""
|
||||
message: opts.message,
|
||||
take_action: opts.takeAction
|
||||
}
|
||||
}).then(null, function (error) {
|
||||
actionSummary.removeAction();
|
||||
|
|
|
@ -6,31 +6,9 @@
|
|||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.PostActionType = Discourse.Model.extend({
|
||||
});
|
||||
Discourse.PostActionType = Discourse.Model.extend({});
|
||||
|
||||
Discourse.BoundPostActionType = Discourse.PostActionType.extend({
|
||||
customPlaceholder: function(){
|
||||
return Em.String.i18n("flagging.custom_placeholder_" + this.get('name_key'));
|
||||
}.property('name_key'),
|
||||
|
||||
formattedName: function(){
|
||||
return this.get('name').replace("{{username}}", this.get('post.username'));
|
||||
}.property('name'),
|
||||
|
||||
messageChanged: function() {
|
||||
var len, message, minLen, _ref;
|
||||
minLen = 10;
|
||||
len = ((_ref = this.get('message')) ? _ref.length : void 0) || 0;
|
||||
this.set("customMessageLengthClasses", "too-short custom-message-length");
|
||||
if (len === 0) {
|
||||
message = Em.String.i18n("flagging.custom_message.at_least", { n: minLen });
|
||||
} else if (len < minLen) {
|
||||
message = Em.String.i18n("flagging.custom_message.more", { n: minLen - len });
|
||||
} else {
|
||||
message = Em.String.i18n("flagging.custom_message.left", { n: 500 - len });
|
||||
this.set("customMessageLengthClasses", "ok custom-message-length");
|
||||
}
|
||||
this.set("customMessageLength", message);
|
||||
}.observes("message")
|
||||
});
|
||||
Discourse.PostActionType.reopenClass({
|
||||
MIN_MESSAGE_LENGTH: 10,
|
||||
MAX_MESSAGE_LENGTH: 500
|
||||
})
|
||||
|
|
|
@ -13,9 +13,7 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||
|
||||
showFlags: function(post) {
|
||||
Discourse.Route.showModal(this, 'flag', post);
|
||||
this.controllerFor('flag').setProperties({
|
||||
postActionTypeId: null
|
||||
});
|
||||
this.controllerFor('flag').setProperties({ selected: null });
|
||||
},
|
||||
|
||||
showAutoClose: function() {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="modal-body">
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
{{view Discourse.ArchetypeOptionsView archetypeBinding="view.archetype"}}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' data-dismiss="modal">{{i18n post.archetypes.save}}</button>
|
||||
</div>
|
||||
<button class='btn btn-primary' {{action closeModal}}>{{i18n post.archetypes.save}}</button>
|
||||
</div>
|
|
@ -1,36 +1,30 @@
|
|||
<div class="modal-body flag-modal">
|
||||
{{#if flagsAvailable}}
|
||||
<form>
|
||||
{{#each boundFlags}}
|
||||
<div class='controls'>
|
||||
<label class='radio'>
|
||||
<input type='radio' id="radio_{{unbound name_key}}" {{action changePostActionType this}} name='post_action_type_index'> <strong>{{formattedName}}</strong>
|
||||
{{#if is_custom_flag}}
|
||||
{{#unless selected}}
|
||||
<div class='description'>{{{description}}}</div>
|
||||
{{/unless}}
|
||||
{{else}}
|
||||
{{#if description}}
|
||||
<div class='description'>{{{description}}}</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</label>
|
||||
{{#if is_custom_flag}}
|
||||
{{#if selected}}
|
||||
{{textarea name="message" class="flag-message" placeholder=customPlaceholder value=message}}
|
||||
<div {{bindAttr class="customMessageLengthClasses"}}>{{customMessageLength}}</div>
|
||||
{{/if}}
|
||||
|
||||
<form>
|
||||
{{#each flagsAvailable itemController="flagActionType"}}
|
||||
<div class='controls'>
|
||||
<label class='radio'>
|
||||
<input type='radio' id="radio_{{unbound name_key}}" {{action changePostActionType this}} name='post_action_type_index'> <strong>{{formattedName}}</strong>
|
||||
{{#if showDescription}}
|
||||
<div class='description'>{{{description}}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</form>
|
||||
{{else}}
|
||||
{{i18n flagging.cant}}
|
||||
</label>
|
||||
{{#if showMessageInput}}
|
||||
{{textarea name="message" class="flag-message" placeholder=customPlaceholder value=message}}
|
||||
<div {{bindAttr class=":custom-message-length customMessageLengthClasses"}}>{{customMessageLength}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
{{i18n flagging.cant}}
|
||||
{{/each}}
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' {{action createFlag}} {{bindAttr disabled="submitDisabled"}}>{{submitText}}</button>
|
||||
|
||||
{{#if canTakeAction}}
|
||||
<button class='btn btn-danger' {{action takeAction}} {{bindAttr disabled="submitDisabled"}}>{{i18n flagging.take_action}}</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if showSubmit}}
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' {{action createFlag}}>{{submitText}}</button>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
{{#if finished}}
|
||||
<button class='btn btn-primary' data-dismiss="modal">{{i18n close}}</button>
|
||||
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
|
||||
{{else}}
|
||||
<button class='btn btn-primary' {{bindAttr disabled="disabled"}} {{action createInvite}}>{{buttonTitle}}</button>
|
||||
{{/if}}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
<div class="modal-footer">
|
||||
{{#if finished}}
|
||||
<button class='btn btn-primary' data-dismiss="modal">{{i18n close}}</button>
|
||||
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
|
||||
{{else}}
|
||||
<button class='btn btn-primary' {{bindAttr disabled="disabled"}} {{action invite}}>{{buttonTitle}}</button>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="modal-header">
|
||||
<a class="close" data-dismiss="modal"><i class='icon-remove icon'></i></a>
|
||||
<a class="close" {{action closeModal}}><i class='icon-remove icon'></i></a>
|
||||
<h3>{{title}}</h3>
|
||||
</div>
|
||||
<div id='modal-alert'></div>
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' data-dismiss="modal">{{i18n close}}</button>
|
||||
<button class='btn btn-primary' {{action closeModal}}>{{i18n close}}</button>
|
||||
</div>
|
|
@ -9,7 +9,11 @@ class PostActionsController < ApplicationController
|
|||
def create
|
||||
guardian.ensure_post_can_act!(@post, PostActionType.types[@post_action_type_id])
|
||||
|
||||
post_action = PostAction.act(current_user, @post, @post_action_type_id, params[:message])
|
||||
args = {}
|
||||
args[:message] = params[:message] if params[:message].present?
|
||||
args[:take_action] = true if guardian.is_staff? and params[:take_action] == 'true'
|
||||
|
||||
post_action = PostAction.act(current_user, @post, @post_action_type_id, args)
|
||||
|
||||
if post_action.blank? || post_action.errors.present?
|
||||
render_json_error(post_action)
|
||||
|
|
|
@ -8,7 +8,7 @@ class PostAction < ActiveRecord::Base
|
|||
include RateLimiter::OnCreateRecord
|
||||
include Trashable
|
||||
|
||||
attr_accessible :post_action_type_id, :post_id, :user_id, :post, :user, :post_action_type, :message, :related_post_id
|
||||
attr_accessible :post_action_type_id, :post_id, :user_id, :post, :user, :post_action_type, :message, :related_post_id, :staff_took_action
|
||||
|
||||
belongs_to :post
|
||||
belongs_to :user
|
||||
|
@ -70,11 +70,11 @@ class PostAction < ActiveRecord::Base
|
|||
update_flagged_posts_count
|
||||
end
|
||||
|
||||
def self.act(user, post, post_action_type_id, message = nil)
|
||||
def self.act(user, post, post_action_type_id, opts={})
|
||||
begin
|
||||
title, target_usernames, target_group_names, subtype, body = nil
|
||||
|
||||
if message
|
||||
if opts[:message]
|
||||
[:notify_moderators, :notify_user].each do |k|
|
||||
if post_action_type_id == PostActionType.types[k]
|
||||
if k == :notify_moderators
|
||||
|
@ -85,7 +85,7 @@ class PostAction < ActiveRecord::Base
|
|||
title = I18n.t("post_action_types.#{k}.email_title",
|
||||
title: post.topic.title)
|
||||
body = I18n.t("post_action_types.#{k}.email_body",
|
||||
message: message,
|
||||
message: opts[:message],
|
||||
link: "#{Discourse.base_url}#{post.url}")
|
||||
subtype = k == :notify_moderators ? TopicSubtype.notify_moderators : TopicSubtype.notify_user
|
||||
end
|
||||
|
@ -103,10 +103,12 @@ class PostAction < ActiveRecord::Base
|
|||
raw: body
|
||||
).create.id
|
||||
end
|
||||
|
||||
create( post_id: post.id,
|
||||
user_id: user.id,
|
||||
post_action_type_id: post_action_type_id,
|
||||
message: message,
|
||||
message: opts[:message],
|
||||
staff_took_action: opts[:take_action] || false,
|
||||
related_post_id: related_post_id )
|
||||
rescue ActiveRecord::RecordNotUnique
|
||||
# can happen despite being .create
|
||||
|
@ -177,13 +179,13 @@ class PostAction < ActiveRecord::Base
|
|||
# can weigh flags differently.
|
||||
def self.flag_counts_for(post_id)
|
||||
flag_counts = exec_sql("SELECT SUM(CASE
|
||||
WHEN pa.deleted_at IS NULL AND u.admin THEN :flags_required_to_hide_post
|
||||
WHEN pa.deleted_at IS NULL AND (NOT u.admin) THEN 1
|
||||
WHEN pa.deleted_at IS NULL AND pa.staff_took_action THEN :flags_required_to_hide_post
|
||||
WHEN pa.deleted_at IS NULL AND (NOT pa.staff_took_action) THEN 1
|
||||
ELSE 0
|
||||
END) AS new_flags,
|
||||
SUM(CASE
|
||||
WHEN pa.deleted_at IS NOT NULL AND u.admin THEN :flags_required_to_hide_post
|
||||
WHEN pa.deleted_at IS NOT NULL AND (NOT u.admin) THEN 1
|
||||
WHEN pa.deleted_at IS NOT NULL AND pa.staff_took_action THEN :flags_required_to_hide_post
|
||||
WHEN pa.deleted_at IS NOT NULL AND (NOT pa.staff_took_action) THEN 1
|
||||
ELSE 0
|
||||
END) AS old_flags
|
||||
FROM post_actions AS pa
|
||||
|
@ -234,7 +236,8 @@ class PostAction < ActiveRecord::Base
|
|||
reason = old_flags > 0 ? Post.hidden_reasons[:flag_threshold_reached_again] : Post.hidden_reasons[:flag_threshold_reached]
|
||||
Post.update_all(["hidden = true, hidden_reason_id = COALESCE(hidden_reason_id, ?)", reason], id: post_id)
|
||||
Topic.update_all({ visible: false },
|
||||
["id = :topic_id AND NOT EXISTS(SELECT 1 FROM POSTS WHERE topic_id = :topic_id AND NOT hidden)", topic_id: post.topic_id])
|
||||
["id = :topic_id AND NOT EXISTS(SELECT 1 FROM POSTS WHERE topic_id = :topic_id AND NOT hidden)",
|
||||
topic_id: post.topic_id])
|
||||
|
||||
# inform user
|
||||
if post.user
|
||||
|
|
|
@ -831,6 +831,7 @@ en:
|
|||
flagging:
|
||||
title: 'Why are you flagging this post?'
|
||||
action: 'Flag Post'
|
||||
take_action: "Take Action"
|
||||
notify_action: 'Notify'
|
||||
cant: "Sorry, you can't flag this post at this time."
|
||||
custom_placeholder_notify_user: "Why does this post require you to speak to this user directly and privately? Be specific, be constructive, and always be kind."
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddStaffTookActionToPostActions < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :post_actions, :staff_took_action, :boolean, default: false, null: false
|
||||
end
|
||||
end
|
|
@ -9,7 +9,7 @@ describe PostActionsController do
|
|||
|
||||
describe 'logged in' do
|
||||
before do
|
||||
@user = log_in
|
||||
@user = log_in(:moderator)
|
||||
@post = Fabricate(:post, user: Fabricate(:coding_horror))
|
||||
end
|
||||
|
||||
|
@ -34,9 +34,26 @@ describe PostActionsController do
|
|||
end
|
||||
|
||||
it 'allows us to create an post action on a post' do
|
||||
PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], nil)
|
||||
PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], {})
|
||||
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like]
|
||||
end
|
||||
|
||||
it 'passes the message through' do
|
||||
PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], {message: 'action message goes here'})
|
||||
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], message: 'action message goes here'
|
||||
end
|
||||
|
||||
it 'passes take_action through' do
|
||||
PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], {take_action: true})
|
||||
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], take_action: 'true'
|
||||
end
|
||||
|
||||
it "doesn't pass take_action through if the user isn't staff" do
|
||||
Guardian.any_instance.stubs(:is_staff?).returns(false)
|
||||
PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], {})
|
||||
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like], take_action: 'true'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ describe PostAction do
|
|||
|
||||
it "notify moderators integration test" do
|
||||
mod = moderator
|
||||
action = PostAction.act(codinghorror, post, PostActionType.types[:notify_moderators], "this is my special long message");
|
||||
action = PostAction.act(codinghorror, post, PostActionType.types[:notify_moderators], message: "this is my special long message");
|
||||
|
||||
posts = Post.joins(:topic)
|
||||
.select('posts.id, topics.subtype, posts.topic_id')
|
||||
|
@ -50,7 +50,7 @@ describe PostAction do
|
|||
it "sends an email to all moderators if selected" do
|
||||
post = build(:post, id: 1000)
|
||||
PostCreator.any_instance.expects(:create).returns(post)
|
||||
PostAction.act(build(:user), build(:post), PostActionType.types[:notify_moderators], "this is my special message");
|
||||
PostAction.act(build(:user), build(:post), PostActionType.types[:notify_moderators], message: "this is my special message");
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -63,7 +63,7 @@ describe PostAction do
|
|||
|
||||
it "sends an email to user if selected" do
|
||||
PostCreator.any_instance.expects(:create).returns(build(:post))
|
||||
PostAction.act(build(:user), post, PostActionType.types[:notify_user], "this is my special message");
|
||||
PostAction.act(build(:user), post, PostActionType.types[:notify_user], message: "this is my special message");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -179,9 +179,9 @@ describe PostAction do
|
|||
flag = PostAction.act(Fabricate(:evil_trout), post, PostActionType.types[:spam])
|
||||
PostAction.flag_counts_for(post.id).should == [0, 1]
|
||||
|
||||
# If an admin flags the post, it is counted higher
|
||||
# If staff takes action, it is ranked higher
|
||||
admin = Fabricate(:admin)
|
||||
PostAction.act(admin, post, PostActionType.types[:spam])
|
||||
pa = PostAction.act(admin, post, PostActionType.types[:spam], take_action: true)
|
||||
PostAction.flag_counts_for(post.id).should == [0, 8]
|
||||
|
||||
# If a flag is dismissed
|
||||
|
|
Loading…
Reference in a new issue