summaryrefslogtreecommitdiff
path: root/rubocop/cop/redirect_with_status.rb
diff options
context:
space:
mode:
Diffstat (limited to 'rubocop/cop/redirect_with_status.rb')
-rw-r--r--rubocop/cop/redirect_with_status.rb44
1 files changed, 44 insertions, 0 deletions
diff --git a/rubocop/cop/redirect_with_status.rb b/rubocop/cop/redirect_with_status.rb
new file mode 100644
index 00000000000..36810642c88
--- /dev/null
+++ b/rubocop/cop/redirect_with_status.rb
@@ -0,0 +1,44 @@
+module RuboCop
+ module Cop
+ # This cop prevents usage of 'redirect_to' in actions 'destroy' without specifying 'status'.
+ # See https://gitlab.com/gitlab-org/gitlab-ce/issues/31840
+ class RedirectWithStatus < RuboCop::Cop::Cop
+ MSG = 'Do not use "redirect_to" without "status" in "destroy" action'.freeze
+
+ def on_def(node)
+ return unless in_controller?(node)
+ return unless destroy?(node) || destroy_all?(node)
+
+ node.each_descendant(:send) do |def_node|
+ next unless redirect_to?(def_node)
+
+ methods = []
+
+ def_node.children.last.each_node(:pair) do |pair|
+ methods << pair.children.first.children.first
+ end
+
+ add_offense(def_node, :selector) unless methods.include?(:status)
+ end
+ end
+
+ private
+
+ def in_controller?(node)
+ node.location.expression.source_buffer.name.end_with?('_controller.rb')
+ end
+
+ def destroy?(node)
+ node.children.first == :destroy
+ end
+
+ def destroy_all?(node)
+ node.children.first == :destroy_all
+ end
+
+ def redirect_to?(node)
+ node.children[1] == :redirect_to
+ end
+ end
+ end
+end