keep track of post approvals to prevent approval cycles
This commit is contained in:
@@ -15,6 +15,7 @@ class DailyMaintenance
|
|||||||
TagAlias.update_cached_post_counts_for_all
|
TagAlias.update_cached_post_counts_for_all
|
||||||
PostDisapproval.dmail_messages!
|
PostDisapproval.dmail_messages!
|
||||||
Tag.clean_up_negative_post_counts!
|
Tag.clean_up_negative_post_counts!
|
||||||
|
PostApproval.prune!
|
||||||
SuperVoter.init!
|
SuperVoter.init!
|
||||||
AntiVoter.init!
|
AntiVoter.init!
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ class Post < ActiveRecord::Base
|
|||||||
|
|
||||||
module ApprovalMethods
|
module ApprovalMethods
|
||||||
def is_approvable?
|
def is_approvable?
|
||||||
!is_status_locked? && (is_pending? || is_flagged? || is_deleted?) && approver_id != CurrentUser.id
|
!is_status_locked? && (is_pending? || is_flagged? || is_deleted?) && !PostApproval.approved?(CurrentUser.id, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def flag!(reason, options = {})
|
def flag!(reason, options = {})
|
||||||
@@ -314,7 +314,7 @@ class Post < ActiveRecord::Base
|
|||||||
raise ApprovalError.new("You cannot approve a post you uploaded")
|
raise ApprovalError.new("You cannot approve a post you uploaded")
|
||||||
end
|
end
|
||||||
|
|
||||||
if approver_id == CurrentUser.id
|
if approver_id == CurrentUser.id || PostApproval.approved?(CurrentUser.id, id)
|
||||||
errors.add(:approver, "have already approved this post")
|
errors.add(:approver, "have already approved this post")
|
||||||
raise ApprovalError.new("You have previously approved this post and cannot approve it again")
|
raise ApprovalError.new("You have previously approved this post and cannot approve it again")
|
||||||
end
|
end
|
||||||
@@ -324,6 +324,9 @@ class Post < ActiveRecord::Base
|
|||||||
self.is_pending = false
|
self.is_pending = false
|
||||||
self.is_deleted = false
|
self.is_deleted = false
|
||||||
self.approver_id = CurrentUser.id
|
self.approver_id = CurrentUser.id
|
||||||
|
|
||||||
|
PostApproval.create(user_id: CurrentUser.id, post_id: id)
|
||||||
|
|
||||||
save!
|
save!
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1362,7 +1365,7 @@ class Post < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
if !CurrentUser.is_admin?
|
if !CurrentUser.is_admin?
|
||||||
if approver_id == CurrentUser.id
|
if approver_id == CurrentUser.id || PostApproval.approved?(CurrentUser.id, id)
|
||||||
raise ApprovalError.new("You have previously approved this post and cannot undelete it")
|
raise ApprovalError.new("You have previously approved this post and cannot undelete it")
|
||||||
elsif uploader_id == CurrentUser.id
|
elsif uploader_id == CurrentUser.id
|
||||||
raise ApprovalError.new("You cannot undelete a post you uploaded")
|
raise ApprovalError.new("You cannot undelete a post you uploaded")
|
||||||
|
|||||||
12
app/models/post_approval.rb
Normal file
12
app/models/post_approval.rb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
class PostApproval < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :post
|
||||||
|
|
||||||
|
def self.prune!
|
||||||
|
where("created_at < ?", 1.month.ago).delete_all
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.approved?(user_id, post_id)
|
||||||
|
where(user_id: user_id, post_id: post_id).exists?
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -148,7 +148,9 @@
|
|||||||
<meta name="favorites" content="<%= @post.fav_string %>">
|
<meta name="favorites" content="<%= @post.fav_string %>">
|
||||||
<meta name="pools" content="<%= @post.pool_string %>">
|
<meta name="pools" content="<%= @post.pool_string %>">
|
||||||
<meta name="post-id" content="<%= @post.id %>">
|
<meta name="post-id" content="<%= @post.id %>">
|
||||||
<meta name="post-is-approvable" content="<%= @post.is_approvable? %>">
|
<% if CurrentUser.can_approve_posts? %>
|
||||||
|
<meta name="post-is-approvable" content="<%= @post.is_approvable? %>">
|
||||||
|
<% end %>
|
||||||
<meta name="post-is-deleted" content="<%= @post.is_deleted? %>">
|
<meta name="post-is-deleted" content="<%= @post.is_deleted? %>">
|
||||||
<meta name="post-is-flagged" content="<%= @post.is_flagged? %>">
|
<meta name="post-is-flagged" content="<%= @post.is_flagged? %>">
|
||||||
<meta name="config-large-width" content="<%= Danbooru.config.large_image_width %>">
|
<meta name="config-large-width" content="<%= Danbooru.config.large_image_width %>">
|
||||||
|
|||||||
12
db/migrate/20161101003139_create_post_approvals.rb
Normal file
12
db/migrate/20161101003139_create_post_approvals.rb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
class CreatePostApprovals < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :post_approvals do |t|
|
||||||
|
t.integer :user_id, null: false
|
||||||
|
t.integer :post_id, null: false
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :post_approvals, :user_id
|
||||||
|
add_index :post_approvals, :post_id
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2617,6 +2617,38 @@ CREATE SEQUENCE post_appeals_id_seq
|
|||||||
ALTER SEQUENCE post_appeals_id_seq OWNED BY post_appeals.id;
|
ALTER SEQUENCE post_appeals_id_seq OWNED BY post_appeals.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: post_approvals; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE post_approvals (
|
||||||
|
id integer NOT NULL,
|
||||||
|
user_id integer NOT NULL,
|
||||||
|
post_id integer NOT NULL,
|
||||||
|
created_at timestamp without time zone NOT NULL,
|
||||||
|
updated_at timestamp without time zone NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: post_approvals_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE post_approvals_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: post_approvals_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE post_approvals_id_seq OWNED BY post_approvals.id;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: post_disapprovals; Type: TABLE; Schema: public; Owner: -
|
-- Name: post_disapprovals; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -4307,6 +4339,13 @@ ALTER TABLE ONLY pools ALTER COLUMN id SET DEFAULT nextval('pools_id_seq'::regcl
|
|||||||
ALTER TABLE ONLY post_appeals ALTER COLUMN id SET DEFAULT nextval('post_appeals_id_seq'::regclass);
|
ALTER TABLE ONLY post_appeals ALTER COLUMN id SET DEFAULT nextval('post_appeals_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY post_approvals ALTER COLUMN id SET DEFAULT nextval('post_approvals_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -4712,6 +4751,14 @@ ALTER TABLE ONLY post_appeals
|
|||||||
ADD CONSTRAINT post_appeals_pkey PRIMARY KEY (id);
|
ADD CONSTRAINT post_appeals_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: post_approvals_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY post_approvals
|
||||||
|
ADD CONSTRAINT post_approvals_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: post_disapprovals_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: post_disapprovals_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -6768,6 +6815,20 @@ CREATE INDEX index_post_appeals_on_creator_ip_addr ON post_appeals USING btree (
|
|||||||
CREATE INDEX index_post_appeals_on_post_id ON post_appeals USING btree (post_id);
|
CREATE INDEX index_post_appeals_on_post_id ON post_appeals USING btree (post_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_post_approvals_on_post_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_post_approvals_on_post_id ON post_approvals USING btree (post_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_post_approvals_on_user_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_post_approvals_on_user_id ON post_approvals USING btree (user_id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_post_disapprovals_on_post_id; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_post_disapprovals_on_post_id; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -7459,3 +7520,5 @@ INSERT INTO schema_migrations (version) VALUES ('20161018221128');
|
|||||||
|
|
||||||
INSERT INTO schema_migrations (version) VALUES ('20161024220345');
|
INSERT INTO schema_migrations (version) VALUES ('20161024220345');
|
||||||
|
|
||||||
|
INSERT INTO schema_migrations (version) VALUES ('20161101003139');
|
||||||
|
|
||||||
|
|||||||
62
test/models/post_approval_test.rb
Normal file
62
test/models/post_approval_test.rb
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class PostApprovalTest < ActiveSupport::TestCase
|
||||||
|
context "a pending post" do
|
||||||
|
setup do
|
||||||
|
@user = FactoryGirl.create(:user)
|
||||||
|
CurrentUser.user = @user
|
||||||
|
CurrentUser.ip_addr = "127.0.0.1"
|
||||||
|
|
||||||
|
@post = FactoryGirl.create(:post, uploader_id: @user.id, is_pending: true)
|
||||||
|
|
||||||
|
@approver = FactoryGirl.create(:user)
|
||||||
|
@approver.can_approve_posts = true
|
||||||
|
@approver.save
|
||||||
|
CurrentUser.user = @approver
|
||||||
|
|
||||||
|
CurrentUser.stubs(:can_approve_posts?).returns(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
teardown do
|
||||||
|
CurrentUser.user = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
should "allow approval" do
|
||||||
|
assert_equal(false, PostApproval.approved?(@approver.id, @post.id))
|
||||||
|
end
|
||||||
|
|
||||||
|
context "That is approved" do
|
||||||
|
should "create a postapproval record" do
|
||||||
|
assert_difference("PostApproval.count") do
|
||||||
|
@post.approve!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "that is then flagged" do
|
||||||
|
setup do
|
||||||
|
@user2 = FactoryGirl.create(:user)
|
||||||
|
@user3 = FactoryGirl.create(:user)
|
||||||
|
@approver2 = FactoryGirl.create(:user)
|
||||||
|
@approver2.can_approve_posts = true
|
||||||
|
@approver2.save
|
||||||
|
end
|
||||||
|
|
||||||
|
should "prevent the first approver from approving again" do
|
||||||
|
@post.approve!
|
||||||
|
CurrentUser.user = @user2
|
||||||
|
@post.flag!("blah")
|
||||||
|
CurrentUser.user = @approver2
|
||||||
|
@post.approve!
|
||||||
|
assert_not_equal(@approver.id, @post.approver_id)
|
||||||
|
CurrentUser.user = @user3
|
||||||
|
@post.flag!("blah blah")
|
||||||
|
CurrentUser.user = @approver
|
||||||
|
|
||||||
|
assert_raises(Post::ApprovalError) do
|
||||||
|
@post.approve!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user