introduce Enum

This commit is contained in:
Gosha Arinich 2013-03-01 15:07:44 +03:00
parent 0c8c41b131
commit 0c99dea153
45 changed files with 242 additions and 216 deletions

View file

@ -21,7 +21,7 @@ join (
limit 100
"
sql.where2 "post_action_type_id in (:flag_types)", flag_types: PostActionType.FlagTypes
sql.where2 "post_action_type_id in (:flag_types)", flag_types: PostActionType.flag_types.values
# it may make sense to add a view that shows flags on deleted posts,
@ -62,7 +62,7 @@ limit 100
from post_actions a
/*where*/
"
sql.where("post_action_type_id in (:flag_types)", flag_types: PostActionType.FlagTypes)
sql.where("post_action_type_id in (:flag_types)", flag_types: PostActionType.flag_types.values)
sql.where("post_id in (:posts)", posts: posts.map{|p| p["id"].to_i})
if params[:filter] == 'old'

View file

@ -8,7 +8,7 @@ class PostActionsController < ApplicationController
def create
id = params[:post_action_type_id].to_i
if action = PostActionType.where(id: id).first
guardian.ensure_post_can_act!(@post, PostActionType.Types.invert[id])
guardian.ensure_post_can_act!(@post, PostActionType.types[id])
post_action = PostAction.act(current_user, @post, action.id, params[:message])

View file

@ -134,9 +134,9 @@ class PostsController < ApplicationController
post = find_post_from_params
if current_user
if params[:bookmarked] == "true"
PostAction.act(current_user, post, PostActionType.Types[:bookmark])
PostAction.act(current_user, post, PostActionType.types[:bookmark])
else
PostAction.remove_act(current_user, post, PostActionType.Types[:bookmark])
PostAction.remove_act(current_user, post, PostActionType.types[:bookmark])
end
end
render :nothing => true

View file

@ -64,7 +64,7 @@ class UserNotifications < ActionMailer::Base
return unless @post.present?
username = @notification.data_hash[:display_username]
notification_type = Notification.InvertedTypes[opts[:notification].notification_type].to_s
notification_type = Notification.types[opts[:notification].notification_type].to_s
email_opts = {
topic_title: @notification.data_hash[:topic_title],

View file

@ -72,7 +72,7 @@ class Invite < ActiveRecord::Base
end
# Notify the invitee
invited_by.notifications.create(notification_type: Notification.Types[:invitee_accepted],
invited_by.notifications.create(notification_type: Notification.types[:invitee_accepted],
data: { display_username: result.username }.to_json)
else

View file

@ -1,5 +1,6 @@
class Notification < ActiveRecord::Base
require_dependency 'enum'
class Notification < ActiveRecord::Base
belongs_to :user
belongs_to :topic
@ -9,21 +10,11 @@ class Notification < ActiveRecord::Base
scope :unread, lambda { where(read: false) }
scope :recent, lambda { order('created_at desc').limit(10) }
def self.Types
{:mentioned => 1,
:replied => 2,
:quoted => 3,
:edited => 4,
:liked => 5,
:private_message => 6,
:invited_to_private_message => 7,
:invitee_accepted => 8,
:posted => 9,
:moved_post => 10}
end
def self.InvertedTypes
@inverted_types ||= Notification.Types.invert
def self.types
@types ||= Enum.new(
:mentioned, :replied, :quoted, :edited, :liked, :private_message,
:invited_to_private_message, :invitee_accepted, :posted, :moved_post
)
end
def self.mark_posts_read(user, topic_id, post_numbers)
@ -35,8 +26,8 @@ class Notification < ActiveRecord::Base
.includes(:topic)
.unread
.limit(20)
.order("CASE WHEN notification_type = #{Notification.Types[:replied]} THEN 1
WHEN notification_type = #{Notification.Types[:mentioned]} THEN 2
.order("CASE WHEN notification_type = #{Notification.types[:replied]} THEN 1
WHEN notification_type = #{Notification.types[:mentioned]} THEN 2
ELSE 3
END, created_at DESC").to_a
@ -69,7 +60,7 @@ class Notification < ActiveRecord::Base
def text_description
link = block_given? ? yield : ""
I18n.t("notification_types.#{Notification.InvertedTypes[notification_type]}", data_hash.merge(link: link))
I18n.t("notification_types.#{Notification.types[notification_type]}", data_hash.merge(link: link))
end
def url

View file

@ -279,7 +279,7 @@ class Post < ActiveRecord::Base
end
def is_flagged?
post_actions.where(post_action_type_id: PostActionType.FlagTypes, deleted_at: nil).count != 0
post_actions.where(post_action_type_id: PostActionType.flag_types.values, deleted_at: nil).count != 0
end
def unhide!

View file

@ -20,7 +20,7 @@ class PostAction < ActiveRecord::Base
def self.update_flagged_posts_count
posts_flagged_count = PostAction.joins(post: :topic)
.where('post_actions.post_action_type_id' => PostActionType.FlagTypes,
.where('post_actions.post_action_type_id' => PostActionType.flag_types.values,
'posts.deleted_at' => nil,
'topics.deleted_at' => nil).count('DISTINCT posts.id')
@ -55,13 +55,12 @@ class PostAction < ActiveRecord::Base
actions = if action_type_id
[action_type_id]
else
moderator_id == -1 ? PostActionType.AutoActionFlagTypes : PostActionType.FlagTypes
moderator_id == -1 ? PostActionType.auto_action_flag_types.values : PostActionType.flag_types.values
end
PostAction.update_all({ deleted_at: Time.now, deleted_by: moderator_id }, { post_id: post.id, post_action_type_id: actions })
r = PostActionType.Types.invert
f = actions.map { |t| ["#{r[t]}_count", 0] }
f = actions.map{|t| ["#{PostActionType.types[t]}_count", 0]}
Post.with_deleted.update_all(Hash[*f.flatten], id: post.id)
@ -87,15 +86,15 @@ class PostAction < ActiveRecord::Base
end
def is_bookmark?
post_action_type_id == PostActionType.Types[:bookmark]
post_action_type_id == PostActionType.types[:bookmark]
end
def is_like?
post_action_type_id == PostActionType.Types[:like]
post_action_type_id == PostActionType.types[:like]
end
def is_flag?
PostActionType.FlagTypes.include?(post_action_type_id)
PostActionType.flag_types.values.include?(post_action_type_id)
end
# A custom rate limiter for this model
@ -124,15 +123,15 @@ class PostAction < ActiveRecord::Base
end
before_create do
raise AlreadyFlagged if is_flag? && PostAction.where(user_id: user_id,
post_id: post_id,
post_action_type_id: PostActionType.FlagTypes).exists?
raise AlreadyFlagged if is_flag? and PostAction.where(user_id: user_id,
post_id: post_id,
post_action_type_id: PostActionType.flag_types.values).exists?
end
after_save do
# Update denormalized counts
post_action_type = PostActionType.Types.invert[post_action_type_id]
column = "#{post_action_type}_count"
post_action_type = PostActionType.types[post_action_type_id]
column = "#{post_action_type.to_s}_count"
delta = deleted_at.nil? ? 1 : -1
# Voting also changes the sort_order
@ -144,7 +143,7 @@ class PostAction < ActiveRecord::Base
Topic.update_all ["#{column} = #{column} + ?", delta], id: post.topic_id
if PostActionType.FlagTypes.include?(post_action_type_id)
if PostActionType.flag_types.values.include?(post_action_type_id)
PostAction.update_flagged_posts_count
end
@ -153,7 +152,7 @@ class PostAction < ActiveRecord::Base
flag_counts = exec_sql("SELECT SUM(CASE WHEN deleted_at IS NULL THEN 1 ELSE 0 END) AS new_flags,
SUM(CASE WHEN deleted_at IS NOT NULL THEN 1 ELSE 0 END) AS old_flags
FROM post_actions
WHERE post_id = ? AND post_action_type_id IN (?)", post.id, PostActionType.AutoActionFlagTypes).first
WHERE post_id = ? AND post_action_type_id IN (?)", post.id, PostActionType.auto_action_flag_types.values).first
old_flags, new_flags = flag_counts['old_flags'].to_i, flag_counts['new_flags'].to_i
if new_flags >= SiteSetting.flags_required_to_hide_post

View file

@ -1,31 +1,28 @@
require_dependency 'enum'
class PostActionType < ActiveRecord::Base
attr_accessible :id, :is_flag, :name_key, :icon
def self.ordered
order('position asc').all
end
class << self
def ordered
order('position asc').all
end
def self.Types
{
bookmark: 1,
like: 2,
off_topic: 3,
inappropriate: 4,
vote: 5,
custom_flag: 6,
spam: 8
}
end
def types
@types ||= Enum.new(:bookmark, :like, :off_topic, :inappropriate, :vote,
:custom_flag, :spam)
end
def self.is_flag?(sym)
self.FlagTypes.include?(self.Types[sym])
end
def auto_action_flag_types
@auto_action_flag_types ||= flag_types.except(:custom_flag)
end
def self.AutoActionFlagTypes
@auto_action_flag_types ||= [self.Types[:off_topic], self.Types[:spam], self.Types[:inappropriate]]
end
def flag_types
@flag_types ||= types.only(:off_topic, :spam, :inappropriate, :custom_flag)
end
def self.FlagTypes
@flag_types ||= self.AutoActionFlagTypes + [self.Types[:custom_flag]]
def is_flag?(sym)
flag_types.valid?(sym)
end
end
end

View file

@ -38,7 +38,7 @@ class PostAlertObserver < ActiveRecord::Observer
return if post.topic.private_message?
create_notification(post.user,
Notification.Types[:liked],
Notification.types[:liked],
post,
display_username: post_action.user.username,
post_action_id: post_action.id)
@ -52,14 +52,14 @@ class PostAlertObserver < ActiveRecord::Observer
return if version.user_id == post.user_id
return if post.topic.private_message?
create_notification(post.user, Notification.Types[:edited], post, display_username: version.user.username)
create_notification(post.user, Notification.types[:edited], post, display_username: version.user.username)
end
def after_create_post(post)
if post.topic.private_message?
# If it's a private message, notify the topic_allowed_users
post.topic.topic_allowed_users.reject { |a| a.user_id == post.user_id }.each do |a|
create_notification(a.user, Notification.Types[:private_message], post)
post.topic.topic_allowed_users.reject{ |a| a.user_id == post.user_id }.each do |a|
create_notification(a.user, Notification.types[:private_message], post)
end
else
# If it's not a private message, notify the users
@ -114,7 +114,7 @@ class PostAlertObserver < ActiveRecord::Observer
def notify_users(users, type, post)
users = [users] unless users.is_a?(Array)
users.each do |u|
create_notification(u, Notification.Types[type], post)
create_notification(u, Notification.types[type], post)
end
end
@ -133,7 +133,7 @@ class PostAlertObserver < ActiveRecord::Observer
exclude_user_ids << extract_quoted_users(post).map(&:id)
exclude_user_ids.flatten!
TopicUser.where(topic_id: post.topic_id, notification_level: TopicUser::NotificationLevel::WATCHING).includes(:user).each do |tu|
create_notification(tu.user, Notification.Types[:posted], post) unless exclude_user_ids.include?(tu.user_id)
create_notification(tu.user, Notification.types[:posted], post) unless exclude_user_ids.include?(tu.user_id)
end
end
end

View file

@ -14,7 +14,7 @@ class Site
end
def notification_types
Notification.Types
Notification.types
end
def trust_levels

View file

@ -334,7 +334,7 @@ class Topic < ActiveRecord::Base
if user.present?
if topic_allowed_users.create!(user_id: user.id)
# Notify the user they've been invited
user.notifications.create(notification_type: Notification.Types[:invited_to_private_message],
user.notifications.create(notification_type: Notification.types[:invited_to_private_message],
topic_id: id,
post_number: 1,
data: { topic_title: title,

View file

@ -210,11 +210,11 @@ class User < ActiveRecord::Base
def unread_private_messages
unread_notifications_by_type[Notification.Types[:private_message]] || 0
unread_notifications_by_type[Notification.types[:private_message]] || 0
end
def unread_notifications
unread_notifications_by_type.except(Notification.Types[:private_message]).values.sum
unread_notifications_by_type.except(Notification.types[:private_message]).values.sum
end
def saw_notification_id(notification_id)
@ -357,11 +357,11 @@ class User < ActiveRecord::Base
end
def flags_given_count
PostAction.where(user_id: id, post_action_type_id: PostActionType.FlagTypes).count
PostAction.where(user_id: id, post_action_type_id: PostActionType.flag_types.values).count
end
def flags_received_count
posts.includes(:post_actions).where(post_actions: { post_action_type_id: PostActionType.FlagTypes }).count
posts.includes(:post_actions).where('post_actions.post_action_type_id' => PostActionType.flag_types.values).count
end
def private_topics_count
@ -397,7 +397,7 @@ class User < ActiveRecord::Base
def change_trust_level(level)
raise "Invalid trust level #{level}" unless TrustLevel.valid_level?(level)
self.trust_level = TrustLevel.Levels[level]
self.trust_level = TrustLevel.levels[level]
end
def guardian

View file

@ -40,13 +40,13 @@ class UserActionObserver < ActiveRecord::Observer
def log_notification(model)
action =
case model.notification_type
when Notification.Types[:quoted]
when Notification.types[:quoted]
UserAction::QUOTE
when Notification.Types[:replied]
when Notification.types[:replied]
UserAction::RESPONSE
when Notification.Types[:mentioned]
when Notification.types[:mentioned]
UserAction::MENTION
when Notification.Types[:edited]
when Notification.types[:edited]
UserAction::EDIT
end

View file

@ -3,7 +3,7 @@ class UserEmailObserver < ActiveRecord::Observer
def after_commit(notification)
if notification.send(:transaction_include_action?, :create)
notification_type = Notification.InvertedTypes[notification.notification_type]
notification_type = Notification.types[notification.notification_type]
# Delegate to email_user_{{NOTIFICATION_TYPE}} if exists
email_method = :"email_user_#{notification_type.to_s}"

View file

@ -3,7 +3,7 @@ class PostActionTypeSerializer < ApplicationSerializer
attributes :name_key, :name, :description, :long_form, :is_flag, :icon, :id, :is_custom_flag
def is_custom_flag
object.id == PostActionType.Types[:custom_flag]
object.id == PostActionType.types[:custom_flag]
end
def name

View file

@ -141,7 +141,7 @@ class PostSerializer < ApplicationSerializer
# Summary of the actions taken on this post
def actions_summary
result = []
PostActionType.Types.each do |sym, id|
PostActionType.types.each do |sym, id|
next if [:bookmark].include?(sym)
count_col = "#{sym}_count".to_sym
@ -154,7 +154,7 @@ class PostSerializer < ApplicationSerializer
# The following only applies if you're logged in
if action_summary[:can_act] and scope.current_user.present?
action_summary[:can_clear_flags] = scope.is_admin? && PostActionType.FlagTypes.include?(id)
action_summary[:can_clear_flags] = scope.is_admin? && PostActionType.flag_types.values.include?(id)
if post_actions.present? and post_actions.has_key?(id)
action_summary[:acted] = true
@ -163,7 +163,7 @@ class PostSerializer < ApplicationSerializer
end
# anonymize flags
if !scope.is_admin? && PostActionType.FlagTypes.include?(id)
if !scope.is_admin? && PostActionType.flag_types.values.include?(id)
action_summary[:count] = action_summary[:acted] ? 1 : 0
end
@ -200,7 +200,7 @@ class PostSerializer < ApplicationSerializer
end
def include_bookmarked?
post_actions.present? and post_actions.keys.include?(PostActionType.Types[:bookmark])
post_actions.present? and post_actions.keys.include?(PostActionType.types[:bookmark])
end
private

View file

@ -1,12 +1,12 @@
PostActionType.seed do |s|
s.id = PostActionType.Types[:bookmark]
s.id = PostActionType.types[:bookmark]
s.name_key = 'bookmark'
s.is_flag = false
s.position = 1
end
PostActionType.seed do |s|
s.id = PostActionType.Types[:like]
s.id = PostActionType.types[:like]
s.name_key = 'like'
s.is_flag = false
s.icon = 'heart'
@ -14,35 +14,35 @@ PostActionType.seed do |s|
end
PostActionType.seed do |s|
s.id = PostActionType.Types[:off_topic]
s.id = PostActionType.types[:off_topic]
s.name_key = 'off_topic'
s.is_flag = true
s.position = 3
end
PostActionType.seed do |s|
s.id = PostActionType.Types[:inappropriate]
s.id = PostActionType.types[:inappropriate]
s.name_key = 'inappropriate'
s.is_flag = true
s.position = 4
end
PostActionType.seed do |s|
s.id = PostActionType.Types[:vote]
s.id = PostActionType.types[:vote]
s.name_key = 'vote'
s.is_flag = false
s.position = 5
end
PostActionType.seed do |s|
s.id = PostActionType.Types[:spam]
s.id = PostActionType.types[:spam]
s.name_key = 'spam'
s.is_flag = true
s.position = 6
end
PostActionType.seed do |s|
s.id = PostActionType.Types[:custom_flag]
s.id = PostActionType.types[:custom_flag]
s.name_key = 'custom_flag'
s.is_flag = true
s.position = 7

View file

@ -1,11 +1,11 @@
class RemoveTrustLevels < ActiveRecord::Migration
def up
drop_table :trust_levels
change_column_default :users, :trust_level_id, TrustLevel.Levels[:new]
change_column_default :users, :trust_level_id, TrustLevel.levels[:new]
rename_column :users, :trust_level_id, :trust_level
update "UPDATE users set trust_level = #{TrustLevel.Levels[:regular]}"
update "UPDATE users set trust_level = #{TrustLevel.Levels[:moderator]} where moderator = true"
update "UPDATE users set trust_level = #{TrustLevel.levels[:regular]}"
update "UPDATE users set trust_level = #{TrustLevel.levels[:moderator]} where moderator = true"
remove_column :users, :moderator
add_column :users, :flag_level, :integer, null: false, default: 0

46
lib/enum.rb Normal file
View file

@ -0,0 +1,46 @@
class Enum < SimpleDelegator
# Public: Initialize an enum.
#
# members - the array of enum members. May contain a hash of options:
# :start - the number of first enum member. Defaults to 1.
#
# Examples
#
# FRUITS = Enum.new(:apple, :orange, :kiwi)
def initialize(*members)
super({})
options = members.extract_options!
start = options.fetch(:start) { 1 }
update Hash[members.zip(start..members.count + start)]
end
# Public: Access the number/value of member.
#
# ids_or_value - number or value of member.
#
# Returns value if number was provided, and number if value was provided.
def [](id_or_value)
fetch(id_or_value) { key(id_or_value) }
end
# Public: Check if supplied member is valid.
def valid?(member)
has_key?(member)
end
# Public: Create a subset of enum, only include specified keys.
def only(*keys)
dup.tap do |d|
d.__getobj__.keep_if { |k| keys.include?(k) }
end
end
# Public: Create a subset of enum, preserve all items but specified ones.
def except(*keys)
dup.tap do |d|
d.__getobj__.delete_if { |k| keys.include?(k) }
end
end
end

View file

@ -135,7 +135,7 @@ class Guardian
return false unless @user.try(:admin?)
return false if moderator.blank?
return false if @user.id == moderator.id
return false unless moderator.trust_level == TrustLevel.Levels[:moderator]
return false unless moderator.trust_level == TrustLevel.levels[:moderator]
true
end
@ -152,7 +152,7 @@ class Guardian
def can_see_post_actors?(topic, post_action_type_id)
return false unless topic.present?
type_symbol = PostActionType.Types.invert[post_action_type_id]
type_symbol = PostActionType.types[post_action_type_id]
return false if type_symbol == :bookmark
return can_see_flags?(topic) if PostActionType.is_flag?(type_symbol)
@ -335,10 +335,10 @@ class Guardian
return false unless @user.has_trust_level?(:basic)
if taken
return false unless (taken & PostActionType.FlagTypes).empty?
return false unless (taken & PostActionType.flag_types.values).empty?
end
else
return false if taken && taken.include?(PostActionType.Types[action_key])
return false if taken && taken.include?(PostActionType.types[action_key])
end
case action_key

View file

@ -14,7 +14,7 @@ module Jobs
posts.each do |p|
unless users_notified.include?(p.user_id)
p.user.notifications.create(notification_type: Notification.Types[:moved_post],
p.user.notifications.create(notification_type: Notification.types[:moved_post],
topic_id: p.topic_id,
post_number: p.post_number,
data: {topic_title: p.topic.title,

View file

@ -13,7 +13,7 @@ class Promotion
# nil users are never promoted
return false if @user.blank?
trust_key = TrustLevel.level_key(@user.trust_level)
trust_key = TrustLevel.levels[@user.trust_level]
review_method = :"review_#{trust_key.to_s}"
return send(review_method) if respond_to?(review_method)
@ -26,7 +26,7 @@ class Promotion
return false if @user.posts_read_count < SiteSetting.basic_requires_read_posts
return false if (@user.time_read / 60) < SiteSetting.basic_requires_time_spent_mins
@user.trust_level = TrustLevel.Levels[:basic]
@user.trust_level = TrustLevel.levels[:basic]
@user.save
true

View file

@ -163,14 +163,14 @@ class TopicView
@voted_in_topic ||= begin
return false unless all_post_actions.present?
all_post_actions.values.flatten.map {|ac| ac.keys}.flatten.include?(PostActionType.Types[:vote])
all_post_actions.values.flatten.map {|ac| ac.keys}.flatten.include?(PostActionType.types[:vote])
end
end
def post_action_visibility
@post_action_visibility ||= begin
result = []
PostActionType.Types.each do |k, v|
PostActionType.types.each do |k, v|
result << v if Guardian.new(@user).can_see_post_actors?(@topic, v)
end
result

View file

@ -1,17 +1,14 @@
class TrustLevel
require_dependency 'enum'
class TrustLevel
attr_reader :id, :name
class << self
def levels
{ new: 0,
basic: 1,
regular: 2,
experienced: 3,
advanced: 4,
moderator: 5 }
@levels ||= Enum.new(
:new, :basic, :regular, :experienced, :advanced, :moderator, start: 0
)
end
alias_method :Levels, :levels
def all
levels.map do |name_key, id|
@ -20,15 +17,11 @@ class TrustLevel
end
def valid_level?(level)
levels.has_key?(level)
levels.valid?(level)
end
def compare(current_level, level)
(current_level || levels[:new]) >= levels[level]
end
def level_key(level)
levels.invert[level]
(current_level || levels[:new]) >= levels[level] rescue binding.pry
end
end

View file

@ -42,26 +42,26 @@ describe Guardian do
end
it "returns false when you've already done it" do
Guardian.new(user).post_can_act?(post, :like, taken_actions: {PostActionType.Types[:like] => 1}).should be_false
Guardian.new(user).post_can_act?(post, :like, taken_actions: {PostActionType.types[:like] => 1}).should be_false
end
it "returns false when you already flagged a post" do
Guardian.new(user).post_can_act?(post, :off_topic, taken_actions: {PostActionType.Types[:spam] => 1}).should be_false
Guardian.new(user).post_can_act?(post, :off_topic, taken_actions: {PostActionType.types[:spam] => 1}).should be_false
end
describe "trust levels" do
it "returns true for a new user liking something" do
user.trust_level = TrustLevel.Levels[:new]
user.trust_level = TrustLevel.levels[:new]
Guardian.new(user).post_can_act?(post, :like).should be_true
end
it "returns false for a new user flagging something as spam" do
user.trust_level = TrustLevel.Levels[:new]
user.trust_level = TrustLevel.levels[:new]
Guardian.new(user).post_can_act?(post, :spam).should be_false
end
it "returns false for a new user flagging something as off topic" do
user.trust_level = TrustLevel.Levels[:new]
user.trust_level = TrustLevel.levels[:new]
Guardian.new(user).post_can_act?(post, :off_topic).should be_false
end
end
@ -108,7 +108,7 @@ describe Guardian do
end
it "returns false when you are untrusted" do
user.trust_level = TrustLevel.Levels[:new]
user.trust_level = TrustLevel.levels[:new]
Guardian.new(user).can_send_private_message?(another_user).should be_false
end
@ -130,7 +130,7 @@ describe Guardian do
end
it "returns false for an untrusted user" do
user.trust_level = TrustLevel.Levels[:new]
user.trust_level = TrustLevel.levels[:new]
Guardian.new(user).can_reply_as_new_topic?(topic).should be_false
end
@ -144,32 +144,32 @@ describe Guardian do
let(:topic) { Fabricate(:topic, user: coding_horror)}
it 'returns false when the post is nil' do
Guardian.new(user).can_see_post_actors?(nil, PostActionType.Types[:like]).should be_false
Guardian.new(user).can_see_post_actors?(nil, PostActionType.types[:like]).should be_false
end
it 'returns true for likes' do
Guardian.new(user).can_see_post_actors?(topic, PostActionType.Types[:like]).should be_true
Guardian.new(user).can_see_post_actors?(topic, PostActionType.types[:like]).should be_true
end
it 'returns false for bookmarks' do
Guardian.new(user).can_see_post_actors?(topic, PostActionType.Types[:bookmark]).should be_false
Guardian.new(user).can_see_post_actors?(topic, PostActionType.types[:bookmark]).should be_false
end
it 'returns false for off-topic flags' do
Guardian.new(user).can_see_post_actors?(topic, PostActionType.Types[:off_topic]).should be_false
Guardian.new(user).can_see_post_actors?(topic, PostActionType.types[:off_topic]).should be_false
end
it 'returns false for spam flags' do
Guardian.new(user).can_see_post_actors?(topic, PostActionType.Types[:spam]).should be_false
Guardian.new(user).can_see_post_actors?(topic, PostActionType.types[:spam]).should be_false
end
it 'returns true for public votes' do
Guardian.new(user).can_see_post_actors?(topic, PostActionType.Types[:vote]).should be_true
Guardian.new(user).can_see_post_actors?(topic, PostActionType.types[:vote]).should be_true
end
it 'returns false for private votes' do
topic.expects(:has_meta_data_boolean?).with(:private_poll).returns(true)
Guardian.new(user).can_see_post_actors?(topic, PostActionType.Types[:vote]).should be_false
Guardian.new(user).can_see_post_actors?(topic, PostActionType.types[:vote]).should be_false
end
end
@ -356,11 +356,11 @@ describe Guardian do
end
it "doesn't allow voting if the user has an action from voting already" do
guardian.post_can_act?(post,:vote,taken_actions: {PostActionType.Types[:vote] => 1}).should be_false
guardian.post_can_act?(post,:vote,taken_actions: {PostActionType.types[:vote] => 1}).should be_false
end
it "allows voting if the user has performed a different action" do
guardian.post_can_act?(post,:vote,taken_actions: {PostActionType.Types[:like] => 1}).should be_true
guardian.post_can_act?(post,:vote,taken_actions: {PostActionType.types[:like] => 1}).should be_true
end
it "isn't allowed on archived topics" do

View file

@ -18,7 +18,7 @@ describe Jobs::NotifyMovedPosts do
let!(:p3) { Fabricate(:post, user: p1.user, topic: p1.topic) }
let(:admin) { Fabricate(:admin) }
let(:moved_post_notifications) { Notification.where(notification_type: Notification.Types[:moved_post]) }
let(:moved_post_notifications) { Notification.where(notification_type: Notification.types[:moved_post]) }
it "should create two notifications" do
lambda { Jobs::NotifyMovedPosts.new.execute(post_ids: [p1.id, p2.id, p3.id], moved_by_id: admin.id) }.should change(moved_post_notifications, :count).by(2)

View file

@ -5,7 +5,7 @@ describe Promotion do
context "new user" do
let(:user) { Fabricate(:user, trust_level: TrustLevel.Levels[:new])}
let(:user) { Fabricate(:user, trust_level: TrustLevel.levels[:new])}
let(:promotion) { Promotion.new(user) }
it "doesn't raise an error with a nil user" do
@ -20,7 +20,7 @@ describe Promotion do
end
it "has not changed the user's trust level" do
user.trust_level.should == TrustLevel.Levels[:new]
user.trust_level.should == TrustLevel.levels[:new]
end
end
@ -38,7 +38,7 @@ describe Promotion do
end
it "has upgraded the user to basic" do
user.trust_level.should == TrustLevel.Levels[:basic]
user.trust_level.should == TrustLevel.levels[:basic]
end
end

View file

@ -66,12 +66,12 @@ describe RateLimiter do
end
it "returns true for can_perform if the user is a mod" do
user.trust_level = TrustLevel.Levels[:moderator]
user.trust_level = TrustLevel.levels[:moderator]
rate_limiter.can_perform?.should be_true
end
it "doesn't raise an error when a moderator performs the task" do
user.trust_level = TrustLevel.Levels[:moderator]
user.trust_level = TrustLevel.levels[:moderator]
lambda { rate_limiter.performed! }.should_not raise_error
end

View file

@ -100,8 +100,8 @@ describe TopicView do
end
it 'returns the like' do
PostAction.act(coding_horror, p1, PostActionType.Types[:like])
topic_view.all_post_actions[p1.id][PostActionType.Types[:like]].should be_present
PostAction.act(coding_horror, p1, PostActionType.types[:like])
topic_view.all_post_actions[p1.id][PostActionType.types[:like]].should be_present
end
end
@ -128,7 +128,7 @@ describe TopicView do
# end
# it "is true when the user has voted for a post" do
# PostAction.act(coding_horror, p1, PostActionType.Types[:vote])
# PostAction.act(coding_horror, p1, PostActionType.types[:vote])
# topic_view.voted_in_topic?.should be_true
# end
# end
@ -136,7 +136,7 @@ describe TopicView do
context '.post_action_visibility' do
it "is allows users to see likes" do
topic_view.post_action_visibility.include?(PostActionType.Types[:like]).should be_true
topic_view.post_action_visibility.include?(PostActionType.types[:like]).should be_true
end
end

View file

@ -24,7 +24,7 @@ describe Admin::FlagsController do
p = Fabricate(:post)
u = Fabricate(:user)
PostAction.act(u, p, PostActionType.Types[:spam])
PostAction.act(u, p, PostActionType.types[:spam])
xhr :get, :index
data = ::JSON.parse(response.body)

View file

@ -14,7 +14,7 @@ describe PostActionsController do
end
it 'raises an error when the id is missing' do
lambda { xhr :post, :create, post_action_type_id: PostActionType.Types[:like] }.should raise_error(Discourse::InvalidParameters)
lambda { xhr :post, :create, post_action_type_id: PostActionType.types[:like] }.should raise_error(Discourse::InvalidParameters)
end
it 'raises an error when the post_action_type_id index is missing' do
@ -23,19 +23,19 @@ describe PostActionsController do
it "fails when the user doesn't have permission to see the post" do
Guardian.any_instance.expects(:can_see?).with(@post).returns(false)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.Types[:like]
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like]
response.should be_forbidden
end
it "fails when the user doesn't have permission to perform that action" do
Guardian.any_instance.expects(:post_can_act?).with(@post, :like).returns(false)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.Types[:like]
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like]
response.should be_forbidden
end
it 'allows us to create an post action on a post' do
PostAction.expects(:act).once.with(@user, @post, PostActionType.Types[:like], nil)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.Types[:like]
PostAction.expects(:act).once.with(@user, @post, PostActionType.types[:like], nil)
xhr :post, :create, id: @post.id, post_action_type_id: PostActionType.types[:like]
end
end
@ -104,24 +104,24 @@ describe PostActionsController do
it "raises an error when the user doesn't have access" do
Guardian.any_instance.expects(:can_clear_flags?).returns(false)
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.Types[:spam]
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam]
response.should be_forbidden
end
context "success" do
before do
Guardian.any_instance.expects(:can_clear_flags?).returns(true)
PostAction.expects(:clear_flags!).with(flagged_post, user.id, PostActionType.Types[:spam])
PostAction.expects(:clear_flags!).with(flagged_post, user.id, PostActionType.types[:spam])
end
it "delegates to clear_flags" do
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.Types[:spam]
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam]
response.should be_success
end
it "works with a deleted post" do
flagged_post.destroy
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.Types[:spam]
xhr :post, :clear_flags, id: flagged_post.id, post_action_type_id: PostActionType.types[:spam]
response.should be_success
end
@ -142,7 +142,7 @@ describe PostActionsController do
it 'raises an error without an id' do
lambda {
xhr :get, :users, post_action_type_id: PostActionType.Types[:like]
xhr :get, :users, post_action_type_id: PostActionType.types[:like]
}.should raise_error(Discourse::InvalidParameters)
end
@ -154,18 +154,18 @@ describe PostActionsController do
it "fails when the user doesn't have permission to see the post" do
Guardian.any_instance.expects(:can_see?).with(post).returns(false)
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.Types[:like]
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.types[:like]
response.should be_forbidden
end
it 'raises an error when the post action type cannot be seen' do
Guardian.any_instance.expects(:can_see_post_actors?).with(instance_of(Topic), PostActionType.Types[:like]).returns(false)
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.Types[:like]
Guardian.any_instance.expects(:can_see_post_actors?).with(instance_of(Topic), PostActionType.types[:like]).returns(false)
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.types[:like]
response.should be_forbidden
end
it 'succeeds' do
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.Types[:like]
xhr :get, :users, id: post.id, post_action_type_id: PostActionType.types[:like]
response.should be_success
end

View file

@ -222,12 +222,12 @@ describe PostsController do
end
it 'creates a bookmark' do
PostAction.expects(:act).with(post.user, post, PostActionType.Types[:bookmark])
PostAction.expects(:act).with(post.user, post, PostActionType.types[:bookmark])
xhr :put, :bookmark, post_id: post.id, bookmarked: 'true'
end
it 'removes a bookmark' do
PostAction.expects(:remove_act).with(post.user, post, PostActionType.Types[:bookmark])
PostAction.expects(:remove_act).with(post.user, post, PostActionType.types[:bookmark])
xhr :put, :bookmark, post_id: post.id
end

View file

@ -266,7 +266,7 @@ describe TopicsController do
end
it "reviews the user for a promotion if they're new" do
user.update_column(:trust_level, TrustLevel.Levels[:new])
user.update_column(:trust_level, TrustLevel.levels[:new])
Promotion.any_instance.expects(:review)
get :show, id: topic.id
end

View file

@ -1,18 +1,18 @@
Fabricator(:notification) do
notification_type Notification.Types[:mentioned]
notification_type Notification.types[:mentioned]
data '{"poison":"ivy","killer":"croc"}'
user
topic {|attrs| Fabricate(:topic, user: attrs[:user] ) }
end
Fabricator(:quote_notification, from: :notification) do
notification_type Notification.Types[:quoted]
notification_type Notification.types[:quoted]
user
topic {|attrs| Fabricate(:topic, user: attrs[:user] ) }
end
Fabricator(:private_message_notification, from: :notification) do
notification_type Notification.Types[:private_message]
notification_type Notification.types[:private_message]
user
topic {|attrs| Fabricate(:topic, user: attrs[:user] ) }
end

View file

@ -3,7 +3,7 @@ Fabricator(:user) do
username { sequence(:username) { |i| "bruce#{i}" } }
email { sequence(:email) { |i| "bruce#{i}@wayne.com" } }
password 'myawesomepassword'
trust_level TrustLevel.Levels[:basic]
trust_level TrustLevel.levels[:basic]
bio_raw "I'm batman!"
end
@ -32,7 +32,7 @@ Fabricator(:moderator, from: :user) do
name 'A. Moderator'
username 'moderator'
email 'moderator@discourse.org'
trust_level TrustLevel.Levels[:moderator]
trust_level TrustLevel.levels[:moderator]
end
Fabricator(:admin, from: :user) do

View file

@ -16,7 +16,7 @@ describe "i18n integrity checks" do
end
it "needs an i18n key (notification_types) for each Notification type" do
Notification.Types.keys.each do |type|
Notification.types.keys.each do |type|
I18n.t("notification_types.#{type}").should_not =~ /translation missing/
end
end

View file

@ -161,8 +161,8 @@ describe Invite do
context 'invite trust levels' do
it "returns the trust level in default_invitee_trust_level" do
SiteSetting.stubs(:default_invitee_trust_level).returns(TrustLevel.Levels[:experienced])
invite.redeem.trust_level.should == TrustLevel.Levels[:experienced]
SiteSetting.stubs(:default_invitee_trust_level).returns(TrustLevel.levels[:experienced])
invite.redeem.trust_level.should == TrustLevel.levels[:experienced]
end
end

View file

@ -77,7 +77,7 @@ describe Notification do
end
it 'should create a private message notification' do
@target.notifications.first.notification_type.should == Notification.Types[:private_message]
@target.notifications.first.notification_type.should == Notification.types[:private_message]
end
it 'should not add a pm notification for the creator' do

View file

@ -9,7 +9,7 @@ describe PostAction do
let(:codinghorror) { Fabricate(:coding_horror) }
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 "flag counts" do
before do
@ -20,7 +20,7 @@ describe PostAction do
end
it "increments the numbers correctly" do
PostAction.act(codinghorror, post, PostActionType.Types[:off_topic])
PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
PostAction.flagged_posts_count.should == 1
PostAction.clear_flags!(post, -1)
@ -28,14 +28,14 @@ describe PostAction do
end
it "should reset counts when a topic is deleted" do
PostAction.act(codinghorror, post, PostActionType.Types[:off_topic])
PostAction.act(codinghorror, post, PostActionType.types[:off_topic])
post.topic.destroy
PostAction.flagged_posts_count.should == 0
end
it "should reset counts when a post is deleted" do
post2 = Fabricate(:post, topic_id: post.topic_id)
PostAction.act(codinghorror, post2, PostActionType.Types[:off_topic])
PostAction.act(codinghorror, post2, PostActionType.types[:off_topic])
post2.destroy
PostAction.flagged_posts_count.should == 0
end
@ -54,14 +54,14 @@ describe PostAction do
describe 'when a user likes something' do
it 'should increase the post counts when a user likes' do
lambda {
PostAction.act(codinghorror, post, PostActionType.Types[:like])
PostAction.act(codinghorror, post, PostActionType.types[:like])
post.reload
}.should change(post, :like_count).by(1)
end
it 'should increase the forum topic like count when a user likes' do
lambda {
PostAction.act(codinghorror, post, PostActionType.Types[:like])
PostAction.act(codinghorror, post, PostActionType.types[:like])
post.topic.reload
}.should change(post.topic, :like_count).by(1)
end
@ -72,14 +72,14 @@ describe PostAction do
describe 'when a user votes for something' do
it 'should increase the vote counts when a user likes' do
lambda {
PostAction.act(codinghorror, post, PostActionType.Types[:vote])
PostAction.act(codinghorror, post, PostActionType.types[:vote])
post.reload
}.should change(post, :vote_count).by(1)
end
it 'should increase the forum topic vote count when a user votes' do
lambda {
PostAction.act(codinghorror, post, PostActionType.Types[:vote])
PostAction.act(codinghorror, post, PostActionType.types[:vote])
post.topic.reload
}.should change(post.topic, :vote_count).by(1)
end
@ -114,14 +114,14 @@ describe PostAction do
it 'does not allow you to flag stuff with 2 reasons' do
post = Fabricate(:post)
u1 = Fabricate(:evil_trout)
PostAction.act(u1, post, PostActionType.Types[:spam])
lambda { PostAction.act(u1, post, PostActionType.Types[:off_topic]) }.should raise_error(PostAction::AlreadyFlagged)
PostAction.act(u1, post, PostActionType.types[:spam])
lambda { PostAction.act(u1, post, PostActionType.types[:off_topic]) }.should raise_error(PostAction::AlreadyFlagged)
end
it 'should update counts when you clear flags' do
post = Fabricate(:post)
u1 = Fabricate(:evil_trout)
PostAction.act(u1, post, PostActionType.Types[:spam])
PostAction.act(u1, post, PostActionType.types[:spam])
post.reload
post.spam_count.should == 1
@ -143,8 +143,8 @@ describe PostAction do
SiteSetting.flags_required_to_hide_post = 2
PostAction.act(u1, post, PostActionType.Types[:spam])
PostAction.act(u2, post, PostActionType.Types[:spam])
PostAction.act(u1, post, PostActionType.types[:spam])
PostAction.act(u2, post, PostActionType.types[:spam])
post.reload
@ -159,8 +159,8 @@ describe PostAction do
post.hidden_reason_id.should be_nil
post.topic.visible.should be_true
PostAction.act(u1, post, PostActionType.Types[:spam])
PostAction.act(u2, post, PostActionType.Types[:off_topic])
PostAction.act(u1, post, PostActionType.types[:spam])
PostAction.act(u2, post, PostActionType.types[:off_topic])
post.reload

View file

@ -9,19 +9,19 @@ describe PostAlertObserver do
context 'when liking a post' do
it 'creates a notification' do
lambda {
PostAction.act(evil_trout, post, PostActionType.Types[:like])
PostAction.act(evil_trout, post, PostActionType.types[:like])
}.should change(Notification, :count).by(1)
end
end
context 'when removing a liked post' do
before do
PostAction.act(evil_trout, post, PostActionType.Types[:like])
PostAction.act(evil_trout, post, PostActionType.types[:like])
end
it 'removes a notification' do
lambda {
PostAction.remove_act(evil_trout, post, PostActionType.Types[:like])
PostAction.remove_act(evil_trout, post, PostActionType.types[:like])
}.should change(Notification, :count).by(-1)
end
end

View file

@ -70,7 +70,7 @@ describe Post do
end
it "returns true for moderators" do
topic.user.trust_level = TrustLevel.Levels[:moderator]
topic.user.trust_level = TrustLevel.levels[:moderator]
Fabricate.build(:post, post_args).should be_valid
end
end
@ -81,12 +81,12 @@ describe Post do
it 'isFlagged is accurate' do
post = Fabricate(:post)
user = Fabricate(:coding_horror)
PostAction.act(user, post, PostActionType.Types[:off_topic])
PostAction.act(user, post, PostActionType.types[:off_topic])
post.reload
post.is_flagged?.should == true
PostAction.remove_act(user, post, PostActionType.Types[:off_topic])
PostAction.remove_act(user, post, PostActionType.types[:off_topic])
post.reload
post.is_flagged?.should == false
end
@ -130,22 +130,22 @@ describe Post do
context "validation" do
it "allows a new user to make a post with one image" do
post_no_images.user.trust_level = TrustLevel.Levels[:new]
post_no_images.user.trust_level = TrustLevel.levels[:new]
post_no_images.should be_valid
end
it "doesn't allow multiple images for new accounts" do
post_one_image.user.trust_level = TrustLevel.Levels[:new]
post_one_image.user.trust_level = TrustLevel.levels[:new]
post_one_image.should_not be_valid
end
it "allows multiple images for basic accounts" do
post_one_image.user.trust_level = TrustLevel.Levels[:basic]
post_one_image.user.trust_level = TrustLevel.levels[:basic]
post_one_image.should be_valid
end
it "doesn't allow a new user to edit their post to insert an image" do
post_no_images.user.trust_level = TrustLevel.Levels[:new]
post_no_images.user.trust_level = TrustLevel.levels[:new]
post_no_images.save
-> {
post_no_images.revise(post_no_images.user, post_two_images.raw)
@ -176,17 +176,17 @@ describe Post do
context "validation" do
it "allows a new user to make a post with one image" do
post_one_link.user.trust_level = TrustLevel.Levels[:new]
post_one_link.user.trust_level = TrustLevel.levels[:new]
post_one_link.should be_valid
end
it "doesn't allow multiple images for new accounts" do
post_two_links.user.trust_level = TrustLevel.Levels[:new]
post_two_links.user.trust_level = TrustLevel.levels[:new]
post_two_links.should_not be_valid
end
it "allows multiple images for basic accounts" do
post_two_links.user.trust_level = TrustLevel.Levels[:basic]
post_two_links.user.trust_level = TrustLevel.levels[:basic]
post_two_links.should be_valid
end
end

View file

@ -16,10 +16,10 @@ describe PostTiming do
post = Fabricate(:post)
user2 = Fabricate(:coding_horror)
PostAction.act(user2, post, PostActionType.Types[:like])
PostAction.act(user2, post, PostActionType.types[:like])
post.user.unread_notifications.should == 1
post.user.unread_notifications_by_type.should == {Notification.Types[:liked] => 1}
post.user.unread_notifications_by_type.should == { Notification.types[:liked] => 1 }
PostTiming.process_timings(post.user, post.topic_id, 1, 100, [[post.post_number, 100]])

View file

@ -97,13 +97,13 @@ describe UserAction do
end
it "creates a new stream entry" do
PostAction.act(liker, post, PostActionType.Types[:like])
PostAction.act(liker, post, PostActionType.types[:like])
likee_stream.count.should == @old_count + 1
end
context "successful like" do
before do
PostAction.act(liker, post, PostActionType.Types[:like])
PostAction.act(liker, post, PostActionType.types[:like])
@liker_action = liker.user_actions.where(action_type: UserAction::LIKE).first
@likee_action = likee.user_actions.where(action_type: UserAction::WAS_LIKED).first
end
@ -124,7 +124,7 @@ describe UserAction do
end
it "doesn't add the entry to the stream" do
PostAction.act(liker, post, PostActionType.Types[:like])
PostAction.act(liker, post, PostActionType.types[:like])
likee_stream.count.should_not == @old_count + 1
end
@ -191,7 +191,7 @@ describe UserAction do
before do
@post = Fabricate(:post)
@user = @post.user
PostAction.act(@user, @post, PostActionType.Types[:bookmark])
PostAction.act(@user, @post, PostActionType.types[:bookmark])
@action = @user.user_actions.where(action_type: UserAction::BOOKMARK).first
end
@ -208,7 +208,7 @@ describe UserAction do
@action.user_id.should == @user.id
end
it 'should nuke the action when unbookmarked' do
PostAction.remove_act(@user, @post, PostActionType.Types[:bookmark])
PostAction.remove_act(@user, @post, PostActionType.types[:bookmark])
@user.user_actions.where(action_type: UserAction::BOOKMARK).first.should be_nil
end
end

View file

@ -123,19 +123,19 @@ describe User do
it "creates a bookmark with the true parameter" do
lambda {
PostAction.act(@post.user, @post, PostActionType.Types[:bookmark])
PostAction.act(@post.user, @post, PostActionType.types[:bookmark])
}.should change(PostAction, :count).by(1)
end
describe 'when removing a bookmark' do
before do
PostAction.act(@post.user, @post, PostActionType.Types[:bookmark])
PostAction.act(@post.user, @post, PostActionType.types[:bookmark])
end
it 'reduces the bookmark count of the post' do
active = PostAction.where(deleted_at: nil)
lambda {
PostAction.remove_act(@post.user, @post, PostActionType.Types[:bookmark])
PostAction.remove_act(@post.user, @post, PostActionType.types[:bookmark])
}.should change(active, :count).by(-1)
end
end
@ -224,11 +224,11 @@ describe User do
end
describe "trust levels" do
let(:user) { Fabricate(:user, trust_level: TrustLevel.Levels[:new]) }
let(:user) { Fabricate(:user, trust_level: TrustLevel.levels[:new]) }
it "sets to the default trust level setting" do
SiteSetting.expects(:default_trust_level).returns(TrustLevel.Levels[:advanced])
User.new.trust_level.should == TrustLevel.Levels[:advanced]
SiteSetting.expects(:default_trust_level).returns(TrustLevel.levels[:advanced])
User.new.trust_level.should == TrustLevel.levels[:advanced]
end
describe 'has_trust_level?' do
@ -246,12 +246,12 @@ describe User do
end
it "is true if you exceed the level" do
user.trust_level = TrustLevel.Levels[:advanced]
user.trust_level = TrustLevel.levels[:advanced]
user.has_trust_level?(:basic).should be_true
end
it "is true for an admin even with a low trust level" do
user.trust_level = TrustLevel.Levels[:new]
user.trust_level = TrustLevel.levels[:new]
user.admin = true
user.has_trust_level?(:advanced).should be_true
end
@ -264,7 +264,7 @@ describe User do
end
it "is a moderator if the user level is moderator" do
user.trust_level = TrustLevel.Levels[:moderator]
user.trust_level = TrustLevel.levels[:moderator]
user.has_trust_level?(:moderator).should be_true
end