Skip to content

Commit c5158ba

Browse files
committed
Handle unknown HTTP status codes for RSpecRails::HttpStatus cop
1 parent 41a3bd4 commit c5158ba

File tree

3 files changed

+66
-9
lines changed

3 files changed

+66
-9
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Master (Unreleased)
44

5+
- Fix invalid autocorrection for `RSpecRails/HttpStatus` cop when unexpected object is passed. ([@viralpraxis])
6+
57
## 2.30.0 (2024-06-12)
68

79
- Fix an runtime error for rubocop-rspec +3.0. ([@bquorning])
@@ -81,4 +83,5 @@
8183
[@r7kamura]: https://github.com/r7kamura
8284
[@splattael]: https://github.com/splattael
8385
[@tmaier]: https://github.com/tmaier
86+
[@viralpraxis]: https://github.com/viralpraxis
8487
[@ydah]: https://github.com/ydah

lib/rubocop/cop/rspec_rails/http_status.rb

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class HttpStatus < ::RuboCop::Cop::Base
6767
(send nil? :have_http_status ${int sym str})
6868
PATTERN
6969

70-
def on_send(node)
70+
def on_send(node) # rubocop:disable Metrics/MethodLength
7171
return unless defined?(::Rack::Utils::SYMBOL_TO_STATUS_CODE)
7272

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

7979
add_offense(checker.offense_range,
8080
message: checker.message) do |corrector|
81+
next unless checker.autocorrectable?
82+
8183
corrector.replace(checker.offense_range, checker.prefer)
8284
end
8385
end
@@ -100,6 +102,7 @@ def checker_class
100102
class StyleCheckerBase
101103
MSG = 'Prefer `%<prefer>s` over `%<current>s` ' \
102104
'to describe HTTP status code.'
105+
MSG_UNKNOWN_STATUS_CODE = 'Unknown status code.'
103106
ALLOWED_STATUSES = %i[error success missing redirect].freeze
104107

105108
attr_reader :node
@@ -109,7 +112,15 @@ def initialize(node)
109112
end
110113

111114
def message
112-
format(MSG, prefer: prefer, current: current)
115+
if autocorrectable?
116+
format(MSG, prefer: prefer, current: current)
117+
else
118+
MSG_UNKNOWN_STATUS_CODE
119+
end
120+
end
121+
122+
def autocorrectable?
123+
true
113124
end
114125

115126
def current
@@ -136,6 +147,10 @@ def offensive?
136147
!node.sym_type? && !custom_http_status_code?
137148
end
138149

150+
def autocorrectable?
151+
!!symbol
152+
end
153+
139154
def prefer
140155
symbol.inspect
141156
end
@@ -157,6 +172,10 @@ def offensive?
157172
!node.int_type? && !allowed_symbol?
158173
end
159174

175+
def autocorrectable?
176+
!!number
177+
end
178+
160179
def prefer
161180
number.to_s
162181
end
@@ -179,22 +198,30 @@ def offensive?
179198
(!node.int_type? && !allowed_symbol?)
180199
end
181200

201+
def autocorrectable?
202+
!!status_code
203+
end
204+
182205
def offense_range
183206
node.parent
184207
end
185208

186209
def prefer
210+
"be_#{status_code}"
211+
end
212+
213+
private
214+
215+
def status_code
187216
if node.sym_type?
188-
"be_#{node.value}"
217+
node.value
189218
elsif node.int_type?
190-
"be_#{symbol}"
191-
elsif node.str_type?
192-
"be_#{normalize_str}"
219+
symbol
220+
else
221+
normalize_str
193222
end
194223
end
195224

196-
private
197-
198225
def symbol
199226
::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(number)
200227
end
@@ -207,7 +234,7 @@ def normalize_str
207234
str = node.value.to_s
208235
if str.match?(/\A\d+\z/)
209236
::Rack::Utils::SYMBOL_TO_STATUS_CODE.key(str.to_i)
210-
else
237+
elsif ::Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(str.to_sym)
211238
str
212239
end
213240
end

spec/rubocop/cop/rspec_rails/http_status_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@
8080
RUBY
8181
end
8282
end
83+
84+
it 'registers an offense for unknown status code' do
85+
expect_offense(<<~RUBY)
86+
it { is_expected.to have_http_status("some-custom-string") }
87+
^^^^^^^^^^^^^^^^^^^^ Unknown status code.
88+
RUBY
89+
90+
expect_no_corrections
91+
end
8392
end
8493

8594
context 'when EnforcedStyle is `numeric`' do
@@ -133,6 +142,15 @@
133142
RUBY
134143
end
135144

145+
it 'registers an offense for unknown status code' do
146+
expect_offense(<<~RUBY)
147+
it { is_expected.to have_http_status("some-custom-string") }
148+
^^^^^^^^^^^^^^^^^^^^ Unknown status code.
149+
RUBY
150+
151+
expect_no_corrections
152+
end
153+
136154
context 'with parenthesis' do
137155
it 'registers an offense when using symbolic value' do
138156
expect_offense(<<~RUBY)
@@ -237,6 +255,15 @@
237255
RUBY
238256
end
239257

258+
it 'registers an offense for unknown status code' do
259+
expect_offense(<<~RUBY)
260+
it { is_expected.to have_http_status("some-custom-string") }
261+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unknown status code.
262+
RUBY
263+
264+
expect_no_corrections
265+
end
266+
240267
context 'with parenthesis' do
241268
it 'registers an offense when using numeric value' do
242269
expect_offense(<<~RUBY)

0 commit comments

Comments
 (0)