rubocop-betterment 1.17.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|