trusty-cms 7.1.3 → 7.2
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/Gemfile.lock +72 -68
- data/lib/string_extensions/string_extensions.rb +4 -2
- data/lib/trusty_cms/version.rb +1 -1
- data/spec/controllers/admin/assets_controller_spec.rb +124 -0
- data/spec/controllers/admin/changes_controller_spec.rb +72 -0
- data/spec/controllers/admin/configuration_controller_spec.rb +49 -0
- data/spec/controllers/admin/page_attachments_controller_spec.rb +54 -0
- data/spec/controllers/admin/pages_controller_spec.rb +162 -0
- data/spec/controllers/admin/preferences_controller_spec.rb +44 -0
- data/spec/controllers/admin/security_controller_spec.rb +85 -0
- data/spec/controllers/admin/sessions_controller_spec.rb +56 -0
- data/spec/controllers/admin/two_factor_controller_spec.rb +63 -0
- data/spec/controllers/admin/users_controller_spec.rb +132 -0
- data/spec/controllers/page_status_controller_spec.rb +66 -0
- data/spec/dummy/bin/rails +3 -3
- data/spec/dummy/bin/rake +2 -2
- data/spec/dummy/bin/setup +21 -13
- data/spec/dummy/config/boot.rb +1 -1
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -2
- data/spec/dummy/config/initializers/inflections.rb +4 -4
- data/spec/dummy/config/initializers/new_framework_defaults_7_2.rb +70 -0
- data/spec/dummy/config/initializers/permissions_policy.rb +13 -0
- data/spec/dummy/config/puma.rb +34 -0
- data/spec/dummy/config/storage.yml +28 -1
- data/spec/dummy/db/migrate/20260729201444_add_service_name_to_active_storage_blobs.active_storage.rb +22 -0
- data/spec/dummy/db/migrate/20260729201445_create_active_storage_variant_records.active_storage.rb +27 -0
- data/spec/dummy/db/migrate/20260729201446_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb +8 -0
- data/spec/dummy/public/404.html +6 -6
- data/spec/dummy/public/406-unsupported-browser.html +66 -0
- data/spec/dummy/public/422.html +6 -6
- data/spec/dummy/public/500.html +6 -6
- data/spec/dummy/public/icon.png +0 -0
- data/spec/dummy/public/icon.svg +3 -0
- data/spec/dummy/public/robots.txt +1 -0
- data/spec/helpers/admin/configuration_helper_spec.rb +62 -0
- data/spec/helpers/admin/node_helper_spec.rb +132 -0
- data/spec/helpers/admin/pages_helper_spec.rb +84 -0
- data/spec/helpers/application_helper_spec.rb +115 -0
- data/spec/lib/string_extensions_spec.rb +41 -0
- data/spec/support/active_record_encryption.rb +10 -0
- data/spec/support/asset_type_registry.rb +29 -0
- data/trusty_cms.gemspec +1 -1
- metadata +68 -8
- data/spec/controllers/assets_controller.rb +0 -66
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2378bbe6b853e3290648de1a8a832b61a25303f3078f4903ac70581a031bb3a5
|
|
4
|
+
data.tar.gz: 3e704c6349a8bf385190cc70ee6cf0021aa8c0cc575d5e033a3c1423a32e5e20
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b4c137e5c84e08a9fc8395282986fe8a7b8b0c7c28d6e3b888b60a4e8a0c19f30d1520bc92a5580c8a3472961470e57558215ff3965546626dbb934863cd9f07
|
|
7
|
+
data.tar.gz: 42f087dbc0e78b43ffb48ad804b891992eafafe7d8e3ee5589b2d983902eaef2590f5325bb03f1df568227e52ae4a391d7ca8000432e9be82f59710c332f34b4
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
trusty-cms (7.
|
|
4
|
+
trusty-cms (7.2)
|
|
5
5
|
RedCloth (= 4.3.4)
|
|
6
6
|
activestorage-validator
|
|
7
7
|
acts_as_list (>= 0.9.5, < 1.3.0)
|
|
@@ -29,7 +29,7 @@ PATH
|
|
|
29
29
|
rack (>= 2.0.1, < 3.2.0)
|
|
30
30
|
rack-cache (~> 1.7)
|
|
31
31
|
radius (~> 0.8)
|
|
32
|
-
rails (
|
|
32
|
+
rails (>= 7.2, < 8.0)
|
|
33
33
|
rake (< 14.0)
|
|
34
34
|
ransack (~> 4.2.1)
|
|
35
35
|
rdoc (>= 5.1, < 9.0)
|
|
@@ -46,68 +46,70 @@ GEM
|
|
|
46
46
|
remote: https://rubygems.org/
|
|
47
47
|
specs:
|
|
48
48
|
RedCloth (4.3.4)
|
|
49
|
-
actioncable (7.2.2
|
|
50
|
-
actionpack (= 7.2.2
|
|
51
|
-
activesupport (= 7.2.2
|
|
49
|
+
actioncable (7.2.3.2)
|
|
50
|
+
actionpack (= 7.2.3.2)
|
|
51
|
+
activesupport (= 7.2.3.2)
|
|
52
52
|
nio4r (~> 2.0)
|
|
53
53
|
websocket-driver (>= 0.6.1)
|
|
54
54
|
zeitwerk (~> 2.6)
|
|
55
|
-
actionmailbox (7.2.2
|
|
56
|
-
actionpack (= 7.2.2
|
|
57
|
-
activejob (= 7.2.2
|
|
58
|
-
activerecord (= 7.2.2
|
|
59
|
-
activestorage (= 7.2.2
|
|
60
|
-
activesupport (= 7.2.2
|
|
55
|
+
actionmailbox (7.2.3.2)
|
|
56
|
+
actionpack (= 7.2.3.2)
|
|
57
|
+
activejob (= 7.2.3.2)
|
|
58
|
+
activerecord (= 7.2.3.2)
|
|
59
|
+
activestorage (= 7.2.3.2)
|
|
60
|
+
activesupport (= 7.2.3.2)
|
|
61
61
|
mail (>= 2.8.0)
|
|
62
|
-
actionmailer (7.2.2
|
|
63
|
-
actionpack (= 7.2.2
|
|
64
|
-
actionview (= 7.2.2
|
|
65
|
-
activejob (= 7.2.2
|
|
66
|
-
activesupport (= 7.2.2
|
|
62
|
+
actionmailer (7.2.3.2)
|
|
63
|
+
actionpack (= 7.2.3.2)
|
|
64
|
+
actionview (= 7.2.3.2)
|
|
65
|
+
activejob (= 7.2.3.2)
|
|
66
|
+
activesupport (= 7.2.3.2)
|
|
67
67
|
mail (>= 2.8.0)
|
|
68
68
|
rails-dom-testing (~> 2.2)
|
|
69
|
-
actionpack (7.2.2
|
|
70
|
-
actionview (= 7.2.2
|
|
71
|
-
activesupport (= 7.2.2
|
|
69
|
+
actionpack (7.2.3.2)
|
|
70
|
+
actionview (= 7.2.3.2)
|
|
71
|
+
activesupport (= 7.2.3.2)
|
|
72
|
+
cgi
|
|
72
73
|
nokogiri (>= 1.8.5)
|
|
73
74
|
racc
|
|
74
|
-
rack (>= 2.2.4, < 3.
|
|
75
|
+
rack (>= 2.2.4, < 3.3)
|
|
75
76
|
rack-session (>= 1.0.1)
|
|
76
77
|
rack-test (>= 0.6.3)
|
|
77
78
|
rails-dom-testing (~> 2.2)
|
|
78
79
|
rails-html-sanitizer (~> 1.6)
|
|
79
80
|
useragent (~> 0.16)
|
|
80
|
-
actiontext (7.2.2
|
|
81
|
-
actionpack (= 7.2.2
|
|
82
|
-
activerecord (= 7.2.2
|
|
83
|
-
activestorage (= 7.2.2
|
|
84
|
-
activesupport (= 7.2.2
|
|
81
|
+
actiontext (7.2.3.2)
|
|
82
|
+
actionpack (= 7.2.3.2)
|
|
83
|
+
activerecord (= 7.2.3.2)
|
|
84
|
+
activestorage (= 7.2.3.2)
|
|
85
|
+
activesupport (= 7.2.3.2)
|
|
85
86
|
globalid (>= 0.6.0)
|
|
86
87
|
nokogiri (>= 1.8.5)
|
|
87
|
-
actionview (7.2.2
|
|
88
|
-
activesupport (= 7.2.2
|
|
88
|
+
actionview (7.2.3.2)
|
|
89
|
+
activesupport (= 7.2.3.2)
|
|
89
90
|
builder (~> 3.1)
|
|
91
|
+
cgi
|
|
90
92
|
erubi (~> 1.11)
|
|
91
93
|
rails-dom-testing (~> 2.2)
|
|
92
94
|
rails-html-sanitizer (~> 1.6)
|
|
93
|
-
activejob (7.2.2
|
|
94
|
-
activesupport (= 7.2.2
|
|
95
|
+
activejob (7.2.3.2)
|
|
96
|
+
activesupport (= 7.2.3.2)
|
|
95
97
|
globalid (>= 0.3.6)
|
|
96
|
-
activemodel (7.2.2
|
|
97
|
-
activesupport (= 7.2.2
|
|
98
|
-
activerecord (7.2.2
|
|
99
|
-
activemodel (= 7.2.2
|
|
100
|
-
activesupport (= 7.2.2
|
|
98
|
+
activemodel (7.2.3.2)
|
|
99
|
+
activesupport (= 7.2.3.2)
|
|
100
|
+
activerecord (7.2.3.2)
|
|
101
|
+
activemodel (= 7.2.3.2)
|
|
102
|
+
activesupport (= 7.2.3.2)
|
|
101
103
|
timeout (>= 0.4.0)
|
|
102
|
-
activestorage (7.2.2
|
|
103
|
-
actionpack (= 7.2.2
|
|
104
|
-
activejob (= 7.2.2
|
|
105
|
-
activerecord (= 7.2.2
|
|
106
|
-
activesupport (= 7.2.2
|
|
104
|
+
activestorage (7.2.3.2)
|
|
105
|
+
actionpack (= 7.2.3.2)
|
|
106
|
+
activejob (= 7.2.3.2)
|
|
107
|
+
activerecord (= 7.2.3.2)
|
|
108
|
+
activesupport (= 7.2.3.2)
|
|
107
109
|
marcel (~> 1.0)
|
|
108
110
|
activestorage-validator (0.4.0)
|
|
109
111
|
rails (>= 6.1.0)
|
|
110
|
-
activesupport (7.2.2
|
|
112
|
+
activesupport (7.2.3.2)
|
|
111
113
|
base64
|
|
112
114
|
benchmark (>= 0.3)
|
|
113
115
|
bigdecimal
|
|
@@ -116,7 +118,7 @@ GEM
|
|
|
116
118
|
drb
|
|
117
119
|
i18n (>= 1.6, < 2)
|
|
118
120
|
logger (>= 1.4.2)
|
|
119
|
-
minitest (>= 5.1)
|
|
121
|
+
minitest (>= 5.1, < 6)
|
|
120
122
|
securerandom (>= 0.3)
|
|
121
123
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
122
124
|
acts_as_list (1.2.6)
|
|
@@ -142,12 +144,13 @@ GEM
|
|
|
142
144
|
rack-test (>= 0.6.3)
|
|
143
145
|
regexp_parser (>= 1.5, < 3.0)
|
|
144
146
|
xpath (~> 3.2)
|
|
147
|
+
cgi (0.5.2)
|
|
145
148
|
childprocess (5.1.0)
|
|
146
149
|
logger (~> 1.5)
|
|
147
150
|
chunky_png (1.4.0)
|
|
148
151
|
cliver (0.3.2)
|
|
149
152
|
coderay (1.1.3)
|
|
150
|
-
concurrent-ruby (1.3.
|
|
153
|
+
concurrent-ruby (1.3.8)
|
|
151
154
|
connection_pool (3.0.2)
|
|
152
155
|
crass (1.0.7)
|
|
153
156
|
css_parser (3.0.0)
|
|
@@ -180,7 +183,7 @@ GEM
|
|
|
180
183
|
diffy (3.4.4)
|
|
181
184
|
docile (1.4.1)
|
|
182
185
|
drb (2.2.3)
|
|
183
|
-
erb (6.0.
|
|
186
|
+
erb (6.0.6)
|
|
184
187
|
erubi (1.13.1)
|
|
185
188
|
execjs (2.10.0)
|
|
186
189
|
factory_bot (6.6.0)
|
|
@@ -201,7 +204,7 @@ GEM
|
|
|
201
204
|
file_validators (3.0.0)
|
|
202
205
|
activemodel (>= 3.2)
|
|
203
206
|
mime-types (>= 1.0)
|
|
204
|
-
globalid (1.
|
|
207
|
+
globalid (1.4.0)
|
|
205
208
|
activesupport (>= 6.1)
|
|
206
209
|
haml (6.3.0)
|
|
207
210
|
temple (>= 0.8.2)
|
|
@@ -251,12 +254,13 @@ GEM
|
|
|
251
254
|
loofah (2.25.2)
|
|
252
255
|
crass (~> 1.0.2)
|
|
253
256
|
nokogiri (>= 1.12.0)
|
|
254
|
-
mail (2.
|
|
257
|
+
mail (2.9.1)
|
|
258
|
+
logger
|
|
255
259
|
mini_mime (>= 0.1.1)
|
|
256
260
|
net-imap
|
|
257
261
|
net-pop
|
|
258
262
|
net-smtp
|
|
259
|
-
marcel (1.
|
|
263
|
+
marcel (1.2.1)
|
|
260
264
|
matrix (0.4.2)
|
|
261
265
|
method_source (1.1.0)
|
|
262
266
|
mime-types (3.6.0)
|
|
@@ -268,15 +272,13 @@ GEM
|
|
|
268
272
|
mini_portile2 (2.8.9)
|
|
269
273
|
mini_racer (0.16.0)
|
|
270
274
|
libv8-node (~> 18.19.0.0)
|
|
271
|
-
minitest (
|
|
272
|
-
drb (~> 2.0)
|
|
273
|
-
prism (~> 1.5)
|
|
275
|
+
minitest (5.27.0)
|
|
274
276
|
multi_xml (0.9.1)
|
|
275
277
|
bigdecimal (>= 3.1, < 5)
|
|
276
278
|
multipart-post (2.4.1)
|
|
277
279
|
mutex_m (0.3.0)
|
|
278
280
|
mysql2 (0.5.6)
|
|
279
|
-
net-imap (0.
|
|
281
|
+
net-imap (0.6.6)
|
|
280
282
|
date
|
|
281
283
|
net-protocol
|
|
282
284
|
net-pop (0.1.2)
|
|
@@ -285,7 +287,7 @@ GEM
|
|
|
285
287
|
timeout
|
|
286
288
|
net-smtp (0.5.1)
|
|
287
289
|
net-protocol
|
|
288
|
-
nio4r (2.7.
|
|
290
|
+
nio4r (2.7.5)
|
|
289
291
|
nokogiri (1.19.4)
|
|
290
292
|
mini_portile2 (~> 2.8.2)
|
|
291
293
|
racc (~> 1.4)
|
|
@@ -342,20 +344,20 @@ GEM
|
|
|
342
344
|
rackup (2.3.1)
|
|
343
345
|
rack (>= 3)
|
|
344
346
|
radius (0.8.0)
|
|
345
|
-
rails (7.2.2
|
|
346
|
-
actioncable (= 7.2.2
|
|
347
|
-
actionmailbox (= 7.2.2
|
|
348
|
-
actionmailer (= 7.2.2
|
|
349
|
-
actionpack (= 7.2.2
|
|
350
|
-
actiontext (= 7.2.2
|
|
351
|
-
actionview (= 7.2.2
|
|
352
|
-
activejob (= 7.2.2
|
|
353
|
-
activemodel (= 7.2.2
|
|
354
|
-
activerecord (= 7.2.2
|
|
355
|
-
activestorage (= 7.2.2
|
|
356
|
-
activesupport (= 7.2.2
|
|
347
|
+
rails (7.2.3.2)
|
|
348
|
+
actioncable (= 7.2.3.2)
|
|
349
|
+
actionmailbox (= 7.2.3.2)
|
|
350
|
+
actionmailer (= 7.2.3.2)
|
|
351
|
+
actionpack (= 7.2.3.2)
|
|
352
|
+
actiontext (= 7.2.3.2)
|
|
353
|
+
actionview (= 7.2.3.2)
|
|
354
|
+
activejob (= 7.2.3.2)
|
|
355
|
+
activemodel (= 7.2.3.2)
|
|
356
|
+
activerecord (= 7.2.3.2)
|
|
357
|
+
activestorage (= 7.2.3.2)
|
|
358
|
+
activesupport (= 7.2.3.2)
|
|
357
359
|
bundler (>= 1.15.0)
|
|
358
|
-
railties (= 7.2.2
|
|
360
|
+
railties (= 7.2.3.2)
|
|
359
361
|
rails-dom-testing (2.3.0)
|
|
360
362
|
activesupport (>= 5.0.0)
|
|
361
363
|
minitest
|
|
@@ -365,20 +367,22 @@ GEM
|
|
|
365
367
|
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
|
366
368
|
rails-observers (0.1.5)
|
|
367
369
|
activemodel (>= 4.0)
|
|
368
|
-
railties (7.2.2
|
|
369
|
-
actionpack (= 7.2.2
|
|
370
|
-
activesupport (= 7.2.2
|
|
370
|
+
railties (7.2.3.2)
|
|
371
|
+
actionpack (= 7.2.3.2)
|
|
372
|
+
activesupport (= 7.2.3.2)
|
|
373
|
+
cgi
|
|
371
374
|
irb (~> 1.13)
|
|
372
375
|
rackup (>= 1.0.0)
|
|
373
376
|
rake (>= 12.2)
|
|
374
377
|
thor (~> 1.0, >= 1.2.2)
|
|
378
|
+
tsort (>= 0.2)
|
|
375
379
|
zeitwerk (~> 2.6)
|
|
376
380
|
rake (13.4.2)
|
|
377
381
|
ransack (4.2.1)
|
|
378
382
|
activerecord (>= 6.1.5)
|
|
379
383
|
activesupport (>= 6.1.5)
|
|
380
384
|
i18n
|
|
381
|
-
rbs (4.0
|
|
385
|
+
rbs (4.1.0)
|
|
382
386
|
logger
|
|
383
387
|
prism (>= 1.6.0)
|
|
384
388
|
tsort
|
|
@@ -14,8 +14,10 @@ class String
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
unless methods.include?('parameterize')
|
|
17
|
-
def parameterize(
|
|
18
|
-
|
|
17
|
+
def parameterize(separator = '-', preserve_case: false, locale: nil)
|
|
18
|
+
separator = '-' unless separator.is_a?(String)
|
|
19
|
+
slug = remove_formatting.replace_whitespace(separator).collapse(separator)
|
|
20
|
+
preserve_case ? slug : slug.downcase
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
|
data/lib/trusty_cms/version.rb
CHANGED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rack/test'
|
|
3
|
+
|
|
4
|
+
# Exercises Admin::AssetsController, which overrides the ResourceController CRUD
|
|
5
|
+
# with custom upload handling (process_uploaded_asset, maybe_compress,
|
|
6
|
+
# failure_response, set_owner_or_editor). Uses the JSON/partial endpoints so the
|
|
7
|
+
# specs don't depend on the asset-pipeline-heavy admin HTML layout. High-value
|
|
8
|
+
# regression net for a Rails/Ruby upgrade — file uploads and content-type
|
|
9
|
+
# negotiation are common breakage points.
|
|
10
|
+
RSpec.describe Admin::AssetsController, type: :controller do
|
|
11
|
+
routes { TrustyCms::Application.routes }
|
|
12
|
+
|
|
13
|
+
let(:user) { create(:admin) }
|
|
14
|
+
let(:fixtures_path) { TrustyCms::Engine.root.join('spec', 'fixtures', 'files') }
|
|
15
|
+
|
|
16
|
+
before do
|
|
17
|
+
# approved_content_types derives from the AssetType registry, which is empty
|
|
18
|
+
# by default; register the canonical set (shared with asset_spec) so uploads
|
|
19
|
+
# of text/plain, images, etc. can be approved. See AssetTypeRegistry.
|
|
20
|
+
register_standard_asset_types
|
|
21
|
+
|
|
22
|
+
# public_url generation needs a host; controller specs don't set one on the
|
|
23
|
+
# Disk service the way a real request would.
|
|
24
|
+
@previous_active_storage_url_options = ActiveStorage::Current.url_options
|
|
25
|
+
ActiveStorage::Current.url_options = { host: 'test.host', protocol: 'http' }
|
|
26
|
+
|
|
27
|
+
allow(controller).to receive(:authenticate_user!).and_return(true)
|
|
28
|
+
allow(controller).to receive(:current_user).and_return(user)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
after do
|
|
32
|
+
ActiveStorage::Current.url_options = @previous_active_storage_url_options
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# A plain stub (not an rspec double) so it can be assigned in an `around`
|
|
36
|
+
# hook, which runs outside the per-test double lifecycle. api_key: nil makes
|
|
37
|
+
# should_compress? false, so uploads skip Kraken compression.
|
|
38
|
+
around do |example|
|
|
39
|
+
original_kraken = defined?($kraken) ? $kraken : nil
|
|
40
|
+
$kraken = Struct.new(:api_key).new(nil)
|
|
41
|
+
example.run
|
|
42
|
+
$kraken = original_kraken
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def upload(filename, content_type)
|
|
46
|
+
Rack::Test::UploadedFile.new(fixtures_path.join(filename), content_type)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe 'POST #uploader' do
|
|
50
|
+
it 'returns the asset url when the upload succeeds' do
|
|
51
|
+
expect {
|
|
52
|
+
post :uploader, params: { upload: upload('sample.txt', 'text/plain') }, format: :json
|
|
53
|
+
}.to change(Asset, :count).by(1)
|
|
54
|
+
|
|
55
|
+
expect(response).to have_http_status(:ok)
|
|
56
|
+
expect(JSON.parse(response.body)).to have_key('url')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'records the uploading user as owner/editor' do
|
|
60
|
+
post :uploader, params: { upload: upload('sample.txt', 'text/plain') }, format: :json
|
|
61
|
+
|
|
62
|
+
asset = Asset.last
|
|
63
|
+
expect(asset.created_by_id).to eq(user.id)
|
|
64
|
+
expect(asset.updated_by_id).to eq(user.id)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'returns unsupported media type for disallowed content types' do
|
|
68
|
+
expect(Asset).not_to receive(:create)
|
|
69
|
+
|
|
70
|
+
post :uploader, params: { upload: upload('sample.txt', 'application/x-unsupported') }, format: :json
|
|
71
|
+
|
|
72
|
+
expect(response).to have_http_status(:unsupported_media_type)
|
|
73
|
+
expect(JSON.parse(response.body)['error']).to eq('Unsupported file type.')
|
|
74
|
+
expect(flash[:error]).to eq('Unsupported file type.')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'rejects the generic octet-stream content type with a notice' do
|
|
78
|
+
post :uploader, params: { upload: upload('sample.txt', 'application/octet-stream') }, format: :json
|
|
79
|
+
|
|
80
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
|
81
|
+
expect(JSON.parse(response.body)['error']).to match(/valid extension/)
|
|
82
|
+
expect(flash[:notice]).to match(/valid extension/)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'returns unprocessable entity when no file is provided' do
|
|
86
|
+
post :uploader, params: {}, format: :json
|
|
87
|
+
|
|
88
|
+
expect(response).to have_http_status(:unprocessable_entity)
|
|
89
|
+
expect(JSON.parse(response.body)['error']).to eq('No file uploaded.')
|
|
90
|
+
expect(flash[:error]).to eq('No file uploaded.')
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe 'POST #create' do
|
|
95
|
+
it 'creates an asset from an uploaded file and redirects (HTML)' do
|
|
96
|
+
expect {
|
|
97
|
+
post :create, params: { asset: { asset: [upload('sample.txt', 'text/plain')] } }
|
|
98
|
+
}.to change(Asset, :count).by(1)
|
|
99
|
+
|
|
100
|
+
expect(response).to be_redirect
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'redirects back to new with a flash error when the upload is unsupported' do
|
|
104
|
+
expect {
|
|
105
|
+
post :create, params: { asset: { asset: [upload('sample.txt', 'application/x-unsupported')] } }
|
|
106
|
+
}.not_to change(Asset, :count)
|
|
107
|
+
|
|
108
|
+
expect(response).to redirect_to(new_admin_asset_path)
|
|
109
|
+
expect(flash[:error]).to eq('Unsupported file type.')
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe 'DELETE #destroy' do
|
|
114
|
+
it 'destroys the asset and redirects' do
|
|
115
|
+
asset = Asset.create!(asset: upload('sample.txt', 'text/plain'), caption: '')
|
|
116
|
+
|
|
117
|
+
expect {
|
|
118
|
+
delete :destroy, params: { id: asset.id }
|
|
119
|
+
}.to change(Asset, :count).by(-1)
|
|
120
|
+
|
|
121
|
+
expect(response).to be_redirect
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# Exercises Admin::ChangesController, which builds a PaperTrail-backed diff view
|
|
4
|
+
# of recent page changes. Controller specs (views not rendered) let us drive the
|
|
5
|
+
# action and its private diff-building helpers without the admin HTML layout.
|
|
6
|
+
# PaperTrail behaviour is a plausible upgrade casualty, so this pins it down.
|
|
7
|
+
RSpec.describe Admin::ChangesController, type: :controller do
|
|
8
|
+
routes { TrustyCms::Application.routes }
|
|
9
|
+
|
|
10
|
+
let(:user) { create(:admin) }
|
|
11
|
+
let!(:site) { create(:site) }
|
|
12
|
+
|
|
13
|
+
before do
|
|
14
|
+
allow(controller).to receive(:authenticate_user!).and_return(true)
|
|
15
|
+
allow(controller).to receive(:current_user).and_return(user)
|
|
16
|
+
# The multi-site extension (which provides #current_site) isn't loaded in the
|
|
17
|
+
# dummy app, so stub it to the site our fixtures are scoped to.
|
|
18
|
+
allow(controller).to receive(:current_site).and_return(site)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Create a page scoped to the current site and give it a versioned change so
|
|
22
|
+
# the controller has something to diff.
|
|
23
|
+
def page_with_change
|
|
24
|
+
page = create(:home, title: 'Original', site_id: site.id)
|
|
25
|
+
PaperTrail.request(whodunnit: user.id.to_s) do
|
|
26
|
+
page.update!(title: 'Updated Title')
|
|
27
|
+
end
|
|
28
|
+
page
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# rails-controller-testing (which provides `assigns`) isn't in the bundle, so
|
|
32
|
+
# read the controller's assigned ivars directly.
|
|
33
|
+
def changes
|
|
34
|
+
controller.instance_variable_get(:@changes)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe 'GET #show' do
|
|
38
|
+
it 'succeeds and assigns recent changes' do
|
|
39
|
+
page_with_change
|
|
40
|
+
|
|
41
|
+
get :show
|
|
42
|
+
|
|
43
|
+
expect(response).to have_http_status(:ok)
|
|
44
|
+
expect(changes).to be_present
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'loads a single change when a version_id is given' do
|
|
48
|
+
page = page_with_change
|
|
49
|
+
version = PaperTrail::Version.where(item_type: 'Page', item_id: page.id).last
|
|
50
|
+
|
|
51
|
+
get :show, params: { version_id: version.id }
|
|
52
|
+
|
|
53
|
+
expect(response).to have_http_status(:ok)
|
|
54
|
+
expect(changes.size).to eq(1)
|
|
55
|
+
expect(changes.first[:id]).to eq(version.id)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'reports an error when the version_id is unknown' do
|
|
59
|
+
get :show, params: { version_id: 0 }
|
|
60
|
+
|
|
61
|
+
expect(changes).to be_empty
|
|
62
|
+
expect(controller.instance_variable_get(:@change_error)).to eq('Version ID not found.')
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'succeeds with no changes present' do
|
|
66
|
+
get :show
|
|
67
|
+
|
|
68
|
+
expect(response).to have_http_status(:ok)
|
|
69
|
+
expect(changes).to eq([])
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
# Exercises Admin::ConfigurationController, which batch-updates TrustyCms::Config
|
|
4
|
+
# entries inside a transaction and is admin-gated. Config plumbing is easy to
|
|
5
|
+
# break in a framework upgrade, so pin the happy path and the auth gate.
|
|
6
|
+
RSpec.describe Admin::ConfigurationController, type: :controller do
|
|
7
|
+
routes { TrustyCms::Application.routes }
|
|
8
|
+
|
|
9
|
+
let(:admin) { create(:admin) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
allow(controller).to receive(:authenticate_user!).and_return(true)
|
|
13
|
+
allow(controller).to receive(:current_user).and_return(admin)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe 'GET #show' do
|
|
17
|
+
it 'succeeds' do
|
|
18
|
+
get :show
|
|
19
|
+
expect(response).to have_http_status(:ok)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'GET #edit' do
|
|
24
|
+
it 'succeeds for an admin' do
|
|
25
|
+
get :edit
|
|
26
|
+
expect(response).to have_http_status(:ok)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'PUT #update' do
|
|
31
|
+
it 'persists the submitted config values and redirects to show' do
|
|
32
|
+
put :update, params: { trusty_config: { 'admin.title' => 'Renamed CMS' } }
|
|
33
|
+
|
|
34
|
+
expect(response).to redirect_to(action: :show)
|
|
35
|
+
expect(TrustyCms::Config['admin.title']).to eq('Renamed CMS')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe 'authorization' do
|
|
40
|
+
it 'denies a non-admin access to edit' do
|
|
41
|
+
allow(controller).to receive(:current_user).and_return(create(:non_admin, email: 'plain@example.com'))
|
|
42
|
+
|
|
43
|
+
get :edit
|
|
44
|
+
|
|
45
|
+
expect(response).to be_redirect
|
|
46
|
+
expect(flash[:error]).to be_present
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rack/test'
|
|
3
|
+
|
|
4
|
+
# Exercises Admin::PageAttachmentsController, whose custom #load_model builds a
|
|
5
|
+
# PageAttachment from an asset_id (+ optional page_id) and rescues a missing
|
|
6
|
+
# asset. Controller spec (views not rendered) drives the action and its
|
|
7
|
+
# before-action without needing the admin HTML layout.
|
|
8
|
+
RSpec.describe Admin::PageAttachmentsController, type: :controller do
|
|
9
|
+
routes { TrustyCms::Application.routes }
|
|
10
|
+
|
|
11
|
+
let(:user) { create(:admin) }
|
|
12
|
+
let(:fixtures_path) { TrustyCms::Engine.root.join('spec', 'fixtures', 'files') }
|
|
13
|
+
let(:asset) do
|
|
14
|
+
Asset.create!(asset: Rack::Test::UploadedFile.new(fixtures_path.join('sample.txt'), 'text/plain'), caption: '')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
before do
|
|
18
|
+
register_standard_asset_types # shared canonical AssetTypes (see AssetTypeRegistry)
|
|
19
|
+
allow(controller).to receive(:authenticate_user!).and_return(true)
|
|
20
|
+
allow(controller).to receive(:current_user).and_return(user)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'GET #new' do
|
|
24
|
+
it 'builds a PageAttachment for the asset with a new (unsaved) page' do
|
|
25
|
+
get :new, params: { asset_id: asset.id }
|
|
26
|
+
|
|
27
|
+
expect(response).to have_http_status(:ok)
|
|
28
|
+
model = controller.instance_variable_get(:@page_attachment)
|
|
29
|
+
expect(model).to be_a(PageAttachment)
|
|
30
|
+
expect(model.asset).to eq(asset)
|
|
31
|
+
expect(model.page).to be_a(Page).and be_new_record
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'associates an existing page when a page_id is given' do
|
|
35
|
+
page = create(:home, title: 'Attach Target')
|
|
36
|
+
|
|
37
|
+
get :new, params: { asset_id: asset.id, page_id: page.id }
|
|
38
|
+
|
|
39
|
+
expect(controller.instance_variable_get(:@page)).to eq(page)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# NOTE: latent bug — load_model rescues a missing asset with
|
|
43
|
+
# `render nothing: true`, but the `nothing:` option was removed in Rails 5.1.
|
|
44
|
+
# It's now ignored, so Rails falls through to rendering the (nonexistent)
|
|
45
|
+
# `new` template and raises MissingTemplate instead of returning an empty
|
|
46
|
+
# body. Characterizing current behavior; the fix is `head :no_content`.
|
|
47
|
+
# This is exactly the kind of breakage a Rails 8 upgrade should clean up.
|
|
48
|
+
it 'raises MissingTemplate for a missing asset (broken rescue path)' do
|
|
49
|
+
expect {
|
|
50
|
+
get :new, params: { asset_id: 0 }
|
|
51
|
+
}.to raise_error(ActionView::MissingTemplate)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|