bidi2pdf-rails 0.0.1.pre.alpha → 0.1.1

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/.idea/bidi2pdf-rails.iml +68 -84
  3. data/.rubocop.yml +14 -0
  4. data/CHANGELOG.md +54 -0
  5. data/README.md +118 -28
  6. data/Rakefile +2 -0
  7. data/cliff.toml +126 -0
  8. data/lib/bidi2pdf_rails/browser_console_log_subscriber.rb +24 -0
  9. data/lib/bidi2pdf_rails/chromedriver_manager_singleton.rb +11 -11
  10. data/lib/bidi2pdf_rails/config.rb +137 -0
  11. data/lib/bidi2pdf_rails/configurable.rb +106 -0
  12. data/lib/bidi2pdf_rails/main_log_subscriber.rb +33 -0
  13. data/lib/bidi2pdf_rails/network_log_subscriber.rb +20 -0
  14. data/lib/bidi2pdf_rails/railtie.rb +13 -45
  15. data/lib/bidi2pdf_rails/services/html_renderer.rb +33 -0
  16. data/lib/bidi2pdf_rails/services/html_to_pdf_converter.rb +37 -0
  17. data/lib/bidi2pdf_rails/services/pdf_browser_session.rb +38 -0
  18. data/lib/bidi2pdf_rails/services/pdf_injection.rb +31 -0
  19. data/lib/bidi2pdf_rails/services/pdf_renderer.rb +94 -0
  20. data/lib/bidi2pdf_rails/services/url_to_pdf_converter.rb +91 -0
  21. data/lib/bidi2pdf_rails/version.rb +1 -1
  22. data/lib/bidi2pdf_rails.rb +41 -58
  23. data/lib/generators/bidi2pdf_rails/USAGE +12 -4
  24. data/lib/generators/bidi2pdf_rails/initializer_generator.rb +136 -30
  25. data/lib/generators/bidi2pdf_rails/templates/bidi2pdf_rails.rb.tt +25 -79
  26. data/spec/acceptance/user_can_download_report_pdf_spec.rb +133 -0
  27. data/spec/acceptance/user_can_generate_pdf_from_protected_remote_url_spec.rb +173 -0
  28. data/spec/acceptance/user_can_inject_css_before_pdf_printing_spec.rb +132 -0
  29. data/spec/acceptance/user_can_inject_js_before_pdf_printing_spec.rb +158 -0
  30. data/spec/dummy/app/assets/javascripts/simple.js +12 -0
  31. data/spec/dummy/app/assets/stylesheets/simple.css +3 -0
  32. data/spec/dummy/app/controllers/reports_controller.rb +47 -0
  33. data/spec/dummy/app/controllers/secure_controller.rb +52 -0
  34. data/spec/dummy/app/views/layouts/simple.html.erb +17 -0
  35. data/spec/dummy/app/views/reports/simple.html.erb +6 -0
  36. data/spec/dummy/app/views/secure/show.html.erb +10 -0
  37. data/spec/dummy/config/environments/production.rb +1 -1
  38. data/spec/dummy/config/initializers/bidi2pdf_rails.rb +72 -54
  39. data/spec/dummy/config/initializers/cors.rb +1 -1
  40. data/spec/dummy/config/routes.rb +14 -0
  41. data/spec/dummy/log/development.log +18331 -158
  42. data/spec/dummy/log/test.log +87874 -0
  43. data/spec/dummy/tmp/pids/server.pid +1 -1
  44. data/spec/integration/generators/bidi2pdf_rails/initializer_generator_spec.rb +64 -0
  45. data/spec/rails_helper.rb +8 -1
  46. data/spec/spec_helper.rb +47 -5
  47. data/spec/support/default_dirs_helper.rb +32 -0
  48. data/spec/support/pdf_helper.rb +12 -0
  49. data/spec/support/render_setting_helpers.rb +47 -0
  50. data/spec/support/request_server_bootstrap.rb +44 -0
  51. data/spec/{bidi2pdf_rails → unit/bidi2pdf_rails}/bidi2pdf_rails_spec.rb +1 -1
  52. data/spec/unit/bidi2pdf_rails/configurable/base_nested_config_spec.rb +133 -0
  53. data/tasks/changelog.rake +29 -0
  54. data/tasks/coverage.rake +23 -0
  55. metadata +108 -27
  56. data/lib/bidi2pdf_rails/log_subscriber.rb +0 -13
  57. data/spec/dummy/spec/helpers/reports_helper_spec.rb +0 -15
  58. data/spec/dummy/spec/requests/reports_spec.rb +0 -10
  59. data/spec/dummy/spec/views/reports/show.html.erb_spec.rb +0 -5
  60. data/spec/generator/bidie2pdf_rails_initializer_generator_spec.rb +0 -5
  61. data/spec/generator/initializer_generator_spec.rb +0 -5
  62. data/spec/requests/reports_spec.rb +0 -17
@@ -2,88 +2,34 @@
2
2
 
3
3
  Bidi2pdfRails.configure do |config|
4
4
  overrides = Rails.application.config.x.bidi2pdf_rails
5
-
6
- config.notification_service = ActiveSupport::Notifications
7
-
8
- config.logger = Rails.logger
9
- config.verbosity = overrides.verbosity.nil? ? :none : overrides.verbosity
10
- config.default_timeout = 10
11
-
12
- # Logging options
13
- config.log_network_events = <%= @log_network_events ? "true" : "false" %>
14
- config.log_browser_console = <%= @log_browser_console ? "true" : "false" %>
15
-
16
- # Chrome & BiDi
17
- # config.remote_browser_url = nil
18
- config.headless = overrides.headless.nil? ? <%= @headless ? "true" : "false" %> : overrides.headless
19
- # config.chromedriver_port = 0
20
- # config.chrome_session_args = [
21
- # "--disable-gpu",
22
- # "--no-sandbox"
23
- # ]
24
-
25
- <% if @proxy %>
26
- config.proxy_addr = "<%= @proxy_addr %>"
27
- config.proxy_port = <%= @proxy_port %>
28
- config.proxy_user = nil
29
- config.proxy_pass = nil
30
- <% else %>
31
- # config.proxy_addr = nil
32
- # config.proxy_port = nil
33
- # config.proxy_user = nil
34
- # config.proxy_pass = nil
35
- <% end %>
36
-
37
- <% if @configure_viewport %>
38
- # Viewport settings
39
- config.viewport_width = <%= @viewport_width || 1920 %>
40
- config.viewport_height = <%= @viewport_height || 1080 %>
41
- <% else %>
42
- # Viewport settings
43
- # config.viewport_width = 1920
44
- # config.viewport_height = 1080
45
- <% end %>
46
-
47
- <% if @configure_pdf %>
48
- # PDF settings
49
- config.pdf_orientation = "<%= @pdf_orientation || "portrait" %>"
50
- <% if @pdf_margins %>
51
- config.pdf_margin_top = <%= @pdf_margin_top || 10 %>
52
- config.pdf_margin_bottom = <%= @pdf_margin_bottom || 10 %>
53
- config.pdf_margin_left = <%= @pdf_margin_left || 10 %>
54
- config.pdf_margin_right = <%= @pdf_margin_right || 10 %>
55
- <% else %>
56
- # config.pdf_margin_top = 10
57
- # config.pdf_margin_bottom = 10
58
- # config.pdf_margin_left = 10
59
- # config.pdf_margin_right = 10
60
- <% end %>
61
- config.pdf_print_background = <%= @pdf_print_background ? "true" : "false" %>
62
- config.pdf_scale = <%= @pdf_scale || 1.0 %>
63
- <% else %>
64
- # PDF settings
65
- # config.pdf_orientation = "portrait"
66
- # config.pdf_margin_top = 10
67
- # config.pdf_margin_bottom = 10
68
- # config.pdf_margin_left = 10
69
- # config.pdf_margin_right = 10
70
- # config.pdf_print_background = true
71
- # config.pdf_scale = 1.0
5
+ <%
6
+ Bidi2pdfRails::Config::CONFIG_OPTIONS.each_pair do |top_level_option_name, top_level_option|
7
+ name = top_level_option[:name]
8
+ %>
9
+
10
+ #
11
+ # <%= name %>
12
+ #
13
+ <% top_level_option[:options].each do |option| %>
14
+ <% if option[:limited_to] %>
15
+ <%= "# Allowed values: #{option[:limited_to].map { |v| v.inspect }.join(", ")}" %>
16
+ <% end -%>
17
+ <% if changed_by_user?(top_level_option_name, option[:name]) -%>
18
+ <%= "config.#{top_level_option_name}.#{option[:name]} = #{get_option_value(top_level_option_name, option[:name]) } # #{option[:desc]}" -%>
19
+ <% else -%>
20
+ <%= "# config.#{top_level_option_name}.#{option[:name]} = #{option[:default_as_str] ? option[:default_as_str] : option[:default].inspect} # #{option[:desc]}" -%>
21
+ <% end -%>
22
+ <% end -%>
72
23
  <% end %>
24
+ end
73
25
 
74
- # config.cookies = [
75
- # { name: "session", value: "abc123", domain: "example.com" }
76
- # ]
26
+ Rails.application.config.after_initialize do
27
+ Bidi2pdfRails::MainLogSubscriber.attach_to "bidi2pdf", inherit_all: true # needed for imported methods
28
+ Bidi2pdfRails::MainLogSubscriber.attach_to "bidi2pdf_rails", inherit_all: true # needed for imported methods
77
29
 
78
- # config.headers = {
79
- # "X-API-KEY" => "topsecret"
80
- # }
30
+ Bidi2pdfRails::BrowserConsoleLogSubscriber.attach_to "bidi2pdf"
81
31
 
82
- # config.auth = {
83
- # username: "admin",
84
- # password: "secret"
85
- # }
32
+ Bidi2pdfRails::MainLogSubscriber.silence /network_event_.*\.bidi2pdf/
86
33
 
87
- # chromedriver install dir
88
- # config.install_dir = Rails.root.join("tmp", "bidi2pdf").to_s
34
+ Bidi2pdfRails::NetworkLogSubscriber.attach_to "bidi2pdf"
89
35
  end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+ require "net/http"
5
+ require "rack/handler/puma"
6
+ require "socket"
7
+
8
+ RSpec.feature "As a devoloper, I want to generate PDF's with bidi2pdf-rails", :pdf, type: :request do
9
+ # This feature demonstrates how to use bidi2pdf-rails to generate PDFs
10
+ # from Rails views, remote URLs, and inline HTML. These specs double as
11
+ # living documentation for gem users.
12
+
13
+ before(:all) do
14
+ # Prepare the PDF rendering engine (chromium, etc.)
15
+ Bidi2pdfRails::ChromedriverManagerSingleton.initialize_manager force: true
16
+ end
17
+
18
+ after(:all) do
19
+ Bidi2pdfRails::ChromedriverManagerSingleton.shutdown
20
+ end
21
+
22
+ scenario "Rendering a controller view to PDF using layout: 'pdf'" do
23
+ # Controller example:
24
+ #
25
+ # def show
26
+ # respond_to do |format|
27
+ # format.html
28
+ # format.pdf { render pdf: 'my-report', layout: 'pdf' }
29
+ # end
30
+ # end
31
+
32
+ when_ "I visit the PDF version of a report" do
33
+ before do
34
+ @response = get_pdf_response "/reports/1.pdf"
35
+ end
36
+
37
+ then_ "I receive a successful HTTP response" do
38
+ expect(@response.code).to eq("200")
39
+ end
40
+
41
+ and_ "I receive a PDF file in response" do
42
+ expect(@response['Content-Type']).to eq("application/pdf")
43
+ end
44
+
45
+ and_ "the PDF contains the expected number of pages" do
46
+ expect(@response.body).to have_pdf_page_count(5)
47
+ end
48
+
49
+ and_ "the disposition header is set to attachment" do
50
+ expect(@response['Content-Disposition']).to start_with('inline; filename="my-report.pdf"')
51
+ end
52
+
53
+ and_ "the PDF contains the expected content" do
54
+ expect(@response.body).to contains_pdf_text("Section Two").at_page(2)
55
+ end
56
+ end
57
+ end
58
+
59
+ scenario "Converting a remote URL into a PDF with custom options" do
60
+ # Controller usage:
61
+ #
62
+ # def convert_remote_url
63
+ # render pdf: 'convert-remote-url', url: "http://example.com", wait_for_page_loaded: false, print_options: { page: { format: :A4 } }
64
+ # end
65
+
66
+ when_ "I visit the PDF version of a report" do
67
+ before do
68
+ @response = get_pdf_response "/convert-remote-url.pdf"
69
+ end
70
+
71
+ then_ "I receive a successful HTTP response" do
72
+ expect(@response.code).to eq("200")
73
+ end
74
+
75
+ and_ "I receive a PDF file in response" do
76
+ expect(@response['Content-Type']).to eq("application/pdf")
77
+ end
78
+
79
+ and_ "the PDF contains the expected number of pages" do
80
+ expect(@response.body).to have_pdf_page_count(1)
81
+ end
82
+
83
+ and_ "the disposition header is set to attachment" do
84
+ expect(@response['Content-Disposition']).to start_with('inline; filename="convert-remote-url.pdf"')
85
+ end
86
+ end
87
+ end
88
+
89
+ scenario "Rendering inline HTML directly to PDF" do
90
+ # Controller usage:
91
+ #
92
+ # def inline_html
93
+ # html = <<~HTML
94
+ # <html>
95
+ # <head>
96
+ # </head>
97
+ # <body>
98
+ # <h1>PDF Rendering Sample</h1>
99
+ # <p style="page-break-after: always;">Page break</p>
100
+ # <p>Content Page 2</p>
101
+ # </body>
102
+ # </html>
103
+ #
104
+ # render pdf: 'inline-html', inline: html, wait_for_page_loaded: false, print_options: { page: { format: :A4 } }
105
+ # end
106
+
107
+ when_ "I visit the PDF version of a report" do
108
+ before do
109
+ @response = get_pdf_response "/inline-html.pdf"
110
+ end
111
+
112
+ then_ "I receive a successful HTTP response" do
113
+ expect(@response.code).to eq("200")
114
+ end
115
+
116
+ and_ "I receive a PDF file in response" do
117
+ expect(@response['Content-Type']).to eq("application/pdf")
118
+ end
119
+
120
+ and_ "the PDF contains the expected number of pages" do
121
+ expect(@response.body).to have_pdf_page_count(2)
122
+ end
123
+
124
+ and_ "the disposition header is set to attachment" do
125
+ expect(@response['Content-Disposition']).to start_with('inline; filename="inline-html.pdf"')
126
+ end
127
+
128
+ and_ "the PDF contains the expected content" do
129
+ expect(@response.body).to contains_pdf_text("PDF Rendering Sample")
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,173 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+ require "net/http"
5
+ require "rack/handler/puma"
6
+ require "socket"
7
+ require "base64"
8
+
9
+ RSpec.feature "As a user, I want to generate a PDF from a protected remote URL", :pdf, type: :request do
10
+ before(:all) do
11
+ # Bidi2pdfRails.config.general_options.headless = false
12
+ Bidi2pdfRails::ChromedriverManagerSingleton.initialize_manager force: true
13
+ end
14
+
15
+ after(:all) do
16
+ Bidi2pdfRails::ChromedriverManagerSingleton.shutdown
17
+ end
18
+
19
+ scenario "Using basic auth for remote PDF rendering" do
20
+ # Controller setup:
21
+ #
22
+ # You can configure basic auth in two ways:
23
+ #
24
+ # 1. In an initializer (global config):
25
+ #
26
+ # Bidi2pdfRails.configure do |config|
27
+ # config.render_remote_settings.basic_auth_user = ->(_controller) { "admin" }
28
+ # config.render_remote_settings.basic_auth_pass = ->(_controller) { "secret" }
29
+ # end
30
+ #
31
+ # 2. Inline within controller action:
32
+ #
33
+ # render pdf: 'convert-remote-url-basic-auth',
34
+ # url: basic_auth_endpoint_url(only_path: false),
35
+ # auth: { username: "admin", password: "secret" }
36
+
37
+ when_ "I request a PDF generated from a basic-auth protected page" do
38
+ before do
39
+ with_render_setting :basic_auth_user, ->(_controller) { "admin" }
40
+ # in prod better to use:
41
+ # Bidi2pdfRails.config.render_remote_settings.basic_auth_pass = ->(_controller) { Rails.application.credentials.dig('bidi2pdf_rails', 'basic_auth_pass') }
42
+ with_render_setting :basic_auth_pass, ->(_controller) { "secret" }
43
+
44
+ @response = get_pdf_response "/convert-remote-url-basic-auth"
45
+ end
46
+
47
+ then_ "I receive a successful HTTP response" do
48
+ expect(@response.code).to eq("200")
49
+ end
50
+
51
+ and_ "I receive a PDF file in response" do
52
+ expect(@response['Content-Type']).to eq("application/pdf")
53
+ end
54
+
55
+ and_ "the PDF contains the expected number of pages" do
56
+ expect(@response.body).to have_pdf_page_count(1)
57
+ end
58
+
59
+ and_ "the disposition header is set to attachment" do
60
+ expect(@response['Content-Disposition']).to start_with('inline; filename="convert-remote-url-basic-auth.pdf"')
61
+ end
62
+
63
+ and_ "the PDF contains the expected content" do
64
+ expect(@response.body).to contains_pdf_text("This page is secured with: HTTPBasicAuthentication").at_page(1)
65
+ end
66
+ end
67
+ end
68
+
69
+ scenario "Using a session cookie for remote PDF rendering" do
70
+ # Controller setup:
71
+ #
72
+ # You can configure cookies in two ways:
73
+ #
74
+ # 1. In an initializer (global config):
75
+ #
76
+ # Bidi2pdfRails.configure do |config|
77
+ # config.render_remote_settings.cookies = = ->(controller) { { "auth_token" => signed_cookie_value("valid-authentication-token", controller) } }
78
+ # end
79
+ #
80
+ # 2. Inline within controller action:
81
+ #
82
+ # render pdf: 'convert-remote-url-cookie',
83
+ # url: cookie_endpoint_url(only_path: false),
84
+ # wait_for_page_loaded: false,
85
+ # cookies: { "auth_token" => signed_cookie_value("valid-authentication-token", controller) }
86
+ #
87
+
88
+ when_ "I request a PDF from a page that requires a session cookie" do
89
+ def signed_cookie_value(value, controller)
90
+ request = controller.request
91
+ secret = request.key_generator.generate_key(request.signed_cookie_salt)
92
+ # Sign the value
93
+ verifier = ActiveSupport::MessageVerifier.new(secret)
94
+ verifier.generate(value)
95
+ end
96
+
97
+ before do
98
+ with_render_setting :cookies, ->(controller) { { "auth_token" => signed_cookie_value("valid-authentication-token", controller) } }
99
+
100
+ @response = get_pdf_response "/convert-remote-url-cookie"
101
+ end
102
+
103
+ then_ "I receive a successful HTTP response" do
104
+ expect(@response.code).to eq("200")
105
+ end
106
+
107
+ and_ "I receive a PDF file in response" do
108
+ expect(@response['Content-Type']).to eq("application/pdf")
109
+ end
110
+
111
+ and_ "the PDF contains the expected number of pages" do
112
+ expect(@response.body).to have_pdf_page_count(1)
113
+ end
114
+
115
+ and_ "the disposition header is set to attachment" do
116
+ expect(@response['Content-Disposition']).to start_with('inline; filename="convert-remote-url-cookie.pdf"')
117
+ end
118
+
119
+ and_ "the PDF contains the expected content" do
120
+ expect(@response.body).to contains_pdf_text("Protected Resource This page is secured with: CookieAuthentication").at_page(1)
121
+ end
122
+ end
123
+ end
124
+
125
+ scenario "Using custom headers for remote PDF rendering" do
126
+ # Controller setup:
127
+ #
128
+ # You can configure headers in two ways:
129
+ #
130
+ # 1. In an initializer (global config):
131
+ #
132
+ # Bidi2pdfRails.configure do |config|
133
+ # config.render_remote_settings.headers = ->(controller) { { "X-API-Key" => "your-secret-api-key" } }
134
+ # end
135
+ #
136
+ # 2. Inline within controller action:
137
+ #
138
+ # render pdf: 'convert-remote-url-cookie',
139
+ # url: api_endpoint_url(only_path: false),
140
+ # wait_for_page_loaded: false,
141
+ # headers: { "X-API-Key" => "your-secret-api-key" }
142
+ #
143
+
144
+ when_ "I request a PDF from a page that requires an auth header" do
145
+ before do
146
+ @old_headers = Bidi2pdfRails.config.render_remote_settings.headers
147
+ with_render_setting :headers, ->(_controller) { { "X-API-Key" => "your-secret-api-key" } }
148
+
149
+ @response = get_pdf_response "/convert-remote-url-header"
150
+ end
151
+
152
+ then_ "I receive a successful HTTP response" do
153
+ expect(@response.code).to eq("200")
154
+ end
155
+
156
+ and_ "I receive a PDF file in response" do
157
+ expect(@response['Content-Type']).to eq("application/pdf")
158
+ end
159
+
160
+ and_ "the PDF contains the expected number of pages" do
161
+ expect(@response.body).to have_pdf_page_count(1)
162
+ end
163
+
164
+ and_ "the disposition header is set to attachment" do
165
+ expect(@response['Content-Disposition']).to start_with('inline; filename="convert-remote-url-cookie.pdf"')
166
+ end
167
+
168
+ and_ "the PDF contains the expected content" do
169
+ expect(@response.body).to contains_pdf_text("Protected Resource This page is secured with: API KeyAuthentication").at_page(1)
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+ require "net/http"
5
+ require "rack/handler/puma"
6
+ require "socket"
7
+ require "base64"
8
+
9
+ RSpec.feature "As a user, I want to inject css into a website before printing a PDF", :pdf, type: :request do
10
+ before(:all) do
11
+ # Bidi2pdfRails.config.general_options.headless = false
12
+ Bidi2pdfRails::ChromedriverManagerSingleton.initialize_manager force: true
13
+ end
14
+
15
+ after(:all) do
16
+ Bidi2pdfRails::ChromedriverManagerSingleton.shutdown
17
+ end
18
+
19
+ scenario "Using raw CSS" do
20
+ # Controller setup:
21
+ #
22
+ # You can configure basic auth in two ways:
23
+ #
24
+ # 1. In an initializer (global config):
25
+ #
26
+ # Bidi2pdfRails.configure do |config|
27
+ # config.pdf_settings.custom_css = <<~CSS
28
+ # p {
29
+ # page-break-after: always;
30
+ # }
31
+ # CSS
32
+ # end
33
+ #
34
+ # 2. Inline within controller action:
35
+ # css = <<~CSS
36
+ # p {
37
+ # page-break-after: always;
38
+ # }
39
+ # CSS
40
+ # render pdf: 'inject-css-raw',
41
+ # custom_css: css,
42
+ # layout: 'simple',
43
+ # template: 'reports/simple',
44
+ # wait_for_page_loaded: false,
45
+ # print_options: { page: { format: :A4 } }
46
+ #
47
+
48
+ when_ "I request a PDF from a page and inject raw css" do
49
+ before do
50
+ with_pdf_settings :custom_css, <<-CSS
51
+ p {
52
+ page-break-after: always;
53
+ }
54
+ CSS
55
+
56
+ @response = get_pdf_response "/inject/raw-css"
57
+ end
58
+
59
+ then_ "I receive a successful HTTP response" do
60
+ expect(@response.code).to eq("200")
61
+ end
62
+
63
+ and_ "I receive a PDF file in response" do
64
+ expect(@response['Content-Type']).to eq("application/pdf")
65
+ end
66
+
67
+ and_ "the PDF contains the expected number of pages" do
68
+ expected_page_count = 6
69
+ expect(@response.body).to have_pdf_page_count(expected_page_count)
70
+ end
71
+
72
+ and_ "the disposition header is set to attachment" do
73
+ expect(@response['Content-Disposition']).to start_with('inline; filename="inject-raw-css.pdf"')
74
+ end
75
+
76
+ and_ 'the last page contains the expected content ("6")' do
77
+ expect(@response.body).to contains_pdf_text("6").at_page(6)
78
+ end
79
+ end
80
+ end
81
+
82
+ scenario "Using an external stylesheet" do
83
+ # Controller setup:
84
+ #
85
+ # You can configure cookies in two ways:
86
+ #
87
+ # 1. In an initializer (global config):
88
+ #
89
+ # Bidi2pdfRails.configure do |config|
90
+ # config.pdf_settings.custom_css_url = ->(controller) { controller.view_context.asset_url 'stylesheets/simple.css' }
91
+ # end
92
+ #
93
+ # 2. Inline within controller action:
94
+ #
95
+ # render pdf: 'inject-css-url',
96
+ # custom_css_url: view_context.asset_url('stylesheets/simple.css'),
97
+ # layout: 'simple',
98
+ # template: 'reports/simple',
99
+ # wait_for_page_loaded: false,
100
+ # print_options: { page: { format: :A4 } }
101
+ #
102
+
103
+ when_ "I request a PDF from a page and inject an external stylesheet" do
104
+ before do
105
+ with_pdf_settings :custom_css_url, ->(controller) { controller.view_context.asset_url 'stylesheets/simple.css' }
106
+
107
+ @response = get_pdf_response "/inject/url-css"
108
+ end
109
+
110
+ then_ "I receive a successful HTTP response" do
111
+ expect(@response.code).to eq("200")
112
+ end
113
+
114
+ and_ "I receive a PDF file in response" do
115
+ expect(@response['Content-Type']).to eq("application/pdf")
116
+ end
117
+
118
+ and_ "the PDF contains the expected number of pages" do
119
+ expected_page_count = 6
120
+ expect(@response.body).to have_pdf_page_count(expected_page_count)
121
+ end
122
+
123
+ and_ "the disposition header is set to attachment" do
124
+ expect(@response['Content-Disposition']).to start_with('inline; filename="inject-url-css.pdf"')
125
+ end
126
+
127
+ and_ 'the last page contains the expected content ("6")' do
128
+ expect(@response.body).to contains_pdf_text(6).at_page(6)
129
+ end
130
+ end
131
+ end
132
+ end