hanami 2.0.0.beta2 → 2.0.0.beta3
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 +10 -1
- data/lib/hanami/configuration/null_configuration.rb +2 -2
- data/lib/hanami/configuration.rb +17 -17
- data/lib/hanami/routes.rb +48 -21
- data/lib/hanami/version.rb +1 -1
- data/spec/{new_integration → integration}/action/cookies_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/csrf_protection_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/routes_spec.rb +3 -5
- data/spec/{new_integration → integration}/action/sessions_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/slice_configuration_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/view_integration_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/view_rendering/automatic_rendering_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/view_rendering/paired_view_inference_spec.rb +0 -0
- data/spec/{new_integration → integration}/action/view_rendering_spec.rb +0 -0
- data/spec/{new_integration → integration}/code_loading/loading_from_app_spec.rb +0 -0
- data/spec/{new_integration → integration}/code_loading/loading_from_lib_spec.rb +0 -0
- data/spec/{new_integration → integration}/code_loading/loading_from_slice_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/application_routes_helper_spec.rb +1 -3
- data/spec/{new_integration → integration}/container/auto_injection_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/auto_registration_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/autoloader_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/imports_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/prepare_container_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/shutdown_spec.rb +0 -0
- data/spec/{new_integration → integration}/container/standard_bootable_components_spec.rb +0 -0
- data/spec/{new_integration → integration}/dotenv_loading_spec.rb +0 -0
- data/spec/{new_integration → integration}/rack_app/middleware_spec.rb +9 -15
- data/spec/{new_integration → integration}/rack_app/non_booted_rack_app_spec.rb +3 -5
- data/spec/{new_integration → integration}/rack_app/rack_app_spec.rb +28 -48
- data/spec/{new_integration → integration}/settings/access_to_constants_spec.rb +0 -0
- data/spec/{new_integration → integration}/settings/loading_from_env_spec.rb +0 -0
- data/spec/{new_integration → integration}/settings/settings_component_loading_spec.rb +0 -0
- data/spec/{new_integration → integration}/settings/using_types_spec.rb +0 -0
- data/spec/{new_integration → integration}/setup_spec.rb +20 -0
- data/spec/{new_integration → integration}/slices/external_slice_spec.rb +2 -4
- data/spec/{new_integration → integration}/slices/slice_configuration_spec.rb +0 -0
- data/spec/{new_integration → integration}/slices/slice_loading_spec.rb +0 -0
- data/spec/{new_integration → integration}/slices/slice_routing_spec.rb +5 -13
- data/spec/{new_integration → integration}/slices/slice_settings_spec.rb +0 -0
- data/spec/{new_integration → integration}/slices_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/context/assets_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/context/inflector_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/context/request_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/context/routes_spec.rb +1 -3
- data/spec/{new_integration → integration}/view/context/settings_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/inflector_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/part_namespace_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/path_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/slice_configuration_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/template_spec.rb +0 -0
- data/spec/{new_integration → integration}/view/views_spec.rb +0 -0
- data/spec/unit/hanami/configuration/actions_spec.rb +4 -15
- data/spec/unit/hanami/configuration/router_spec.rb +45 -0
- data/spec/unit/hanami/configuration/views_spec.rb +4 -15
- data/spec/unit/hanami/version_spec.rb +1 -1
- metadata +97 -244
- data/lib/hanami/server.rb +0 -29
- data/spec/integration/application_middleware_stack_spec.rb +0 -84
- data/spec/integration/assets/cdn_spec.rb +0 -48
- data/spec/integration/assets/fingerprint_spec.rb +0 -42
- data/spec/integration/assets/helpers_spec.rb +0 -50
- data/spec/integration/assets/serve_spec.rb +0 -70
- data/spec/integration/assets/subresource_integrity_spec.rb +0 -54
- data/spec/integration/body_parsers_spec.rb +0 -50
- data/spec/integration/cli/assets/precompile_spec.rb +0 -147
- data/spec/integration/cli/assets_spec.rb +0 -14
- data/spec/integration/cli/console_spec.rb +0 -105
- data/spec/integration/cli/db/apply_spec.rb +0 -74
- data/spec/integration/cli/db/console_spec.rb +0 -40
- data/spec/integration/cli/db/create_spec.rb +0 -50
- data/spec/integration/cli/db/drop_spec.rb +0 -54
- data/spec/integration/cli/db/migrate_spec.rb +0 -108
- data/spec/integration/cli/db/prepare_spec.rb +0 -36
- data/spec/integration/cli/db/rollback_spec.rb +0 -96
- data/spec/integration/cli/db/version_spec.rb +0 -38
- data/spec/integration/cli/db_spec.rb +0 -21
- data/spec/integration/cli/destroy/action_spec.rb +0 -143
- data/spec/integration/cli/destroy/app_spec.rb +0 -118
- data/spec/integration/cli/destroy/mailer_spec.rb +0 -74
- data/spec/integration/cli/destroy/migration_spec.rb +0 -70
- data/spec/integration/cli/destroy/model_spec.rb +0 -113
- data/spec/integration/cli/destroy_spec.rb +0 -18
- data/spec/integration/cli/generate/action_spec.rb +0 -469
- data/spec/integration/cli/generate/app_spec.rb +0 -215
- data/spec/integration/cli/generate/mailer_spec.rb +0 -189
- data/spec/integration/cli/generate/migration_spec.rb +0 -72
- data/spec/integration/cli/generate/model_spec.rb +0 -290
- data/spec/integration/cli/generate/secret_spec.rb +0 -56
- data/spec/integration/cli/generate_spec.rb +0 -19
- data/spec/integration/cli/new/database_spec.rb +0 -235
- data/spec/integration/cli/new/hanami_head_spec.rb +0 -27
- data/spec/integration/cli/new/template_spec.rb +0 -118
- data/spec/integration/cli/new/test_spec.rb +0 -274
- data/spec/integration/cli/new_spec.rb +0 -970
- data/spec/integration/cli/plugins_spec.rb +0 -39
- data/spec/integration/cli/routes_spec.rb +0 -49
- data/spec/integration/cli/server_spec.rb +0 -626
- data/spec/integration/cli/version_spec.rb +0 -85
- data/spec/integration/early_hints_spec.rb +0 -35
- data/spec/integration/handle_exceptions_spec.rb +0 -244
- data/spec/integration/head_spec.rb +0 -89
- data/spec/integration/http_headers_spec.rb +0 -29
- data/spec/integration/mailer_spec.rb +0 -32
- data/spec/integration/middleware_spec.rb +0 -81
- data/spec/integration/mount_applications_spec.rb +0 -88
- data/spec/integration/project_initializers_spec.rb +0 -40
- data/spec/integration/rackup_spec.rb +0 -35
- data/spec/integration/rake/with_minitest_spec.rb +0 -67
- data/spec/integration/rake/with_rspec_spec.rb +0 -69
- data/spec/integration/routing_helpers_spec.rb +0 -61
- data/spec/integration/security/content_security_policy_spec.rb +0 -46
- data/spec/integration/security/csrf_protection_spec.rb +0 -42
- data/spec/integration/security/force_ssl_spec.rb +0 -29
- data/spec/integration/security/x_content_type_options_spec.rb +0 -46
- data/spec/integration/security/x_frame_options_spec.rb +0 -46
- data/spec/integration/security/x_xss_protection_spec.rb +0 -46
- data/spec/integration/send_file_spec.rb +0 -51
- data/spec/integration/sessions_spec.rb +0 -247
- data/spec/integration/static_middleware_spec.rb +0 -21
- data/spec/integration/streaming_spec.rb +0 -41
- data/spec/integration/unsafe_send_file_spec.rb +0 -52
- data/spec/support/fixtures/hanami-plugin/Gemfile +0 -8
- data/spec/support/fixtures/hanami-plugin/README.md +0 -35
- data/spec/support/fixtures/hanami-plugin/Rakefile +0 -4
- data/spec/support/fixtures/hanami-plugin/bin/console +0 -15
- data/spec/support/fixtures/hanami-plugin/bin/setup +0 -8
- data/spec/support/fixtures/hanami-plugin/hanami-plugin.gemspec +0 -28
- data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin/cli.rb +0 -19
- data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin/version.rb +0 -7
- data/spec/support/fixtures/hanami-plugin/lib/hanami/plugin.rb +0 -8
- data/spec/unit/hanami/routes_spec.rb +0 -25
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "App middleware stack", type: :integration do
|
|
4
|
-
it "mounts Rack middleware" do
|
|
5
|
-
with_project do
|
|
6
|
-
generate "action web home#index --url=/"
|
|
7
|
-
generate_middleware
|
|
8
|
-
|
|
9
|
-
# Add apps/web/middleware to the load paths
|
|
10
|
-
replace "apps/web/app.rb", "load_paths << [", "load_paths << ['middleware',"
|
|
11
|
-
|
|
12
|
-
# Require Rack::ETag
|
|
13
|
-
unshift "apps/web/app.rb", "require 'rack/etag'"
|
|
14
|
-
|
|
15
|
-
# Mount middleware
|
|
16
|
-
replace "apps/web/app.rb", "# middleware.use", "middleware.use 'Web::Middleware::Runtime'\nmiddleware.use 'Web::Middleware::Custom', 'OK'\nmiddleware.use Rack::ETag"
|
|
17
|
-
|
|
18
|
-
rewrite "apps/web/controllers/home/index.rb", <<~EOF
|
|
19
|
-
module Web::Controllers::Home
|
|
20
|
-
class Index
|
|
21
|
-
include Web::Action
|
|
22
|
-
|
|
23
|
-
def call(params)
|
|
24
|
-
self.body = "OK"
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
EOF
|
|
29
|
-
|
|
30
|
-
server do
|
|
31
|
-
get "/"
|
|
32
|
-
|
|
33
|
-
expect(last_response.status).to eq(200)
|
|
34
|
-
|
|
35
|
-
expect(last_response.headers["X-Runtime"]).to eq("1ms")
|
|
36
|
-
expect(last_response.headers["X-Custom"]).to eq("OK")
|
|
37
|
-
expect(last_response.headers["ETag"]).to_not be_nil
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
private
|
|
43
|
-
|
|
44
|
-
def generate_middleware # rubocop:disable Metrics/MethodLength
|
|
45
|
-
write "apps/web/middleware/runtime.rb", <<~EOF
|
|
46
|
-
module Web
|
|
47
|
-
module Middleware
|
|
48
|
-
class Runtime
|
|
49
|
-
def initialize(app)
|
|
50
|
-
@app = app
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def call(env)
|
|
54
|
-
status, headers, body = @app.call(env)
|
|
55
|
-
headers["X-Runtime"] = "1ms"
|
|
56
|
-
|
|
57
|
-
[status, headers, body]
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
EOF
|
|
63
|
-
|
|
64
|
-
write "apps/web/middleware/custom.rb", <<~EOF
|
|
65
|
-
module Web
|
|
66
|
-
module Middleware
|
|
67
|
-
class Custom
|
|
68
|
-
def initialize(app, value)
|
|
69
|
-
@app = app
|
|
70
|
-
@value = value
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def call(env)
|
|
74
|
-
status, headers, body = @app.call(env)
|
|
75
|
-
headers["X-Custom"] = @value
|
|
76
|
-
|
|
77
|
-
[status, headers, body]
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
EOF
|
|
83
|
-
end
|
|
84
|
-
end
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "assets", type: :integration do
|
|
4
|
-
describe "CDN mode" do
|
|
5
|
-
it "servers assets with CDN url" do
|
|
6
|
-
with_project do
|
|
7
|
-
generate "action web home#index --url=/"
|
|
8
|
-
|
|
9
|
-
write "apps/web/assets/javascripts/app.css", <<~EOF
|
|
10
|
-
body { color: #333 };
|
|
11
|
-
EOF
|
|
12
|
-
rewrite "apps/web/templates/app.html.erb", <<~EOF
|
|
13
|
-
<!DOCTYPE html>
|
|
14
|
-
<html>
|
|
15
|
-
<head>
|
|
16
|
-
<title>Web</title>
|
|
17
|
-
<%= favicon %>
|
|
18
|
-
<%= stylesheet 'app' %>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
<%= yield %>
|
|
22
|
-
</body>
|
|
23
|
-
</html>
|
|
24
|
-
EOF
|
|
25
|
-
|
|
26
|
-
replace_last "apps/web/app.rb", "# scheme 'https'", "scheme 'https'"
|
|
27
|
-
replace "apps/web/app.rb", "# host 'cdn.example.org'", "host 'cdn.example.org'"
|
|
28
|
-
replace_last "apps/web/app.rb", "# port 443", "port 443"
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
# Precompile
|
|
32
|
-
#
|
|
33
|
-
RSpec::Support::Env["HANAMI_ENV"] = "production"
|
|
34
|
-
RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}"
|
|
35
|
-
RSpec::Support::Env["SMTP_HOST"] = "localhost"
|
|
36
|
-
RSpec::Support::Env["SMTP_PORT"] = "25"
|
|
37
|
-
|
|
38
|
-
hanami "assets precompile"
|
|
39
|
-
|
|
40
|
-
server do
|
|
41
|
-
visit "/"
|
|
42
|
-
|
|
43
|
-
expect(page.body).to include(%(<link href="https://cdn.example.org/assets/app-5df86b4e9cbd733a027762b2f6bf8693.css" type="text/css" rel="stylesheet" integrity="sha256-LxaTcWkL8TAWFQWeHJ7OqoSoEXXaYapNIS+TCvGNf48=" crossorigin="anonymous">))
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "assets", type: :integration do
|
|
4
|
-
describe "fingerprint mode" do
|
|
5
|
-
it "servers assets with fingerprint url" do
|
|
6
|
-
with_project do
|
|
7
|
-
generate "action web home#index --url=/"
|
|
8
|
-
|
|
9
|
-
write "apps/web/assets/javascripts/app.css", <<~EOF
|
|
10
|
-
body { color: #333 };
|
|
11
|
-
EOF
|
|
12
|
-
rewrite "apps/web/templates/app.html.erb", <<~EOF
|
|
13
|
-
<!DOCTYPE html>
|
|
14
|
-
<html>
|
|
15
|
-
<head>
|
|
16
|
-
<title>Web</title>
|
|
17
|
-
<%= favicon %>
|
|
18
|
-
<%= stylesheet 'app' %>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
<%= yield %>
|
|
22
|
-
</body>
|
|
23
|
-
</html>
|
|
24
|
-
EOF
|
|
25
|
-
#
|
|
26
|
-
# Precompile
|
|
27
|
-
#
|
|
28
|
-
RSpec::Support::Env["HANAMI_ENV"] = "production"
|
|
29
|
-
RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}"
|
|
30
|
-
RSpec::Support::Env["SMTP_HOST"] = "localhost"
|
|
31
|
-
RSpec::Support::Env["SMTP_PORT"] = "25"
|
|
32
|
-
hanami "assets precompile"
|
|
33
|
-
|
|
34
|
-
server do
|
|
35
|
-
visit "/"
|
|
36
|
-
|
|
37
|
-
expect(page.body).to include(%(<link href="/assets/app-5df86b4e9cbd733a027762b2f6bf8693.css" type="text/css" rel="stylesheet" integrity="sha256-LxaTcWkL8TAWFQWeHJ7OqoSoEXXaYapNIS+TCvGNf48=" crossorigin="anonymous">))
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "assets", type: :integration do
|
|
4
|
-
describe "helpers" do
|
|
5
|
-
it "renders assets tags" do
|
|
6
|
-
with_project do
|
|
7
|
-
generate "action web home#index --url=/"
|
|
8
|
-
|
|
9
|
-
rewrite "apps/web/templates/app.html.erb", <<~EOF
|
|
10
|
-
<!DOCTYPE html>
|
|
11
|
-
<html>
|
|
12
|
-
<head>
|
|
13
|
-
<title>Web</title>
|
|
14
|
-
<%= favicon %>
|
|
15
|
-
<%= stylesheet 'app' %>
|
|
16
|
-
</head>
|
|
17
|
-
<body>
|
|
18
|
-
<%= yield %>
|
|
19
|
-
<%= javascript 'app' %>
|
|
20
|
-
</body>
|
|
21
|
-
</html>
|
|
22
|
-
EOF
|
|
23
|
-
|
|
24
|
-
rewrite "apps/web/templates/home/index.html.erb", <<~EOF
|
|
25
|
-
<%= image('app.jpg') %>
|
|
26
|
-
<%= video('movie.mp4') %>
|
|
27
|
-
<%=
|
|
28
|
-
video do
|
|
29
|
-
text "Your browser does not support the video tag"
|
|
30
|
-
source src: view.asset_path('movie.mp4'), type: 'video/mp4'
|
|
31
|
-
source src: view.asset_path('movie.ogg'), type: 'video/ogg'
|
|
32
|
-
end
|
|
33
|
-
%>
|
|
34
|
-
EOF
|
|
35
|
-
|
|
36
|
-
server do
|
|
37
|
-
visit "/"
|
|
38
|
-
|
|
39
|
-
expect(page.body).to include(%(<link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">))
|
|
40
|
-
expect(page.body).to include(%(<link href="/assets/app.css" type="text/css" rel="stylesheet">))
|
|
41
|
-
expect(page.body).to include(%(<script src="/assets/app.js" type="text/javascript"></script>))
|
|
42
|
-
|
|
43
|
-
expect(page.body).to include(%(<img src="/assets/app.jpg" alt="App">))
|
|
44
|
-
expect(page.body).to include(%(<video src="/assets/movie.mp4"></video>))
|
|
45
|
-
expect(page.body).to include(%(<video>\nYour browser does not support the video tag\n<source src="/assets/movie.mp4" type="video/mp4">\n<source src="/assets/movie.ogg" type="video/ogg">\n</video>))
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "assets", type: :integration do
|
|
4
|
-
describe "serve" do
|
|
5
|
-
it "compiles and serves assets in development mode" do
|
|
6
|
-
project = "bookshelf_serve_assets"
|
|
7
|
-
|
|
8
|
-
with_project(project, gems: ['sassc']) do
|
|
9
|
-
generate "action web home#index --url=/"
|
|
10
|
-
|
|
11
|
-
write "apps/web/assets/javascripts/app.css.sass", <<~EOF
|
|
12
|
-
$font-family: Helvetica, sans-serif
|
|
13
|
-
|
|
14
|
-
body
|
|
15
|
-
font: 100% $font-family
|
|
16
|
-
EOF
|
|
17
|
-
rewrite "apps/web/templates/app.html.erb", <<~EOF
|
|
18
|
-
<!DOCTYPE html>
|
|
19
|
-
<html>
|
|
20
|
-
<head>
|
|
21
|
-
<title>Web</title>
|
|
22
|
-
<%= favicon %>
|
|
23
|
-
<%= stylesheet 'app' %>
|
|
24
|
-
</head>
|
|
25
|
-
<body>
|
|
26
|
-
<%= yield %>
|
|
27
|
-
</body>
|
|
28
|
-
</html>
|
|
29
|
-
EOF
|
|
30
|
-
|
|
31
|
-
server do
|
|
32
|
-
visit "/"
|
|
33
|
-
expect(page.body).to include(%(<link href="/assets/app.css" type="text/css" rel="stylesheet">))
|
|
34
|
-
|
|
35
|
-
visit "/assets/app.css"
|
|
36
|
-
expect(page.body).to include(%(body {\n font: 100% Helvetica, sans-serif; }\n))
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "serve assets with prefixes" do
|
|
42
|
-
with_project do
|
|
43
|
-
generate "action web home#index --url=/"
|
|
44
|
-
|
|
45
|
-
replace(
|
|
46
|
-
"apps/web/app.rb",
|
|
47
|
-
"# Specify sources for assets",
|
|
48
|
-
"prefix '/library/assets'\n# Specify sources for assets"
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
replace(
|
|
52
|
-
"apps/web/config/routes.rb",
|
|
53
|
-
"/",
|
|
54
|
-
"namespace :library { get '/', to: 'home#index' }"
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
write "apps/web/assets/javascripts/app.js", <<~EOF
|
|
58
|
-
console.log('test');
|
|
59
|
-
EOF
|
|
60
|
-
|
|
61
|
-
hanami "assets precompile"
|
|
62
|
-
|
|
63
|
-
server do
|
|
64
|
-
visit "/library/assets/app.js"
|
|
65
|
-
expect(page).to have_content("console.log('test');")
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "json"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "assets", type: :integration do
|
|
6
|
-
describe "subresource integrity" do
|
|
7
|
-
it "precompiles assets with checksums calculated with given algorithms" do
|
|
8
|
-
with_project do
|
|
9
|
-
generate "action web home#index --url=/"
|
|
10
|
-
|
|
11
|
-
write "apps/web/assets/javascripts/app.css", <<~EOF
|
|
12
|
-
body { font: Helvetica; }
|
|
13
|
-
EOF
|
|
14
|
-
rewrite "apps/web/templates/app.html.erb", <<~EOF
|
|
15
|
-
<!DOCTYPE html>
|
|
16
|
-
<html>
|
|
17
|
-
<head>
|
|
18
|
-
<title>Web</title>
|
|
19
|
-
<%= favicon %>
|
|
20
|
-
<%= stylesheet 'app' %>
|
|
21
|
-
</head>
|
|
22
|
-
<body>
|
|
23
|
-
<%= yield %>
|
|
24
|
-
</body>
|
|
25
|
-
</html>
|
|
26
|
-
EOF
|
|
27
|
-
|
|
28
|
-
replace "apps/web/app.rb", "subresource_integrity :sha256", "subresource_integrity :sha256, :sha512"
|
|
29
|
-
|
|
30
|
-
#
|
|
31
|
-
# Precompile
|
|
32
|
-
#
|
|
33
|
-
RSpec::Support::Env["HANAMI_ENV"] = "production"
|
|
34
|
-
# FIXME: database connection shouldn't be required for `assets precompile`
|
|
35
|
-
RSpec::Support::Env["DATABASE_URL"] = "sqlite://#{Pathname.new('db').join('bookshelf.sqlite')}"
|
|
36
|
-
RSpec::Support::Env["SMTP_HOST"] = "localhost"
|
|
37
|
-
RSpec::Support::Env["SMTP_PORT"] = "25"
|
|
38
|
-
|
|
39
|
-
hanami "assets precompile"
|
|
40
|
-
|
|
41
|
-
manifest = File.read("public/assets.json")
|
|
42
|
-
expect(JSON.parse(manifest)).to be_kind_of(Hash) # assert it's a well-formed JSON
|
|
43
|
-
|
|
44
|
-
expect(manifest).to include(%("/assets/app.css":{"target":"/assets/app-068e7d97b3671a14824bc20437ac5d06.css","sri":["sha256-cHgODQTP2nNk9ER+ViDGp+lC+ddHRmuLgJk05glJ4+w=","sha512-TDyxo1Ow7UjBib6ykALJh7J1OHEcE0yX4X21s1714ZBAhwdOz7k9t8+QQDAwWAmeH97bNaZGY7oTfVrwyTQ3cw=="]}))
|
|
45
|
-
expect(manifest).to include(%("/assets/favicon.ico":{"target":"/assets/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico","sri":["sha256-PLEDhpDsTBpxl1KtXjzBjg+PUG67zpf05B1z2db4iJU=","sha512-9NvaW7aVAywbLPPi3fw5s4wtWwd37i8VpzgfEo9uCOyr/mDT2dbYJtGNjfTJa4R8TOw69yHr4NhazPQsLt1WHw=="]}))
|
|
46
|
-
|
|
47
|
-
server do
|
|
48
|
-
visit "/"
|
|
49
|
-
expect(page.body).to include(%(<link href="/assets/app-068e7d97b3671a14824bc20437ac5d06.css" type="text/css" rel="stylesheet" integrity="sha256-cHgODQTP2nNk9ER+ViDGp+lC+ddHRmuLgJk05glJ4+w= sha512-TDyxo1Ow7UjBib6ykALJh7J1OHEcE0yX4X21s1714ZBAhwdOz7k9t8+QQDAwWAmeH97bNaZGY7oTfVrwyTQ3cw==" crossorigin="anonymous">))
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "body parsers", type: :integration do
|
|
4
|
-
it "parses JSON payload for non-GET requests" do
|
|
5
|
-
with_project do
|
|
6
|
-
generate_action
|
|
7
|
-
enable_json_body_parser
|
|
8
|
-
|
|
9
|
-
server do
|
|
10
|
-
post "/books", %({"book": {"title": "CLI apps with Ruby"}}), "CONTENT_TYPE" => "app/json", "HTTP_ACCEPT" => "app/json"
|
|
11
|
-
expect(last_response.body).to eq(%({"book":{"title":"CLI apps with Ruby"}}))
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "doesn't eval untrusted JSON" do
|
|
17
|
-
with_project do
|
|
18
|
-
generate_action
|
|
19
|
-
enable_json_body_parser
|
|
20
|
-
|
|
21
|
-
server do
|
|
22
|
-
post "/books", %({"json_class": "Foo"}), "CONTENT_TYPE" => "app/json", "HTTP_ACCEPT" => "app/json"
|
|
23
|
-
expect(last_response.body).to eq(%({"json_class":"Foo"}))
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
def generate_action
|
|
31
|
-
generate "action web books#create --url=/books --method=POST"
|
|
32
|
-
|
|
33
|
-
rewrite "apps/web/controllers/books/create.rb", <<~EOF
|
|
34
|
-
require 'hanami/utils/json'
|
|
35
|
-
module Web::Controllers::Books
|
|
36
|
-
class Create
|
|
37
|
-
include Web::Action
|
|
38
|
-
|
|
39
|
-
def call(params)
|
|
40
|
-
self.body = Hanami::Utils::Json.generate(params.to_hash)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
EOF
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def enable_json_body_parser
|
|
48
|
-
inject_line_after "apps/web/app.rb", "configure do", "body_parsers :json"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "json"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "hanami assets", type: :integration do
|
|
6
|
-
describe "precompile" do
|
|
7
|
-
it "precompiles assets" do
|
|
8
|
-
gems = %w[sassc coffee-script]
|
|
9
|
-
|
|
10
|
-
Platform.match do
|
|
11
|
-
os(:linux).engine(:ruby) { gems.push("therubyracer") }
|
|
12
|
-
os(:linux).engine(:jruby) { gems.push("therubyrhino") }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
with_project("bookshelf_assets_precompile", gems: gems) do
|
|
16
|
-
#
|
|
17
|
-
# Web assets
|
|
18
|
-
#
|
|
19
|
-
write "apps/web/assets/javascripts/app.js.coffee", <<~EOF
|
|
20
|
-
class App
|
|
21
|
-
constructor: () ->
|
|
22
|
-
@init = true
|
|
23
|
-
EOF
|
|
24
|
-
write "apps/web/assets/stylesheets/_colors.scss", <<~EOF
|
|
25
|
-
$background-color: #f5f5f5;
|
|
26
|
-
EOF
|
|
27
|
-
|
|
28
|
-
write "apps/web/assets/stylesheets/app.css.scss", <<~EOF
|
|
29
|
-
@import 'colors';
|
|
30
|
-
|
|
31
|
-
body {
|
|
32
|
-
background-color: $background-color;
|
|
33
|
-
}
|
|
34
|
-
EOF
|
|
35
|
-
#
|
|
36
|
-
# Admin assets
|
|
37
|
-
#
|
|
38
|
-
generate "app admin"
|
|
39
|
-
write "apps/admin/assets/javascripts/dashboard.js.coffee", <<~EOF
|
|
40
|
-
class Dashboard
|
|
41
|
-
constructor: (@data) ->
|
|
42
|
-
EOF
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
# Precompile
|
|
46
|
-
#
|
|
47
|
-
RSpec::Support::Env["HANAMI_ENV"] = "production"
|
|
48
|
-
hanami "assets precompile"
|
|
49
|
-
|
|
50
|
-
# rubocop:disable Lint/ImplicitStringConcatenation
|
|
51
|
-
|
|
52
|
-
#
|
|
53
|
-
# Verify manifest
|
|
54
|
-
#
|
|
55
|
-
manifest = retry_exec(Errno::ENOENT) do
|
|
56
|
-
File.read("public/assets.json")
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
expect(JSON.parse(manifest)).to be_kind_of(Hash) # assert it's a well-formed JSON
|
|
60
|
-
|
|
61
|
-
expect(manifest).to include(%("/assets/admin/dashboard.js":{"target":"/assets/admin/dashboard-39744f9626a70683b6c2d46305798883.js","sri":["sha256-1myPVWoqrq+uAVP2DSkmAown+5dm0x61+E3AjlGOKEc="]}))
|
|
62
|
-
expect(manifest).to include(%("/assets/admin/favicon.ico":{"target":"/assets/admin/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico","sri":["sha256-PLEDhpDsTBpxl1KtXjzBjg+PUG67zpf05B1z2db4iJU="]}))
|
|
63
|
-
expect(manifest).to include(%("/assets/app.css":{"target":"/assets/app-adb4104884aadde9abfef0bd98ac461e.css","sri":["sha256-S6V565W2In9pWE0uzMASpp58xCg32TN3at3Fv4g9aRA="]}))
|
|
64
|
-
expect(manifest).to include(%("/assets/app.js":{"target":"/assets/app-bb8f10498d83d401db238549409dc4c5.js","sri":["sha256-9m4OTbWigbDPp4oCe1LZz9isqidvW1c3jNL6mXMj2xs="]}))
|
|
65
|
-
expect(manifest).to include(%("/assets/favicon.ico":{"target":"/assets/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico","sri":["sha256-PLEDhpDsTBpxl1KtXjzBjg+PUG67zpf05B1z2db4iJU="]}))
|
|
66
|
-
|
|
67
|
-
#
|
|
68
|
-
# Verify web assets (w/ checksum)
|
|
69
|
-
#
|
|
70
|
-
expect("public/assets/app-adb4104884aadde9abfef0bd98ac461e.css").to have_file_content <<~EOF
|
|
71
|
-
body {background-color: #f5f5f5}
|
|
72
|
-
EOF
|
|
73
|
-
|
|
74
|
-
expect("public/assets/app-bb8f10498d83d401db238549409dc4c5.js").to have_file_content \
|
|
75
|
-
"""
|
|
76
|
-
(function(){var App;App=(function(){function App(){this.init=true;}
|
|
77
|
-
return App;})();}).call(this);
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
expect("public/assets/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico").to be_an_existing_file
|
|
81
|
-
|
|
82
|
-
#
|
|
83
|
-
# Verify web assets (w/o checksum)
|
|
84
|
-
#
|
|
85
|
-
expect("public/assets/app.css").to have_file_content <<~EOF
|
|
86
|
-
body {background-color: #f5f5f5}
|
|
87
|
-
EOF
|
|
88
|
-
|
|
89
|
-
expect("public/assets/app.js").to have_file_content \
|
|
90
|
-
"""
|
|
91
|
-
(function(){var App;App=(function(){function App(){this.init=true;}
|
|
92
|
-
return App;})();}).call(this);
|
|
93
|
-
"""
|
|
94
|
-
|
|
95
|
-
expect("public/assets/favicon.ico").to be_an_existing_file
|
|
96
|
-
|
|
97
|
-
#
|
|
98
|
-
# Verify admin assets (w/ checksum)
|
|
99
|
-
#
|
|
100
|
-
expect("public/assets/admin/dashboard-39744f9626a70683b6c2d46305798883.js").to have_file_content \
|
|
101
|
-
"""
|
|
102
|
-
(function(){var Dashboard;Dashboard=(function(){function Dashboard(data){this.data=data;}
|
|
103
|
-
return Dashboard;})();}).call(this);
|
|
104
|
-
"""
|
|
105
|
-
|
|
106
|
-
expect("public/assets/admin/favicon-b0979f93c7f7246ac70949a80f7cbdfd.ico").to be_an_existing_file
|
|
107
|
-
|
|
108
|
-
#
|
|
109
|
-
# Verify admin assets (w/o checksum)
|
|
110
|
-
#
|
|
111
|
-
expect("public/assets/admin/dashboard.js").to have_file_content \
|
|
112
|
-
"""
|
|
113
|
-
(function(){var Dashboard;Dashboard=(function(){function Dashboard(data){this.data=data;}
|
|
114
|
-
return Dashboard;})();}).call(this);
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
expect("public/assets/admin/favicon.ico").to be_an_existing_file
|
|
118
|
-
|
|
119
|
-
# rubocop:enable Lint/ImplicitStringConcatenation
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
it "prints help message" do
|
|
124
|
-
with_project do
|
|
125
|
-
output = <<~OUT
|
|
126
|
-
Command:
|
|
127
|
-
hanami assets precompile
|
|
128
|
-
|
|
129
|
-
Usage:
|
|
130
|
-
hanami assets precompile
|
|
131
|
-
|
|
132
|
-
Description:
|
|
133
|
-
Precompile assets for deployment
|
|
134
|
-
|
|
135
|
-
Options:
|
|
136
|
-
--help, -h # Print this help
|
|
137
|
-
|
|
138
|
-
Examples:
|
|
139
|
-
hanami assets precompile # Basic usage
|
|
140
|
-
hanami assets precompile HANAMI_ENV=production # Precompile assets for production environment
|
|
141
|
-
OUT
|
|
142
|
-
|
|
143
|
-
run_cmd "hanami assets precompile --help", output
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "hanami assets", type: :integration do
|
|
4
|
-
it "prints subcommands" do
|
|
5
|
-
with_project do
|
|
6
|
-
output = <<~OUT
|
|
7
|
-
Commands:
|
|
8
|
-
hanami assets precompile # Precompile assets for deployment
|
|
9
|
-
OUT
|
|
10
|
-
|
|
11
|
-
run_cmd "hanami assets", output, exit_status: 1
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
RSpec.describe "hanami console", type: :integration do
|
|
4
|
-
context "irb" do
|
|
5
|
-
it "starts console" do
|
|
6
|
-
project_name = "bookshelf_console_irb"
|
|
7
|
-
with_project(project_name, console: :irb) do
|
|
8
|
-
setup_model
|
|
9
|
-
|
|
10
|
-
console do |input, _, _|
|
|
11
|
-
input.puts("Hanami::VERSION")
|
|
12
|
-
input.puts("Web::App")
|
|
13
|
-
input.puts("Web.routes")
|
|
14
|
-
input.puts("BookRepository.new.all.to_a")
|
|
15
|
-
input.puts("exit")
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
expect(out).to include(Hanami::VERSION)
|
|
19
|
-
expect(out).to include("Web::App")
|
|
20
|
-
expect(out).to include("#<Hanami::Routes")
|
|
21
|
-
expect(out).to include("[]")
|
|
22
|
-
expect(out).to include("[#{project_name}] [INFO]")
|
|
23
|
-
expect(out).to include("SELECT `id`, `title` FROM `books` ORDER BY `books`.`id`")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "starts console with --engine option" do
|
|
28
|
-
with_project("bookshelf_console_irb", console: :irb) do
|
|
29
|
-
console(" --engine=irb") do |input, _, _|
|
|
30
|
-
input.puts("Hanami::VERSION")
|
|
31
|
-
input.puts("exit")
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
expect(out).to include(Hanami::VERSION)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "starts console without hanami-model" do
|
|
39
|
-
project_without_hanami_model("bookshelf", gems: ["dry-struct"], console: :irb) do
|
|
40
|
-
write "lib/entities/access_token.rb", <<~EOF
|
|
41
|
-
require 'dry-struct'
|
|
42
|
-
require 'securerandom'
|
|
43
|
-
|
|
44
|
-
module Types
|
|
45
|
-
include Dry::Types.module
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
class AccessToken < Dry::Struct
|
|
49
|
-
attribute :id, Types::String.default { SecureRandom.uuid }
|
|
50
|
-
attribute :secret, Types::String
|
|
51
|
-
attribute :digest, Types::String
|
|
52
|
-
end
|
|
53
|
-
EOF
|
|
54
|
-
console do |input, _, _|
|
|
55
|
-
input.puts("AccessToken.new(id: '1', secret: 'shh', digest: 'def')")
|
|
56
|
-
input.puts("exit")
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
expect(out).to include('#<AccessToken id="1" secret="shh" digest="def">')
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end # irb
|
|
63
|
-
|
|
64
|
-
xit "returns error when known engine isn't bundled" do
|
|
65
|
-
with_project("bookshelf_console_irb", console: :irb) do
|
|
66
|
-
output = "Missing gem for `pry' console engine. Please make sure to add it to `Gemfile'."
|
|
67
|
-
run_cmd "hanami console --engine=pry", output, exit_status: 1
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it "returns error when unknown engine is requested" do
|
|
72
|
-
with_project("bookshelf_console_irb", console: :irb) do
|
|
73
|
-
output = "Unknown console engine: `foo'."
|
|
74
|
-
run_cmd "hanami console --engine=foo", output, exit_status: 1
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it "prints help message" do
|
|
79
|
-
with_project do
|
|
80
|
-
output = <<~OUT
|
|
81
|
-
Command:
|
|
82
|
-
hanami console
|
|
83
|
-
|
|
84
|
-
Usage:
|
|
85
|
-
hanami console
|
|
86
|
-
|
|
87
|
-
Description:
|
|
88
|
-
Starts Hanami console
|
|
89
|
-
|
|
90
|
-
Options:
|
|
91
|
-
--engine=VALUE # Force a specific console engine: (pry/ripl/irb)
|
|
92
|
-
--help, -h # Print this help
|
|
93
|
-
|
|
94
|
-
Examples:
|
|
95
|
-
hanami console # Uses the bundled engine
|
|
96
|
-
hanami console --engine=pry # Force to use Pry
|
|
97
|
-
OUT
|
|
98
|
-
|
|
99
|
-
run_cmd "hanami console --help", output
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# TODO: test with pry
|
|
104
|
-
# TODO: test with ripl
|
|
105
|
-
end
|