Skip to content

Commit

Permalink
Add Rails/HttpUrl cop to enforce passing a string literal as a URL …
Browse files Browse the repository at this point in the history
…to http method calls

For the test cases; to make the actual URL obvious and to facilitate tracking endpoint path changes.

Original discussion: rubocop/rails-style-guide#328

Signed-off-by: moznion <[email protected]>
  • Loading branch information
moznion committed Aug 22, 2024
1 parent 75be327 commit 7b71247
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,14 @@ Rails/HttpStatus:
- numeric
- symbolic

Rails/HttpUrl:
Description: 'Enforces passing a string literal as a URL to http method calls.'
Enabled: true
VersionAdded: '2.26'
Include:
- 'spec/**/*'
- 'test/**/*'

Rails/I18nLazyLookup:
Description: 'Checks for places where I18n "lazy" lookup can be used.'
StyleGuide: 'https://rails.rubystyle.guide/#lazy-lookup'
Expand Down
34 changes: 34 additions & 0 deletions lib/rubocop/cop/rails/http_url.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Rails
# Enforces passing a string literal as a URL to http method calls.
#
# @example
# # bad
# get photos_path
# put photo_path(id)
# post edit_photo_path(id)
#
# # good
# get "/photos"
# put "/photos/#{id}"
# post "/photos/#{id}/edit"
class HttpUrl < Base
MSG = 'The first argument to `%<method>s` should be a string.'
RESTRICT_ON_SEND = %i[get post put patch delete head].freeze

def_node_matcher :request_method?, <<-PATTERN
(send nil? {#{RESTRICT_ON_SEND.map(&:inspect).join(' ')}} $!str ...)
PATTERN

def on_send(node)
request_method?(node) do |arg|
add_offense(arg, message: format(MSG, method: node.method_name))
end
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails_cops.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
require_relative 'rails/has_many_or_has_one_dependent'
require_relative 'rails/helper_instance_variable'
require_relative 'rails/http_positional_arguments'
require_relative 'rails/http_url'
require_relative 'rails/http_status'
require_relative 'rails/i18n_lazy_lookup'
require_relative 'rails/i18n_locale_assignment'
Expand Down
19 changes: 19 additions & 0 deletions spec/rubocop/cop/rails/http_url_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Rails::HttpUrl, :config do
%i[get post put delete patch head].each do |http_method|
it "registers an offense when first argument to `#{http_method}` is not a string" do
padding = " #{' ' * http_method.length}"
expect_offense(<<~RUBY, http_method: http_method)
#{http_method} :resource
#{padding}^^^^^^^^^ The first argument to `#{http_method}` should be a string.
RUBY
end

it "does not register an offense when the first argument to #{http_method} is a string" do
expect_no_offenses(<<~RUBY)
#{http_method} '/resource'
RUBY
end
end
end

0 comments on commit 7b71247

Please sign in to comment.