bidi2pdf-rails 0.0.1.pre.alpha → 0.1.0
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/.idea/bidi2pdf-rails.iml +55 -9
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +33 -0
- data/README.md +117 -27
- data/Rakefile +2 -0
- data/cliff.toml +126 -0
- data/lib/bidi2pdf_rails/browser_console_log_subscriber.rb +24 -0
- data/lib/bidi2pdf_rails/chromedriver_manager_singleton.rb +11 -11
- data/lib/bidi2pdf_rails/config.rb +133 -0
- data/lib/bidi2pdf_rails/configurable.rb +106 -0
- data/lib/bidi2pdf_rails/main_log_subscriber.rb +33 -0
- data/lib/bidi2pdf_rails/network_log_subscriber.rb +20 -0
- data/lib/bidi2pdf_rails/railtie.rb +12 -45
- data/lib/bidi2pdf_rails/services/html_renderer.rb +33 -0
- data/lib/bidi2pdf_rails/services/html_to_pdf_converter.rb +28 -0
- data/lib/bidi2pdf_rails/services/pdf_browser_session.rb +39 -0
- data/lib/bidi2pdf_rails/services/pdf_renderer.rb +82 -0
- data/lib/bidi2pdf_rails/services/url_to_pdf_converter.rb +82 -0
- data/lib/bidi2pdf_rails/version.rb +1 -1
- data/lib/bidi2pdf_rails.rb +41 -58
- data/lib/generators/bidi2pdf_rails/USAGE +12 -4
- data/lib/generators/bidi2pdf_rails/initializer_generator.rb +136 -30
- data/lib/generators/bidi2pdf_rails/templates/bidi2pdf_rails.rb.tt +25 -79
- data/spec/acceptance/user_can_download_report_pdf_spec.rb +133 -0
- data/spec/acceptance/user_can_generate_pdf_from_protected_remote_url_spec.rb +173 -0
- data/spec/dummy/app/controllers/reports_controller.rb +37 -0
- data/spec/dummy/app/controllers/secure_controller.rb +52 -0
- data/spec/dummy/app/views/layouts/simple.html.erb +17 -0
- data/spec/dummy/app/views/secure/show.html.erb +10 -0
- data/spec/dummy/config/environments/production.rb +1 -1
- data/spec/dummy/config/initializers/bidi2pdf_rails.rb +68 -54
- data/spec/dummy/config/initializers/cors.rb +1 -1
- data/spec/dummy/config/routes.rb +10 -0
- data/spec/dummy/log/development.log +16567 -156
- data/spec/dummy/log/test.log +53046 -0
- data/spec/dummy/tmp/pids/server.pid +1 -1
- data/spec/integration/generators/bidi2pdf_rails/initializer_generator_spec.rb +64 -0
- data/spec/rails_helper.rb +8 -1
- data/spec/spec_helper.rb +47 -5
- data/spec/support/default_dirs_helper.rb +32 -0
- data/spec/support/pdf_helper.rb +12 -0
- data/spec/support/render_setting_helpers.rb +28 -0
- data/spec/support/request_server_bootstrap.rb +44 -0
- data/spec/{bidi2pdf_rails → unit/bidi2pdf_rails}/bidi2pdf_rails_spec.rb +1 -1
- data/spec/unit/bidi2pdf_rails/configurable/base_nested_config_spec.rb +133 -0
- data/tasks/changelog.rake +29 -0
- data/tasks/coverage.rake +23 -0
- metadata +95 -25
- data/lib/bidi2pdf_rails/log_subscriber.rb +0 -13
- data/spec/dummy/spec/helpers/reports_helper_spec.rb +0 -15
- data/spec/dummy/spec/requests/reports_spec.rb +0 -10
- data/spec/dummy/spec/views/reports/show.html.erb_spec.rb +0 -5
- data/spec/generator/bidie2pdf_rails_initializer_generator_spec.rb +0 -5
- data/spec/generator/initializer_generator_spec.rb +0 -5
- data/spec/requests/reports_spec.rb +0 -17
data/lib/bidi2pdf_rails.rb
CHANGED
@@ -1,87 +1,70 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "bidi2pdf"
|
4
|
-
require "
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
require "bidi2pdf/bidi/commands/print_parameters_validator"
|
5
|
+
require_relative "bidi2pdf_rails/version"
|
6
|
+
require_relative "bidi2pdf_rails/config"
|
7
|
+
require_relative "bidi2pdf_rails/railtie"
|
8
|
+
require_relative "bidi2pdf_rails/chromedriver_manager_singleton"
|
9
|
+
require_relative "bidi2pdf_rails/main_log_subscriber"
|
10
|
+
require_relative "bidi2pdf_rails/browser_console_log_subscriber"
|
11
|
+
require_relative "bidi2pdf_rails/network_log_subscriber"
|
8
12
|
|
9
13
|
module Bidi2pdfRails
|
10
14
|
class << self
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
:viewport_width, :viewport_height,
|
15
|
-
:pdf_margin_top, :pdf_margin_bottom, :pdf_margin_left, :pdf_margin_right,
|
16
|
-
:pdf_scale, :pdf_print_background, :pdf_format, :pdf_orientation, :verbosity
|
15
|
+
def config
|
16
|
+
Config.instance
|
17
|
+
end
|
17
18
|
|
18
19
|
# Allow configuration through a block
|
19
20
|
def configure
|
20
|
-
yield
|
21
|
+
yield config if block_given?
|
21
22
|
|
22
|
-
|
23
|
-
end
|
23
|
+
config.validate_print_options!
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
Bidi2pdf.configure do |config|
|
28
|
-
config.notification_service = notification_service
|
25
|
+
apply_bidi2pdf_config config
|
26
|
+
end
|
29
27
|
|
30
|
-
|
31
|
-
|
28
|
+
def apply_bidi2pdf_config(config = Config.instance)
|
29
|
+
Bidi2pdf.configure do |bidi2pdf_config|
|
30
|
+
bidi2pdf_config.notification_service = config.general_options.notification_service_value
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
else
|
36
|
-
config.network_events_logger = Logger.new(nil) # Disable network events logging
|
37
|
-
end
|
32
|
+
bidi2pdf_config.logger = config.general_options.logger_value&.tagged("bidi2pdf")
|
33
|
+
bidi2pdf_config.default_timeout = config.general_options.default_timeout_value
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
else
|
42
|
-
config.browser_console_logger = Logger.new(nil) # Disable browser console logging
|
43
|
-
end
|
35
|
+
bidi2pdf_config.network_events_logger = Logger.new(nil)
|
36
|
+
bidi2pdf_config.browser_console_logger = Logger.new(nil)
|
44
37
|
|
45
|
-
|
38
|
+
bidi2pdf_config.enable_default_logging_subscriber = false
|
46
39
|
end
|
47
40
|
|
48
|
-
Chromedriver::Binary.configure do |
|
49
|
-
|
41
|
+
Chromedriver::Binary.configure do |chromedriver_config|
|
42
|
+
chromedriver_config.logger = config.general_options.logger_value&.tagged("bidi2pdf")
|
50
43
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
chromedriver_config.proxy_addr = config.proxy_settings.addr_value
|
45
|
+
chromedriver_config.proxy_port = config.proxy_settings.port_value
|
46
|
+
chromedriver_config.proxy_user = config.proxy_settings.user_value
|
47
|
+
chromedriver_config.proxy_pass = config.proxy_settings.pass_value
|
55
48
|
|
56
|
-
|
49
|
+
chromedriver_config.install_dir = config.chromedriver_settings.install_dir_value
|
57
50
|
end
|
58
51
|
end
|
59
52
|
|
60
|
-
def
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
@remote_browser_url = nil
|
67
|
-
@cookies = {}
|
68
|
-
@headers = {}
|
69
|
-
@auth = nil
|
70
|
-
@headless = !Rails.env.development?
|
71
|
-
@chromedriver_port = 0
|
72
|
-
@chrome_session_args = Bidi2pdf::Bidi::Session::DEFAULT_CHROME_ARGS
|
73
|
-
|
74
|
-
@proxy_addr = nil
|
75
|
-
@proxy_port = nil
|
76
|
-
@proxy_user = nil
|
77
|
-
@proxy_pass = nil
|
78
|
-
@install_dir = nil
|
53
|
+
def use_local_chromedriver?
|
54
|
+
!use_remote_browser?
|
55
|
+
end
|
56
|
+
|
57
|
+
def use_remote_browser?
|
58
|
+
config.render_remote_settings.browser_url_value.present?
|
79
59
|
end
|
80
60
|
|
81
61
|
def logger
|
82
|
-
|
62
|
+
config.general_options.logger_value&.tagged("bidi2pdf-rails")
|
83
63
|
end
|
84
64
|
end
|
85
65
|
|
86
|
-
self
|
66
|
+
that = self
|
67
|
+
ActiveSupport.on_load(:action_controller_base, run_once: true) do
|
68
|
+
that.configure # apply the default configuration at load time
|
69
|
+
end
|
87
70
|
end
|
@@ -1,8 +1,16 @@
|
|
1
1
|
Description:
|
2
|
-
|
2
|
+
Generates a configuration file for Bidi2pdfRails in config/initializers/bidi2pdf_rails.rb
|
3
|
+
and adds development environment settings.
|
3
4
|
|
4
5
|
Example:
|
5
|
-
bin/rails generate initializer
|
6
|
+
bin/rails generate bidi2pdf_rails:initializer
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
# With options
|
9
|
+
bin/rails generate bidi2pdf_rails:initializer --quiet # Skip interactive prompts
|
10
|
+
bin/rails generate bidi2pdf_rails:initializer --force # Overwrite existing config
|
11
|
+
|
12
|
+
This will create:
|
13
|
+
config/initializers/bidi2pdf_rails.rb
|
14
|
+
|
15
|
+
And add settings to:
|
16
|
+
config/environments/development.rb
|
@@ -1,43 +1,72 @@
|
|
1
1
|
module Bidi2pdfRails
|
2
2
|
class InitializerGenerator < Rails::Generators::Base
|
3
3
|
source_root File.expand_path("templates", __dir__)
|
4
|
-
desc "Generates a config/initializers/bidi2pdf.rb config file"
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
def self.infer_option_type(default)
|
6
|
+
case default
|
7
|
+
when true, false then :boolean
|
8
|
+
when Numeric then :numeric
|
9
|
+
when Hash then :hash
|
10
|
+
when Array then :array
|
11
|
+
when Proc then :string
|
12
|
+
else :string
|
13
|
+
end
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
@proxy = yes?("Use a proxy server? (y/n)", :green)
|
16
|
+
def self.normalize_group(key)
|
17
|
+
key.to_s.sub(/(_settings|_options)$/, "")
|
18
|
+
end
|
16
19
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
+
def self.with_group_config
|
21
|
+
that = self
|
22
|
+
Bidi2pdfRails::Config::CONFIG_OPTIONS.each_pair do |group_key, group_config|
|
23
|
+
group_prefix = that.normalize_group(group_key)
|
24
|
+
yield group_key, group_prefix, group_config
|
20
25
|
end
|
26
|
+
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
28
|
+
def self.with_group_option
|
29
|
+
with_group_config do |group_key, group_prefix, group_config|
|
30
|
+
group_config[:options].each do |opt|
|
31
|
+
yield group_key, group_prefix, opt
|
32
|
+
end
|
26
33
|
end
|
34
|
+
end
|
35
|
+
|
36
|
+
with_group_option do |_group_key, group_prefix, opt|
|
37
|
+
next unless opt[:ask]
|
38
|
+
|
39
|
+
name = "#{group_prefix}_#{opt[:name]}"
|
40
|
+
type = infer_option_type(opt[:default])
|
41
|
+
default = opt[:default_as_str] || opt[:default]
|
42
|
+
|
43
|
+
class_option name,
|
44
|
+
type: type,
|
45
|
+
desc: opt[:desc],
|
46
|
+
default: default,
|
47
|
+
enum: opt[:limited_to]
|
48
|
+
end
|
27
49
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
50
|
+
def ask_questions
|
51
|
+
@answers = {}
|
52
|
+
|
53
|
+
return if options[:quiet]
|
54
|
+
|
55
|
+
self.class.with_group_config do |_group_key, group_prefix, group_config|
|
56
|
+
next unless group_config[:ask]
|
57
|
+
if group_config[:ask]
|
58
|
+
next unless yes?(group_config[:ask], :green)
|
59
|
+
end
|
60
|
+
|
61
|
+
group_config[:options].select { |opt| opt[:ask] }.each do |opt|
|
62
|
+
option_key = "#{group_prefix}_#{opt[:name]}".to_sym
|
63
|
+
next if cli_option_set?(option_key, opt)
|
64
|
+
|
65
|
+
@answers[option_key] = prompt_for_option(opt)
|
37
66
|
end
|
38
|
-
@pdf_print_background = yes?("Print background graphics? (y/n)", :green)
|
39
|
-
@pdf_scale = ask("PDF scale (e.g., 1.0):", :yellow)
|
40
67
|
end
|
68
|
+
|
69
|
+
@answers.compact!
|
41
70
|
end
|
42
71
|
|
43
72
|
def generate_config
|
@@ -48,9 +77,10 @@ module Bidi2pdfRails
|
|
48
77
|
|
49
78
|
def inject_environment_config
|
50
79
|
env_file = "config/environments/development.rb"
|
80
|
+
env_path = File.join(destination_root, env_file)
|
51
81
|
|
52
|
-
if File.exist?(
|
53
|
-
if File.read(
|
82
|
+
if File.exist?(env_path)
|
83
|
+
if File.read(env_path).include?("config.x.bidi2pdf_rails")
|
54
84
|
say_status :skipped, "Bidi2PDF settings already present in #{env_file}", :yellow
|
55
85
|
else
|
56
86
|
content = <<~RUBY.gsub(/^(?=[\w#])/, " ")
|
@@ -69,5 +99,81 @@ module Bidi2pdfRails
|
|
69
99
|
say_status :error, "Could not find #{env_file}", :red
|
70
100
|
end
|
71
101
|
end
|
102
|
+
|
103
|
+
no_commands do
|
104
|
+
def cli_option_set?(option_key, opt_def)
|
105
|
+
return false unless options.key?(option_key.to_s)
|
106
|
+
|
107
|
+
default = opt_def[:default_as_str] || opt_def[:default]
|
108
|
+
options[option_key.to_s].to_s != default.to_s
|
109
|
+
end
|
110
|
+
|
111
|
+
def prompt_for_option(opt)
|
112
|
+
type = self.class.infer_option_type(opt[:default])
|
113
|
+
|
114
|
+
if type == :boolean
|
115
|
+
question = opt[:desc].match?(/y\/n/i) ? opt[:desc] : "#{opt[:desc]} (y/n)?"
|
116
|
+
yes?(question, opt[:color])
|
117
|
+
else
|
118
|
+
opts = {
|
119
|
+
default: opt[:default_as_str] || opt[:default],
|
120
|
+
limited_to: opt[:limited_to],
|
121
|
+
echo: !opt[:secret]
|
122
|
+
}.compact
|
123
|
+
|
124
|
+
ask(opt[:desc], opt[:color], **opts)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def normalize_group(key)
|
129
|
+
self.class.normalize_group(key)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def changed_by_user?(full_top_level_name, option_name)
|
136
|
+
top_level_name = normalize_group full_top_level_name
|
137
|
+
|
138
|
+
full_qual_option_name = "#{top_level_name}_#{option_name}".to_sym
|
139
|
+
return false unless options.key?(full_qual_option_name.to_s)
|
140
|
+
|
141
|
+
option_def = Bidi2pdfRails::Config::CONFIG_OPTIONS.dig(full_top_level_name.to_sym, :options).find { |opt| opt[:name] == option_name.to_sym }
|
142
|
+
default = option_def[:default_as_str] ? option_def[:default_as_str] : option_def[:default]
|
143
|
+
|
144
|
+
current_value = get_option_value(top_level_name, option_name)
|
145
|
+
|
146
|
+
return false if default.nil? && current_value.empty?
|
147
|
+
return true if default.nil? && current_value.present?
|
148
|
+
|
149
|
+
!current_value.to_s.match /#{Regexp.escape(default.to_s)}/
|
150
|
+
end
|
151
|
+
|
152
|
+
def get_option_value(top_level_name, option_name)
|
153
|
+
top_level_name = top_level_name.to_s.sub(/(_settings)|(_options)$/, "")
|
154
|
+
full_qual_option_name = "#{top_level_name}_#{option_name}".to_sym
|
155
|
+
|
156
|
+
result = if @answers.key?(full_qual_option_name)
|
157
|
+
@answers[full_qual_option_name]
|
158
|
+
elsif options.key?(full_qual_option_name.to_s)
|
159
|
+
options[full_qual_option_name.to_s]
|
160
|
+
else
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
|
164
|
+
if result.is_a?(String)
|
165
|
+
if result.match(/(^\s+->\s+{)|(.*Rails\.)/) || numeric?(result)
|
166
|
+
return result
|
167
|
+
end
|
168
|
+
'"' + result + '"'
|
169
|
+
else
|
170
|
+
result
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def numeric?(string)
|
175
|
+
# Float/Integer conversion with rescue catches most numeric formats
|
176
|
+
true if Float(string) rescue false
|
177
|
+
end
|
72
178
|
end
|
73
179
|
end
|
@@ -2,88 +2,34 @@
|
|
2
2
|
|
3
3
|
Bidi2pdfRails.configure do |config|
|
4
4
|
overrides = Rails.application.config.x.bidi2pdf_rails
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
75
|
-
|
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
|
-
|
79
|
-
# "X-API-KEY" => "topsecret"
|
80
|
-
# }
|
30
|
+
Bidi2pdfRails::BrowserConsoleLogSubscriber.attach_to "bidi2pdf"
|
81
31
|
|
82
|
-
|
83
|
-
# username: "admin",
|
84
|
-
# password: "secret"
|
85
|
-
# }
|
32
|
+
Bidi2pdfRails::MainLogSubscriber.silence /network_event_.*\.bidi2pdf/
|
86
33
|
|
87
|
-
|
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
|