resque 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of resque might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5993f1eacb5b40caa0c88229f31a68b92065e85a5c06c75aa90efece81578cd
4
- data.tar.gz: e69e5e519f05e01ab93769bc74904b86bea2365c9299f9420c9cc233e34b0867
3
+ metadata.gz: 0153ab38ce4b063a60d22d1a0629e590baa6658e514fd369394982e6ce2ad2cd
4
+ data.tar.gz: a86e978107b5ca99bc97df0a6a6ec718e64f4dcfe3816d7fab08885ebb49b070
5
5
  SHA512:
6
- metadata.gz: f25f2bf8b605425708f1b3c3815d3073adcdd4decf16a2914af761017d6a02a5a2c231caae7647abd7820be033040845d68a9a24e7993609fb6516c55bbdf58e
7
- data.tar.gz: 0c7003a64a94af3293d2cc271420534b35b9bf31738eb3110fb3d777c424e51ef5ce2300bb932d4263875aa1e79c7e13ce0d758815aebe09b421cb7e1f954b3e
6
+ metadata.gz: 93877c6bb80781a7d8d53c2697ea8c87bcddf2fc38addc49f6f05e7d3ab1a243a23de7c4bd29c0f14b575535a62f721313f8968150bf863af852237d15715cee
7
+ data.tar.gz: 7483844c869aaee817b2dd064e1b9dd3c7f7ab451ee2a8b73dfbb45f14e7b70de3981ac75a6290b526728797513557523ee015c644875ba5d4a6fc23f261e097
data/HISTORY.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 2.5.0
2
+
3
+ ### Fixed
4
+
5
+ * Replace `File.exists?` with `File.exist?` (#1846)
6
+ * Escape `Resque.redis_id` for stats page (#1834)
7
+ * Escape resque info values (#1832)
8
+ * Correctly show the values of hash and none type on stats tab (#1838)
9
+ * Fix logging the worker name when starting the task (#1837)
10
+
11
+ ### Added
12
+
13
+ * Raise an error when no available Rack server was found (#1836)
14
+ * Move code in `Resque::Server.helpers` block into a module to make it testable (#1851)
15
+
1
16
  ## 2.4.0
2
17
 
3
18
  ### Fixed
@@ -38,7 +38,7 @@
38
38
 
39
39
  <div id="footer">
40
40
  <p>Powered by <a href="http://github.com/resque/resque">Resque</a> v<%=Resque::VERSION%></p>
41
- <p>Connected to Redis namespace <%= Resque.redis.namespace %> on <%=Resque.redis_id%></p>
41
+ <p>Connected to Redis namespace <%= Resque.redis.namespace %> on <%= h Resque.redis_id %></p>
42
42
  </div>
43
43
 
44
44
  </body>
@@ -6,7 +6,7 @@
6
6
 
7
7
  <% elsif params[:id] == "resque" %>
8
8
 
9
- <h1><%= resque %></h1>
9
+ <h1><%= h resque %></h1>
10
10
  <table class='stats'>
11
11
  <% for key, value in resque.info.to_a.sort_by { |i| i[0].to_s } %>
12
12
  <tr>
@@ -14,7 +14,7 @@
14
14
  <%= key %>
15
15
  </th>
16
16
  <td>
17
- <%= value %>
17
+ <%= h value %>
18
18
  </td>
19
19
  </tr>
20
20
  <% end %>
@@ -22,7 +22,7 @@
22
22
 
23
23
  <% elsif params[:id] == 'redis' %>
24
24
 
25
- <h1><%= resque.redis_id %></h1>
25
+ <h1><%= h resque.redis_id %></h1>
26
26
  <table class='stats'>
27
27
  <% for key, value in resque.redis.redis.info.to_a.sort_by { |i| i[0].to_s } %>
28
28
  <tr>
@@ -38,7 +38,7 @@
38
38
 
39
39
  <% elsif params[:id] == 'keys' %>
40
40
 
41
- <h1>Keys owned by <%= resque %></h1>
41
+ <h1>Keys owned by <%= h resque.redis_id %></h1>
42
42
  <p class='sub'>(All keys are actually prefixed with "<%= Resque.redis.namespace %>:")</p>
43
43
  <table class='stats'>
44
44
  <tr>
data/lib/resque/server.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'sinatra/base'
2
2
  require 'tilt/erb'
3
3
  require 'resque'
4
+ require 'resque/server_helper'
4
5
  require 'resque/version'
5
6
  require 'time'
6
7
  require 'yaml'
@@ -11,8 +12,6 @@ end
11
12
 
12
13
  module Resque
13
14
  class Server < Sinatra::Base
14
- require 'resque/server/helpers'
15
-
16
15
  dir = File.dirname(File.expand_path(__FILE__))
17
16
 
18
17
  set :views, "#{dir}/server/views"
@@ -26,117 +25,7 @@ module Resque
26
25
  set :static, true
27
26
 
28
27
  helpers do
29
- include Rack::Utils
30
- alias_method :h, :escape_html
31
-
32
- def current_section
33
- url_path request.path_info.sub('/','').split('/')[0].downcase
34
- end
35
-
36
- def current_page
37
- url_path request.path_info.sub('/','')
38
- end
39
-
40
- def url_path(*path_parts)
41
- [ url_prefix, path_prefix, path_parts ].join("/").squeeze('/')
42
- end
43
- alias_method :u, :url_path
44
-
45
- def path_prefix
46
- request.env['SCRIPT_NAME']
47
- end
48
-
49
- def class_if_current(path = '')
50
- 'class="current"' if current_page[0, path.size] == path
51
- end
52
-
53
- def tab(name)
54
- dname = name.to_s.downcase
55
- path = url_path(dname)
56
- "<li #{class_if_current(path)}><a href='#{path.gsub(" ", "_")}'>#{name}</a></li>"
57
- end
58
-
59
- def tabs
60
- Resque::Server.tabs
61
- end
62
-
63
- def url_prefix
64
- Resque::Server.url_prefix
65
- end
66
-
67
- def redis_get_size(key)
68
- case Resque.redis.type(key)
69
- when 'none'
70
- []
71
- when 'list'
72
- Resque.redis.llen(key)
73
- when 'set'
74
- Resque.redis.scard(key)
75
- when 'string'
76
- Resque.redis.get(key).length
77
- when 'zset'
78
- Resque.redis.zcard(key)
79
- end
80
- end
81
-
82
- def redis_get_value_as_array(key, start=0)
83
- case Resque.redis.type(key)
84
- when 'none'
85
- []
86
- when 'list'
87
- Resque.redis.lrange(key, start, start + 20)
88
- when 'set'
89
- Resque.redis.smembers(key)[start..(start + 20)]
90
- when 'string'
91
- [Resque.redis.get(key)]
92
- when 'zset'
93
- Resque.redis.zrange(key, start, start + 20)
94
- end
95
- end
96
-
97
- def show_args(args)
98
- Array(args).map do |a|
99
- a.to_yaml
100
- end.join("\n")
101
- rescue
102
- args.to_s
103
- end
104
-
105
- def worker_hosts
106
- @worker_hosts ||= worker_hosts!
107
- end
108
-
109
- def worker_hosts!
110
- hosts = Hash.new { [] }
111
-
112
- Resque.workers.each do |worker|
113
- host, _ = worker.to_s.split(':')
114
- hosts[host] += [worker.to_s]
115
- end
116
-
117
- hosts
118
- end
119
-
120
- def partial?
121
- @partial
122
- end
123
-
124
- def partial(template, local_vars = {})
125
- @partial = true
126
- erb(template.to_sym, {:layout => false}, local_vars)
127
- ensure
128
- @partial = false
129
- end
130
-
131
- def poll
132
- if defined?(@polling) && @polling
133
- text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
134
- else
135
- text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll</a>"
136
- end
137
- "<p class='poll'>#{text}</p>"
138
- end
139
-
28
+ include Resque::ServerHelper
140
29
  end
141
30
 
142
31
  def show(page, layout = true)
@@ -0,0 +1,185 @@
1
+ require 'rack/utils'
2
+
3
+ module Resque
4
+ module ServerHelper
5
+ include Rack::Utils
6
+ alias_method :h, :escape_html
7
+
8
+ def current_section
9
+ url_path request.path_info.sub('/','').split('/')[0].downcase
10
+ end
11
+
12
+ def current_page
13
+ url_path request.path_info.sub('/','')
14
+ end
15
+
16
+ def url_path(*path_parts)
17
+ [ url_prefix, path_prefix, path_parts ].join("/").squeeze('/')
18
+ end
19
+ alias_method :u, :url_path
20
+
21
+ def path_prefix
22
+ request.env['SCRIPT_NAME']
23
+ end
24
+
25
+ def class_if_current(path = '')
26
+ 'class="current"' if current_page[0, path.size] == path
27
+ end
28
+
29
+ def tab(name)
30
+ dname = name.to_s.downcase
31
+ path = url_path(dname)
32
+ "<li #{class_if_current(path)}><a href='#{path.gsub(" ", "_")}'>#{name}</a></li>"
33
+ end
34
+
35
+ def tabs
36
+ Resque::Server.tabs
37
+ end
38
+
39
+ def url_prefix
40
+ Resque::Server.url_prefix
41
+ end
42
+
43
+ def redis_get_size(key)
44
+ case Resque.redis.type(key)
45
+ when 'none'
46
+ 0
47
+ when 'hash'
48
+ Resque.redis.hlen(key)
49
+ when 'list'
50
+ Resque.redis.llen(key)
51
+ when 'set'
52
+ Resque.redis.scard(key)
53
+ when 'string'
54
+ Resque.redis.get(key).length
55
+ when 'zset'
56
+ Resque.redis.zcard(key)
57
+ end
58
+ end
59
+
60
+ def redis_get_value_as_array(key, start=0)
61
+ case Resque.redis.type(key)
62
+ when 'none'
63
+ []
64
+ when 'hash'
65
+ Resque.redis.hgetall(key).to_a[start..(start + 20)]
66
+ when 'list'
67
+ Resque.redis.lrange(key, start, start + 20)
68
+ when 'set'
69
+ Resque.redis.smembers(key)[start..(start + 20)]
70
+ when 'string'
71
+ [Resque.redis.get(key)]
72
+ when 'zset'
73
+ Resque.redis.zrange(key, start, start + 20)
74
+ end
75
+ end
76
+
77
+ def show_args(args)
78
+ Array(args).map do |a|
79
+ a.to_yaml
80
+ end.join("\n")
81
+ rescue
82
+ args.to_s
83
+ end
84
+
85
+ def worker_hosts
86
+ @worker_hosts ||= worker_hosts!
87
+ end
88
+
89
+ def worker_hosts!
90
+ hosts = Hash.new { [] }
91
+
92
+ Resque.workers.each do |worker|
93
+ host, _ = worker.to_s.split(':')
94
+ hosts[host] += [worker.to_s]
95
+ end
96
+
97
+ hosts
98
+ end
99
+
100
+ def partial?
101
+ @partial
102
+ end
103
+
104
+ def partial(template, local_vars = {})
105
+ @partial = true
106
+ erb(template.to_sym, {:layout => false}, local_vars)
107
+ ensure
108
+ @partial = false
109
+ end
110
+
111
+ def poll
112
+ if defined?(@polling) && @polling
113
+ text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
114
+ else
115
+ text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll!!</a>"
116
+ end
117
+ "<p class='poll'>#{text}</p>"
118
+ end
119
+
120
+ ####################
121
+ #failed.erb helpers#
122
+ ####################
123
+
124
+ def failed_date_format
125
+ "%Y/%m/%d %T %z"
126
+ end
127
+
128
+ def failed_multiple_queues?
129
+ return @multiple_failed_queues if defined?(@multiple_failed_queues)
130
+
131
+ @multiple_failed_queues = Resque::Failure.queues.size > 1 ||
132
+ (defined?(Resque::Failure::RedisMultiQueue) && Resque::Failure.backend == Resque::Failure::RedisMultiQueue)
133
+ end
134
+
135
+ def failed_size
136
+ @failed_size ||= Resque::Failure.count(params[:queue], params[:class])
137
+ end
138
+
139
+ def failed_per_page
140
+ @failed_per_page = if params[:class]
141
+ failed_size
142
+ else
143
+ 20
144
+ end
145
+ end
146
+
147
+ def failed_start_at
148
+ params[:start].to_i
149
+ end
150
+
151
+ def failed_end_at
152
+ if failed_start_at + failed_per_page > failed_size
153
+ failed_size
154
+ else
155
+ failed_start_at + failed_per_page - 1
156
+ end
157
+ end
158
+
159
+ def failed_order
160
+ params[:order] || 'desc'
161
+ end
162
+
163
+ def failed_class_counts(queue = params[:queue])
164
+ classes = Hash.new(0)
165
+ Resque::Failure.each(0, Resque::Failure.count(queue), queue) do |_, item|
166
+ class_name = item['payload']['class'] if item['payload']
167
+ class_name ||= "nil"
168
+ classes[class_name] += 1
169
+ end
170
+ classes
171
+ end
172
+
173
+ def page_entries_info(start, stop, size, name = nil)
174
+ if size == 0
175
+ name ? "No #{name}s" : '<b>0</b>'
176
+ elsif size == 1
177
+ 'Showing <b>1</b>' + (name ? " #{name}" : '')
178
+ elsif size > failed_per_page
179
+ "Showing #{start}-#{stop} of <b>#{size}</b>" + (name ? " #{name}s" : '')
180
+ else
181
+ "Showing #{start} to <b>#{size - 1}</b>" + (name ? " #{name}s" : '')
182
+ end
183
+ end
184
+ end
185
+ end
data/lib/resque/tasks.rb CHANGED
@@ -16,7 +16,7 @@ namespace :resque do
16
16
  end
17
17
 
18
18
  worker.prepare
19
- worker.log "Starting worker #{self}"
19
+ worker.log "Starting worker #{worker}"
20
20
  worker.work(ENV['INTERVAL'] || 5) # interval, will block
21
21
  end
22
22
 
@@ -1,3 +1,3 @@
1
1
  module Resque
2
- VERSION = '2.4.0'
2
+ VERSION = '2.5.0'
3
3
  end
@@ -234,10 +234,10 @@ module Resque
234
234
  end
235
235
 
236
236
  def status
237
- if File.exists?(pid_file)
237
+ if File.exist?(pid_file)
238
238
  logger.info "'#{app_name}' running"
239
239
  logger.info "PID #{File.read(pid_file)}"
240
- logger.info "URL #{File.read(url_file)}" if File.exists?(url_file)
240
+ logger.info "URL #{File.read(url_file)}" if File.exist?(url_file)
241
241
  else
242
242
  logger.info "'#{app_name}' not running!"
243
243
  end
@@ -290,6 +290,8 @@ module Resque
290
290
  next
291
291
  end
292
292
  end
293
+ raise 'No available Rack handler (e.g. WEBrick, Thin, Puma, etc.) was found.' if handler.nil?
294
+
293
295
  handler
294
296
 
295
297
  # :server might be set explicitly to a single option like "mongrel"
data/lib/tasks/redis.rake CHANGED
@@ -17,7 +17,7 @@ class RedisRunner
17
17
  end
18
18
 
19
19
  def self.config
20
- @config ||= if File.exists?(redis_dir + 'etc/redis.conf')
20
+ @config ||= if File.exist?(redis_dir + 'etc/redis.conf')
21
21
  redis_dir + 'etc/redis.conf'
22
22
  else
23
23
  redis_dir + '../etc/redis.conf'
@@ -30,7 +30,7 @@ class RedisRunner
30
30
 
31
31
  # Just check for existance of dtach socket
32
32
  def self.running?
33
- File.exists? dtach_socket
33
+ File.exist? dtach_socket
34
34
  end
35
35
 
36
36
  def self.start
@@ -90,10 +90,10 @@ namespace :redis do
90
90
 
91
91
  if ENV['PREFIX']
92
92
  bin_dir = "#{ENV['PREFIX']}/bin"
93
- sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
93
+ sh "mkdir -p #{bin_dir}" unless File.exist?("#{bin_dir}")
94
94
 
95
95
  conf_dir = "#{ENV['PREFIX']}/etc"
96
- sh "mkdir -p #{conf_dir}" unless File.exists?("#{conf_dir}")
96
+ sh "mkdir -p #{conf_dir}" unless File.exist?("#{conf_dir}")
97
97
  end
98
98
 
99
99
  %w(redis-benchmark redis-cli redis-server).each do |bin|
@@ -102,7 +102,7 @@ namespace :redis do
102
102
 
103
103
  puts "Installed redis-benchmark, redis-cli and redis-server to #{bin_dir}"
104
104
 
105
- unless File.exists?("#{conf_dir}/redis.conf")
105
+ unless File.exist?("#{conf_dir}/redis.conf")
106
106
  sh "cp #{INSTALL_DIR}/redis.conf #{conf_dir}/redis.conf"
107
107
  puts "Installed redis.conf to #{conf_dir} \n You should look at this file!"
108
108
  end
@@ -115,9 +115,9 @@ namespace :redis do
115
115
 
116
116
  desc "Download package"
117
117
  task :download do
118
- sh "rm -rf #{INSTALL_DIR}/" if File.exists?("#{INSTALL_DIR}/.svn")
119
- sh "git clone git://github.com/antirez/redis.git #{INSTALL_DIR}" unless File.exists?(INSTALL_DIR)
120
- sh "cd #{INSTALL_DIR} && git pull" if File.exists?("#{INSTALL_DIR}/.git")
118
+ sh "rm -rf #{INSTALL_DIR}/" if File.exist?("#{INSTALL_DIR}/.svn")
119
+ sh "git clone git://github.com/antirez/redis.git #{INSTALL_DIR}" unless File.exist?(INSTALL_DIR)
120
+ sh "cd #{INSTALL_DIR} && git pull" if File.exist?("#{INSTALL_DIR}/.git")
121
121
  end
122
122
  end
123
123
 
@@ -135,7 +135,7 @@ namespace :dtach do
135
135
 
136
136
  if ENV['PREFIX']
137
137
  bin_dir = "#{ENV['PREFIX']}/bin"
138
- sh "mkdir -p #{bin_dir}" unless File.exists?("#{bin_dir}")
138
+ sh "mkdir -p #{bin_dir}" unless File.exist?("#{bin_dir}")
139
139
  end
140
140
 
141
141
  sh "cp #{INSTALL_DIR}/dtach-0.8/dtach #{bin_dir}"
@@ -147,7 +147,7 @@ namespace :dtach do
147
147
 
148
148
  desc "Download package"
149
149
  task :download do
150
- unless File.exists?("#{INSTALL_DIR}/dtach-0.8.tar.gz")
150
+ unless File.exist?("#{INSTALL_DIR}/dtach-0.8.tar.gz")
151
151
  require 'net/http'
152
152
 
153
153
  url = 'http://downloads.sourceforge.net/project/dtach/dtach/0.8/dtach-0.8.tar.gz'
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wanstrath
8
8
  - Steve Klabnik
9
9
  - Terence Lee
10
10
  - Michael Bianco
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-09-06 00:00:00.000000000 Z
14
+ date: 2023-03-01 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: redis-namespace
@@ -145,7 +145,6 @@ files:
145
145
  - lib/resque/plugin.rb
146
146
  - lib/resque/railtie.rb
147
147
  - lib/resque/server.rb
148
- - lib/resque/server/helpers.rb
149
148
  - lib/resque/server/public/favicon.ico
150
149
  - lib/resque/server/public/idle.png
151
150
  - lib/resque/server/public/jquery-3.6.0.min.js
@@ -156,7 +155,6 @@ files:
156
155
  - lib/resque/server/public/reset.css
157
156
  - lib/resque/server/public/style.css
158
157
  - lib/resque/server/public/working.png
159
- - lib/resque/server/test_helper.rb
160
158
  - lib/resque/server/views/error.erb
161
159
  - lib/resque/server/views/failed.erb
162
160
  - lib/resque/server/views/failed_job.erb
@@ -172,6 +170,7 @@ files:
172
170
  - lib/resque/server/views/stats.erb
173
171
  - lib/resque/server/views/workers.erb
174
172
  - lib/resque/server/views/working.erb
173
+ - lib/resque/server_helper.rb
175
174
  - lib/resque/stat.rb
176
175
  - lib/resque/tasks.rb
177
176
  - lib/resque/thread_signal.rb
@@ -187,7 +186,7 @@ licenses:
187
186
  metadata:
188
187
  changelog_uri: https://github.com/resque/resque/blob/master/HISTORY.md
189
188
  rubygems_mfa_required: 'true'
190
- post_install_message:
189
+ post_install_message:
191
190
  rdoc_options:
192
191
  - "--charset=UTF-8"
193
192
  require_paths:
@@ -203,8 +202,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
202
  - !ruby/object:Gem::Version
204
203
  version: '0'
205
204
  requirements: []
206
- rubygems_version: 3.3.5
207
- signing_key:
205
+ rubygems_version: 3.4.1
206
+ signing_key:
208
207
  specification_version: 4
209
208
  summary: Resque is a Redis-backed queueing system.
210
209
  test_files: []
@@ -1,66 +0,0 @@
1
- Resque::Server.helpers do
2
- ####################
3
- #failed.erb helpers#
4
- ####################
5
-
6
- def failed_date_format
7
- "%Y/%m/%d %T %z"
8
- end
9
-
10
- def failed_multiple_queues?
11
- return @multiple_failed_queues if defined?(@multiple_failed_queues)
12
-
13
- @multiple_failed_queues = Resque::Failure.queues.size > 1 ||
14
- (defined?(Resque::Failure::RedisMultiQueue) && Resque::Failure.backend == Resque::Failure::RedisMultiQueue)
15
- end
16
-
17
- def failed_size
18
- @failed_size ||= Resque::Failure.count(params[:queue], params[:class])
19
- end
20
-
21
- def failed_per_page
22
- @failed_per_page = if params[:class]
23
- failed_size
24
- else
25
- 20
26
- end
27
- end
28
-
29
- def failed_start_at
30
- params[:start].to_i
31
- end
32
-
33
- def failed_end_at
34
- if failed_start_at + failed_per_page > failed_size
35
- failed_size
36
- else
37
- failed_start_at + failed_per_page - 1
38
- end
39
- end
40
-
41
- def failed_order
42
- params[:order] || 'desc'
43
- end
44
-
45
- def failed_class_counts(queue = params[:queue])
46
- classes = Hash.new(0)
47
- Resque::Failure.each(0, Resque::Failure.count(queue), queue) do |_, item|
48
- class_name = item['payload']['class'] if item['payload']
49
- class_name ||= "nil"
50
- classes[class_name] += 1
51
- end
52
- classes
53
- end
54
-
55
- def page_entries_info(start, stop, size, name = nil)
56
- if size == 0
57
- name ? "No #{name}s" : '<b>0</b>'
58
- elsif size == 1
59
- 'Showing <b>1</b>' + (name ? " #{name}" : '')
60
- elsif size > failed_per_page
61
- "Showing #{start}-#{stop} of <b>#{size}</b>" + (name ? " #{name}s" : '')
62
- else
63
- "Showing #{start} to <b>#{size - 1}</b>" + (name ? " #{name}s" : '')
64
- end
65
- end
66
- end
@@ -1,19 +0,0 @@
1
- require 'rack/test'
2
- require 'resque/server'
3
-
4
- module Resque
5
- module TestHelper
6
- class Test::Unit::TestCase
7
- include Rack::Test::Methods
8
- def app
9
- Resque::Server.new
10
- end
11
-
12
- def self.should_respond_with_success
13
- test "should respond with success" do
14
- assert last_response.ok?, last_response.errors
15
- end
16
- end
17
- end
18
- end
19
- end