slimmer 14.0.0 → 15.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e29edb1500e56cda58cd5b43463f19beb2b8e1e53a2a0c0c7bf4f88b1542c3d
4
- data.tar.gz: 90a425692e649c7f941f9f45a8966babff2f31dc888ada70d47ea86b7b365002
3
+ metadata.gz: 5423f67907cfbc074dcc3ec3be3763ee1b4de7194746d3465e2bd8962f131589
4
+ data.tar.gz: 9378a917a3a686ac18dda3d401596ff3c749f2c45897409cf9ca79af02d19005
5
5
  SHA512:
6
- metadata.gz: 2132180bb938d0db3a8dfe094a45b173254b52ec6847977480ae14a9ceec8a2c44da0dd54bfc7c4f062a2e050710ac5cdf3137b46a238993c40b148df631032f
7
- data.tar.gz: cb45e29c4f0d6d3874352a89f29146cc154279430a58535fe3e9ff6d46e53900171534a29209e5432f203073fe1708f578181d800f595d07844be52eda8d15f4
6
+ metadata.gz: 0e5d62fedf19a951a60d82df37a9b3ca5258b2f46bc8e521e44050e00ff4755681f07ef6b5a540ea72702d5a5ae86fdd4792b86b9feeff07c1dd47dd075ea085
7
+ data.tar.gz: 79a18ae53ba25f1d3c3dacb186b1b7d239457b4a3201aad806aefad5547e55368021acdc94c46d35ad479686777c07ee88bf3a7a145237e7f64413b0bd13dd49
@@ -1,3 +1,27 @@
1
+ # 15.3.0
2
+
3
+ * Introduce separate, internal exception class for intermittent
4
+ template retrieval errors.
5
+
6
+ # 15.2.0
7
+
8
+ * Add X-Slimmer-Show-Accounts header to choose between accounts
9
+ header components. (#255)
10
+ * Update to Ruby 2.7.2. (#254)
11
+
12
+ # 15.1.1
13
+
14
+ * Amend toggle button selector (#251)
15
+
16
+ # 15.1.0
17
+
18
+ * Add `<base>` tag into the `<head>`.
19
+
20
+ # 15.0.0
21
+
22
+ * BREAKING: Test templates no longer embed links to production JavaScript files,
23
+ apps should provide their own dependencies.
24
+
1
25
  # 14.0.0
2
26
 
3
27
  * Remove handling of non-200 responses (#245)
data/README.md CHANGED
@@ -96,3 +96,7 @@ Add the following code to spec/spec_helper:
96
96
  ```rb
97
97
  require 'slimmer/rspec'
98
98
  ```
99
+
100
+ ## Licence
101
+
102
+ [MIT License](LICENCE)
data/Rakefile CHANGED
@@ -1,8 +1,9 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  require "bundler/gem_tasks"
4
2
  require "rdoc/task"
5
3
  require "rake/testtask"
4
+ require "rubocop/rake_task"
5
+
6
+ RuboCop::RakeTask.new
6
7
 
7
8
  Dir.glob("lib/tasks/*.rake").each { |r| import r }
8
9
 
@@ -18,4 +19,4 @@ Rake::TestTask.new("test") do |t|
18
19
  t.verbose = true
19
20
  end
20
21
 
21
- task default: %i[test]
22
+ task default: %i[test rubocop]
@@ -28,6 +28,7 @@ module Slimmer
28
28
  autoload :HTTPClient, "slimmer/http_client"
29
29
 
30
30
  module Processors
31
+ autoload :AccountsShower, "slimmer/processors/accounts_shower"
31
32
  autoload :BodyClassCopier, "slimmer/processors/body_class_copier"
32
33
  autoload :BodyInserter, "slimmer/processors/body_inserter"
33
34
  autoload :ConditionalCommentMover, "slimmer/processors/conditional_comment_mover"
@@ -44,6 +45,7 @@ module Slimmer
44
45
  autoload :TitleInserter, "slimmer/processors/title_inserter"
45
46
  end
46
47
 
47
- class TemplateNotFoundException < StandardError; end
48
48
  class CouldNotRetrieveTemplate < StandardError; end
49
+ class TemplateNotFoundException < CouldNotRetrieveTemplate; end
50
+ class IntermittentRetrievalError < CouldNotRetrieveTemplate; end
49
51
  end
@@ -35,7 +35,7 @@ module Slimmer
35
35
  if response_can_be_rewritten?(status, headers)
36
36
  response = Rack::Response.new(body, status, headers)
37
37
 
38
- if !skip_slimmer?(env, response)
38
+ unless skip_slimmer?(env, response)
39
39
  status, headers, body = rewrite_response(env, response)
40
40
  end
41
41
  end
@@ -61,7 +61,7 @@ module Slimmer
61
61
  end
62
62
 
63
63
  def skip_slimmer_header?(response)
64
- !!response.headers[Headers::SKIP_HEADER]
64
+ response.headers.key?(Headers::SKIP_HEADER)
65
65
  end
66
66
 
67
67
  def s(body)
@@ -9,17 +9,18 @@ module Slimmer
9
9
 
10
10
  # @private
11
11
  SLIMMER_HEADER_MAPPING = {
12
- application_name: "Application-Name",
13
- format: "Format",
14
- page_owner: "Page-Owner",
15
- organisations: "Organisations",
16
- world_locations: "World-Locations",
17
- result_count: "Result-Count",
18
- search_parameters: "Search-Parameters",
19
- section: "Section",
20
- skip: "Skip",
21
- template: "Template",
22
- remove_search: "Remove-Search",
12
+ application_name: "Application-Name",
13
+ format: "Format",
14
+ page_owner: "Page-Owner",
15
+ organisations: "Organisations",
16
+ world_locations: "World-Locations",
17
+ result_count: "Result-Count",
18
+ search_parameters: "Search-Parameters",
19
+ section: "Section",
20
+ skip: "Skip",
21
+ template: "Template",
22
+ remove_search: "Remove-Search",
23
+ show_accounts: "Show-Accounts",
23
24
  }.freeze
24
25
 
25
26
  # @private
@@ -55,6 +56,9 @@ module Slimmer
55
56
  # @private
56
57
  REMOVE_SEARCH_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:remove_search]}".freeze
57
58
 
59
+ # @private
60
+ SHOW_ACCOUNTS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:show_accounts]}".freeze
61
+
58
62
  # Set the "slimmer headers" to configure the page
59
63
  #
60
64
  # @param hash [Hash] the options
@@ -66,6 +70,7 @@ module Slimmer
66
70
  # @option hash [String] result_count
67
71
  # @option hash [String] search_parameters
68
72
  # @option hash [String] section
73
+ # @option hash [String] show_accounts
69
74
  # @option hash [String] skip
70
75
  # @option hash [String] template
71
76
  # @option hash [String] world_locations
@@ -0,0 +1,29 @@
1
+ module Slimmer::Processors
2
+ class AccountsShower
3
+ def initialize(headers)
4
+ @headers = headers
5
+ end
6
+
7
+ def filter(_src, dest)
8
+ header_value = @headers[Slimmer::Headers::SHOW_ACCOUNTS_HEADER]
9
+ if header_value == "signed-in"
10
+ remove_signed_out(dest)
11
+ elsif header_value == "signed-out"
12
+ remove_signed_in(dest)
13
+ else
14
+ remove_signed_out(dest)
15
+ remove_signed_in(dest)
16
+ end
17
+ end
18
+
19
+ def remove_signed_out(dest)
20
+ signed_out = dest.at_css("#global-header #accounts-signed-out")
21
+ signed_out.remove if signed_out
22
+ end
23
+
24
+ def remove_signed_in(dest)
25
+ signed_in = dest.at_css("#global-header #accounts-signed-in")
26
+ signed_in.remove if signed_in
27
+ end
28
+ end
29
+ end
@@ -9,7 +9,7 @@ module Slimmer::Processors
9
9
  search = dest.at_css("#global-header #search")
10
10
  search.remove if search
11
11
 
12
- search_link = dest.at_css("#global-header a[href='#search']")
12
+ search_link = dest.at_css("#global-header .search-toggle")
13
13
  search_link.remove if search_link
14
14
  end
15
15
  end
@@ -1,10 +1,11 @@
1
1
  module Slimmer::Processors
2
2
  class TagMover
3
3
  def filter(src, dest)
4
- move_tags(src, dest, "script", dest_node: "body", keys: %w(src inner_html))
4
+ move_tags(src, dest, "script", dest_node: "body", keys: %w[src inner_html])
5
5
  move_tags(src, dest, "link", must_have: %w[href])
6
- move_tags(src, dest, "meta", must_have: %w(name content), keys: %w[name content http-equiv], insertion_location: :top)
7
- move_tags(src, dest, "meta", must_have: %w(property content), keys: %w(property content), insertion_location: :top)
6
+ move_tags(src, dest, "meta", must_have: %w[name content], keys: %w[name content http-equiv], insertion_location: :top)
7
+ move_tags(src, dest, "meta", must_have: %w[property content], keys: %w[property content], insertion_location: :top)
8
+ move_tags(src, dest, "base", must_have: %w[href])
8
9
  end
9
10
 
10
11
  def include_tag?(node, min_attrs)
@@ -39,15 +40,15 @@ module Slimmer::Processors
39
40
  dest_node = opts[:dest_node] || "head"
40
41
 
41
42
  src.css(type).each do |node|
42
- if include_tag?(node, min_attrs) && !already_there.include?(tag_fingerprint(node, comparison_attrs))
43
- node = wrap_node(src, node)
44
- node.remove
45
-
46
- if opts[:insertion_location] == :top
47
- dest.at_xpath("/html/#{dest_node}").prepend_child(node)
48
- else
49
- dest.at_xpath("/html/#{dest_node}") << node
50
- end
43
+ next unless include_tag?(node, min_attrs) && !already_there.include?(tag_fingerprint(node, comparison_attrs))
44
+
45
+ node = wrap_node(src, node)
46
+ node.remove
47
+
48
+ if opts[:insertion_location] == :top
49
+ dest.at_xpath("/html/#{dest_node}").prepend_child(node)
50
+ else
51
+ dest.at_xpath("/html/#{dest_node}") << node
51
52
  end
52
53
  end
53
54
  end
@@ -5,12 +5,12 @@ module Slimmer
5
5
  class Skin
6
6
  attr_accessor :asset_host, :logger, :strict, :options
7
7
 
8
- def initialize options = {}
8
+ def initialize(options = {})
9
9
  @options = options
10
10
  @asset_host = options[:asset_host]
11
11
 
12
12
  @logger = options[:logger] || NullLogger.instance
13
- @strict = options[:strict] || %w{development test}.include?(ENV["RACK_ENV"])
13
+ @strict = options[:strict] || %w[development test].include?(ENV["RACK_ENV"])
14
14
  end
15
15
 
16
16
  def template(template_name)
@@ -22,10 +22,18 @@ module Slimmer
22
22
  def load_template(template_name)
23
23
  url = template_url(template_name)
24
24
  HTTPClient.get(url)
25
- rescue RestClient::Exception => e
26
- raise TemplateNotFoundException, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller
27
- rescue Errno::ECONNREFUSED, SocketError, OpenSSL::SSL::SSLError => e
28
- raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_name}' from '#{url}' because #{e}", caller
25
+ rescue Errno::ECONNREFUSED, SocketError, OpenSSL::SSL::SSLError, RestClient::Exception => e
26
+ message = "Unable to fetch: '#{template_name}' from '#{url}' because #{e}"
27
+
28
+ if e.is_a?(RestClient::Exception) && e.http_code == 404
29
+ raise TemplateNotFoundException, message, caller
30
+ end
31
+
32
+ if e.is_a?(RestClient::Exception) && [502, 503, 504].include?(e.http_code)
33
+ raise IntermittentRetrievalError, message, caller
34
+ end
35
+
36
+ raise CouldNotRetrieveTemplate, message, caller
29
37
  end
30
38
 
31
39
  def template_url(template_name)
@@ -42,7 +50,7 @@ module Slimmer
42
50
  doc = Nokogiri::HTML.parse(html)
43
51
  if strict
44
52
  errors = doc.errors.select(&:error?).reject { |e| ignorable?(e) }
45
- if !errors.empty?
53
+ unless errors.empty?
46
54
  error = errors.first
47
55
  message = "In #{description_for_error_message}: '#{error.message}' at line #{error.line} col #{error.column} (code #{error.code}).\n"
48
56
  message << "Add ?skip_slimmer=1 to the url to show the raw backend request.\n\n"
@@ -59,7 +67,7 @@ module Slimmer
59
67
  lines = [""] + html.split("\n")
60
68
  from = [1, error.line - context_size].max
61
69
  to = [lines.size - 1, error.line + context_size].min
62
- context = (from..to).zip(lines[from..to]).map { |lineno, line| "%4d: %s" % [lineno, line] }
70
+ context = (from..to).zip(lines[from..to]).map { |lineno, line| sprintf("%4d: %s", lineno, line) }
63
71
  marker = " " * (error.column - 1) + "-----v"
64
72
  context.insert(context_size, marker)
65
73
  context.join("\n")
@@ -107,6 +115,7 @@ module Slimmer
107
115
  Processors::SearchParameterInserter.new(response),
108
116
  Processors::SearchPathSetter.new(response),
109
117
  Processors::SearchRemover.new(response.headers),
118
+ Processors::AccountsShower.new(response.headers),
110
119
  ]
111
120
 
112
121
  template_name = response.headers[Headers::TEMPLATE_HEADER] || "core_layout"
@@ -1,16 +1,15 @@
1
1
  module Slimmer
2
2
  module Template
3
- def self.included into
3
+ def self.included(into)
4
4
  into.extend ClassMethods
5
5
  end
6
6
 
7
- def slimmer_template template_name
7
+ def slimmer_template(template_name)
8
8
  response.headers[Slimmer::Headers::TEMPLATE_HEADER] = template_name.to_s
9
9
  end
10
10
 
11
-
12
11
  module ClassMethods
13
- def slimmer_template template_name
12
+ def slimmer_template(template_name)
14
13
  after_action do
15
14
  response.headers[Slimmer::Headers::TEMPLATE_HEADER] ||= template_name.to_s
16
15
  end
@@ -2,10 +2,10 @@ require "slimmer/skin"
2
2
 
3
3
  module Slimmer
4
4
  class Skin
5
- def load_template name
5
+ def load_template(name)
6
6
  logger.debug "Slimmer: TEST MODE - Loading fixture template from #{__FILE__}"
7
7
  if name =~ /\A(.*)\.raw\z/
8
- %{<div id="test-#{$1}"></div>}
8
+ %(<div id="test-#{Regexp.last_match(1)}"></div>)
9
9
  elsif File.exist?(template_path = File.join(File.dirname(__FILE__), "test_templates", "#{name}.html"))
10
10
  File.read(template_path)
11
11
  else
@@ -19,9 +19,5 @@
19
19
  <div id="wrapper"></div>
20
20
 
21
21
  <footer id="footer"></footer>
22
-
23
- <script src="https://assets.publishing.service.gov.uk/static/govuk-template.js" type="text/javascript"></script>
24
- <script src="https://assets.publishing.service.gov.uk/static/libs/jquery/jquery-1.7.2.js" type="text/javascript"></script>
25
- <script src="https://assets.publishing.service.gov.uk/static/header-footer-only.js" type="text/javascript"></script>
26
22
  </body>
27
23
  </html>
@@ -19,9 +19,5 @@
19
19
  <div id="wrapper"></div>
20
20
 
21
21
  <footer id="footer"></footer>
22
-
23
- <script src="https://assets.publishing.service.gov.uk/static/govuk-template.js" type="text/javascript"></script>
24
- <script src="https://assets.publishing.service.gov.uk/static/libs/jquery/jquery-1.7.2.js" type="text/javascript"></script>
25
- <script src="https://assets.publishing.service.gov.uk/static/application.js" type="text/javascript"></script>
26
22
  </body>
27
23
  </html>
@@ -1,3 +1,3 @@
1
1
  module Slimmer
2
- VERSION = "14.0.0".freeze
2
+ VERSION = "15.3.0".freeze
3
3
  end
@@ -6,9 +6,9 @@ namespace :slimmer do
6
6
  path_to_static = "../static/public"
7
7
  path_to_public = "public"
8
8
  commands = ["cd #{path_to_public}"]
9
- Dir.glob("../static/public/*") { |f|
9
+ Dir.glob("../static/public/*") do |f|
10
10
  commands << "ln -s #{path_to_static}/#{f}"
11
- }
11
+ end
12
12
  commands << ["cd .."]
13
13
  run commands.join(" && ")
14
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 14.0.0
4
+ version: 15.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-14 00:00:00.000000000 Z
11
+ date: 2020-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: 2.0.0
187
+ version: '3'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: 2.0.0
194
+ version: '3'
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: timecop
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -252,6 +252,7 @@ files:
252
252
  - lib/slimmer/govuk_request_id.rb
253
253
  - lib/slimmer/headers.rb
254
254
  - lib/slimmer/http_client.rb
255
+ - lib/slimmer/processors/accounts_shower.rb
255
256
  - lib/slimmer/processors/body_class_copier.rb
256
257
  - lib/slimmer/processors/body_inserter.rb
257
258
  - lib/slimmer/processors/conditional_comment_mover.rb
@@ -294,7 +295,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
294
295
  - !ruby/object:Gem::Version
295
296
  version: '0'
296
297
  requirements: []
297
- rubygems_version: 3.0.3
298
+ rubygems_version: 3.1.4
298
299
  signing_key:
299
300
  specification_version: 4
300
301
  summary: Thinner than the skinner