Skip to content

Commit

Permalink
Add support for RSpec/HaveHttpStatus when using response.code.
Browse files Browse the repository at this point in the history
Fixes #1609
This PR adds support for `RSpec/HaveHttpStatus` when using `response.code`.
  • Loading branch information
ydah committed Apr 18, 2023
1 parent 80c7d96 commit cde8a69
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Add autocorrect support for `RSpec/ScatteredSetup`. ([@ydah])
- Fix a false negative for `RSpec/RedundantAround` when redundant numblock `around`. ([@ydah])
- Add support for shared example groups to `RSpec/EmptyLineAfterExampleGroup`. ([@pirj])
- Add support for `RSpec/HaveHttpStatus` when using `response.code`. ([@ydah])

## 2.19.0 (2023-03-06)

Expand Down
1 change: 1 addition & 0 deletions docs/modules/ROOT/pages/cops_rspec_rails.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Checks that tests use `have_http_status` instead of equality matchers.
----
# bad
expect(response.status).to be(200)
expect(response.code).to eq("200")
# good
expect(response).to have_http_status(200)
Expand Down
11 changes: 7 additions & 4 deletions lib/rubocop/cop/rspec/rails/have_http_status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module Rails
# @example
# # bad
# expect(response.status).to be(200)
# expect(response.code).to eq("200")
#
# # good
# expect(response).to have_http_status(200)
Expand All @@ -18,7 +19,7 @@ class HaveHttpStatus < ::RuboCop::Cop::Base

MSG =
'Prefer `expect(response).%<to>s have_http_status(%<status>i)` ' \
'over `expect(response.status).%<to>s %<match>s`.'
'over `%<bad_code>s`.'

RUNNERS = %i[to to_not not_to].to_set
RESTRICT_ON_SEND = RUNNERS
Expand All @@ -27,19 +28,21 @@ class HaveHttpStatus < ::RuboCop::Cop::Base
def_node_matcher :match_status, <<-PATTERN
(send
(send nil? :expect
$(send (send nil? :response) :status)
$(send (send nil? :response) {:status :code})
)
$RUNNERS
$(send nil? {:be :eq :eql :equal} (int $_))
$(send nil? {:be :eq :eql :equal} ({int str} $_))
)
PATTERN

def on_send(node)
match_status(node) do |response_status, to, match, status|
message = format(MSG, to: to, match: match.source, status: status)
message = format(MSG, to: to, status: status,
bad_code: node.source)
add_offense(node, message: message) do |corrector|
corrector.replace(response_status, 'response')
corrector.replace(match.loc.selector, 'have_http_status')
corrector.replace(match.first_argument, status.to_i.to_s)
end
end
end
Expand Down
11 changes: 11 additions & 0 deletions spec/rubocop/cop/rspec/rails/have_http_status_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@
RUBY
end

it 'registers an offense for `expect(response.code).to eq("200")`' do
expect_offense(<<~RUBY)
it { expect(response.code).to eq("200") }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Prefer `expect(response).to have_http_status(200)` over `expect(response.code).to eq("200")`.
RUBY

expect_correction(<<~RUBY)
it { expect(response).to have_http_status(200) }
RUBY
end

it 'does not register an offense for `is_expected.to be(200)`' do
expect_no_offenses(<<~RUBY)
it { is_expected.to be(200) }
Expand Down

0 comments on commit cde8a69

Please sign in to comment.