hanami 2.1.0.beta1 → 2.1.0.beta2

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -4
  3. data/README.md +1 -1
  4. data/lib/hanami/app.rb +5 -0
  5. data/lib/hanami/config/actions.rb +4 -7
  6. data/lib/hanami/config/assets.rb +84 -0
  7. data/lib/hanami/config/null_config.rb +3 -0
  8. data/lib/hanami/config.rb +17 -5
  9. data/lib/hanami/extensions/action.rb +4 -2
  10. data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
  11. data/lib/hanami/helpers/assets_helper.rb +752 -0
  12. data/lib/hanami/middleware/assets.rb +21 -0
  13. data/lib/hanami/middleware/render_errors.rb +4 -7
  14. data/lib/hanami/providers/assets.rb +44 -0
  15. data/lib/hanami/rake_tasks.rb +19 -18
  16. data/lib/hanami/settings.rb +1 -1
  17. data/lib/hanami/slice.rb +25 -4
  18. data/lib/hanami/version.rb +1 -1
  19. data/lib/hanami.rb +2 -2
  20. data/spec/integration/assets/assets_spec.rb +101 -0
  21. data/spec/integration/assets/serve_static_assets_spec.rb +152 -0
  22. data/spec/integration/logging/exception_logging_spec.rb +115 -0
  23. data/spec/integration/logging/notifications_spec.rb +68 -0
  24. data/spec/integration/logging/request_logging_spec.rb +128 -0
  25. data/spec/integration/rack_app/middleware_spec.rb +4 -4
  26. data/spec/integration/rack_app/rack_app_spec.rb +0 -221
  27. data/spec/integration/rake_tasks_spec.rb +107 -0
  28. data/spec/integration/view/context/assets_spec.rb +3 -9
  29. data/spec/integration/web/render_detailed_errors_spec.rb +17 -0
  30. data/spec/integration/web/render_errors_spec.rb +6 -4
  31. data/spec/support/app_integration.rb +46 -2
  32. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +24 -36
  33. data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +4 -3
  34. data/spec/unit/hanami/config/actions/default_values_spec.rb +3 -2
  35. data/spec/unit/hanami/env_spec.rb +11 -25
  36. data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +109 -0
  37. data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +132 -0
  38. data/spec/unit/hanami/helpers/assets_helper/favicon_link_tag_spec.rb +91 -0
  39. data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +92 -0
  40. data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +143 -0
  41. data/spec/unit/hanami/helpers/assets_helper/stylesheet_link_tag_spec.rb +126 -0
  42. data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +132 -0
  43. data/spec/unit/hanami/version_spec.rb +1 -1
  44. metadata +32 -4
  45. data/lib/hanami/assets/app_config.rb +0 -61
  46. data/lib/hanami/assets/config.rb +0 -53
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rack/test"
5
+ require "stringio"
6
+
7
+ RSpec.describe "Logging / Request logging", :app_integration do
8
+ include Rack::Test::Methods
9
+
10
+ let(:app) { Hanami.app }
11
+
12
+ let(:logger_stream) { StringIO.new }
13
+
14
+ def configure_logger
15
+ Hanami.app.config.logger.stream = logger_stream
16
+ end
17
+
18
+ def logs
19
+ @logs ||= (logger_stream.rewind and logger_stream.read)
20
+ end
21
+
22
+ before do
23
+ with_directory(make_tmp_directory) do
24
+ write "config/app.rb", <<~RUBY
25
+ module TestApp
26
+ class App < Hanami::App
27
+ end
28
+ end
29
+ RUBY
30
+
31
+ require "hanami/setup"
32
+ configure_logger
33
+
34
+ before_prepare if respond_to?(:before_prepare)
35
+ require "hanami/prepare"
36
+ end
37
+ end
38
+
39
+ describe "app router" do
40
+ def before_prepare
41
+ write "config/routes.rb", <<~RUBY
42
+ module TestApp
43
+ class Routes < Hanami::Routes
44
+ root to: ->(env) { [200, {}, ["OK"]] }
45
+ end
46
+ end
47
+ RUBY
48
+ end
49
+
50
+ it "logs the requests" do
51
+ get "/"
52
+
53
+ expect(logs.split("\n").length).to eq 1
54
+ expect(logs).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
55
+ end
56
+
57
+ context "production env" do
58
+ around do |example|
59
+ @prev_hanami_env = ENV["HANAMI_ENV"]
60
+ ENV["HANAMI_ENV"] = "production"
61
+ example.run
62
+ ensure
63
+ ENV["HANAMI_ENV"] = @prev_hanami_env
64
+ end
65
+
66
+ it "logs the requests as JSON" do
67
+ get "/"
68
+
69
+ expect(logs.split("\n").length).to eq 1
70
+
71
+ json = JSON.parse(logs, symbolize_names: true)
72
+ expect(json).to include(
73
+ verb: "GET",
74
+ path: "/",
75
+ ip: "127.0.0.1",
76
+ elapsed: Integer,
77
+ elapsed_unit: a_string_matching(/(µs|ms)/),
78
+ )
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "slice router" do
84
+ let(:app) { Main::Slice.rack_app }
85
+
86
+ def before_prepare
87
+ write "slices/main/config/routes.rb", <<~RUBY
88
+ module Main
89
+ class Routes < Hanami::Routes
90
+ root to: ->(env) { [200, {}, ["OK"]] }
91
+ end
92
+ end
93
+ RUBY
94
+ end
95
+
96
+ it "logs the requests" do
97
+ get "/"
98
+
99
+ expect(logs.split("\n").length).to eq 1
100
+ expect(logs).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
101
+ end
102
+
103
+ context "production env" do
104
+ around do |example|
105
+ @prev_hanami_env = ENV["HANAMI_ENV"]
106
+ ENV["HANAMI_ENV"] = "production"
107
+ example.run
108
+ ensure
109
+ ENV["HANAMI_ENV"] = @prev_hanami_env
110
+ end
111
+
112
+ it "logs the requests as JSON" do
113
+ get "/"
114
+
115
+ expect(logs.split("\n").length).to eq 1
116
+
117
+ json = JSON.parse(logs, symbolize_names: true)
118
+ expect(json).to include(
119
+ verb: "GET",
120
+ path: "/",
121
+ ip: "127.0.0.1",
122
+ elapsed: Integer,
123
+ elapsed_unit: a_string_matching(/(µs|ms)/),
124
+ )
125
+ end
126
+ end
127
+ end
128
+ end
@@ -317,7 +317,7 @@ RSpec.describe "Hanami web app", :app_integration do
317
317
  it "excludes not found routes in root scope" do
318
318
  get "/foo"
319
319
 
320
- expect(last_response.status).to eq 500
320
+ expect(last_response.status).to eq 404
321
321
  expect(last_response.headers).to_not have_key("X-Auth-User-ID")
322
322
  end
323
323
 
@@ -333,7 +333,7 @@ RSpec.describe "Hanami web app", :app_integration do
333
333
  it "does not uses the Rack middleware for not found paths" do
334
334
  get "/admin/users"
335
335
 
336
- expect(last_response.status).to eq 500
336
+ expect(last_response.status).to eq 404
337
337
  expect(last_response.headers).not_to have_key("X-Auth-User-ID")
338
338
  end
339
339
  end
@@ -600,7 +600,7 @@ RSpec.describe "Hanami web app", :app_integration do
600
600
  it "does not use Rack middleware for other paths" do
601
601
  get "/__not_found__"
602
602
 
603
- expect(last_response.status).to eq 500
603
+ expect(last_response.status).to eq 404
604
604
  expect(last_response.headers).not_to have_key("X-Identifier-Root")
605
605
  expect(last_response.headers).not_to have_key("X-Elapsed")
606
606
  expect(last_response.headers).not_to have_key("X-Auth-User-ID")
@@ -623,7 +623,7 @@ RSpec.describe "Hanami web app", :app_integration do
623
623
  it "uses Rack middleware for other paths" do
624
624
  get "/admin/__not_found__"
625
625
 
626
- expect(last_response.status).to eq 500
626
+ expect(last_response.status).to eq 404
627
627
  expect(last_response.headers).not_to have_key("X-Identifier-Admin")
628
628
  expect(last_response.headers).not_to have_key("X-Elapsed")
629
629
  expect(last_response.headers).not_to have_key("X-Elapsed")
@@ -33,227 +33,6 @@ RSpec.describe "Hanami web app", :app_integration do
33
33
  end
34
34
  end
35
35
 
36
- specify "Has rack monitor preconfigured with default request logging" do
37
- dir = Dir.mktmpdir
38
-
39
- with_tmp_directory(dir) do
40
- write "config/app.rb", <<~RUBY
41
- require "hanami"
42
-
43
- module TestApp
44
- class App < Hanami::App
45
- config.actions.format :json
46
- config.logger.options = {colorize: true}
47
- config.logger.stream = config.root.join("test.log")
48
- end
49
- end
50
- RUBY
51
-
52
- write "app/actions/users/index.rb", <<~RUBY
53
- module TestApp
54
- module Actions
55
- module Users
56
- class Index < Hanami::Action
57
- def handle(req, _resp)
58
- raise StandardError, "OH NOEZ"
59
- end
60
- end
61
- end
62
- end
63
- end
64
- RUBY
65
-
66
- write "app/actions/users/create.rb", <<~RUBY
67
- module TestApp
68
- module Actions
69
- module Users
70
- class Create < Hanami::Action
71
- def handle(req, resp)
72
- resp.body = req.params.to_h.keys
73
- end
74
- end
75
- end
76
- end
77
- end
78
- RUBY
79
-
80
- write "config/routes.rb", <<~RUBY
81
- module TestApp
82
- class Routes < Hanami::Routes
83
- root to: ->(env) { [200, {}, ["OK"]] }
84
- get "/users", to: "users.index"
85
- post "/users", to: "users.create"
86
- end
87
- end
88
- RUBY
89
-
90
- require "hanami/prepare"
91
-
92
- expect(Hanami.app["rack.monitor"]).to be_instance_of(Dry::Monitor::Rack::Middleware)
93
-
94
- get "/"
95
-
96
- logs = -> { Pathname(dir).join("test.log").realpath.read }
97
-
98
- expect(logs.()).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
99
-
100
- post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
101
-
102
- expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
103
-
104
- begin
105
- get "/users"
106
- rescue => e # rubocop:disable Style/RescueStandardError
107
- raise unless e.to_s == "OH NOEZ"
108
- end
109
-
110
- err_log = logs.()
111
-
112
- expect(err_log).to include("OH NOEZ")
113
- expect(err_log).to include("app/actions/users/index.rb:6:in `handle'")
114
- end
115
- end
116
-
117
- specify "Logging via the rack monitor even when notifications bus has already been used" do
118
- dir = Dir.mktmpdir
119
-
120
- with_tmp_directory(dir) do
121
- write "config/app.rb", <<~RUBY
122
- require "hanami"
123
-
124
- module TestApp
125
- class App < Hanami::App
126
- config.actions.format :json
127
- config.logger.options = {colorize: true}
128
- config.logger.stream = config.root.join("test.log")
129
- end
130
- end
131
- RUBY
132
-
133
- write "config/routes.rb", <<~RUBY
134
- module TestApp
135
- class Routes < Hanami::Routes
136
- post "/users", to: "users.create"
137
- end
138
- end
139
- RUBY
140
-
141
- write "app/actions/users/create.rb", <<~RUBY
142
- module TestApp
143
- module Actions
144
- module Users
145
- class Create < Hanami::Action
146
- def handle(req, resp)
147
- resp.body = req.params.to_h.keys
148
- end
149
- end
150
- end
151
- end
152
- end
153
- RUBY
154
-
155
- require "hanami/prepare"
156
-
157
- # Simulate any component interacting with the notifications bus such that it creates its
158
- # internal bus with a duplicate copy of all currently registered events. This means that the
159
- # class-level Dry::Monitor::Notification events implicitly registered by the
160
- # Dry::Monitor::Rack::Middleware activated via the rack provider are ignored, unless our
161
- # provider explicitly re-registers them on _instance_ of the notifications bus.
162
- #
163
- # See Hanami::Providers::Rack for more detail.
164
- Hanami.app["notifications"].instrument(:sql)
165
-
166
- logs = -> { Pathname(dir).join("test.log").realpath.read }
167
-
168
- post "/users", JSON.generate(name: "jane", password: "secret"), {"CONTENT_TYPE" => "application/json"}
169
- expect(logs.()).to match %r{POST 200 \d+(µs|ms) 127.0.0.1 /}
170
- end
171
- end
172
-
173
- describe "Request logging when using slice router" do
174
- let(:app) { Main::Slice.rack_app }
175
-
176
- specify "Has rack monitor preconfigured with default request logging (when used via a slice)" do
177
- dir = Dir.mktmpdir
178
-
179
- with_tmp_directory(dir) do
180
- write "config/app.rb", <<~RUBY
181
- require "hanami"
182
-
183
- module TestApp
184
- class App < Hanami::App
185
- config.logger.stream = config.root.join("test.log")
186
- end
187
- end
188
- RUBY
189
-
190
- write "slices/main/config/routes.rb", <<~RUBY
191
- module Main
192
- class Routes < Hanami::Routes
193
- root to: ->(env) { [200, {}, ["OK"]] }
194
- end
195
- end
196
- RUBY
197
-
198
- require "hanami/prepare"
199
-
200
- get "/"
201
-
202
- logs = -> { Pathname(dir).join("test.log").realpath.read }
203
-
204
- expect(logs.()).to match %r{GET 200 \d+(µs|ms) 127.0.0.1 /}
205
- end
206
- end
207
- end
208
-
209
- describe "Request logging on production" do
210
- let(:app) { Main::Slice.rack_app }
211
-
212
- around do |example|
213
- @prev_hanami_env = ENV["HANAMI_ENV"]
214
- ENV["HANAMI_ENV"] = "production"
215
- example.run
216
- ensure
217
- ENV["HANAMI_ENV"] = @prev_hanami_env
218
- end
219
-
220
- specify "Has rack monitor preconfigured with default request logging (when used via a slice)" do
221
- dir = Dir.mktmpdir
222
-
223
- with_tmp_directory(dir) do
224
- write "config/app.rb", <<~RUBY
225
- require "hanami"
226
-
227
- module TestApp
228
- class App < Hanami::App
229
- config.logger.stream = config.root.join("test.log")
230
- end
231
- end
232
- RUBY
233
-
234
- write "slices/main/config/routes.rb", <<~RUBY
235
- module Main
236
- class Routes < Hanami::Routes
237
- root to: ->(env) { [200, {}, ["OK"]] }
238
- end
239
- end
240
- RUBY
241
-
242
- require "hanami/boot"
243
-
244
- get "/"
245
-
246
- logs = -> { Pathname(dir).join("test.log").realpath.read }
247
-
248
- log_content = logs.()
249
-
250
- expect(log_content).to match(%r["verb":"GET"])
251
- expect(log_content).to match(%r["path":"/"])
252
- expect(log_content).to match(%r[elapsed":\d+,"elapsed_unit":"µs"])
253
- end
254
- end
255
- end
256
-
257
36
  specify "Routing to actions based on their container identifiers" do
258
37
  with_tmp_directory(Dir.mktmpdir) do
259
38
  write "config/app.rb", <<~RUBY
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+ require "hanami/cli/bundler"
5
+
6
+ RSpec.describe "Rake tasks", :app_integration do
7
+ describe "assets:precompile" do
8
+ before do
9
+ allow(Hanami).to receive(:bundled?)
10
+ allow(Hanami).to receive(:bundled?).with("hanami-assets").and_return(hanami_assets_bundled)
11
+ end
12
+
13
+ context "when hanami-assets is bundled" do
14
+ let(:hanami_assets_bundled) { true }
15
+
16
+ xit "compiles assets" do
17
+ with_tmp_directory(Dir.mktmpdir) do
18
+ write "config/app.rb", <<~'RUBY'
19
+ require "hanami"
20
+
21
+ module TestApp
22
+ class App < Hanami::App
23
+ end
24
+ end
25
+ RUBY
26
+
27
+ write "Rakefile", <<~RUBY
28
+ # frozen_string_literal: true
29
+
30
+ require "hanami/rake_tasks"
31
+ RUBY
32
+
33
+ write "app/assets/js/app.js", <<~JS
34
+ console.log("Hello from index.js");
35
+ JS
36
+
37
+ before_prepare if respond_to?(:before_prepare)
38
+ require "hanami/prepare"
39
+
40
+ expect_any_instance_of(Hanami::CLI::Bundler).to receive(:hanami_exec).with("assets compile").and_return(true)
41
+
42
+ Rake::Task["assets:precompile"].invoke
43
+ end
44
+ end
45
+
46
+ it "doesn't list the task" do
47
+ with_tmp_directory(Dir.mktmpdir) do
48
+ write "config/app.rb", <<~'RUBY'
49
+ require "hanami"
50
+
51
+ module TestApp
52
+ class App < Hanami::App
53
+ end
54
+ end
55
+ RUBY
56
+
57
+ write "Rakefile", <<~RUBY
58
+ # frozen_string_literal: true
59
+
60
+ require "hanami/rake_tasks"
61
+ RUBY
62
+
63
+ before_prepare if respond_to?(:before_prepare)
64
+ require "hanami/prepare"
65
+
66
+ output = `bundle exec rake -T`
67
+ expect(output).to_not include("assets:precompile")
68
+ end
69
+ end
70
+ end
71
+
72
+ context "when hanami-assets is not bundled" do
73
+ let(:hanami_assets_bundled) { false }
74
+
75
+ it "raises error" do
76
+ with_tmp_directory(Dir.mktmpdir) do
77
+ write "config/app.rb", <<~'RUBY'
78
+ require "hanami"
79
+
80
+ module TestApp
81
+ class App < Hanami::App
82
+ end
83
+ end
84
+ RUBY
85
+
86
+ write "Rakefile", <<~RUBY
87
+ # frozen_string_literal: true
88
+
89
+ require "hanami/rake_tasks"
90
+ RUBY
91
+
92
+ write "app/assets/js/app.js", <<~JS
93
+ console.log("Hello from index.js");
94
+ JS
95
+
96
+ before_prepare if respond_to?(:before_prepare)
97
+ require "hanami/prepare"
98
+
99
+ expect { Rake::Task["assets:precompile"].invoke }.to raise_error do |exception|
100
+ expect(exception).to be_a(RuntimeError)
101
+ expect(exception.message).to match(/Don't know how to build task 'assets:precompile'/)
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -24,21 +24,15 @@ RSpec.describe "App view / Context / Assets", :app_integration do
24
24
 
25
25
  describe "#assets" do
26
26
  context "without assets provider" do
27
- it "raises error" do
27
+ xit "raises error" do
28
+ allow(Hanami).to receive(:bundled?).with("hanami-assets").and_return(false)
29
+
28
30
  expect { context.assets }
29
31
  .to raise_error(Hanami::ComponentLoadError, /hanami-assets/)
30
32
  end
31
33
  end
32
34
 
33
35
  context "with assets provider" do
34
- before do
35
- Hanami.app.register_provider(:assets) do
36
- start do
37
- register "assets", Object.new
38
- end
39
- end
40
- end
41
-
42
36
  it "is the app assets by default" do
43
37
  expect(context.assets).to be TestApp::App[:assets]
44
38
  end
@@ -56,6 +56,15 @@ RSpec.describe "Web / Rendering detailed errors", :app_integration do
56
56
  expect(html).to have_selector("header", text: "RuntimeError at /error")
57
57
  expect(html).to have_selector("ul.frames li.application", text: "app/actions/error.rb")
58
58
  end
59
+
60
+ it "renders a detailed HTML error page and returns a 404 status for a not found error" do
61
+ get "/__not_found__", {}, "HTTP_ACCEPT" => "text/html"
62
+
63
+ expect(last_response.status).to eq 404
64
+
65
+ html = Capybara.string(last_response.body)
66
+ expect(html).to have_selector("header", text: "Hanami::Router::NotFoundError at /__not_found__")
67
+ end
59
68
  end
60
69
 
61
70
  describe "Other request types" do
@@ -67,6 +76,14 @@ RSpec.describe "Web / Rendering detailed errors", :app_integration do
67
76
  expect(last_response.body).to include "RuntimeError at /error"
68
77
  expect(last_response.body).to match %r{App backtrace.+app/actions/error.rb}m
69
78
  end
79
+
80
+ it "renders a detailed error page in text and returns a 404 status for a not found error" do
81
+ get "/__not_found__", {}, "HTTP_ACCEPT" => "text/html"
82
+
83
+ expect(last_response.status).to eq 404
84
+
85
+ expect(last_response.body).to include "Hanami::Router::NotFoundError at /__not_found__"
86
+ end
70
87
  end
71
88
 
72
89
  describe "render_detailed_errors config disabled" do
@@ -225,12 +225,14 @@ RSpec.describe "Web / Rendering errors", :app_integration do
225
225
  HTML
226
226
  end
227
227
 
228
- it "raises a Hanami::Router::NotFoundError for a 404" do
229
- expect { get "/__not_found__" }.to raise_error(Hanami::Router::NotFoundError)
228
+ it "renders the hanami-router default 404 response for a not found error" do
229
+ get "/__not_found__"
230
+ expect(last_response.status).to eq 404
230
231
  end
231
232
 
232
- it "raises a Hanami::Router::NotAllowedError for a 405" do
233
- expect { post "/index" }.to raise_error(Hanami::Router::NotAllowedError)
233
+ it "renders the hanami-router default 405 response for a not allowed error" do
234
+ post "/index"
235
+ expect(last_response.status).to eq 405
234
236
  end
235
237
 
236
238
  it "raises the original error for a 500" do
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "hanami/devtools/integration/files"
4
4
  require "hanami/devtools/integration/with_tmp_directory"
5
+ require "json"
5
6
  require "tmpdir"
6
7
  require "zeitwerk"
7
8
 
@@ -16,10 +17,52 @@ module RSpec
16
17
  end
17
18
  end
18
19
  end
20
+
21
+ module App
22
+ def self.included(base)
23
+ super
24
+
25
+ base.class_eval do
26
+ let!(:node_modules_path) { File.join(Dir.pwd, "node_modules") }
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def stub_assets(*assets)
33
+ manifest_hash = assets.each_with_object({}) { |source_path, hsh|
34
+ hsh[source_path] = {url: File.join("/assets", source_path)}
35
+ }
36
+
37
+ write "public/assets.json", JSON.generate(manifest_hash)
38
+ end
39
+
40
+ def compile_assets!
41
+ link_node_modules
42
+
43
+ require "hanami/cli/command"
44
+ require "hanami/cli/commands/app/command"
45
+ require "hanami/cli/commands/app/assets/compile"
46
+ compiler = Hanami::CLI::Commands::App::Assets::Compile.new(config: Hanami.app.config.assets)
47
+
48
+ with_directory(Hanami.app.root) do
49
+ compiler.call
50
+ end
51
+ end
52
+
53
+ def link_node_modules
54
+ root = Hanami.app.root
55
+
56
+ return if File.exist?(File.join(root, "node_modules", "hanami-assets", "dist", "hanami-assets.js"))
57
+
58
+ FileUtils.ln_s(node_modules_path, root)
59
+ rescue Errno::EEXIST # rubocop:disable Lint/SuppressedException
60
+ end
61
+ end
19
62
  end
20
63
  end
21
64
 
22
- RSpec.shared_context "Application integration" do
65
+ RSpec.shared_context "App integration" do
23
66
  let(:app_modules) { %i[TestApp Admin Main Search] }
24
67
  end
25
68
 
@@ -35,7 +78,8 @@ end
35
78
  RSpec.configure do |config|
36
79
  config.include RSpec::Support::Files, :app_integration
37
80
  config.include RSpec::Support::WithTmpDirectory, :app_integration
38
- config.include_context "Application integration", :app_integration
81
+ config.include RSpec::Support::App, :app_integration
82
+ config.include_context "App integration", :app_integration
39
83
 
40
84
  config.before :each, :app_integration do
41
85
  # Conditionally assign these in case they have been assigned earlier for specific