hanami 2.3.2 → 3.0.0.rc1
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/CHANGELOG.md +55 -19
- data/LICENSE +20 -0
- data/README.md +18 -35
- data/hanami.gemspec +36 -37
- data/lib/hanami/config/db.rb +2 -0
- data/lib/hanami/config/i18n.rb +138 -0
- data/lib/hanami/config/logger.rb +15 -7
- data/lib/hanami/config/null_config.rb +1 -1
- data/lib/hanami/config/views.rb +17 -0
- data/lib/hanami/config.rb +66 -22
- data/lib/hanami/errors.rb +6 -0
- data/lib/hanami/extensions/action/slice_configured_action.rb +1 -1
- data/lib/hanami/extensions/action.rb +2 -2
- data/lib/hanami/extensions/mailer/slice_configured_mailer.rb +120 -0
- data/lib/hanami/extensions/mailer.rb +28 -0
- data/lib/hanami/extensions/operation/slice_configured_db_operation.rb +2 -0
- data/lib/hanami/extensions/view/context.rb +26 -4
- data/lib/hanami/extensions/view/part.rb +2 -0
- data/lib/hanami/extensions/view/slice_configured_context.rb +7 -0
- data/lib/hanami/extensions/view/slice_configured_part.rb +2 -0
- data/lib/hanami/extensions/view/slice_configured_view.rb +8 -8
- data/lib/hanami/extensions/view/standard_helpers.rb +4 -0
- data/lib/hanami/extensions.rb +6 -1
- data/lib/hanami/helpers/assets_helper.rb +0 -4
- data/lib/hanami/helpers/form_helper.rb +1 -1
- data/lib/hanami/helpers/i18n_helper.rb +176 -0
- data/lib/hanami/logger/rack_formatter.rb +73 -0
- data/lib/hanami/logger/sql_formatter.rb +80 -0
- data/lib/hanami/logger/sql_logger.rb +48 -0
- data/lib/hanami/middleware/render_errors.rb +2 -2
- data/lib/hanami/providers/db.rb +7 -2
- data/lib/hanami/providers/db_logging.rb +4 -7
- data/lib/hanami/providers/i18n/backend.rb +369 -0
- data/lib/hanami/providers/i18n/locale/en.yml +57 -0
- data/lib/hanami/providers/i18n.rb +114 -0
- data/lib/hanami/providers/mailers.rb +101 -0
- data/lib/hanami/routes.rb +1 -0
- data/lib/hanami/settings/composite_store.rb +53 -0
- data/lib/hanami/settings.rb +4 -4
- data/lib/hanami/slice/router.rb +15 -10
- data/lib/hanami/slice.rb +71 -11
- data/lib/hanami/slice_registrar.rb +2 -2
- data/lib/hanami/universal_logger.rb +250 -0
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami/web/rack_logger.rb +2 -80
- data/lib/hanami/web/welcome.html.erb +443 -58
- data/lib/hanami.rb +4 -2
- metadata +28 -276
- data/CODE_OF_CONDUCT.md +0 -74
- data/FEATURES.md +0 -269
- data/LICENSE.md +0 -22
- data/spec/integration/action/cookies_spec.rb +0 -58
- data/spec/integration/action/csrf_protection_spec.rb +0 -54
- data/spec/integration/action/format_config_spec.rb +0 -129
- data/spec/integration/action/routes_spec.rb +0 -71
- data/spec/integration/action/sessions_spec.rb +0 -50
- data/spec/integration/action/slice_configuration_spec.rb +0 -284
- data/spec/integration/action/view_rendering/automatic_rendering_spec.rb +0 -247
- data/spec/integration/action/view_rendering/paired_view_inference_spec.rb +0 -115
- data/spec/integration/action/view_rendering/view_context_spec.rb +0 -221
- data/spec/integration/action/view_rendering_spec.rb +0 -89
- data/spec/integration/assets/assets_spec.rb +0 -155
- data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +0 -129
- data/spec/integration/assets/serve_static_assets_spec.rb +0 -152
- data/spec/integration/code_loading/loading_from_app_spec.rb +0 -152
- data/spec/integration/code_loading/loading_from_lib_spec.rb +0 -242
- data/spec/integration/code_loading/loading_from_slice_spec.rb +0 -165
- data/spec/integration/container/application_routes_helper_spec.rb +0 -48
- data/spec/integration/container/auto_injection_spec.rb +0 -53
- data/spec/integration/container/auto_registration_spec.rb +0 -86
- data/spec/integration/container/autoloader_spec.rb +0 -82
- data/spec/integration/container/imports_spec.rb +0 -253
- data/spec/integration/container/prepare_container_spec.rb +0 -125
- data/spec/integration/container/provider_environment_spec.rb +0 -52
- data/spec/integration/container/provider_lifecycle_spec.rb +0 -61
- data/spec/integration/container/shutdown_spec.rb +0 -91
- data/spec/integration/container/standard_providers/rack_provider_spec.rb +0 -44
- data/spec/integration/container/standard_providers_spec.rb +0 -124
- data/spec/integration/db/auto_registration_spec.rb +0 -39
- data/spec/integration/db/commands_spec.rb +0 -80
- data/spec/integration/db/db_inflector_spec.rb +0 -57
- data/spec/integration/db/db_slices_spec.rb +0 -398
- data/spec/integration/db/db_spec.rb +0 -245
- data/spec/integration/db/gateways_spec.rb +0 -361
- data/spec/integration/db/logging_spec.rb +0 -301
- data/spec/integration/db/mappers_spec.rb +0 -84
- data/spec/integration/db/provider_config_spec.rb +0 -88
- data/spec/integration/db/provider_spec.rb +0 -35
- data/spec/integration/db/relations_spec.rb +0 -60
- data/spec/integration/db/repo_spec.rb +0 -300
- data/spec/integration/db/slices_importing_from_parent.rb +0 -130
- data/spec/integration/dotenv_loading_spec.rb +0 -138
- data/spec/integration/logging/exception_logging_spec.rb +0 -120
- data/spec/integration/logging/notifications_spec.rb +0 -68
- data/spec/integration/logging/request_logging_spec.rb +0 -202
- data/spec/integration/operations/extension_spec.rb +0 -122
- data/spec/integration/rack_app/body_parser_spec.rb +0 -108
- data/spec/integration/rack_app/method_override_spec.rb +0 -97
- data/spec/integration/rack_app/middleware_spec.rb +0 -720
- data/spec/integration/rack_app/non_booted_rack_app_spec.rb +0 -104
- data/spec/integration/rack_app/rack_app_spec.rb +0 -442
- data/spec/integration/rake_tasks_spec.rb +0 -107
- data/spec/integration/router/resource_routes_spec.rb +0 -281
- data/spec/integration/settings/access_in_slice_class_body_spec.rb +0 -83
- data/spec/integration/settings/access_to_constants_spec.rb +0 -46
- data/spec/integration/settings/loading_from_env_spec.rb +0 -188
- data/spec/integration/settings/settings_component_loading_spec.rb +0 -113
- data/spec/integration/settings/slice_registration_spec.rb +0 -145
- data/spec/integration/settings/using_types_spec.rb +0 -80
- data/spec/integration/setup_spec.rb +0 -165
- data/spec/integration/slices/external_slice_spec.rb +0 -91
- data/spec/integration/slices/slice_configuration_spec.rb +0 -42
- data/spec/integration/slices/slice_loading_spec.rb +0 -171
- data/spec/integration/slices/slice_registrations_spec.rb +0 -80
- data/spec/integration/slices/slice_routing_spec.rb +0 -219
- data/spec/integration/slices_spec.rb +0 -471
- data/spec/integration/view/config/default_context_spec.rb +0 -149
- data/spec/integration/view/config/inflector_spec.rb +0 -57
- data/spec/integration/view/config/part_class_spec.rb +0 -147
- data/spec/integration/view/config/part_namespace_spec.rb +0 -103
- data/spec/integration/view/config/paths_spec.rb +0 -119
- data/spec/integration/view/config/scope_class_spec.rb +0 -147
- data/spec/integration/view/config/scope_namespace_spec.rb +0 -103
- data/spec/integration/view/config/template_spec.rb +0 -38
- data/spec/integration/view/context/assets_spec.rb +0 -79
- data/spec/integration/view/context/inflector_spec.rb +0 -40
- data/spec/integration/view/context/request_spec.rb +0 -57
- data/spec/integration/view/context/routes_spec.rb +0 -84
- data/spec/integration/view/helpers/form_helper_spec.rb +0 -174
- data/spec/integration/view/helpers/part_helpers_spec.rb +0 -124
- data/spec/integration/view/helpers/scope_helpers_spec.rb +0 -84
- data/spec/integration/view/helpers/user_defined_helpers/part_helpers_spec.rb +0 -162
- data/spec/integration/view/helpers/user_defined_helpers/scope_helpers_spec.rb +0 -119
- data/spec/integration/view/parts/default_rendering_spec.rb +0 -138
- data/spec/integration/view/slice_configuration_spec.rb +0 -289
- data/spec/integration/view/views_spec.rb +0 -103
- data/spec/integration/web/content_security_policy_nonce_spec.rb +0 -251
- data/spec/integration/web/render_detailed_errors_spec.rb +0 -107
- data/spec/integration/web/render_errors_spec.rb +0 -242
- data/spec/integration/web/welcome_view_spec.rb +0 -84
- data/spec/spec_helper.rb +0 -28
- data/spec/support/app_integration.rb +0 -157
- data/spec/support/coverage.rb +0 -1
- data/spec/support/matchers.rb +0 -32
- data/spec/support/rspec.rb +0 -27
- data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +0 -96
- data/spec/unit/hanami/config/actions/cookies_spec.rb +0 -46
- data/spec/unit/hanami/config/actions/csrf_protection_spec.rb +0 -58
- data/spec/unit/hanami/config/actions/default_values_spec.rb +0 -43
- data/spec/unit/hanami/config/actions/sessions_spec.rb +0 -48
- data/spec/unit/hanami/config/actions_spec.rb +0 -52
- data/spec/unit/hanami/config/base_url_spec.rb +0 -25
- data/spec/unit/hanami/config/console_spec.rb +0 -22
- data/spec/unit/hanami/config/db_spec.rb +0 -38
- data/spec/unit/hanami/config/inflector_spec.rb +0 -35
- data/spec/unit/hanami/config/logger_spec.rb +0 -195
- data/spec/unit/hanami/config/render_detailed_errors_spec.rb +0 -25
- data/spec/unit/hanami/config/render_errors_spec.rb +0 -25
- data/spec/unit/hanami/config/router_spec.rb +0 -44
- data/spec/unit/hanami/config/slices_spec.rb +0 -34
- data/spec/unit/hanami/config/views_spec.rb +0 -80
- data/spec/unit/hanami/env_spec.rb +0 -37
- data/spec/unit/hanami/extensions/view/context_spec.rb +0 -59
- data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +0 -120
- data/spec/unit/hanami/helpers/assets_helper/audio_tag_spec.rb +0 -132
- data/spec/unit/hanami/helpers/assets_helper/favicon_tag_spec.rb +0 -87
- data/spec/unit/hanami/helpers/assets_helper/image_tag_spec.rb +0 -92
- data/spec/unit/hanami/helpers/assets_helper/javascript_tag_spec.rb +0 -143
- data/spec/unit/hanami/helpers/assets_helper/stylesheet_tag_spec.rb +0 -126
- data/spec/unit/hanami/helpers/assets_helper/video_tag_spec.rb +0 -136
- data/spec/unit/hanami/helpers/form_helper_spec.rb +0 -2857
- data/spec/unit/hanami/port_spec.rb +0 -117
- data/spec/unit/hanami/providers/db/config/default_config_spec.rb +0 -100
- data/spec/unit/hanami/providers/db/config/gateway_spec.rb +0 -73
- data/spec/unit/hanami/providers/db/config_spec.rb +0 -143
- data/spec/unit/hanami/router/errors/not_allowed_error_spec.rb +0 -27
- data/spec/unit/hanami/router/errors/not_found_error_spec.rb +0 -22
- data/spec/unit/hanami/settings/env_store_spec.rb +0 -52
- data/spec/unit/hanami/settings_spec.rb +0 -111
- data/spec/unit/hanami/slice_configurable_spec.rb +0 -141
- data/spec/unit/hanami/slice_name_spec.rb +0 -47
- data/spec/unit/hanami/slice_spec.rb +0 -99
- data/spec/unit/hanami/web/rack_logger_spec.rb +0 -99
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "App action / Slice configuration", :app_integration do
|
|
4
|
-
before do
|
|
5
|
-
with_directory(@dir = make_tmp_directory) do
|
|
6
|
-
write "config/app.rb", <<~'RUBY'
|
|
7
|
-
require "hanami"
|
|
8
|
-
|
|
9
|
-
module TestApp
|
|
10
|
-
class App < Hanami::App
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
RUBY
|
|
14
|
-
|
|
15
|
-
write "app/action.rb", <<~'RUBY'
|
|
16
|
-
require "hanami/action"
|
|
17
|
-
|
|
18
|
-
module TestApp
|
|
19
|
-
class Action < Hanami::Action
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
RUBY
|
|
23
|
-
|
|
24
|
-
require "hanami/setup"
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def prepare_app
|
|
29
|
-
with_directory(@dir) { require "hanami/prepare" }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe "inheriting from app-level base class" do
|
|
33
|
-
describe "app-level base class" do
|
|
34
|
-
it "applies default actions config from the app", :aggregate_failures do
|
|
35
|
-
prepare_app
|
|
36
|
-
|
|
37
|
-
expect(TestApp::Action.config.formats.accepted).to eq []
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "applies actions config from the app" do
|
|
41
|
-
Hanami.app.config.actions.formats.accepted = [:json]
|
|
42
|
-
|
|
43
|
-
prepare_app
|
|
44
|
-
|
|
45
|
-
expect(TestApp::Action.config.formats.accepted).to eq [:json]
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "does not override config in the base class" do
|
|
49
|
-
Hanami.app.config.actions.formats.accepted = [:csv]
|
|
50
|
-
|
|
51
|
-
prepare_app
|
|
52
|
-
|
|
53
|
-
TestApp::Action.config.formats.accepted = [:json]
|
|
54
|
-
|
|
55
|
-
expect(TestApp::Action.config.formats.accepted).to eq [:json]
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
describe "subclass in app" do
|
|
60
|
-
before do
|
|
61
|
-
with_directory(@dir) do
|
|
62
|
-
write "app/actions/articles/index.rb", <<~'RUBY'
|
|
63
|
-
module TestApp
|
|
64
|
-
module Actions
|
|
65
|
-
module Articles
|
|
66
|
-
class Index < TestApp::Action
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
RUBY
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "applies default actions config from the app", :aggregate_failures do
|
|
76
|
-
prepare_app
|
|
77
|
-
|
|
78
|
-
expect(TestApp::Actions::Articles::Index.config.formats.accepted).to eq []
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
it "applies actions config from the app" do
|
|
82
|
-
Hanami.app.config.actions.formats.accepted = [:json]
|
|
83
|
-
|
|
84
|
-
prepare_app
|
|
85
|
-
|
|
86
|
-
expect(TestApp::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "applies config from the base class" do
|
|
90
|
-
prepare_app
|
|
91
|
-
|
|
92
|
-
TestApp::Action.config.formats.accepted = [:json]
|
|
93
|
-
|
|
94
|
-
expect(TestApp::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
describe "subclass in slice" do
|
|
99
|
-
before do
|
|
100
|
-
with_directory(@dir) do
|
|
101
|
-
write "slices/admin/actions/articles/index.rb", <<~'RUBY'
|
|
102
|
-
module Admin
|
|
103
|
-
module Actions
|
|
104
|
-
module Articles
|
|
105
|
-
class Index < TestApp::Action
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
RUBY
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
it "applies default actions config from the app", :aggregate_failures do
|
|
115
|
-
prepare_app
|
|
116
|
-
|
|
117
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq []
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
it "applies actions config from the app" do
|
|
121
|
-
Hanami.app.config.actions.formats.accepted = [:json]
|
|
122
|
-
|
|
123
|
-
prepare_app
|
|
124
|
-
|
|
125
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
it "applies config from the base class" do
|
|
129
|
-
prepare_app
|
|
130
|
-
|
|
131
|
-
TestApp::Action.config.formats.accepted = [:json]
|
|
132
|
-
|
|
133
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
describe "inheriting from a slice-level base class, in turn inheriting from an app-level base class" do
|
|
139
|
-
before do
|
|
140
|
-
with_directory(@dir) do
|
|
141
|
-
write "slices/admin/action.rb", <<~'RUBY'
|
|
142
|
-
module Admin
|
|
143
|
-
class Action < TestApp::Action
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
RUBY
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
describe "slice-level base class" do
|
|
151
|
-
it "applies default actions config from the app", :aggregate_failures do
|
|
152
|
-
prepare_app
|
|
153
|
-
|
|
154
|
-
expect(Admin::Action.config.formats.accepted).to eq []
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
it "applies actions config from the app" do
|
|
158
|
-
Hanami.app.config.actions.formats.accepted = [:json]
|
|
159
|
-
|
|
160
|
-
prepare_app
|
|
161
|
-
|
|
162
|
-
expect(Admin::Action.config.formats.accepted).to eq [:json]
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it "applies config from the app base class" do
|
|
166
|
-
prepare_app
|
|
167
|
-
|
|
168
|
-
TestApp::Action.config.formats.accepted = [:json]
|
|
169
|
-
|
|
170
|
-
expect(Admin::Action.config.formats.accepted).to eq [:json]
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
context "slice actions config present" do
|
|
174
|
-
before do
|
|
175
|
-
with_directory(@dir) do
|
|
176
|
-
write "config/slices/admin.rb", <<~'RUBY'
|
|
177
|
-
module Admin
|
|
178
|
-
class Slice < Hanami::Slice
|
|
179
|
-
config.actions.format :csv
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
RUBY
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
it "applies actions config from the slice" do
|
|
187
|
-
prepare_app
|
|
188
|
-
|
|
189
|
-
expect(Admin::Action.config.formats.accepted).to eq [:csv]
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
it "prefers actions config from the slice over config from the app-level base class" do
|
|
193
|
-
prepare_app
|
|
194
|
-
|
|
195
|
-
TestApp::Action.config.formats.accepted = [:json]
|
|
196
|
-
|
|
197
|
-
expect(Admin::Action.config.formats.accepted).to eq [:csv]
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
it "prefers config from the base class over actions config from the slice" do
|
|
201
|
-
prepare_app
|
|
202
|
-
|
|
203
|
-
TestApp::Action.config.formats.accepted = [:csv]
|
|
204
|
-
Admin::Action.config.formats.accepted = [:json]
|
|
205
|
-
|
|
206
|
-
expect(Admin::Action.config.formats.accepted).to eq [:json]
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
describe "subclass in slice" do
|
|
212
|
-
before do
|
|
213
|
-
with_directory(@dir) do
|
|
214
|
-
write "slices/admin/actions/articles/index.rb", <<~'RUBY'
|
|
215
|
-
module Admin
|
|
216
|
-
module Actions
|
|
217
|
-
module Articles
|
|
218
|
-
class Index < Admin::Action
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
|
-
end
|
|
223
|
-
RUBY
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
it "applies default actions config from the app", :aggregate_failures do
|
|
228
|
-
prepare_app
|
|
229
|
-
|
|
230
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq []
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
it "applies actions config from the app" do
|
|
234
|
-
Hanami.app.config.actions.formats.accepted = [:json]
|
|
235
|
-
|
|
236
|
-
prepare_app
|
|
237
|
-
|
|
238
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
239
|
-
end
|
|
240
|
-
|
|
241
|
-
it "applies actions config from the slice" do
|
|
242
|
-
with_directory(@dir) do
|
|
243
|
-
write "config/slices/admin.rb", <<~'RUBY'
|
|
244
|
-
module Admin
|
|
245
|
-
class Slice < Hanami::Slice
|
|
246
|
-
config.actions.formats.accepted = [:json]
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
RUBY
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
prepare_app
|
|
253
|
-
|
|
254
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
it "applies config from the slice base class" do
|
|
258
|
-
prepare_app
|
|
259
|
-
|
|
260
|
-
Admin::Action.config.formats.accepted = [:json]
|
|
261
|
-
|
|
262
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
it "prefers config from the slice base class over actions config from the slice" do
|
|
266
|
-
with_directory(@dir) do
|
|
267
|
-
write "config/slices/admin.rb", <<~'RUBY'
|
|
268
|
-
module Admin
|
|
269
|
-
class Slice < Hanami::Slice
|
|
270
|
-
config.actions.format :csv
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
RUBY
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
prepare_app
|
|
277
|
-
|
|
278
|
-
Admin::Action.config.formats.accepted = [:json]
|
|
279
|
-
|
|
280
|
-
expect(Admin::Actions::Articles::Index.config.formats.accepted).to eq [:json]
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
end
|
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "App action / View rendering / Automatic rendering", :app_integration do
|
|
4
|
-
it "Renders a view automatically, passing all params and exposures" do
|
|
5
|
-
within_app do
|
|
6
|
-
write "app/actions/profile/show.rb", <<~RUBY
|
|
7
|
-
module TestApp
|
|
8
|
-
module Actions
|
|
9
|
-
module Profile
|
|
10
|
-
class Show < TestApp::Action
|
|
11
|
-
def handle(req, res)
|
|
12
|
-
res[:favorite_number] = 123
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
RUBY
|
|
19
|
-
|
|
20
|
-
write "app/views/profile/show.rb", <<~RUBY
|
|
21
|
-
module TestApp
|
|
22
|
-
module Views
|
|
23
|
-
module Profile
|
|
24
|
-
class Show < TestApp::View
|
|
25
|
-
expose :name, :favorite_number
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
RUBY
|
|
31
|
-
|
|
32
|
-
write "app/templates/profile/show.html.slim", <<~'SLIM'
|
|
33
|
-
h1 Hello, #{name}. Your favorite number is #{favorite_number}, right?
|
|
34
|
-
SLIM
|
|
35
|
-
|
|
36
|
-
require "hanami/prepare"
|
|
37
|
-
|
|
38
|
-
action = TestApp::App["actions.profile.show"]
|
|
39
|
-
response = action.(name: "Jennifer")
|
|
40
|
-
rendered = response.body[0]
|
|
41
|
-
|
|
42
|
-
expect(rendered).to eq "<html><body><h1>Hello, Jennifer. Your favorite number is 123, right?</h1></body></html>"
|
|
43
|
-
expect(response.status).to eq 200
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
it "Does not render a view automatically when #render? returns false " do
|
|
48
|
-
within_app do
|
|
49
|
-
write "app/actions/profile/show.rb", <<~RUBY
|
|
50
|
-
module TestApp
|
|
51
|
-
module Actions
|
|
52
|
-
module Profile
|
|
53
|
-
class Show < TestApp::Action
|
|
54
|
-
def handle(req, res)
|
|
55
|
-
res[:favorite_number] = 123
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def auto_render?(_res)
|
|
59
|
-
false
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
RUBY
|
|
66
|
-
|
|
67
|
-
write "app/views/profile/show.rb", <<~RUBY
|
|
68
|
-
module TestApp
|
|
69
|
-
module Views
|
|
70
|
-
module Profile
|
|
71
|
-
class Show < TestApp::View
|
|
72
|
-
expose :name, :favorite_number
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
RUBY
|
|
78
|
-
|
|
79
|
-
write "app/templates/profile/show.html.slim", <<~'SLIM'
|
|
80
|
-
h1 Hello, #{name}. Your favorite number is #{favorite_number}, right?
|
|
81
|
-
SLIM
|
|
82
|
-
|
|
83
|
-
require "hanami/prepare"
|
|
84
|
-
|
|
85
|
-
action = TestApp::App["actions.profile.show"]
|
|
86
|
-
response = action.(name: "Jennifer")
|
|
87
|
-
|
|
88
|
-
expect(response.body).to eq []
|
|
89
|
-
expect(response.status).to eq 200
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
it "Doesn't render view automatically when body is already assigned" do
|
|
94
|
-
within_app do
|
|
95
|
-
write "app/actions/profile/show.rb", <<~RUBY
|
|
96
|
-
module TestApp
|
|
97
|
-
module Actions
|
|
98
|
-
module Profile
|
|
99
|
-
class Show < TestApp::Action
|
|
100
|
-
def handle(req, res)
|
|
101
|
-
res.body = "200: Okay okay okay"
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
RUBY
|
|
108
|
-
|
|
109
|
-
write "app/views/profile/show.rb", <<~RUBY
|
|
110
|
-
module TestApp
|
|
111
|
-
module Views
|
|
112
|
-
module Profile
|
|
113
|
-
class Show < TestApp::View
|
|
114
|
-
expose :name, :favorite_number
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
RUBY
|
|
120
|
-
|
|
121
|
-
write "app/templates/profile/show.html.slim", <<~'SLIM'
|
|
122
|
-
h1 Hello, #{name}. Your favorite number is #{favorite_number}, right?
|
|
123
|
-
SLIM
|
|
124
|
-
|
|
125
|
-
require "hanami/prepare"
|
|
126
|
-
|
|
127
|
-
action = TestApp::App["actions.profile.show"]
|
|
128
|
-
response = action.(name: "Jennifer")
|
|
129
|
-
rendered = response.body[0]
|
|
130
|
-
|
|
131
|
-
expect(rendered).to eq "200: Okay okay okay"
|
|
132
|
-
expect(response.status).to eq 200
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "Doesn't render view automatically when halt is called" do
|
|
137
|
-
within_app do
|
|
138
|
-
write "app/actions/profile/show.rb", <<~RUBY
|
|
139
|
-
module TestApp
|
|
140
|
-
module Actions
|
|
141
|
-
module Profile
|
|
142
|
-
class Show < TestApp::Action
|
|
143
|
-
def handle(req, res)
|
|
144
|
-
halt 404
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
RUBY
|
|
151
|
-
|
|
152
|
-
write "app/views/profile/show.rb", <<~RUBY
|
|
153
|
-
module TestApp
|
|
154
|
-
module Views
|
|
155
|
-
module Profile
|
|
156
|
-
class Show < TestApp::View
|
|
157
|
-
expose :name
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
RUBY
|
|
163
|
-
|
|
164
|
-
# This template will crash if not rendered with a valid `name` string. The absence
|
|
165
|
-
# of a crash here tells us that the view was never rendered.
|
|
166
|
-
write "app/templates/profile/show.html.slim", <<~'SLIM'
|
|
167
|
-
h1 Hello, #{name.to_str}!
|
|
168
|
-
SLIM
|
|
169
|
-
|
|
170
|
-
require "hanami/prepare"
|
|
171
|
-
|
|
172
|
-
# Call the action without a `name` param, thereby ensuring the view will raise an
|
|
173
|
-
# error if rendered
|
|
174
|
-
action = TestApp::App["actions.profile.show"]
|
|
175
|
-
response = action.({})
|
|
176
|
-
rendered = response.body[0]
|
|
177
|
-
|
|
178
|
-
aggregate_failures do
|
|
179
|
-
expect(rendered).to eq "Not Found"
|
|
180
|
-
expect(response.status).to eq 404
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
it "Does not render if no view is available" do
|
|
186
|
-
within_app do
|
|
187
|
-
write "app/actions/profile/show.rb", <<~RUBY
|
|
188
|
-
module TestApp
|
|
189
|
-
module Actions
|
|
190
|
-
module Profile
|
|
191
|
-
class Show < TestApp::Action
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
RUBY
|
|
197
|
-
|
|
198
|
-
require "hanami/prepare"
|
|
199
|
-
|
|
200
|
-
action = TestApp::App["actions.profile.show"]
|
|
201
|
-
response = action.({})
|
|
202
|
-
expect(response.body).to eq []
|
|
203
|
-
expect(response.status).to eq 200
|
|
204
|
-
end
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def within_app
|
|
208
|
-
with_tmp_directory(Dir.mktmpdir) do
|
|
209
|
-
write "config/app.rb", <<~RUBY
|
|
210
|
-
require "hanami"
|
|
211
|
-
|
|
212
|
-
module TestApp
|
|
213
|
-
class App < Hanami::App
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
RUBY
|
|
217
|
-
|
|
218
|
-
write "app/action.rb", <<~RUBY
|
|
219
|
-
# auto_register: false
|
|
220
|
-
|
|
221
|
-
module TestApp
|
|
222
|
-
class Action < Hanami::Action
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
RUBY
|
|
226
|
-
|
|
227
|
-
write "app/view.rb", <<~RUBY
|
|
228
|
-
# auto_register: false
|
|
229
|
-
|
|
230
|
-
require "hanami/view"
|
|
231
|
-
|
|
232
|
-
module TestApp
|
|
233
|
-
class View < Hanami::View
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
RUBY
|
|
237
|
-
|
|
238
|
-
write "app/templates/layouts/app.html.slim", <<~SLIM
|
|
239
|
-
html
|
|
240
|
-
body
|
|
241
|
-
== yield
|
|
242
|
-
SLIM
|
|
243
|
-
|
|
244
|
-
yield
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
|
-
end
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "hanami"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "App action / View rendering / Paired view inference", :app_integration do
|
|
6
|
-
before do
|
|
7
|
-
module TestApp
|
|
8
|
-
class App < Hanami::App
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
Hanami.app.prepare
|
|
13
|
-
|
|
14
|
-
module TestApp
|
|
15
|
-
class Action < Hanami::Action
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
let(:action) { action_class.new }
|
|
21
|
-
|
|
22
|
-
describe "Ordinary action" do
|
|
23
|
-
before do
|
|
24
|
-
module TestApp
|
|
25
|
-
module Actions
|
|
26
|
-
module Articles
|
|
27
|
-
class Index < TestApp::Action
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
let(:action_class) { TestApp::Actions::Articles::Index }
|
|
35
|
-
|
|
36
|
-
context "Paired view exists" do
|
|
37
|
-
before do
|
|
38
|
-
TestApp::App.register "views.articles.index", view
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
let(:view) { double(:view) }
|
|
42
|
-
|
|
43
|
-
it "auto-injects a paired view from a matching container identifier" do
|
|
44
|
-
expect(action.view).to be view
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
context "Another view explicitly auto-injected" do
|
|
48
|
-
before do
|
|
49
|
-
module TestApp
|
|
50
|
-
module Actions
|
|
51
|
-
module Articles
|
|
52
|
-
class Index < TestApp::Action
|
|
53
|
-
include Deps[view: "views.articles.custom"]
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
TestApp::App.register "views.articles.custom", explicit_view
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
let(:action_class) { TestApp::Actions::Articles::Index }
|
|
63
|
-
let(:explicit_view) { double(:explicit_view) }
|
|
64
|
-
|
|
65
|
-
it "respects the explicitly auto-injected view" do
|
|
66
|
-
expect(action.view).to be explicit_view
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
context "No paired view exists" do
|
|
72
|
-
it "does not auto-inject any view" do
|
|
73
|
-
expect(action.view).to be_nil
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
describe "RESTful action" do
|
|
79
|
-
before do
|
|
80
|
-
module TestApp
|
|
81
|
-
module Actions
|
|
82
|
-
module Articles
|
|
83
|
-
class Create < TestApp::Action
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
let(:action_class) { TestApp::Actions::Articles::Create }
|
|
91
|
-
let(:direct_paired_view) { double(:direct_paired_view) }
|
|
92
|
-
let(:alternative_paired_view) { double(:alternative_paired_view) }
|
|
93
|
-
|
|
94
|
-
context "Direct paired view exists" do
|
|
95
|
-
before do
|
|
96
|
-
TestApp::App.register "views.articles.create", direct_paired_view
|
|
97
|
-
TestApp::App.register "views.articles.new", alternative_paired_view
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
it "auto-injects the directly paired view" do
|
|
101
|
-
expect(action.view).to be direct_paired_view
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
context "Alternative paired view exists" do
|
|
106
|
-
before do
|
|
107
|
-
TestApp::App.register "views.articles.new", alternative_paired_view
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
it "auto-injects the alternative paired view" do
|
|
111
|
-
expect(action.view).to be alternative_paired_view
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|