Skip to content

Commit

Permalink
Handle unknown HTTP status codes for RSpecRails::HttpStatus cop
Browse files Browse the repository at this point in the history
  • Loading branch information
viralpraxis committed Oct 2, 2024
1 parent 41a3bd4 commit c5158ba
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Master (Unreleased)

- Fix invalid autocorrection for `RSpecRails/HttpStatus` cop when unexpected object is passed. ([@viralpraxis])

## 2.30.0 (2024-06-12)

- Fix an runtime error for rubocop-rspec +3.0. ([@bquorning])
Expand Down Expand Up @@ -81,4 +83,5 @@
[@r7kamura]: https://github.com/r7kamura
[@splattael]: https://github.com/splattael
[@tmaier]: https://github.com/tmaier
[@viralpraxis]: https://github.com/viralpraxis
[@ydah]: https://github.com/ydah
45 changes: 36 additions & 9 deletions lib/rubocop/cop/rspec_rails/http_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class HttpStatus < ::RuboCop::Cop::Base
(send nil? :have_http_status ${int sym str})
PATTERN

def on_send(node)
def on_send(node) # rubocop:disable Metrics/MethodLength
return unless defined?(::Rack::Utils::SYMBOL_TO_STATUS_CODE)

http_status(node) do |arg|
Expand All @@ -78,6 +78,8 @@ def on_send(node)

add_offense(checker.offense_range,
message: checker.message) do |corrector|
next unless checker.autocorrectable?

corrector.replace(checker.offense_range, checker.prefer)
end
end
Expand All @@ -100,6 +102,7 @@ def checker_class
class StyleCheckerBase
MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
'to describe HTTP status code.'
MSG_UNKNOWN_STATUS_CODE = 'Unknown status code.'
ALLOWED_STATUSES = %i[error success missing redirect].freeze

attr_reader :node
Expand All @@ -109,7 +112,15 @@ def initialize(node)
end

def message
format(MSG, prefer: prefer, current: current)
if autocorrectable?
format(MSG, prefer: prefer, current: current)
else
MSG_UNKNOWN_STATUS_CODE
end
end

def autocorrectable?
true
end

def current
Expand All @@ -136,6 +147,10 @@ def offensive?
!node.sym_type? && !custom_http_status_code?
end

def autocorrectable?
!!symbol
end

def prefer
symbol.inspect
end
Expand All @@ -157,6 +172,10 @@ def offensive?
!node.int_type? && !allowed_symbol?
end

def autocorrectable?
!!number
end

def prefer
number.to_s
end
Expand All @@ -179,22 +198,30 @@ def offensive?
(!node.int_type? && !allowed_symbol?)
end

def autocorrectable?
!!status_code
end

def offense_range
node.parent
end

def prefer
"be_#{status_code}"
end

private

def status_code
if node.sym_type?
"be_#{node.value}"
node.value
elsif node.int_type?
"be_#{symbol}"
elsif node.str_type?
"be_#{normalize_str}"
symbol
else
normalize_str
end
end

private

def symbol
::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
end
Expand All @@ -207,7 +234,7 @@ def normalize_str
str = node.value.to_s
if str.match?(/\A\d+\z/)
::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(str.to_i)
else
elsif ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(str.to_sym)
str
end
end
Expand Down
27 changes: 27 additions & 0 deletions spec/rubocop/cop/rspec_rails/http_status_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@
RUBY
end
end

it 'registers an offense for unknown status code' do
expect_offense(<<~RUBY)
it { is_expected.to have_http_status("some-custom-string") }
^^^^^^^^^^^^^^^^^^^^ Unknown status code.
RUBY

expect_no_corrections
end
end

context 'when EnforcedStyle is `numeric`' do
Expand Down Expand Up @@ -133,6 +142,15 @@
RUBY
end

it 'registers an offense for unknown status code' do
expect_offense(<<~RUBY)
it { is_expected.to have_http_status("some-custom-string") }
^^^^^^^^^^^^^^^^^^^^ Unknown status code.
RUBY

expect_no_corrections
end

context 'with parenthesis' do
it 'registers an offense when using symbolic value' do
expect_offense(<<~RUBY)
Expand Down Expand Up @@ -237,6 +255,15 @@
RUBY
end

it 'registers an offense for unknown status code' do
expect_offense(<<~RUBY)
it { is_expected.to have_http_status("some-custom-string") }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unknown status code.
RUBY

expect_no_corrections
end

context 'with parenthesis' do
it 'registers an offense when using numeric value' do
expect_offense(<<~RUBY)
Expand Down

0 comments on commit c5158ba

Please sign in to comment.