solid_queue_monitor 0.1.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 +7 -0
- data/README.md +128 -0
- data/Rakefile +23 -0
- data/app/controllers/solid_queue_monitor/monitor_controller.rb +250 -0
- data/app/presenters/solid_queue_monitor/base_presenter.rb +136 -0
- data/app/presenters/solid_queue_monitor/failed_jobs_presenter.rb +70 -0
- data/app/presenters/solid_queue_monitor/jobs_presenter.rb +100 -0
- data/app/presenters/solid_queue_monitor/queues_presenter.rb +62 -0
- data/app/presenters/solid_queue_monitor/ready_jobs_presenter.rb +72 -0
- data/app/presenters/solid_queue_monitor/recurring_jobs_presenter.rb +77 -0
- data/app/presenters/solid_queue_monitor/scheduled_jobs_presenter.rb +114 -0
- data/app/presenters/solid_queue_monitor/stats_presenter.rb +35 -0
- data/app/services/solid_queue_monitor/authentication_service.rb +14 -0
- data/app/services/solid_queue_monitor/execute_job_service.rb +28 -0
- data/app/services/solid_queue_monitor/html_generator.rb +88 -0
- data/app/services/solid_queue_monitor/pagination_service.rb +31 -0
- data/app/services/solid_queue_monitor/stats_calculator.rb +15 -0
- data/app/services/solid_queue_monitor/status_calculator.rb +14 -0
- data/app/services/solid_queue_monitor/stylesheet_generator.rb +395 -0
- data/config/initializers/solid_queue_monitor.rb +5 -0
- data/config/routes.rb +11 -0
- data/lib/generators/solid_queue_monitor/install_generator.rb +23 -0
- data/lib/generators/solid_queue_monitor/templates/README.md +23 -0
- data/lib/generators/solid_queue_monitor/templates/initializer.rb +14 -0
- data/lib/solid_queue_monitor/engine.rb +14 -0
- data/lib/solid_queue_monitor/version.rb +5 -0
- data/lib/solid_queue_monitor.rb +24 -0
- data/lib/tasks/app.rake +135 -0
- metadata +240 -0
@@ -0,0 +1,395 @@
|
|
1
|
+
module SolidQueueMonitor
|
2
|
+
class StylesheetGenerator
|
3
|
+
def generate
|
4
|
+
<<-CSS
|
5
|
+
:root {
|
6
|
+
--primary-color: #3b82f6;
|
7
|
+
--success-color: #10b981;
|
8
|
+
--error-color: #ef4444;
|
9
|
+
--text-color: #1f2937;
|
10
|
+
--border-color: #e5e7eb;
|
11
|
+
--background-color: #f9fafb;
|
12
|
+
}
|
13
|
+
|
14
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
15
|
+
|
16
|
+
body {
|
17
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
18
|
+
line-height: 1.5;
|
19
|
+
color: var(--text-color);
|
20
|
+
background: var(--background-color);
|
21
|
+
}
|
22
|
+
|
23
|
+
.container {
|
24
|
+
max-width: 1200px;
|
25
|
+
margin: 0 auto;
|
26
|
+
padding: 2rem;
|
27
|
+
}
|
28
|
+
|
29
|
+
header {
|
30
|
+
margin-bottom: 2rem;
|
31
|
+
text-align: center;
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 2rem;
|
36
|
+
font-weight: 600;
|
37
|
+
margin-bottom: 0.5rem;
|
38
|
+
}
|
39
|
+
|
40
|
+
.navigation {
|
41
|
+
display: flex;
|
42
|
+
flex-wrap: wrap;
|
43
|
+
justify-content: center;
|
44
|
+
gap: 0.5rem;
|
45
|
+
padding: 0.5rem;
|
46
|
+
}
|
47
|
+
|
48
|
+
.nav-link {
|
49
|
+
text-decoration: none;
|
50
|
+
color: var(--text-color);
|
51
|
+
padding: 0.5rem 1rem;
|
52
|
+
border-radius: 0.375rem;
|
53
|
+
background: white;
|
54
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
55
|
+
transition: all 0.2s;
|
56
|
+
}
|
57
|
+
|
58
|
+
.nav-link:hover {
|
59
|
+
background: var(--primary-color);
|
60
|
+
color: white;
|
61
|
+
}
|
62
|
+
|
63
|
+
.section-wrapper {
|
64
|
+
margin-top: 2rem;
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
.section h2 {
|
69
|
+
padding: 1rem;
|
70
|
+
border-bottom: 1px solid var(--border-color);
|
71
|
+
font-size: 1.25rem;
|
72
|
+
background: var(--background-color);
|
73
|
+
}
|
74
|
+
|
75
|
+
.stats-container {
|
76
|
+
margin-bottom: 2rem;
|
77
|
+
}
|
78
|
+
|
79
|
+
.stats {
|
80
|
+
display: flex;
|
81
|
+
flex-direction: row;
|
82
|
+
flex-wrap: wrap;
|
83
|
+
gap: 1rem;
|
84
|
+
margin: 0 -0.5rem;
|
85
|
+
}
|
86
|
+
|
87
|
+
.stat-card {
|
88
|
+
flex: 1 1 0;
|
89
|
+
min-width: 150px;
|
90
|
+
background: white;
|
91
|
+
padding: 1.5rem 1rem;
|
92
|
+
border-radius: 0.5rem;
|
93
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
94
|
+
text-align: center;
|
95
|
+
}
|
96
|
+
|
97
|
+
.stat-card h3 {
|
98
|
+
color: #6b7280;
|
99
|
+
font-size: 0.875rem;
|
100
|
+
text-transform: uppercase;
|
101
|
+
letter-spacing: 0.05em;
|
102
|
+
margin-bottom: 0.5rem;
|
103
|
+
}
|
104
|
+
|
105
|
+
.stat-card p {
|
106
|
+
font-size: 1.5rem;
|
107
|
+
font-weight: 600;
|
108
|
+
color: var(--primary-color);
|
109
|
+
}
|
110
|
+
|
111
|
+
.section h2 {
|
112
|
+
padding: 1rem;
|
113
|
+
border-bottom: 1px solid var(--border-color);
|
114
|
+
font-size: 1.25rem;
|
115
|
+
}
|
116
|
+
|
117
|
+
.table-container {
|
118
|
+
width: 100%;
|
119
|
+
overflow-x: auto;
|
120
|
+
-webkit-overflow-scrolling: touch;
|
121
|
+
}
|
122
|
+
|
123
|
+
table {
|
124
|
+
width: 100%;
|
125
|
+
min-width: 800px; /* Ensures table doesn't get too squeezed */
|
126
|
+
border-collapse: collapse;
|
127
|
+
white-space: nowrap;
|
128
|
+
}
|
129
|
+
|
130
|
+
th, td {
|
131
|
+
padding: 0.75rem 1rem;
|
132
|
+
text-align: left;
|
133
|
+
border-bottom: 1px solid var(--border-color);
|
134
|
+
}
|
135
|
+
|
136
|
+
th {
|
137
|
+
background: var(--background-color);
|
138
|
+
font-weight: 500;
|
139
|
+
font-size: 0.875rem;
|
140
|
+
text-transform: uppercase;
|
141
|
+
letter-spacing: 0.05em;
|
142
|
+
}
|
143
|
+
|
144
|
+
.status-badge {
|
145
|
+
display: inline-block;
|
146
|
+
padding: 0.25rem 0.5rem;
|
147
|
+
border-radius: 9999px;
|
148
|
+
font-size: 0.75rem;
|
149
|
+
font-weight: 500;
|
150
|
+
}
|
151
|
+
|
152
|
+
.table-actions {
|
153
|
+
display: flex;
|
154
|
+
justify-content: space-between;
|
155
|
+
align-items: center;
|
156
|
+
padding: 1rem;
|
157
|
+
border-top: 1px solid var(--border-color);
|
158
|
+
}
|
159
|
+
|
160
|
+
.select-all {
|
161
|
+
display: flex;
|
162
|
+
align-items: center;
|
163
|
+
gap: 0.5rem;
|
164
|
+
cursor: pointer;
|
165
|
+
}
|
166
|
+
|
167
|
+
.execute-btn:disabled {
|
168
|
+
opacity: 0.5;
|
169
|
+
cursor: not-allowed;
|
170
|
+
}
|
171
|
+
|
172
|
+
input[type="checkbox"] {
|
173
|
+
width: 1rem;
|
174
|
+
height: 1rem;
|
175
|
+
cursor: pointer;
|
176
|
+
}
|
177
|
+
|
178
|
+
.status-completed { background: #d1fae5; color: #065f46; }
|
179
|
+
.status-failed { background: #fee2e2; color: #991b1b; }
|
180
|
+
.status-scheduled { background: #dbeafe; color: #1e40af; }
|
181
|
+
.status-pending { background: #f3f4f6; color: #374151; }
|
182
|
+
|
183
|
+
.execute-btn {
|
184
|
+
background: var(--primary-color);
|
185
|
+
color: white;
|
186
|
+
border: none;
|
187
|
+
padding: 0.5rem 1rem;
|
188
|
+
border-radius: 0.375rem;
|
189
|
+
font-size: 0.875rem;
|
190
|
+
cursor: pointer;
|
191
|
+
transition: background-color 0.2s;
|
192
|
+
}
|
193
|
+
|
194
|
+
.execute-btn:hover {
|
195
|
+
background: #2563eb;
|
196
|
+
}
|
197
|
+
|
198
|
+
.message {
|
199
|
+
padding: 1rem;
|
200
|
+
margin-bottom: 1rem;
|
201
|
+
border-radius: 0.375rem;
|
202
|
+
}
|
203
|
+
|
204
|
+
.message-success {
|
205
|
+
background: #d1fae5;
|
206
|
+
color: #065f46;
|
207
|
+
}
|
208
|
+
|
209
|
+
.message-error {
|
210
|
+
background: #fee2e2;
|
211
|
+
color: #991b1b;
|
212
|
+
}
|
213
|
+
|
214
|
+
footer {
|
215
|
+
text-align: center;
|
216
|
+
padding: 2rem 0;
|
217
|
+
color: #6b7280;
|
218
|
+
}
|
219
|
+
|
220
|
+
.pagination {
|
221
|
+
display: flex;
|
222
|
+
justify-content: center;
|
223
|
+
gap: 0.5rem;
|
224
|
+
margin-top: 1rem;
|
225
|
+
padding: 1rem;
|
226
|
+
}
|
227
|
+
|
228
|
+
.pagination-nav {
|
229
|
+
padding: 0.5rem 1rem;
|
230
|
+
font-size: 0.875rem;
|
231
|
+
}
|
232
|
+
|
233
|
+
.pagination-gap {
|
234
|
+
display: inline-flex;
|
235
|
+
align-items: center;
|
236
|
+
justify-content: center;
|
237
|
+
min-width: 2rem;
|
238
|
+
height: 2rem;
|
239
|
+
padding: 0 0.5rem;
|
240
|
+
color: var(--text-color);
|
241
|
+
}
|
242
|
+
|
243
|
+
.pagination-link.disabled {
|
244
|
+
opacity: 0.5;
|
245
|
+
cursor: not-allowed;
|
246
|
+
pointer-events: none;
|
247
|
+
}
|
248
|
+
|
249
|
+
.pagination-link,
|
250
|
+
.pagination-current {
|
251
|
+
display: inline-flex;
|
252
|
+
align-items: center;
|
253
|
+
justify-content: center;
|
254
|
+
min-width: 2rem;
|
255
|
+
height: 2rem;
|
256
|
+
padding: 0 0.5rem;
|
257
|
+
border-radius: 0.375rem;
|
258
|
+
font-size: 0.875rem;
|
259
|
+
text-decoration: none;
|
260
|
+
transition: all 0.2s;
|
261
|
+
}
|
262
|
+
|
263
|
+
.pagination-link {
|
264
|
+
background: white;
|
265
|
+
color: var(--text-color);
|
266
|
+
border: 1px solid var(--border-color);
|
267
|
+
}
|
268
|
+
|
269
|
+
.pagination-link:hover {
|
270
|
+
background: var(--primary-color);
|
271
|
+
color: white;
|
272
|
+
border-color: var(--primary-color);
|
273
|
+
}
|
274
|
+
|
275
|
+
.pagination-current {
|
276
|
+
background: var(--primary-color);
|
277
|
+
color: white;
|
278
|
+
font-weight: 500;
|
279
|
+
}
|
280
|
+
|
281
|
+
@media (max-width: 768px) {
|
282
|
+
.container {
|
283
|
+
padding: 0.5rem;
|
284
|
+
}
|
285
|
+
|
286
|
+
.stats {
|
287
|
+
margin: 0;
|
288
|
+
}
|
289
|
+
|
290
|
+
.stat-card {
|
291
|
+
flex: 1 1 calc(33.333% - 1rem);
|
292
|
+
min-width: 120px;
|
293
|
+
}
|
294
|
+
|
295
|
+
.section {
|
296
|
+
margin: 0.5rem 0;
|
297
|
+
border-radius: 0.375rem;
|
298
|
+
}
|
299
|
+
|
300
|
+
.table-container {
|
301
|
+
width: 100%;
|
302
|
+
overflow-x: auto;
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
@media (max-width: 480px) {
|
307
|
+
.stat-card {
|
308
|
+
flex: 1 1 calc(50% - 1rem);
|
309
|
+
}
|
310
|
+
|
311
|
+
.nav-link {
|
312
|
+
width: 100%;
|
313
|
+
text-align: center;
|
314
|
+
}
|
315
|
+
.pagination-nav {
|
316
|
+
display: none;
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
.filter-form-container {
|
321
|
+
background: white;
|
322
|
+
padding: 1rem;
|
323
|
+
border-radius: 0.5rem;
|
324
|
+
margin-bottom: 1rem;
|
325
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
326
|
+
}
|
327
|
+
|
328
|
+
.filter-form {
|
329
|
+
display: flex;
|
330
|
+
flex-wrap: wrap;
|
331
|
+
gap: 1rem;
|
332
|
+
align-items: flex-end;
|
333
|
+
}
|
334
|
+
|
335
|
+
.filter-group {
|
336
|
+
flex: 1;
|
337
|
+
min-width: 200px;
|
338
|
+
}
|
339
|
+
|
340
|
+
.filter-group label {
|
341
|
+
display: block;
|
342
|
+
margin-bottom: 0.5rem;
|
343
|
+
font-size: 0.875rem;
|
344
|
+
font-weight: 500;
|
345
|
+
color: #4b5563;
|
346
|
+
}
|
347
|
+
|
348
|
+
.filter-group input,
|
349
|
+
.filter-group select {
|
350
|
+
width: 100%;
|
351
|
+
padding: 0.5rem;
|
352
|
+
border: 1px solid #d1d5db;
|
353
|
+
border-radius: 0.375rem;
|
354
|
+
font-size: 0.875rem;
|
355
|
+
}
|
356
|
+
|
357
|
+
.filter-actions {
|
358
|
+
display: flex;
|
359
|
+
gap: 0.5rem;
|
360
|
+
}
|
361
|
+
|
362
|
+
.filter-button {
|
363
|
+
background: var(--primary-color);
|
364
|
+
color: white;
|
365
|
+
border: none;
|
366
|
+
padding: 0.5rem 1rem;
|
367
|
+
border-radius: 0.375rem;
|
368
|
+
font-size: 0.875rem;
|
369
|
+
cursor: pointer;
|
370
|
+
transition: background-color 0.2s;
|
371
|
+
}
|
372
|
+
|
373
|
+
.filter-button:hover {
|
374
|
+
background: #2563eb;
|
375
|
+
}
|
376
|
+
|
377
|
+
.reset-button {
|
378
|
+
background: #f3f4f6;
|
379
|
+
color: #4b5563;
|
380
|
+
border: 1px solid #d1d5db;
|
381
|
+
padding: 0.5rem 1rem;
|
382
|
+
border-radius: 0.375rem;
|
383
|
+
font-size: 0.875rem;
|
384
|
+
text-decoration: none;
|
385
|
+
cursor: pointer;
|
386
|
+
transition: background-color 0.2s;
|
387
|
+
}
|
388
|
+
|
389
|
+
.reset-button:hover {
|
390
|
+
background: #e5e7eb;
|
391
|
+
}
|
392
|
+
CSS
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
SolidQueueMonitor::Engine.routes.draw do
|
2
|
+
root to: 'monitor#index'
|
3
|
+
|
4
|
+
get 'ready_jobs', to: 'monitor#ready_jobs'
|
5
|
+
get 'scheduled_jobs', to: 'monitor#scheduled_jobs'
|
6
|
+
get 'failed_jobs', to: 'monitor#failed_jobs'
|
7
|
+
get 'recurring_jobs', to: 'monitor#recurring_jobs'
|
8
|
+
get 'queues', to: 'monitor#queues'
|
9
|
+
|
10
|
+
post 'execute_jobs', to: 'monitor#execute_jobs'
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails/generators/base'
|
2
|
+
|
3
|
+
module SolidQueueMonitor
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path('templates', __dir__)
|
7
|
+
|
8
|
+
def copy_initializer
|
9
|
+
template "initializer.rb", "config/initializers/solid_queue_monitor.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_routes
|
13
|
+
prepend_to_file "config/routes.rb", "require 'solid_queue_monitor'\n\n"
|
14
|
+
|
15
|
+
route "mount SolidQueueMonitor::Engine => '/solid_queue'"
|
16
|
+
end
|
17
|
+
|
18
|
+
def show_readme
|
19
|
+
readme "README.md" if behavior == :invoke
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# SolidQueueMonitor Installation
|
2
|
+
|
3
|
+
The SolidQueueMonitor has been installed.
|
4
|
+
|
5
|
+
## Next Steps
|
6
|
+
|
7
|
+
1. Configure your settings in `config/initializers/solid_queue_monitor.rb`
|
8
|
+
|
9
|
+
2. Access your dashboard at: http://your-app-url/solid_queue
|
10
|
+
|
11
|
+
3. Authentication:
|
12
|
+
- Authentication is disabled by default for ease of setup
|
13
|
+
- To enable authentication, set `config.authentication_enabled = true` in the initializer
|
14
|
+
- Default credentials (when authentication is enabled):
|
15
|
+
- Username: admin
|
16
|
+
- Password: password
|
17
|
+
|
18
|
+
## Security Note
|
19
|
+
|
20
|
+
For production environments, it's strongly recommended to:
|
21
|
+
|
22
|
+
1. Enable authentication
|
23
|
+
2. Change the default credentials to secure values
|
@@ -0,0 +1,14 @@
|
|
1
|
+
SolidQueueMonitor.setup do |config|
|
2
|
+
# Enable or disable authentication
|
3
|
+
# When disabled, no authentication is required to access the monitor
|
4
|
+
config.authentication_enabled = false
|
5
|
+
|
6
|
+
# Set the username for HTTP Basic Authentication (only used if authentication is enabled)
|
7
|
+
# config.username = 'admin'
|
8
|
+
|
9
|
+
# Set the password for HTTP Basic Authentication (only used if authentication is enabled)
|
10
|
+
# config.password = 'password'
|
11
|
+
|
12
|
+
# Number of jobs to display per page
|
13
|
+
# config.jobs_per_page = 25
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SolidQueueMonitor
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace SolidQueueMonitor
|
4
|
+
|
5
|
+
config.autoload_paths << root.join('app', 'services')
|
6
|
+
|
7
|
+
# Optional: Add eager loading for production
|
8
|
+
config.eager_load_paths << root.join('app', 'services')
|
9
|
+
|
10
|
+
initializer "solid_queue_monitor.assets" do |app|
|
11
|
+
# Optional: Add assets if needed
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "solid_queue_monitor/version"
|
4
|
+
require_relative "solid_queue_monitor/engine"
|
5
|
+
|
6
|
+
module SolidQueueMonitor
|
7
|
+
class Error < StandardError; end
|
8
|
+
# Configuration options
|
9
|
+
mattr_accessor :username
|
10
|
+
@@username = 'admin'
|
11
|
+
|
12
|
+
mattr_accessor :password
|
13
|
+
@@password = 'password'
|
14
|
+
|
15
|
+
mattr_accessor :jobs_per_page
|
16
|
+
@@jobs_per_page = 25
|
17
|
+
|
18
|
+
mattr_accessor :authentication_enabled
|
19
|
+
@@authentication_enabled = false
|
20
|
+
|
21
|
+
def self.setup
|
22
|
+
yield self
|
23
|
+
end
|
24
|
+
end
|
data/lib/tasks/app.rake
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
namespace :app do
|
2
|
+
desc "Setup the dummy app for testing"
|
3
|
+
task :setup do
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
# Create dummy app directories
|
7
|
+
dummy_app_path = File.expand_path("../../spec/dummy", __FILE__)
|
8
|
+
|
9
|
+
# Ensure directories exist
|
10
|
+
%w[
|
11
|
+
app/controllers
|
12
|
+
app/models
|
13
|
+
app/views
|
14
|
+
config/environments
|
15
|
+
config/initializers
|
16
|
+
db
|
17
|
+
lib
|
18
|
+
log
|
19
|
+
].each do |dir|
|
20
|
+
FileUtils.mkdir_p(File.join(dummy_app_path, dir))
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create necessary files if they don't exist
|
24
|
+
unless File.exist?(File.join(dummy_app_path, "config/boot.rb"))
|
25
|
+
File.write(File.join(dummy_app_path, "config/boot.rb"), <<~RUBY)
|
26
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
|
27
|
+
require 'bundler/setup'
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
|
31
|
+
unless File.exist?(File.join(dummy_app_path, "config/application.rb"))
|
32
|
+
File.write(File.join(dummy_app_path, "config/application.rb"), <<~RUBY)
|
33
|
+
require_relative "boot"
|
34
|
+
|
35
|
+
require "rails"
|
36
|
+
require "active_model/railtie"
|
37
|
+
require "active_record/railtie"
|
38
|
+
require "action_controller/railtie"
|
39
|
+
require "action_view/railtie"
|
40
|
+
require "rails/test_unit/railtie"
|
41
|
+
require "solid_queue"
|
42
|
+
require "solid_queue_monitor"
|
43
|
+
|
44
|
+
module Dummy
|
45
|
+
class Application < Rails::Application
|
46
|
+
config.load_defaults Rails::VERSION::STRING.to_f
|
47
|
+
|
48
|
+
# Settings in config/environments/* take precedence over those specified here.
|
49
|
+
# Application configuration can go into files in config/initializers
|
50
|
+
# -- all .rb files in that directory are automatically loaded after loading
|
51
|
+
# the framework and any gems in your application.
|
52
|
+
|
53
|
+
# Only loads a smaller set of middleware suitable for API only apps.
|
54
|
+
# Middleware like session, flash, cookies can be added back manually.
|
55
|
+
config.api_only = true
|
56
|
+
|
57
|
+
# Don't generate system test files.
|
58
|
+
config.generators.system_tests = nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RUBY
|
62
|
+
end
|
63
|
+
|
64
|
+
unless File.exist?(File.join(dummy_app_path, "config/environment.rb"))
|
65
|
+
File.write(File.join(dummy_app_path, "config/environment.rb"), <<~RUBY)
|
66
|
+
# Load the Rails application.
|
67
|
+
require_relative 'application'
|
68
|
+
|
69
|
+
# Initialize the Rails application.
|
70
|
+
Rails.application.initialize!
|
71
|
+
RUBY
|
72
|
+
end
|
73
|
+
|
74
|
+
unless File.exist?(File.join(dummy_app_path, "config/environments/test.rb"))
|
75
|
+
File.write(File.join(dummy_app_path, "config/environments/test.rb"), <<~RUBY)
|
76
|
+
Rails.application.configure do
|
77
|
+
# Settings specified here will take precedence over those in config/application.rb.
|
78
|
+
|
79
|
+
# The test environment is used exclusively to run your application's
|
80
|
+
# test suite. You never need to work with it otherwise. Remember that
|
81
|
+
# your test database is "scratch space" for the test suite and is wiped
|
82
|
+
# and recreated between test runs. Don't rely on the data there!
|
83
|
+
config.cache_classes = true
|
84
|
+
|
85
|
+
# Do not eager load code on boot. This avoids loading your whole application
|
86
|
+
# just for the purpose of running a single test. If you are using a tool that
|
87
|
+
# preloads Rails for running tests, you may have to set it to true.
|
88
|
+
config.eager_load = false
|
89
|
+
|
90
|
+
# Configure public file server for tests with Cache-Control for performance.
|
91
|
+
config.public_file_server.enabled = true
|
92
|
+
config.public_file_server.headers = {
|
93
|
+
'Cache-Control' => "public, max-age=\#{1.hour.to_i}"
|
94
|
+
}
|
95
|
+
|
96
|
+
# Show full error reports and disable caching.
|
97
|
+
config.consider_all_requests_local = true
|
98
|
+
config.action_controller.perform_caching = false
|
99
|
+
|
100
|
+
# Raise exceptions instead of rendering exception templates.
|
101
|
+
config.action_dispatch.show_exceptions = false
|
102
|
+
|
103
|
+
# Disable request forgery protection in test environment.
|
104
|
+
config.action_controller.allow_forgery_protection = false
|
105
|
+
|
106
|
+
# Print deprecation notices to the stderr.
|
107
|
+
config.active_support.deprecation = :stderr
|
108
|
+
|
109
|
+
# Raises error for missing translations.
|
110
|
+
# config.action_view.raise_on_missing_translations = true
|
111
|
+
end
|
112
|
+
RUBY
|
113
|
+
end
|
114
|
+
|
115
|
+
unless File.exist?(File.join(dummy_app_path, "config/database.yml"))
|
116
|
+
File.write(File.join(dummy_app_path, "config/database.yml"), <<~YAML)
|
117
|
+
test:
|
118
|
+
adapter: sqlite3
|
119
|
+
database: ":memory:"
|
120
|
+
pool: 5
|
121
|
+
timeout: 5000
|
122
|
+
YAML
|
123
|
+
end
|
124
|
+
|
125
|
+
unless File.exist?(File.join(dummy_app_path, "config/routes.rb"))
|
126
|
+
File.write(File.join(dummy_app_path, "config/routes.rb"), <<~RUBY)
|
127
|
+
Rails.application.routes.draw do
|
128
|
+
mount SolidQueueMonitor::Engine => "/solid_queue"
|
129
|
+
end
|
130
|
+
RUBY
|
131
|
+
end
|
132
|
+
|
133
|
+
puts "Dummy app setup complete!"
|
134
|
+
end
|
135
|
+
end
|