summaryrefslogtreecommitdiff
path: root/rubocop
diff options
context:
space:
mode:
Diffstat (limited to 'rubocop')
-rw-r--r--rubocop/cop/redirect_with_status.rb44
-rw-r--r--rubocop/rubocop.rb1
2 files changed, 45 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
diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb
index 17d2bf6aa1c..22815090508 100644
--- a/rubocop/rubocop.rb
+++ b/rubocop/rubocop.rb
@@ -1,6 +1,7 @@
require_relative 'cop/custom_error_class'
require_relative 'cop/gem_fetcher'
require_relative 'cop/activerecord_serialize'
+require_relative 'cop/redirect_with_status'
require_relative 'cop/migration/add_column'
require_relative 'cop/migration/add_column_with_default_to_large_table'
require_relative 'cop/migration/add_concurrent_foreign_key'