posts: remove rating, note, and status locks.

Remove the ability for users to lock ratings, note, and post statuses.

Historically the majority of locked posts were from 10+ years ago when
certain users habitually locked ratings and notes on every post they
touched for no reason. Nowadays most posts have been unlocked. Only a
handful of locked posts are left, none of which deserve to be locked.

The is_rating_locked, is_note_locked, and is_status_locked columns still
exist in the database, but aren't used.
This commit is contained in:
evazion
2021-09-27 21:56:41 -05:00
parent 3e4492ce33
commit 126046cb69
13 changed files with 39 additions and 447 deletions

View File

@@ -162,8 +162,6 @@ class PostQueryBuilder
child_matches(value)
when "rating"
Post.where(rating: value.first.downcase)
when "locked"
locked_matches(value)
when "embedded"
embedded_matches(value)
when "source"
@@ -470,19 +468,6 @@ class PostQueryBuilder
end
end
def locked_matches(query)
case query.downcase
when "rating"
Post.where(is_rating_locked: true)
when "note", "notes"
Post.where(is_note_locked: true)
when "status"
Post.where(is_status_locked: true)
else
Post.none
end
end
def table_for_metatag(metatag)
if metatag.in?(COUNT_METATAGS)
metatag[/(?<table>[a-z]+)_count\z/i, :table]

View File

@@ -35,8 +35,6 @@ class ModAction < ApplicationRecord
post_note_lock_delete: 212,
post_rating_lock_create: 220,
post_rating_lock_delete: 222,
post_status_lock_create: 230,
post_status_lock_delete: 232,
pool_delete: 62,
pool_undelete: 63,
artist_ban: 184,

View File

@@ -13,7 +13,6 @@ class Note < ApplicationRecord
validate :note_within_image
after_save :update_post
after_save :create_version
validate :validate_post_is_not_locked
scope :active, -> { where(is_active: true) }
@@ -28,10 +27,6 @@ class Note < ApplicationRecord
extend SearchMethods
def validate_post_is_not_locked
errors.add(:post, "is note locked") if post.is_note_locked?
end
def note_within_image
return false unless post.present?
if x < 0 || y < 0 || (x > post.image_width) || (y > post.image_height) || width < 0 || height < 0 || (x + width > post.image_width) || (y + height > post.image_height)

View File

@@ -27,11 +27,9 @@ class Post < ApplicationRecord
validate :has_copyright_tag
validate :has_enough_tags
validate :post_is_not_its_own_parent
validate :updater_can_change_rating
validate :uploader_is_not_limited, on: :create
before_save :update_tag_post_counts
before_save :set_tag_counts
before_save :create_mod_action_for_lock_change
before_create :autoban
after_save :create_version
after_save :update_parent_on_save
@@ -255,7 +253,7 @@ class Post < ApplicationRecord
end
def is_approvable?(user = CurrentUser.user)
!is_status_locked? && !is_active? && uploader != user
!is_active? && uploader != user
end
def flag!(reason, is_deletion: false)
@@ -533,7 +531,7 @@ class Post < ApplicationRecord
end
def filter_metatags(tags)
@pre_metatags, tags = tags.partition {|x| x =~ /\A(?:rating|parent|-parent|-?locked):/i}
@pre_metatags, tags = tags.partition {|x| x =~ /\A(?:rating|parent|-parent):/i}
tags = apply_categorization_metatags(tags)
@post_metatags, tags = tags.partition {|x| x =~ /\A(?:-pool|pool|newpool|fav|-fav|child|-child|-favgroup|favgroup|upvote|downvote|status|-status|disapproved):/i}
apply_pre_metatags
@@ -653,15 +651,6 @@ class Post < ApplicationRecord
when /^rating:([qse])/i
self.rating = $1
when /^(-?)locked:notes?$/i
self.is_note_locked = ($1 != "-") if CurrentUser.is_builder?
when /^(-?)locked:rating$/i
self.is_rating_locked = ($1 != "-") if CurrentUser.is_builder?
when /^(-?)locked:status$/i
self.is_status_locked = ($1 != "-") if CurrentUser.is_admin?
end
end
end
@@ -912,11 +901,6 @@ class Post < ApplicationRecord
module DeletionMethods
def expunge!
if is_status_locked?
errors.add(:is_status_locked, "; cannot delete post")
return false
end
transaction do
Post.without_timeout do
ModAction.log("permanently deleted post ##{id} (md5=#{md5})", :post_permanent_delete)
@@ -1257,12 +1241,11 @@ class Post < ApplicationRecord
:id, :created_at, :updated_at, :rating, :source, :pixiv_id, :fav_count,
:score, :up_score, :down_score, :md5, :file_ext, :file_size, :image_width,
:image_height, :tag_count, :has_children, :has_active_children,
:is_note_locked, :is_rating_locked, :is_status_locked, :is_pending,
:is_flagged, :is_deleted, :is_banned, :last_comment_bumped_at,
:last_commented_at, :last_noted_at, :uploader_ip_addr,
:uploader, :approver, :parent, :upload, :artist_commentary,
:flags, :appeals, :notes, :comments, :children, :approvals,
:replacements, :pixiv_ugoira_frame_data
:is_pending, :is_flagged, :is_deleted, :is_banned,
:last_comment_bumped_at, :last_commented_at, :last_noted_at,
:uploader_ip_addr, :uploader, :approver, :parent, :upload,
:artist_commentary, :flags, :appeals, :notes, :comments, :children,
:approvals, :replacements, :pixiv_ugoira_frame_data
)
if params[:tags].present?
@@ -1354,13 +1337,6 @@ class Post < ApplicationRecord
end
end
def updater_can_change_rating
# Don't forbid changes if the rating lock was just now set in the same update.
if rating_changed? && is_rating_locked? && !is_rating_locked_changed?
errors.add(:rating, "is locked and cannot be changed. Unlock the post first.")
end
end
def uploader_is_not_limited
errors.add(:uploader, "have reached your upload limit") if uploader.upload_limit.limited?
end
@@ -1487,32 +1463,6 @@ class Post < ApplicationRecord
save
end
def create_mod_action_for_lock_change
if is_note_locked != is_note_locked_was
if is_note_locked
ModAction.log("locked notes for post ##{id}", :post_note_lock_create)
else
ModAction.log("unlocked notes for post ##{id}", :post_note_lock_delete)
end
end
if is_rating_locked != is_rating_locked_was
if is_rating_locked
ModAction.log("locked rating for post ##{id}", :post_rating_lock_create)
else
ModAction.log("unlocked rating for post ##{id}", :post_rating_lock_delete)
end
end
if is_status_locked != is_status_locked_was
if is_status_locked
ModAction.log("locked status for post ##{id}", :post_status_lock_create)
else
ModAction.log("unlocked status for post ##{id}", :post_status_lock_delete)
end
end
end
def self.model_restriction(table)
super.where(table[:is_pending].eq(false)).where(table[:is_flagged].eq(false)).where(table[:is_deleted].eq(false))
end

View File

@@ -31,7 +31,7 @@ class PostAppeal < ApplicationRecord
end
def validate_post_is_appealable
errors.add(:post, "cannot be appealed") if post.is_status_locked? || !post.is_appealable?
errors.add(:post, "cannot be appealed") if !post.is_appealable?
end
def self.available_includes

View File

@@ -8,10 +8,6 @@ class PostApproval < ApplicationRecord
def validate_approval
post.lock!
if post.is_status_locked?
errors.add(:post, "is locked and cannot be approved")
end
if post.is_active?
errors.add(:post, "is already active and cannot be approved")
end

View File

@@ -99,7 +99,6 @@ class PostFlag < ApplicationRecord
def validate_post
errors.add(:post, "is pending and cannot be flagged") if post.is_pending? && !is_deletion
errors.add(:post, "is deleted and cannot be flagged") if post.is_deleted? && !is_deletion
errors.add(:post, "is locked and cannot be flagged") if post.is_status_locked?
flag = post.flags.in_cooldown.last
if !is_deletion && flag.present?

View File

@@ -55,18 +55,6 @@ class PostPolicy < ApplicationPolicy
record.visible?(user)
end
def can_lock_rating?
user.is_builder?
end
def can_lock_notes?
user.is_builder?
end
def can_lock_status?
user.is_admin?
end
def can_use_mode_menu?
user.is_gold?
end
@@ -84,9 +72,6 @@ class PostPolicy < ApplicationPolicy
[
:tag_string, :old_tag_string, :parent_id, :old_parent_id,
:source, :old_source, :rating, :old_rating, :has_embedded_notes,
(:is_rating_locked if can_lock_rating?),
(:is_note_locked if can_lock_notes?),
(:is_status_locked if can_lock_status?),
].compact
end

View File

@@ -15,33 +15,13 @@
<%= f.input :old_source, as: :hidden, input_html: { value: post.source } %>
<%= f.input :old_rating, as: :hidden, input_html: { value: post.rating } %>
<% if post.is_rating_locked? %>
This post is rating locked.
<% else %>
<%= f.input :rating, collection: [["Explicit", "e"], ["Questionable", "q"], ["Safe", "s"]], as: :radio_buttons, boolean_style: :inline %>
<% end %>
<%= f.input :rating, collection: [["Explicit", "e"], ["Questionable", "q"], ["Safe", "s"]], as: :radio_buttons, boolean_style: :inline %>
<fieldset class="inline-fieldset post_has_embedded_notes_fieldset">
<label>Notes</label>
<%= f.input :has_embedded_notes, label: "Embed notes", as: :boolean, boolean_style: :inline, disabled: post.is_note_locked? %>
<%= f.input :has_embedded_notes, label: "Embed notes", as: :boolean, boolean_style: :inline %>
</fieldset>
<% if policy(post).can_lock_rating? || policy(post).can_lock_notes? || policy(post).can_lock_status? %>
<fieldset class="inline-fieldset post_lock_fieldset">
<label>Lock</label>
<% if policy(post).can_lock_rating? %>
<%= f.input :is_rating_locked, label: "Rating", as: :boolean, boolean_style: :inline %>
<% end %>
<% if policy(post).can_lock_notes? %>
<%= f.input :is_note_locked, label: "Notes", as: :boolean, boolean_style: :inline %>
<% end %>
<% if policy(post).can_lock_status? %>
<%= f.input :is_status_locked, label: "Status", as: :boolean, boolean_style: :inline %>
<% end %>
</fieldset>
<% end %>
<%= f.input :parent_id, label: "Parent", as: :string %>
<%= f.input :source %>

View File

@@ -33,11 +33,7 @@
<li id="post-option-edit"><%= link_to "Edit", "#edit", id: "side-edit-link" %></li>
<li id="post-option-add-to-pool"><%= link_to "Add to pool", "#", id: "pool" %></li>
<li id="post-option-add-note">
<% if post.is_note_locked? %>
<span id="note-locked-notice">Note locked</span>
<% else %>
<%= link_to "Add note", "#", id: "translate", "data-shortcut": "n" %>
<% end %>
<%= link_to "Add note", "#", id: "translate", "data-shortcut": "n" %>
</li>
<% if post.has_notes? %>
<li id="post-option-copy-notes"><%= link_to "Copy notes", "#", id: "copy-notes" %></li>
@@ -48,43 +44,39 @@
<li id="post-option-add-fav-group"><%= link_to "Add to fav group", "#", id: "open-favgroup-dialog-link", "data-shortcut": "g" %></li>
<% end %>
<% if post.is_status_locked? %>
<li id="post-option-status-locked">Status locked</li>
<% else %>
<% if post.is_active? && policy(PostFlag).create? %>
<li id="post-option-flag"><%= link_to "Flag", new_post_flag_path(post_flag: { post_id: post.id }), remote: true %></li>
<% elsif post.is_appealable? && policy(PostAppeal).create? %>
<li id="post-option-appeal"><%= link_to "Appeal", new_post_appeal_path(post_appeal: { post_id: post.id }), remote: true %></li>
<% if post.is_active? && policy(PostFlag).create? %>
<li id="post-option-flag"><%= link_to "Flag", new_post_flag_path(post_flag: { post_id: post.id }), remote: true %></li>
<% elsif post.is_appealable? && policy(PostAppeal).create? %>
<li id="post-option-appeal"><%= link_to "Appeal", new_post_appeal_path(post_appeal: { post_id: post.id }), remote: true %></li>
<% end %>
<% if policy(PostApproval).create? %>
<% if post.is_approvable? %>
<li id="post-option-approve"><%= link_to (post.is_deleted? ? "Undelete" : "Approve"), post_approvals_path(post_id: post.id), remote: true, method: :post, "data-shortcut": "shift+o", "data-confirm": "Are you sure you want to approve this post?" %></li>
<li id="post-option-disapprove"><%= link_to "Hide from queue", post_disapprovals_path(post_disapproval: { post_id: post.id, reason: "disinterest" }), remote: true, method: :post %></li>
<% end %>
<% if policy(PostApproval).create? %>
<% if post.is_approvable? %>
<li id="post-option-approve"><%= link_to (post.is_deleted? ? "Undelete" : "Approve"), post_approvals_path(post_id: post.id), remote: true, method: :post, "data-shortcut": "shift+o", "data-confirm": "Are you sure you want to approve this post?" %></li>
<li id="post-option-disapprove"><%= link_to "Hide from queue", post_disapprovals_path(post_disapproval: { post_id: post.id, reason: "disinterest" }), remote: true, method: :post %></li>
<% end %>
<% if post.is_deleted? && policy(post).move_favorites? %>
<li id="post-option-move-favorites"><%= link_to "Move favorites", confirm_move_favorites_moderator_post_post_path(post_id: post.id) %></li>
<% end %>
<% if !post.is_deleted? && policy(post).delete? %>
<li id="post-option-delete"><%= link_to "Delete", post, method: :delete, remote: true %></li>
<% end %>
<% if policy(post).unban? %>
<li id="post-option-unban"><%= link_to "Unban", unban_moderator_post_post_path(post), method: :post, "data-confirm": "Are you sure you want to unban this post?" %></li>
<% elsif policy(post).ban? %>
<li id="post-option-ban"><%= link_to "Ban", ban_moderator_post_post_path(post), method: :post, "data-confirm": "Are you sure you want to ban this post?" %></li>
<% end %>
<% if policy(post).expunge? %>
<li id="post-option-expunge"><%= link_to "Expunge", expunge_moderator_post_post_path(post_id: post.id), remote: true, method: :post, "data-confirm": "This will permanently delete this post (meaning the file will be deleted). Are you sure you want to delete this post?" %></li>
<% end %>
<% if post.is_deleted? && policy(post).move_favorites? %>
<li id="post-option-move-favorites"><%= link_to "Move favorites", confirm_move_favorites_moderator_post_post_path(post_id: post.id) %></li>
<% end %>
<% if policy(PostReplacement).create? %>
<li id="post-option-replace-image"><%= link_to "Replace image", new_post_replacement_path(post_id: post.id), remote: true %></li>
<% if !post.is_deleted? && policy(post).delete? %>
<li id="post-option-delete"><%= link_to "Delete", post, method: :delete, remote: true %></li>
<% end %>
<% if policy(post).unban? %>
<li id="post-option-unban"><%= link_to "Unban", unban_moderator_post_post_path(post), method: :post, "data-confirm": "Are you sure you want to unban this post?" %></li>
<% elsif policy(post).ban? %>
<li id="post-option-ban"><%= link_to "Ban", ban_moderator_post_post_path(post), method: :post, "data-confirm": "Are you sure you want to ban this post?" %></li>
<% end %>
<% if policy(post).expunge? %>
<li id="post-option-expunge"><%= link_to "Expunge", expunge_moderator_post_post_path(post_id: post.id), remote: true, method: :post, "data-confirm": "This will permanently delete this post (meaning the file will be deleted). Are you sure you want to delete this post?" %></li>
<% end %>
<% end %>
<% if policy(PostReplacement).create? %>
<li id="post-option-replace-image"><%= link_to "Replace image", new_post_replacement_path(post_id: post.id), remote: true %></li>
<% end %>
<% if policy(post).regenerate? %>

View File

@@ -86,20 +86,6 @@ class NoteTest < ActiveSupport::TestCase
@post.reload
assert_not_nil(@post.last_noted_at)
end
context "for a note-locked post" do
setup do
@post.update_attribute(:is_note_locked, true)
end
should "fail" do
assert_difference("Note.count", 0) do
@note = FactoryBot.build(:note, :post => @post)
@note.save
end
assert_equal(["Post is note locked"], @note.errors.full_messages)
end
end
end
context "updating a note" do
@@ -137,17 +123,6 @@ class NoteTest < ActiveSupport::TestCase
assert_equal(CurrentUser.ip_addr, @note.versions.last.updater_ip_addr.to_s)
end
context "for a note-locked post" do
setup do
@post.update_attribute(:is_note_locked, true)
end
should "fail" do
@note.update(x: 500)
assert_equal(["Post is note locked"], @note.errors.full_messages)
end
end
context "without making any changes" do
should "not create a new version" do
assert_no_difference("@note.versions.count") do

View File

@@ -836,28 +836,6 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match(all - [e], "-rating:e")
end
should "return posts for a locked:<rating|note|status> metatag" do
rating_locked = create(:post, is_rating_locked: true)
note_locked = create(:post, is_note_locked: true)
status_locked = create(:post, is_status_locked: true)
all = [status_locked, note_locked, rating_locked]
assert_tag_match([rating_locked], "locked:rating")
assert_tag_match([note_locked], "locked:note")
assert_tag_match([status_locked], "locked:status")
assert_tag_match(all - [rating_locked], "-locked:rating")
assert_tag_match(all - [note_locked], "-locked:note")
assert_tag_match(all - [status_locked], "-locked:status")
assert_tag_match([rating_locked], "locked:RATING")
assert_tag_match([status_locked], "-locked:rating -locked:note")
assert_tag_match([], "locked:rating locked:note")
assert_tag_match([], "locked:garbage")
assert_tag_match(all, "-locked:garbage")
end
should "return posts for a upvote:<user>, downvote:<user> metatag" do
CurrentUser.scoped(create(:mod_user)) do
upvoted = create(:post, tag_string: "upvote:self")

View File

@@ -91,17 +91,6 @@ class PostTest < ActiveSupport::TestCase
assert_performed_jobs(1, only: IqdbRemovePostJob)
end
context "that is status locked" do
setup do
@post.update(is_status_locked: true)
end
should "not destroy the record" do
@post.expunge!
assert_equal(1, Post.where("id = ?", @post.id).count)
end
end
context "that belongs to a pool" do
setup do
# must be a builder to update deleted pools. must be >1 week old to remove posts from pools.
@@ -136,20 +125,6 @@ class PostTest < ActiveSupport::TestCase
end
context "Deleting a post" do
context "that is status locked" do
setup do
@post = FactoryBot.create(:post, is_status_locked: true)
end
should "fail" do
assert_raise(ActiveRecord::RecordInvalid) do
@post.delete!("test")
end
assert_equal(false, @post.reload.is_deleted?)
end
end
context "that is pending" do
setup do
@post = FactoryBot.create(:post, is_pending: true)
@@ -375,18 +350,6 @@ class PostTest < ActiveSupport::TestCase
@post = FactoryBot.create(:post, :is_deleted => true)
end
context "that is status locked" do
setup do
@post.update(is_status_locked: true)
end
should "not allow undeletion" do
approval = @post.approve!
assert_equal(["Post is locked and cannot be approved"], approval.errors.full_messages)
assert_equal(true, @post.is_deleted?)
end
end
context "that is undeleted" do
setup do
@mod = FactoryBot.create(:moderator_user)
@@ -511,75 +474,6 @@ class PostTest < ActiveSupport::TestCase
end
end
end
context "A status locked post" do
should "not allow new flags" do
assert_raises(PostFlag::Error) do
@post = create(:post, is_status_locked: true)
@post.flag!("wrong")
end
end
should "not allow new appeals" do
@post = create(:post, is_status_locked: true, is_deleted: true)
@appeal = build(:post_appeal, post: @post)
assert_equal(false, @appeal.valid?)
assert_equal(["Post cannot be appealed"], @appeal.errors.full_messages)
end
should "not allow approval" do
@post = create(:post, is_status_locked: true, is_pending: true)
approval = @post.approve!
assert_includes(approval.errors.full_messages, "Post is locked and cannot be approved")
end
end
context "Locking post fields" do
should "create ModAction entries" do
@post = create(:post)
assert_difference("ModAction.post_note_lock_create.count", 1) do
@post.is_note_locked = true
@post.save!
end
assert_difference("ModAction.post_note_lock_delete.count", 1) do
@post.is_note_locked = false
@post.save!
end
assert_difference("ModAction.post_rating_lock_create.count", 1) do
@post.is_rating_locked = true
@post.save!
end
assert_difference("ModAction.post_rating_lock_delete.count", 1) do
@post.is_rating_locked = false
@post.save!
end
assert_difference("ModAction.post_status_lock_create.count", 1) do
@post.is_status_locked = true
@post.save!
end
assert_difference("ModAction.post_status_lock_delete.count", 1) do
@post.is_status_locked = false
@post.save!
end
assert_difference("ModAction.post_status_lock_create.count", 1) do
assert_difference("ModAction.post_rating_lock_create.count", 1) do
assert_difference("ModAction.post_note_lock_create.count", 1) do
@post.is_status_locked = true
@post.is_rating_locked = true
@post.is_note_locked = true
@post.save!
end
end
end
end
end
end
context "Tagging:" do
@@ -943,25 +837,6 @@ class PostTest < ActiveSupport::TestCase
assert_equal("q", @post.rating)
end
end
context "that is locked" do
should "change the rating if locked in the same update" do
@post.update(tag_string: "rating:e", is_rating_locked: true)
assert(@post.valid?)
assert_equal("e", @post.reload.rating)
end
should "not change the rating if locked previously" do
@post.is_rating_locked = true
@post.save
@post.update(:tag_string => "rating:e")
assert(@post.invalid?)
assert_not_equal("e", @post.reload.rating)
end
end
end
context "for a fav" do
@@ -1131,75 +1006,6 @@ class PostTest < ActiveSupport::TestCase
end
end
context "of" do
setup do
@builder = FactoryBot.create(:builder_user)
end
context "locked:notes" do
context "by a member" do
should "not lock the notes" do
@post.update(:tag_string => "locked:notes")
assert_equal(false, @post.is_note_locked)
end
end
context "by a builder" do
should "lock/unlock the notes" do
CurrentUser.scoped(@builder) do
@post.update(:tag_string => "locked:notes")
assert_equal(true, @post.is_note_locked)
@post.update(:tag_string => "-locked:notes")
assert_equal(false, @post.is_note_locked)
end
end
end
end
context "locked:rating" do
context "by a member" do
should "not lock the rating" do
@post.update(:tag_string => "locked:rating")
assert_equal(false, @post.is_rating_locked)
end
end
context "by a builder" do
should "lock/unlock the rating" do
CurrentUser.scoped(@builder) do
@post.update(:tag_string => "locked:rating")
assert_equal(true, @post.is_rating_locked)
@post.update(:tag_string => "-locked:rating")
assert_equal(false, @post.is_rating_locked)
end
end
end
end
context "locked:status" do
context "by a member" do
should "not lock the status" do
@post.update(:tag_string => "locked:status")
assert_equal(false, @post.is_status_locked)
end
end
context "by an admin" do
should "lock/unlock the status" do
CurrentUser.scoped(FactoryBot.create(:admin_user)) do
@post.update(:tag_string => "locked:status")
assert_equal(true, @post.is_status_locked)
@post.update(:tag_string => "-locked:status")
assert_equal(false, @post.is_status_locked)
end
end
end
end
end
context "of" do
setup do
@gold = FactoryBot.create(:gold_user)
@@ -1723,25 +1529,6 @@ class PostTest < ActiveSupport::TestCase
end
end
end
context "A rating locked post" do
setup { @post = FactoryBot.create(:post, :is_rating_locked => true) }
subject { @post }
should "not allow values S, safe, derp" do
["S", "safe", "derp"].each do |rating|
subject.rating = rating
assert(!subject.valid?)
end
end
should "not allow values s, e" do
["s", "e"].each do |rating|
subject.rating = rating
assert(!subject.valid?)
end
end
end
end
context "Favorites:" do
@@ -2004,34 +1791,6 @@ class PostTest < ActiveSupport::TestCase
end
context "Reverting: " do
context "a post that is rating locked" do
setup do
@post = FactoryBot.create(:post, :rating => "s")
travel(2.hours) do
@post.update(rating: "q", is_rating_locked: true)
end
end
should "not revert the rating" do
assert_raises ActiveRecord::RecordInvalid do
@post.revert_to!(@post.versions.first)
end
assert_equal(["Rating is locked and cannot be changed. Unlock the post first."], @post.errors.full_messages)
assert_equal(@post.versions.last.rating, @post.reload.rating)
end
should "revert the rating after unlocking" do
@post.update(rating: "e", is_rating_locked: false)
assert_nothing_raised do
@post.revert_to!(@post.versions.first)
end
assert(@post.valid?)
assert_equal(@post.versions.first.rating, @post.rating)
end
end
context "a post that has been updated" do
setup do
PostVersion.sqs_service.stubs(:merge?).returns(false)