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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8239d7858cb48ea9f9d93ee9f84ad1619b85eba879b9d426ee6170013b8fa822
4
- data.tar.gz: b3543e852dd249fa2be8ee46d12a8742a2c9de750a1a77847a7a22cb4c47a98b
3
+ metadata.gz: e45880e05081ae8b62a4b1e1fb9778a5580b9b17fe839973f1046242222881e1
4
+ data.tar.gz: 4212f8e0f60a70d61db53a2f9af447248efc686d593af0145c715a5a831db683
5
5
  SHA512:
6
- metadata.gz: f2195af7a4f7c629cfee631d365854d507791fa5aa96fbdcbcbab0dadb6e0d70f13c6908fd5949ba3be565527098a37112cdc55dc8dd1b1b13664c3f489d9298
7
- data.tar.gz: 5cda689379c9b1ba9d5508120b0a6479a73f06f158273ef67b0039e64f7c56a2199f23658204b3c873f2623b99f2d54580cf930e51002a84addc8767805134d6
6
+ metadata.gz: be0a7163ee430bcc93333c227cdbe56180864dbac0f128e0e70fc526a2a82b202d36f8e54fad30d8bdf33c66fc668c9ad207ddc29d1f6eaeea97b35f4a676070
7
+ data.tar.gz: a4aefcc523eb8c4c63ce31d851e4a47461288a6ee152e9a53572258135778098e55e7b470d1058f2dbd283d4d9c45abcd714717327db5ee1d6114d4f0bfd8d91
@@ -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
+ ```
@@ -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'
@@ -21,7 +21,7 @@ module RuboCop
21
21
  def evaluate_node(node)
22
22
  return unless should_use_allowlist?(node) || should_use_blocklist?(node)
23
23
 
24
- add_offense(node, message: MSG)
24
+ add_offense(node)
25
25
  end
26
26
 
27
27
  def should_use_allowlist?(node)
@@ -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.type == :send
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.type == :hash
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.type == :class
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.type == :class
146
+ return [] unless node.children && node.class_type?
147
147
 
148
148
  node.descendants.select do |descendant|
149
- descendant.type == :def
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.type == :def || method.type == :send
161
+ return [] unless method.def_type? || method.send_type?
162
162
 
163
- method.descendants.each do |child|
164
- next unless child.type == :send
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.type == :array && find_dynamic_param(arg.values) || !arg.literal? && !arg.const_type?
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, message: MSG)
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, message: MSG)
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
@@ -21,7 +21,7 @@ module RuboCop
21
21
  PATTERN
22
22
 
23
23
  def on_send(node)
24
- add_offense(node, message: MSG) if requires_spec_helper?(node) && !spec_directory?
24
+ add_offense(node) if requires_spec_helper?(node) && !spec_directory?
25
25
  end
26
26
 
27
27
  private
@@ -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, message: MSG) if find_param_arg(arg_nodes)
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.type == :hash
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.17.0
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-08-13 00:00:00.000000000 Z
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: []