rubocop-betterment 1.17.0 → 1.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/STYLEGUIDE.md +22 -1
- data/config/default.yml +5 -0
- data/lib/rubocop/cop/betterment.rb +1 -0
- data/lib/rubocop/cop/betterment/allowlist_blocklist.rb +1 -1
- data/lib/rubocop/cop/betterment/authorization_in_controller.rb +8 -8
- data/lib/rubocop/cop/betterment/dynamic_params.rb +1 -1
- data/lib/rubocop/cop/betterment/implicit_redirect_type.rb +2 -2
- data/lib/rubocop/cop/betterment/server_error_assertion.rb +63 -0
- data/lib/rubocop/cop/betterment/spec_helper_required_outside_spec_dir.rb +1 -1
- data/lib/rubocop/cop/betterment/unscoped_find.rb +2 -2
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e45880e05081ae8b62a4b1e1fb9778a5580b9b17fe839973f1046242222881e1
|
4
|
+
data.tar.gz: 4212f8e0f60a70d61db53a2f9af447248efc686d593af0145c715a5a831db683
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: be0a7163ee430bcc93333c227cdbe56180864dbac0f128e0e70fc526a2a82b202d36f8e54fad30d8bdf33c66fc668c9ad207ddc29d1f6eaeea97b35f4a676070
|
7
|
+
data.tar.gz: a4aefcc523eb8c4c63ce31d851e4a47461288a6ee152e9a53572258135778098e55e7b470d1058f2dbd283d4d9c45abcd714717327db5ee1d6114d4f0bfd8d91
|
data/STYLEGUIDE.md
CHANGED
@@ -87,4 +87,25 @@ user1 = User.first
|
|
87
87
|
user2 = User.second
|
88
88
|
```
|
89
89
|
|
90
|
-
The snake case style is more readable.
|
90
|
+
The snake case style is more readable.
|
91
|
+
|
92
|
+
## Betterment/ServerErrorAssertion
|
93
|
+
|
94
|
+
In RSpec tests, we prevent HTTP response status assertions against server error codes (e.g., 500). While it’s acceptable to
|
95
|
+
“under-build” APIs under assumption of controlled and well-behaving clients, these exceptions should be treated as undefined behavior and
|
96
|
+
thus do not need request spec coverage. In cases where the server must communicate an expected failure to the client, an appropriate
|
97
|
+
semantic status code must be used (e.g., 403, 422, etc.).
|
98
|
+
|
99
|
+
### GOOD:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
expect(response).to have_http_status :forbidden
|
103
|
+
expect(response).to have_http_status 422
|
104
|
+
```
|
105
|
+
|
106
|
+
### BAD:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
expect(response).to have_http_status :internal_server_error
|
110
|
+
expect(response).to have_http_status 500
|
111
|
+
```
|
data/config/default.yml
CHANGED
@@ -17,6 +17,11 @@ AllCops:
|
|
17
17
|
DisplayStyleGuide: true
|
18
18
|
DisplayCopNames: true
|
19
19
|
|
20
|
+
Betterment/ServerErrorAssertion:
|
21
|
+
Description: 'Detects assertions on 5XX HTTP statuses.'
|
22
|
+
Include:
|
23
|
+
- 'spec/requests/**/*_spec.rb'
|
24
|
+
|
20
25
|
Betterment/AuthorizationInController:
|
21
26
|
Description: 'Detects unsafe handling of id-like parameters in controllers.'
|
22
27
|
Enabled: false
|
@@ -10,3 +10,4 @@ require 'rubocop/cop/betterment/spec_helper_required_outside_spec_dir'
|
|
10
10
|
require 'rubocop/cop/betterment/implicit_redirect_type'
|
11
11
|
require 'rubocop/cop/betterment/active_job_performable'
|
12
12
|
require 'rubocop/cop/betterment/allowlist_blocklist'
|
13
|
+
require 'rubocop/cop/betterment/server_error_assertion'
|
@@ -51,12 +51,12 @@ module RuboCop
|
|
51
51
|
return if !model_new?(node) && !model_update?(node)
|
52
52
|
|
53
53
|
arg_nodes.each do |argument|
|
54
|
-
if argument.
|
54
|
+
if argument.send_type?
|
55
55
|
tag_unsafe_param_hash(argument)
|
56
56
|
tag_unsafe_param_permit_wrapper(argument)
|
57
57
|
elsif argument.variable?
|
58
58
|
tag_unsafe_param_permit_wrapper(argument)
|
59
|
-
elsif argument.
|
59
|
+
elsif argument.hash_type?
|
60
60
|
argument.children.each do |pair|
|
61
61
|
next if pair.type != :pair
|
62
62
|
|
@@ -130,7 +130,7 @@ module RuboCop
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def get_all_assignments(node)
|
133
|
-
return [] unless node.children && node.
|
133
|
+
return [] unless node.children && node.class_type?
|
134
134
|
|
135
135
|
node.descendants.select do |descendant|
|
136
136
|
_lhs, rhs = *descendant
|
@@ -143,10 +143,10 @@ module RuboCop
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def get_all_methods(node)
|
146
|
-
return [] unless node.children && node.
|
146
|
+
return [] unless node.children && node.class_type?
|
147
147
|
|
148
148
|
node.descendants.select do |descendant|
|
149
|
-
descendant.
|
149
|
+
descendant.def_type?
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
@@ -158,10 +158,10 @@ module RuboCop
|
|
158
158
|
wrappers = []
|
159
159
|
|
160
160
|
methods.each do |method|
|
161
|
-
return [] unless method.
|
161
|
+
return [] unless method.def_type? || method.send_type?
|
162
162
|
|
163
|
-
method.descendants.each
|
164
|
-
next unless child.
|
163
|
+
method.descendants.each do |child|
|
164
|
+
next unless child.send_type?
|
165
165
|
next unless param_symbol?(child.method_name)
|
166
166
|
|
167
167
|
child.ancestors.each do |ancestor|
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
27
27
|
return unless arg_nodes
|
28
28
|
|
29
29
|
arg_nodes.find do |arg|
|
30
|
-
arg.
|
30
|
+
arg.array_type? && find_dynamic_param(arg.values) || !arg.literal? && !arg.const_type?
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
return unless routes_file?
|
48
48
|
|
49
49
|
if block_form_with_options(node) { |options| options.none?(&method(:valid_status_option?)) } || block_form_without_options?(node)
|
50
|
-
add_offense(node
|
50
|
+
add_offense(node)
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -55,7 +55,7 @@ module RuboCop
|
|
55
55
|
return unless routes_file?
|
56
56
|
|
57
57
|
if arg_form_with_options(node) { |options| options.none?(&method(:valid_status_option?)) } || arg_form_without_options?(node)
|
58
|
-
add_offense(node
|
58
|
+
add_offense(node)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Betterment
|
6
|
+
# Checks the status passed to have_http_status
|
7
|
+
#
|
8
|
+
# If a number, enforces that it doesn't start with 5. If a symbol or a string, enforces that it's not one of:
|
9
|
+
#
|
10
|
+
# * internal_server_error
|
11
|
+
# * not_implemented
|
12
|
+
# * bad_gateway
|
13
|
+
# * service_unavailable
|
14
|
+
# * gateway_timeout
|
15
|
+
# * http_version_not_supported
|
16
|
+
# * insufficient_storage
|
17
|
+
# * not_extended
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# expect(response).to have_http_status :internal_server_error
|
23
|
+
#
|
24
|
+
# # bad
|
25
|
+
# expect(response).to have_http_status 500
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# expect(response).to have_http_status :forbidden
|
29
|
+
#
|
30
|
+
# # good
|
31
|
+
# expect(response).to have_http_status 422
|
32
|
+
class ServerErrorAssertion < Cop
|
33
|
+
MSG = 'Do not assert on 5XX statuses. Use a semantic status (e.g., 403, 422, etc.) or treat them as bugs (omit tests).'
|
34
|
+
BAD_STATUSES = %i(
|
35
|
+
internal_server_error
|
36
|
+
not_implemented
|
37
|
+
bad_gateway
|
38
|
+
service_unavailable
|
39
|
+
gateway_timeout
|
40
|
+
http_version_not_supported
|
41
|
+
insufficient_storage
|
42
|
+
not_extended
|
43
|
+
).freeze
|
44
|
+
|
45
|
+
def_node_matcher :offensive_node?, <<-PATTERN
|
46
|
+
(send nil? :have_http_status
|
47
|
+
{
|
48
|
+
(int {#{(500..599).map(&:to_s).join(' ')}})
|
49
|
+
(str {#{BAD_STATUSES.map(&:to_s).map(&:inspect).join(' ')}})
|
50
|
+
(sym {#{BAD_STATUSES.map(&:inspect).join(' ')}})
|
51
|
+
}
|
52
|
+
)
|
53
|
+
PATTERN
|
54
|
+
|
55
|
+
def on_send(node)
|
56
|
+
return unless offensive_node?(node)
|
57
|
+
|
58
|
+
add_offense(node)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -43,7 +43,7 @@ module RuboCop
|
|
43
43
|
static_method_name(node.method_name)
|
44
44
|
) && !@unauthenticated_models.include?(Utils::Parser.get_root_token(node))
|
45
45
|
|
46
|
-
add_offense(node
|
46
|
+
add_offense(node) if find_param_arg(arg_nodes)
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
52
52
|
return unless arg_nodes
|
53
53
|
|
54
54
|
arg_nodes.find do |arg|
|
55
|
-
if arg.
|
55
|
+
if arg.hash_type?
|
56
56
|
arg.children.each do |pair|
|
57
57
|
_key, value = *pair.children
|
58
58
|
return arg if Utils::Parser.get_root_token(value) == :params
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-betterment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Development
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubocop
|
@@ -97,16 +97,17 @@ files:
|
|
97
97
|
- lib/rubocop/cop/betterment/dynamic_params.rb
|
98
98
|
- lib/rubocop/cop/betterment/implicit_redirect_type.rb
|
99
99
|
- lib/rubocop/cop/betterment/memoization_with_arguments.rb
|
100
|
+
- lib/rubocop/cop/betterment/server_error_assertion.rb
|
100
101
|
- lib/rubocop/cop/betterment/site_prism_loaded.rb
|
101
102
|
- lib/rubocop/cop/betterment/spec_helper_required_outside_spec_dir.rb
|
102
103
|
- lib/rubocop/cop/betterment/timeout.rb
|
103
104
|
- lib/rubocop/cop/betterment/unscoped_find.rb
|
104
105
|
- lib/rubocop/cop/betterment/utils/parser.rb
|
105
|
-
homepage:
|
106
|
+
homepage:
|
106
107
|
licenses:
|
107
108
|
- MIT
|
108
109
|
metadata: {}
|
109
|
-
post_install_message:
|
110
|
+
post_install_message:
|
110
111
|
rdoc_options: []
|
111
112
|
require_paths:
|
112
113
|
- lib
|
@@ -122,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
123
|
version: '0'
|
123
124
|
requirements: []
|
124
125
|
rubygems_version: 3.1.4
|
125
|
-
signing_key:
|
126
|
+
signing_key:
|
126
127
|
specification_version: 4
|
127
128
|
summary: Betterment rubocop configuration
|
128
129
|
test_files: []
|