slimmer 4.1.1 → 4.2.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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 4.2.0
2
+
3
+ * Add ability to load shared erb templates over the network
4
+
1
5
  # 4.1.1
2
6
 
3
7
  * Assets are loaded from production instead of preview environment in test mode
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
- Slimmer provides Rack middleware for applying a standard header and footer around pages
2
- returned by a Ruby (Rack) application.
1
+ Slimmer provides Rack middleware for applying a standard header and footer around pages
2
+ returned by a Ruby (Rack) application.
3
3
 
4
4
  It does this by taking the page rendered by the application, extracting the contents of
5
5
  a `div` with id 'wrapper' and inserting that into a `div` with the same id in one of its
@@ -31,7 +31,7 @@ or
31
31
 
32
32
  ## Asset tag helpers
33
33
 
34
- To get asset tag helpers to point to your external asset server, add
34
+ To get asset tag helpers to point to your external asset server, add
35
35
 
36
36
  config.action_controller.asset_host = "http://my.alternative.host"
37
37
 
@@ -39,7 +39,7 @@ to `application.rb`.
39
39
 
40
40
  ## Specifying a template
41
41
 
42
- A specific template can be requested by giving its name in the `X-Slimmer-Template` HTTP header.
42
+ A specific template can be requested by giving its name in the `X-Slimmer-Template` HTTP header.
43
43
 
44
44
  In a controller action, you can do this by calling `slimmer_template`.
45
45
 
@@ -81,8 +81,30 @@ By default if you pass in a logger with its log level set to `debug`, slimmer wi
81
81
  config.slimmer.enable_debugging = true
82
82
  end
83
83
 
84
+ ## Shared components
85
+
86
+ To use shared template components you need to include the shared template resolver
87
+
88
+ class ApplicationController < ActionController::Base
89
+ include Slimmer::SharedTemplates
90
+ end
91
+
92
+ This will make calls out to static when you try and render a partial prefixed with `govuk-component`:
93
+
94
+ <%= render partial: 'govuk-component/example_component' %>
95
+
96
+ You will need a copy of static running for the templates to be loaded from.
97
+
98
+ ### Testing shared components
99
+
100
+ There is a test helper which can produce a CSS selector for a given component.
101
+ This can then be incorporated into your test framework of choice to assert that
102
+ the component is called. For example:
103
+
104
+ page.should have_css(shared_component_selector('metadata'))
105
+
84
106
  ## The name
85
107
 
86
- Slimmer was extracted from a much larger project called 'skinner'. 'slimmer' referred to the size
87
- of its code compared to skinner (which also acted as an HTTP proxy and mixed in a few other
108
+ Slimmer was extracted from a much larger project called 'skinner'. 'slimmer' referred to the size
109
+ of its code compared to skinner (which also acted as an HTTP proxy and mixed in a few other
88
110
  concerns). Over time the codebase has grown a little, but the name stuck.
data/lib/slimmer.rb CHANGED
@@ -22,6 +22,9 @@ module Slimmer
22
22
  autoload :Headers, 'slimmer/headers'
23
23
  autoload :Artefact, 'slimmer/artefact'
24
24
 
25
+ autoload :SharedTemplates, 'slimmer/shared_templates'
26
+ autoload :ComponentResolver, 'slimmer/component_resolver'
27
+
25
28
  module Processors
26
29
  autoload :AlphaLabelInserter, 'slimmer/processors/alpha_label_inserter'
27
30
  autoload :BetaNoticeInserter, 'slimmer/processors/beta_notice_inserter'
@@ -0,0 +1,59 @@
1
+ require 'slimmer/govuk_request_id'
2
+ require 'active_support/core_ext/string/inflections'
3
+
4
+ module Slimmer
5
+ class ComponentResolver < ::ActionView::Resolver
6
+ def find_templates(name, prefix, partial, details)
7
+ return [] unless prefix == 'govuk_component'
8
+
9
+ template_path = [prefix, name].join('/')
10
+ if test?
11
+ template_body = test_body(template_path)
12
+ else
13
+ template_body = fetch(template_url(template_path))
14
+ end
15
+
16
+ details = {
17
+ :format => 'text/html',
18
+ :updated_at => Time.now,
19
+ :virtual_path => template_path
20
+ }
21
+
22
+ [ActionView::Template.new(template_body, template_path, erb_handler, details)]
23
+ end
24
+
25
+ private
26
+ def test?
27
+ defined?(Rails) && Rails.env.test?
28
+ end
29
+
30
+ def erb_handler
31
+ @erb_handler ||= ActionView::Template.registered_template_handler(:erb)
32
+ end
33
+
34
+ def fetch(template_url)
35
+ headers = {}
36
+ headers[:govuk_request_id] = GovukRequestId.value if GovukRequestId.set?
37
+ response = RestClient.get(template_url, headers)
38
+ response.body
39
+ rescue RestClient::Exception => e
40
+ raise TemplateNotFoundException, "Unable to fetch: '#{template_url}' because #{e}", caller
41
+ rescue Errno::ECONNREFUSED => e
42
+ raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_url}' because #{e}", caller
43
+ rescue SocketError => e
44
+ raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_url}' because #{e}", caller
45
+ end
46
+
47
+ def template_url(template_path)
48
+ [static_host, "templates", "#{template_path}.raw.html.erb"].join('/')
49
+ end
50
+
51
+ def static_host
52
+ @static_host ||= Plek.new.find('static')
53
+ end
54
+
55
+ def test_body(path)
56
+ %Q{<div class="#{path.parameterize}"><%= local_assigns.keys.join(' ') %></div>}
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,11 @@
1
+ module Slimmer
2
+ module SharedTemplates
3
+ def self.included into
4
+ into.before_filter :add_shared_templates
5
+ end
6
+
7
+ def add_shared_templates
8
+ append_view_path Slimmer::ComponentResolver.new
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Slimmer
2
+ module TestHelpers
3
+ module SharedTemplates
4
+ def shared_component_selector(name)
5
+ "div[class='govuk_component-#{name}']"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module Slimmer
2
- VERSION = '4.1.1'
2
+ VERSION = '4.2.0'
3
3
  end
@@ -0,0 +1,29 @@
1
+ require_relative "test_helper"
2
+
3
+ describe Slimmer::ComponentResolver do
4
+ describe "find_templates" do
5
+ before do
6
+ @resolver = Slimmer::ComponentResolver.new
7
+ end
8
+
9
+ it "should return nothing if the prefix doesn't match 'govuk_component'" do
10
+ assert_equal [], @resolver.find_templates('name', 'prefix', false, {})
11
+ end
12
+
13
+ it "should request a valid template from the server" do
14
+ expected_url = "http://static.dev.gov.uk/templates/govuk_component/name.raw.html.erb"
15
+ stub_request(:get, expected_url).to_return :body => "<foo />"
16
+
17
+ templates = @resolver.find_templates('name', 'govuk_component', false, {})
18
+ assert_requested :get, expected_url
19
+ assert_equal '<foo />', templates.first.args[0]
20
+ end
21
+
22
+ it "should return a known template in test mode" do
23
+ @resolver.expects(:test?).returns(true)
24
+
25
+ templates = @resolver.find_templates('name', 'govuk_component', false, {})
26
+ assert_match /<div class="govuk_component-name">/, templates.first.args[0]
27
+ end
28
+ end
29
+ end
data/test/test_helper.rb CHANGED
@@ -42,6 +42,23 @@ end
42
42
  require 'webmock/minitest'
43
43
  WebMock.disable_net_connect!
44
44
 
45
+ # Including action_view is dificualt because it depends on rails and internal
46
+ # ~*magic*~. To avoid depending on the whole of rails mock out the method we
47
+ # need so we can tests the internal implementations which don't depend on rails
48
+ module ActionView
49
+ class Resolver
50
+ end
51
+ class Template
52
+ attr_reader :args
53
+ def initialize(*args)
54
+ @args = args
55
+ end
56
+ def self.registered_template_handler(*args)
57
+ args
58
+ end
59
+ end
60
+ end
61
+
45
62
  class SlimmerIntegrationTest < MiniTest::Unit::TestCase
46
63
  include Rack::Test::Methods
47
64
  include GdsApi::TestHelpers::ContentApi
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 4.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-07-25 00:00:00.000000000 Z
13
+ date: 2014-08-07 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: nokogiri
@@ -252,6 +252,22 @@ dependencies:
252
252
  - - ~>
253
253
  - !ruby/object:Gem::Version
254
254
  version: 0.5.1
255
+ - !ruby/object:Gem::Dependency
256
+ name: activesupport
257
+ requirement: !ruby/object:Gem::Requirement
258
+ none: false
259
+ requirements:
260
+ - - '='
261
+ - !ruby/object:Gem::Version
262
+ version: 3.2.13
263
+ type: :development
264
+ prerelease: false
265
+ version_requirements: !ruby/object:Gem::Requirement
266
+ none: false
267
+ requirements:
268
+ - - '='
269
+ - !ruby/object:Gem::Version
270
+ version: 3.2.13
255
271
  description: Rack middleware for skinning pages using a specific template
256
272
  email:
257
273
  - bengriffiths@gmail.com
@@ -274,9 +290,12 @@ files:
274
290
  - lib/slimmer/test_templates/beta_label.html
275
291
  - lib/slimmer/test.rb
276
292
  - lib/slimmer/version.rb
293
+ - lib/slimmer/test_helpers/shared_templates.rb
277
294
  - lib/slimmer/artefact.rb
295
+ - lib/slimmer/shared_templates.rb
278
296
  - lib/slimmer/govuk_request_id.rb
279
297
  - lib/slimmer/template.rb
298
+ - lib/slimmer/component_resolver.rb
280
299
  - lib/slimmer/processors/header_context_inserter.rb
281
300
  - lib/slimmer/processors/navigation_mover.rb
282
301
  - lib/slimmer/processors/google_analytics_configurator.rb
@@ -298,6 +317,7 @@ files:
298
317
  - lib/tasks/slimmer.rake
299
318
  - lib/slimmer.rb
300
319
  - Rakefile
320
+ - test/component_resolver_test.rb
301
321
  - test/changelog_test.rb
302
322
  - test/typical_usage_test.rb
303
323
  - test/skin_test.rb
@@ -343,7 +363,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
343
363
  version: '0'
344
364
  segments:
345
365
  - 0
346
- hash: 3014844610957979413
366
+ hash: 3545050969228992216
347
367
  required_rubygems_version: !ruby/object:Gem::Requirement
348
368
  none: false
349
369
  requirements:
@@ -352,7 +372,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
352
372
  version: '0'
353
373
  segments:
354
374
  - 0
355
- hash: 3014844610957979413
375
+ hash: 3545050969228992216
356
376
  requirements: []
357
377
  rubyforge_project: slimmer
358
378
  rubygems_version: 1.8.23
@@ -360,6 +380,7 @@ signing_key:
360
380
  specification_version: 3
361
381
  summary: Thinner than the skinner
362
382
  test_files:
383
+ - test/component_resolver_test.rb
363
384
  - test/changelog_test.rb
364
385
  - test/typical_usage_test.rb
365
386
  - test/skin_test.rb