mirror of
https://github.com/discourse/discourse.git
synced 2025-03-22 15:15:30 +08:00
FEATURE: show the user's flagged/deleted posts
This commit is contained in:
parent
71c67c43a1
commit
7dcf2a2c4f
48
app/assets/javascripts/discourse/models/admin_post.js
Normal file
48
app/assets/javascripts/discourse/models/admin_post.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
A data model for flagged/deleted posts.
|
||||||
|
|
||||||
|
@class AdminPost
|
||||||
|
@extends Discourse.Post
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.AdminPost = Discourse.Post.extend({
|
||||||
|
|
||||||
|
_attachCategory: function () {
|
||||||
|
var categoryId = this.get("category_id");
|
||||||
|
if (categoryId) {
|
||||||
|
this.set("category", Discourse.Category.findById(categoryId));
|
||||||
|
}
|
||||||
|
}.on("init"),
|
||||||
|
|
||||||
|
presentName: Em.computed.any('name', 'username'),
|
||||||
|
|
||||||
|
sameUser: function() {
|
||||||
|
return this.get("username") === Discourse.User.currentProp("username");
|
||||||
|
}.property("username"),
|
||||||
|
|
||||||
|
descriptionKey: function () {
|
||||||
|
if (this.get("reply_to_post_number")) {
|
||||||
|
return this.get("sameUser") ? "you_replied_to_post" : "user_replied_to_post";
|
||||||
|
} else {
|
||||||
|
return this.get("sameUser") ? "you_replied_to_topic" : "user_replied_to_topic";
|
||||||
|
}
|
||||||
|
}.property("reply_to_post_number", "sameUser"),
|
||||||
|
|
||||||
|
descriptionHtml: function () {
|
||||||
|
var descriptionKey = this.get("descriptionKey");
|
||||||
|
if (!descriptionKey) { return; }
|
||||||
|
|
||||||
|
var description = I18n.t("user_action." + descriptionKey, {
|
||||||
|
userUrl: this.get("usernameUrl"),
|
||||||
|
user: Handlebars.Utils.escapeExpression(this.get("presentName")),
|
||||||
|
postUrl: this.get("url"),
|
||||||
|
post_number: "#" + this.get("reply_to_post_number"),
|
||||||
|
topicUrl: this.get("url"),
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Handlebars.SafeString(description);
|
||||||
|
|
||||||
|
}.property("descriptionKey")
|
||||||
|
|
||||||
|
});
|
@ -22,6 +22,16 @@ Discourse.User = Discourse.Model.extend({
|
|||||||
return Discourse.UserStream.create({ user: this });
|
return Discourse.UserStream.create({ user: this });
|
||||||
}.property(),
|
}.property(),
|
||||||
|
|
||||||
|
/**
|
||||||
|
The user's posts stream
|
||||||
|
|
||||||
|
@property postsStream
|
||||||
|
@type {Discourse.UserPostsStream}
|
||||||
|
**/
|
||||||
|
postsStream: function() {
|
||||||
|
return Discourse.UserPostsStream.create({ user: this });
|
||||||
|
}.property(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Is this user a member of staff?
|
Is this user a member of staff?
|
||||||
|
|
||||||
|
53
app/assets/javascripts/discourse/models/user_posts_stream.js
Normal file
53
app/assets/javascripts/discourse/models/user_posts_stream.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
Represents a user's stream
|
||||||
|
|
||||||
|
@class UserPostsStream
|
||||||
|
@extends Discourse.Model
|
||||||
|
@namespace Discourse
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.UserPostsStream = Discourse.Model.extend({
|
||||||
|
loaded: false,
|
||||||
|
|
||||||
|
_initialize: function () {
|
||||||
|
this.setProperties({
|
||||||
|
itemsLoaded: 0,
|
||||||
|
content: []
|
||||||
|
});
|
||||||
|
}.on("init"),
|
||||||
|
|
||||||
|
url: Discourse.computed.url("user.username_lower", "filter", "itemsLoaded", "/posts/%@/%@?offset=%@"),
|
||||||
|
|
||||||
|
filterBy: function (filter) {
|
||||||
|
if (this.get("loaded") && this.get("filter") === filter) { return Ember.RSVP.resolve(); }
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
filter: filter,
|
||||||
|
itemsLoaded: 0,
|
||||||
|
content: []
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.findItems();
|
||||||
|
},
|
||||||
|
|
||||||
|
findItems: function () {
|
||||||
|
var self = this;
|
||||||
|
if (this.get("loading")) { return Ember.RSVP.reject(); }
|
||||||
|
|
||||||
|
this.set("loading", true);
|
||||||
|
|
||||||
|
return Discourse.ajax(this.get("url"), { cache: false }).then(function (result) {
|
||||||
|
if (result) {
|
||||||
|
var posts = result.map(function (post) { return Discourse.AdminPost.create(post); });
|
||||||
|
self.get("content").pushObjects(posts);
|
||||||
|
self.setProperties({
|
||||||
|
loaded: true,
|
||||||
|
itemsLoaded: self.get("itemsLoaded") + posts.length
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).finally(function () {
|
||||||
|
self.set("loading", false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
@ -9,9 +9,12 @@
|
|||||||
Discourse.UserStream = Discourse.Model.extend({
|
Discourse.UserStream = Discourse.Model.extend({
|
||||||
loaded: false,
|
loaded: false,
|
||||||
|
|
||||||
init: function() {
|
_initialize: function() {
|
||||||
this.setProperties({ itemsLoaded: 0, content: [] });
|
this.setProperties({
|
||||||
},
|
itemsLoaded: 0,
|
||||||
|
content: []
|
||||||
|
});
|
||||||
|
}.on("init"),
|
||||||
|
|
||||||
filterParam: function() {
|
filterParam: function() {
|
||||||
var filter = this.get('filter');
|
var filter = this.get('filter');
|
||||||
@ -33,6 +36,7 @@ Discourse.UserStream = Discourse.Model.extend({
|
|||||||
itemsLoaded: 0,
|
itemsLoaded: 0,
|
||||||
content: []
|
content: []
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.findItems();
|
return this.findItems();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -73,6 +73,8 @@ Discourse.Route.buildRoutes(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.route('badges');
|
this.route('badges');
|
||||||
|
this.route('flaggedPosts', { path: '/flagged-posts' });
|
||||||
|
this.route('deletedPosts', { path: '/deleted-posts' });
|
||||||
|
|
||||||
this.resource('userPrivateMessages', { path: '/private-messages' }, function() {
|
this.resource('userPrivateMessages', { path: '/private-messages' }, function() {
|
||||||
this.route('mine');
|
this.route('mine');
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
function createAdminPostRoute (filter) {
|
||||||
|
return Discourse.Route.extend({
|
||||||
|
model: function () {
|
||||||
|
return this.modelFor("user").get("postsStream");
|
||||||
|
},
|
||||||
|
|
||||||
|
afterModel: function () {
|
||||||
|
return this.modelFor("user").get("postsStream").filterBy(filter);
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController: function (controller, model) {
|
||||||
|
controller.set("model", model);
|
||||||
|
this.controllerFor("user").set("indexStream", true);
|
||||||
|
},
|
||||||
|
|
||||||
|
renderTemplate: function() {
|
||||||
|
this.render("user/posts", { into: "user", outlet: "userOutlet" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Discourse.UserDeletedPostsRoute = createAdminPostRoute("deleted");
|
||||||
|
Discourse.UserFlaggedPostsRoute = createAdminPostRoute("flagged");
|
@ -0,0 +1,32 @@
|
|||||||
|
{{#each model.content}}
|
||||||
|
<div {{bind-attr class=":item hidden deleted moderator_action"}}>
|
||||||
|
<div class="clearfix info">
|
||||||
|
<a href="{{unbound usernameUrl}}" class="avatar-link">
|
||||||
|
<div class="avatar-wrapper">
|
||||||
|
{{avatar this imageSize="large" extraClasses="actor" ignoreTitle="true"}}
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<span class="time">
|
||||||
|
{{date path="created_at" leaveAgo="true"}}
|
||||||
|
</span>
|
||||||
|
<span class="title">
|
||||||
|
<a href="{{unbound url}}">{{unbound topic_title}}</a>
|
||||||
|
{{category-link category}}
|
||||||
|
</span>
|
||||||
|
<span class="type">
|
||||||
|
{{descriptionHtml}}
|
||||||
|
</span>
|
||||||
|
{{#if deleted}}
|
||||||
|
<span class="time">
|
||||||
|
{{i18n post.deleted_by}} {{avatar deleted_by imageSize="tiny" extraClasses="actor" ignoreTitle="true"}} {{date path="deleted_at" leaveAgo="true"}}
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
<p class="excerpt">
|
||||||
|
{{{excerpt}}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{#if loading}}
|
||||||
|
<div class='spinner'>{{i18n loading}}</div>
|
||||||
|
{{/if}}
|
@ -27,3 +27,6 @@
|
|||||||
{{/groupedEach}}
|
{{/groupedEach}}
|
||||||
</div>
|
</div>
|
||||||
{{/groupedEach}}
|
{{/groupedEach}}
|
||||||
|
{{#if loading}}
|
||||||
|
<div class='spinner'>{{i18n loading}}</div>
|
||||||
|
{{/if}}
|
||||||
|
@ -69,10 +69,17 @@
|
|||||||
<div><span class="pill helpful-flags">{{number_of_flags_given}}</span> {{i18n user.staff_counters.flags_given}}</div>
|
<div><span class="pill helpful-flags">{{number_of_flags_given}}</span> {{i18n user.staff_counters.flags_given}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if number_of_flagged_posts}}
|
{{#if number_of_flagged_posts}}
|
||||||
<div><span class="pill flagged-posts">{{number_of_flagged_posts}}</span> {{i18n user.staff_counters.flagged_posts}}</div>
|
<div>
|
||||||
|
{{#link-to 'user.flaggedPosts' this}}
|
||||||
|
<span class="pill flagged-posts">{{number_of_flagged_posts}}</span> {{i18n user.staff_counters.flagged_posts}}</div>
|
||||||
|
{{/link-to}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if number_of_deleted_posts}}
|
{{#if number_of_deleted_posts}}
|
||||||
<div><span class="pill deleted-posts">{{number_of_deleted_posts}}</span> {{i18n user.staff_counters.deleted_posts}}</div>
|
<div>
|
||||||
|
{{#link-to 'user.deletedPosts' this}}
|
||||||
|
<span class="pill deleted-posts">{{number_of_deleted_posts}}</span> {{i18n user.staff_counters.deleted_posts}}
|
||||||
|
{{/link-to}}
|
||||||
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if number_of_suspensions}}
|
{{#if number_of_suspensions}}
|
||||||
<div><span class="pill suspensions">{{number_of_suspensions}}</span> {{i18n user.staff_counters.suspensions}}</div>
|
<div><span class="pill suspensions">{{number_of_suspensions}}</span> {{i18n user.staff_counters.suspensions}}</div>
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
This view handles rendering of a user's posts
|
||||||
|
|
||||||
|
@class UserPostsView
|
||||||
|
@extends Discourse.View
|
||||||
|
@namespace Discourse
|
||||||
|
@uses Discourse.LoadMore
|
||||||
|
@module Discourse
|
||||||
|
**/
|
||||||
|
Discourse.UserPostsView = Discourse.View.extend(Discourse.LoadMore, {
|
||||||
|
loading: false,
|
||||||
|
eyelineSelector: ".user-stream .item",
|
||||||
|
classNames: ["user-stream"],
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
loadMore: function() {
|
||||||
|
var self = this;
|
||||||
|
if (this.get("loading")) { return; }
|
||||||
|
|
||||||
|
var postsStream = this.get("controller.model");
|
||||||
|
postsStream.findItems().then(function () {
|
||||||
|
self.set("loading", false);
|
||||||
|
self.get("eyeline").flushRest();
|
||||||
|
}).catch(function () { });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -364,6 +364,9 @@
|
|||||||
> div {
|
> div {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
a.active {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pill {
|
.pill {
|
||||||
|
@ -244,6 +244,37 @@ class PostsController < ApplicationController
|
|||||||
render nothing: true
|
render nothing: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def flagged_posts
|
||||||
|
params.permit(:offset, :limit)
|
||||||
|
guardian.ensure_can_see_flagged_posts!
|
||||||
|
|
||||||
|
user = fetch_user_from_params
|
||||||
|
offset = [params[:offset].to_i, 0].max
|
||||||
|
limit = [(params[:limit] || 60).to_i, 100].min
|
||||||
|
|
||||||
|
posts = user_posts(user.id, offset, limit)
|
||||||
|
.where(id: PostAction.with_deleted
|
||||||
|
.where(post_action_type_id: PostActionType.notify_flag_type_ids)
|
||||||
|
.select(:post_id))
|
||||||
|
|
||||||
|
render_serialized(posts, AdminPostSerializer)
|
||||||
|
end
|
||||||
|
|
||||||
|
def deleted_posts
|
||||||
|
params.permit(:offset, :limit)
|
||||||
|
guardian.ensure_can_see_deleted_posts!
|
||||||
|
|
||||||
|
user = fetch_user_from_params
|
||||||
|
offset = [params[:offset].to_i, 0].max
|
||||||
|
limit = [(params[:limit] || 60).to_i, 100].min
|
||||||
|
|
||||||
|
posts = user_posts(user.id, offset, limit)
|
||||||
|
.where(user_deleted: false)
|
||||||
|
.where.not(deleted_by_id: user.id)
|
||||||
|
|
||||||
|
render_serialized(posts, AdminPostSerializer)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def find_post_revision_from_params
|
def find_post_revision_from_params
|
||||||
@ -272,6 +303,15 @@ class PostsController < ApplicationController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def user_posts(user_id, offset=0, limit=60)
|
||||||
|
Post.includes(:user, :topic, :deleted_by, :user_actions)
|
||||||
|
.with_deleted
|
||||||
|
.where(user_id: user_id)
|
||||||
|
.order(created_at: :desc)
|
||||||
|
.offset(offset)
|
||||||
|
.limit(limit)
|
||||||
|
end
|
||||||
|
|
||||||
def params_key(params)
|
def params_key(params)
|
||||||
"post##" << Digest::SHA1.hexdigest(params
|
"post##" << Digest::SHA1.hexdigest(params
|
||||||
.to_a
|
.to_a
|
||||||
|
@ -23,6 +23,7 @@ class Post < ActiveRecord::Base
|
|||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :topic, counter_cache: :posts_count
|
belongs_to :topic, counter_cache: :posts_count
|
||||||
|
|
||||||
belongs_to :reply_to_user, class_name: "User"
|
belongs_to :reply_to_user, class_name: "User"
|
||||||
|
|
||||||
has_many :post_replies
|
has_many :post_replies
|
||||||
@ -40,6 +41,8 @@ class Post < ActiveRecord::Base
|
|||||||
has_many :post_revisions
|
has_many :post_revisions
|
||||||
has_many :revisions, foreign_key: :post_id, class_name: 'PostRevision'
|
has_many :revisions, foreign_key: :post_id, class_name: 'PostRevision'
|
||||||
|
|
||||||
|
has_many :user_actions, foreign_key: :target_post_id
|
||||||
|
|
||||||
validates_with ::Validators::PostValidator
|
validates_with ::Validators::PostValidator
|
||||||
|
|
||||||
# We can pass several creating options to a post via attributes
|
# We can pass several creating options to a post via attributes
|
||||||
|
76
app/serializers/admin_post_serializer.rb
Normal file
76
app/serializers/admin_post_serializer.rb
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
class AdminPostSerializer < ApplicationSerializer
|
||||||
|
|
||||||
|
attributes :id,
|
||||||
|
:created_at,
|
||||||
|
:post_number,
|
||||||
|
:name, :username, :avatar_template, :uploaded_avatar_id,
|
||||||
|
:topic_id, :topic_slug, :topic_title,
|
||||||
|
:category_id,
|
||||||
|
:excerpt,
|
||||||
|
:hidden,
|
||||||
|
:moderator_action,
|
||||||
|
:deleted_at, :deleted_by,
|
||||||
|
:reply_to_post_number,
|
||||||
|
:action_type
|
||||||
|
|
||||||
|
def name
|
||||||
|
object.user.name
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_name?
|
||||||
|
SiteSetting.enable_names?
|
||||||
|
end
|
||||||
|
|
||||||
|
def username
|
||||||
|
object.user.username
|
||||||
|
end
|
||||||
|
|
||||||
|
def avatar_template
|
||||||
|
object.user.avatar_template
|
||||||
|
end
|
||||||
|
|
||||||
|
def uploaded_avatar_id
|
||||||
|
object.user.uploaded_avatar_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def topic_slug
|
||||||
|
topic.slug
|
||||||
|
end
|
||||||
|
|
||||||
|
def topic_title
|
||||||
|
topic.title
|
||||||
|
end
|
||||||
|
|
||||||
|
def category_id
|
||||||
|
topic.category_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def moderator_action
|
||||||
|
object.post_type == Post.types[:moderator_action]
|
||||||
|
end
|
||||||
|
|
||||||
|
def deleted_by
|
||||||
|
BasicUserSerializer.new(object.deleted_by, root: false).as_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_deleted_by?
|
||||||
|
object.trashed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_type
|
||||||
|
object.user_actions.select { |ua| ua.user_id = object.user_id }
|
||||||
|
.select { |ua| [UserAction::REPLY, UserAction::RESPONSE].include? ua.action_type }
|
||||||
|
.first.try(:action_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# we need this to handle deleted topics which aren't loaded via the .includes(:topic)
|
||||||
|
# because Rails 4 "unscoped" support is bugged (cf. https://github.com/rails/rails/issues/13775)
|
||||||
|
def topic
|
||||||
|
return @topic if @topic
|
||||||
|
@topic = object.topic || Topic.with_deleted.find(object.topic_id)
|
||||||
|
@topic
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -218,6 +218,8 @@ Discourse::Application.routes.draw do
|
|||||||
get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
|
get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
delete "users/:username" => "users#destroy", constraints: {username: USERNAME_ROUTE_FORMAT}
|
delete "users/:username" => "users#destroy", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
get "users/by-external/:external_id" => "users#show"
|
get "users/by-external/:external_id" => "users#show"
|
||||||
|
get "users/:username/flagged-posts" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
|
get "users/:username/deleted-posts" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
|
|
||||||
post "user_avatar/:username/refresh_gravatar" => "user_avatars#refresh_gravatar"
|
post "user_avatar/:username/refresh_gravatar" => "user_avatars#refresh_gravatar"
|
||||||
get "letter_avatar/:username/:size/:version.png" => "user_avatars#show_letter",
|
get "letter_avatar/:username/:size/:version.png" => "user_avatars#show_letter",
|
||||||
@ -231,6 +233,8 @@ Discourse::Application.routes.draw do
|
|||||||
|
|
||||||
get "posts/by_number/:topic_id/:post_number" => "posts#by_number"
|
get "posts/by_number/:topic_id/:post_number" => "posts#by_number"
|
||||||
get "posts/:id/reply-history" => "posts#reply_history"
|
get "posts/:id/reply-history" => "posts#reply_history"
|
||||||
|
get "posts/:username/deleted" => "posts#deleted_posts", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
|
get "posts/:username/flagged" => "posts#flagged_posts", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
|
|
||||||
resources :groups do
|
resources :groups do
|
||||||
get 'members'
|
get 'members'
|
||||||
|
@ -156,4 +156,12 @@ module PostGuardian
|
|||||||
def can_wiki?
|
def can_wiki?
|
||||||
is_staff? || @user.has_trust_level?(:elder)
|
is_staff? || @user.has_trust_level?(:elder)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_see_flagged_posts?
|
||||||
|
is_staff?
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_see_deleted_posts?
|
||||||
|
is_staff?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -606,4 +606,51 @@ describe PostsController do
|
|||||||
::JSON.parse(response.body)['cooked'].should == "full content"
|
::JSON.parse(response.body)['cooked'].should == "full content"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "flagged posts" do
|
||||||
|
|
||||||
|
include_examples "action requires login", :get, :flagged_posts, username: "system"
|
||||||
|
|
||||||
|
describe "when logged in" do
|
||||||
|
before { log_in }
|
||||||
|
|
||||||
|
it "raises an error if the user doesn't have permission to see the flagged posts" do
|
||||||
|
Guardian.any_instance.expects(:can_see_flagged_posts?).returns(false)
|
||||||
|
xhr :get, :flagged_posts, username: "system"
|
||||||
|
response.should be_forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can see the flagged posts when authorized" do
|
||||||
|
Guardian.any_instance.expects(:can_see_flagged_posts?).returns(true)
|
||||||
|
xhr :get, :flagged_posts, username: "system"
|
||||||
|
response.should be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "deleted posts" do
|
||||||
|
|
||||||
|
include_examples "action requires login", :get, :deleted_posts, username: "system"
|
||||||
|
|
||||||
|
describe "when logged in" do
|
||||||
|
before { log_in }
|
||||||
|
|
||||||
|
it "raises an error if the user doesn't have permission to see the deleted posts" do
|
||||||
|
Guardian.any_instance.expects(:can_see_deleted_posts?).returns(false)
|
||||||
|
xhr :get, :deleted_posts, username: "system"
|
||||||
|
response.should be_forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can see the deleted posts when authorized" do
|
||||||
|
Guardian.any_instance.expects(:can_see_deleted_posts?).returns(true)
|
||||||
|
xhr :get, :deleted_posts, username: "system"
|
||||||
|
response.should be_success
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user