diff --git a/app/controllers/post_disapprovals_controller.rb b/app/controllers/post_disapprovals_controller.rb
index 2ac4440c1..f4d9cb803 100644
--- a/app/controllers/post_disapprovals_controller.rb
+++ b/app/controllers/post_disapprovals_controller.rb
@@ -17,4 +17,17 @@ class PostDisapprovalsController < ApplicationController
respond_with(@post_disapprovals)
end
+
+ def edit
+ @post_disapproval = authorize PostDisapproval.find(params[:id])
+ respond_with(@post_disapproval)
+ end
+
+ def update
+ @post_disapproval = authorize PostDisapproval.find(params[:id])
+ @post_disapproval.update(permitted_attributes(@post_disapproval))
+ respond_with(@post_disapproval) do |fmt|
+ fmt.html { redirect_to post_path(@post_disapproval.post) }
+ end
+ end
end
diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
index a92b85ca3..9cfc623e0 100644
--- a/app/controllers/posts_controller.rb
+++ b/app/controllers/posts_controller.rb
@@ -38,6 +38,10 @@ class PostsController < ApplicationController
@child_posts = @post.children
@child_posts = @child_posts.undeleted unless include_deleted
@sibling_posts = @sibling_posts.includes(:media_asset)
+
+ if CurrentUser.user.is_approver?
+ @previous_disapproval = @post.disapprovals.select { |disapproval| disapproval.user_id == CurrentUser.user.id }.first
+ end
end
respond_with(@post) do |format|
diff --git a/app/models/post.rb b/app/models/post.rb
index 9f981b194..f7ef04b0c 100644
--- a/app/models/post.rb
+++ b/app/models/post.rb
@@ -267,10 +267,6 @@ class Post < ApplicationRecord
!is_active? && uploader != user
end
- def disapproved_by?(user)
- PostDisapproval.exists?(user_id: user.id, post_id: id)
- end
-
def autoban
if has_tag?("banned_artist") || has_tag?("paid_reward")
self.is_banned = true
diff --git a/app/policies/post_disapproval_policy.rb b/app/policies/post_disapproval_policy.rb
index 49fa56916..a8b1ef27c 100644
--- a/app/policies/post_disapproval_policy.rb
+++ b/app/policies/post_disapproval_policy.rb
@@ -9,10 +9,22 @@ class PostDisapprovalPolicy < ApplicationPolicy
user.is_moderator? || record.user_id == user.id
end
- def permitted_attributes
+ def permitted_attributes_for_create
[:post_id, :reason, :message]
end
+ def permitted_attributes_for_update
+ [:reason, :message]
+ end
+
+ def edit?
+ update?
+ end
+
+ def update?
+ unbanned? && record.post.in_modqueue? && record.user_id == user.id
+ end
+
def api_attributes
attributes = super
attributes -= [:user_id] unless can_view_creator?
diff --git a/app/views/modqueue/_quick_mod.html.erb b/app/views/modqueue/_quick_mod.html.erb
index 916763dee..38565e315 100644
--- a/app/views/modqueue/_quick_mod.html.erb
+++ b/app/views/modqueue/_quick_mod.html.erb
@@ -1,7 +1,13 @@
<%= link_to_if post.is_approvable?, "Approve", post_approvals_path(post_id: post.id), method: :post, remote: true, class: "approve-link btn" %> |
- <%= link_to "Breaks Rules", post_disapprovals_path(post_disapproval: { post_id: post.id, reason: "breaks_rules" }), method: :post, remote: true, class: "disapprove-link btn" %> |
- <%= link_to "Poor Quality", post_disapprovals_path(post_disapproval: { post_id: post.id, reason: "poor_quality" }), method: :post, remote: true, class: "disapprove-link btn" %> |
- <%= link_to "No Interest", post_disapprovals_path(post_disapproval: { post_id: post.id, reason: "disinterest" }), method: :post, remote: true, class: "disapprove-link btn" %> |
+ <% PostDisapproval::REASONS.each do |reason| %>
+ <% if @previous_disapproval&.reason == reason %>
+ <%= reason.humanize %> |
+ <% elsif @previous_disapproval %>
+ <%= link_to reason.humanize, post_disapproval_path(@previous_disapproval, post_disapproval: { reason: reason }), method: :put, remote: true, class: "disapprove-link disapprove-link-#{reason.gsub("_", "-")} btn" %> |
+ <% else %>
+ <%= link_to reason.humanize, post_disapprovals_path(post_disapproval: { post_id: post.id, reason: reason }), method: :post, remote: true, class: "disapprove-link disapprove-link-#{reason.gsub("_", "-")} btn" %> |
+ <% end %>
+ <% end %>
<%= link_to "Detailed Rejection", "#", "data-post-id" => post.id, class: "detailed-rejection-link btn" %>
diff --git a/app/views/post_disapprovals/_detailed_rejection_dialog.html.erb b/app/views/post_disapprovals/_detailed_rejection_dialog.html.erb
index a72e1e5ed..758050af4 100644
--- a/app/views/post_disapprovals/_detailed_rejection_dialog.html.erb
+++ b/app/views/post_disapprovals/_detailed_rejection_dialog.html.erb
@@ -1,9 +1,16 @@
You can supply a short message to the uploader explaining why you rejected this upload.
- <%= edit_form_for(PostDisapproval.new, url: post_disapprovals_path, remote: true, html: { id: "detailed-rejection-form" }) do |f| %>
- <%= f.hidden_field :post_id, value: "x" %>
- <%= f.input :reason, collection: PostDisapproval::REASONS.map { |x| [x.humanize, x] } %>
- <%= f.input :message, as: :string %>
+ <% if @previous_disapproval %>
+ <%= edit_form_for(@previous_disapproval, remote: true, html: { id: "detailed-rejection-form" }) do |f| %>
+ <%= f.input :reason, collection: PostDisapproval::REASONS.map { |x| [x.humanize, x] }, :selected => @previous_disapproval.reason %>
+ <%= f.input :message, as: :string, :input_html => {:value => @previous_disapproval.message } %>
+ <% end %>
+ <% else %>
+ <%= edit_form_for(PostDisapproval.new, remote: true, html: { id: "detailed-rejection-form" }) do |f| %>
+ <%= f.hidden_field :post_id, value: "x" %>
+ <%= f.input :reason, collection: PostDisapproval::REASONS.map { |x| [x.humanize, x] } %>
+ <%= f.input :message, as: :string %>
+ <% end %>
<% end %>
diff --git a/app/views/post_disapprovals/update.js.erb b/app/views/post_disapprovals/update.js.erb
new file mode 100644
index 000000000..345366b9b
--- /dev/null
+++ b/app/views/post_disapprovals/update.js.erb
@@ -0,0 +1 @@
+location.reload();
diff --git a/app/views/posts/partials/show/_notices.html.erb b/app/views/posts/partials/show/_notices.html.erb
index f47540bed..21d664722 100644
--- a/app/views/posts/partials/show/_notices.html.erb
+++ b/app/views/posts/partials/show/_notices.html.erb
@@ -18,7 +18,7 @@
<%= render "post_disapprovals/counts", disapprovals: post.disapprovals.order(id: :asc), post: post %>
- <% if policy(PostDisapproval).create? && !post.disapproved_by?(CurrentUser.user) %>
+ <% if CurrentUser.user.is_approver? %>
<%= render "modqueue/quick_mod", post: post %>
<%= render "post_disapprovals/detailed_rejection_dialog" %>
<% end %>
diff --git a/app/views/posts/partials/show/_options.html.erb b/app/views/posts/partials/show/_options.html.erb
index a9f3c3347..cc066e73d 100644
--- a/app/views/posts/partials/show/_options.html.erb
+++ b/app/views/posts/partials/show/_options.html.erb
@@ -51,11 +51,6 @@
<% end %>
<% if policy(PostApproval).create? %>
- <% if post.is_approvable? %>
- <%= 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?" %>
- <%= link_to "Hide from queue", post_disapprovals_path(post_disapproval: { post_id: post.id, reason: "disinterest" }), remote: true, method: :post %>
- <% end %>
-
<% if post.is_deleted? && policy(post).move_favorites? %>
<%= link_to "Move favorites", confirm_move_favorites_moderator_post_post_path(post_id: post.id) %>
<% end %>
diff --git a/config/routes.rb b/config/routes.rb
index 665c09cfa..ca9b90873 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -214,7 +214,7 @@ Rails.application.routes.draw do
resources :post_appeals
resources :post_flags
resources :post_approvals, only: [:create, :index]
- resources :post_disapprovals, only: [:create, :show, :index]
+ resources :post_disapprovals
resources :post_versions, :only => [:index, :search] do
member do
put :undo
diff --git a/test/functional/post_disapprovals_controller_test.rb b/test/functional/post_disapprovals_controller_test.rb
index ec5f05841..7ae7a9cf1 100644
--- a/test/functional/post_disapprovals_controller_test.rb
+++ b/test/functional/post_disapprovals_controller_test.rb
@@ -85,5 +85,28 @@ class PostDisapprovalsControllerTest < ActionDispatch::IntegrationTest
should respond_to_search(user_name: "eiki").with { @user_disapproval }
end
end
+
+ context "update action" do
+ setup do
+ @post = create(:post, is_pending: true)
+ @approver = create(:approver, name: "alice-san")
+ @another_approver = create(:approver, name: "bob-kun")
+ @post_disapproval = create(:post_disapproval, post: @post, user: @approver, reason: "poor_quality")
+ end
+
+ should "allow editing of disapprovals" do
+ put_auth post_disapproval_path(@post_disapproval), @approver, params: {post_disapproval: {reason: "breaks_rules"}}
+
+ assert_redirected_to(@post)
+ assert_equal("breaks_rules", @post_disapproval.reload.reason)
+ end
+
+ should "not allow editing by another user" do
+ put_auth post_disapproval_path(@post_disapproval), @another_approver, params: {post_disapproval: {reason: "disinterest"}}
+
+ assert_response 403
+ assert_equal("poor_quality", @post_disapproval.reload.reason)
+ end
+ end
end
end