new built-in JS method for the action liquid tag: redirectTo
did
committed Jan 17, 2017
commit 64fa43e7d861c3dc83b0dc35e117a449aa2b798e
Showing 9
changed files with
123 additions
and 16 deletions
locomotive/steam/errors.rb b/lib/locomotive/steam/errors.rb
+8
-1
| @@ | @@ -4,7 +4,14 @@ module Locomotive::Steam |
| end | |
| class RedirectionException < ::Exception | |
| - | alias url message |
| + | |
| + | attr_reader :url |
| + | |
| + | def initialize(url) |
| + | @url = url |
| + | super("Redirect to #{url}") |
| + | end |
| + | |
| end | |
| class ParsingRenderingError < ::StandardError | |
locomotive/steam/liquid/tags/authorize.rb b/lib/locomotive/steam/liquid/tags/authorize.rb
+2
-9
| @@ | @@ -39,21 +39,14 @@ module Locomotive |
| @context = context | |
| unless authenticated_entry = context["current_#{@content_type_slug.singularize}"] | |
| - | raise Locomotive::Steam::RedirectionException.new(page_url) |
| + | services.page_redirection.redirect_to(@page_handle, locale) |
| end | |
| + | |
| '' | |
| end | |
| private | |
| - | def page_url |
| - | if page = services.page_finder.by_handle(@page_handle) |
| - | services.url_builder.url_for(page, locale) |
| - | else |
| - | |
| - | end |
| - | end |
| - | |
| def locale | |
| @context.registers[:locale] | |
| end | |
locomotive/steam/middlewares/redirection.rb b/lib/locomotive/steam/middlewares/redirection.rb
+1
-1
| @@ | @@ -14,7 +14,7 @@ module Locomotive::Steam |
| begin | |
| self.next | |
| rescue Locomotive::Steam::RedirectionException => e | |
| - | redirect_to e.message, 302 |
| + | redirect_to e.url, 302 |
| end | |
| end | |
locomotive/steam/services.rb b/lib/locomotive/steam/services.rb
+5
-1
| @@ | @@ -63,7 +63,7 @@ module Locomotive |
| end | |
| register :action do | |
| - | Steam::ActionService.new(current_site, email, content_entry, external_api) |
| + | Steam::ActionService.new(current_site, email, content_entry: content_entry, api: external_api, redirection: page_redirection) |
| end | |
| register :content_entry do | |
| @@ | @@ -82,6 +82,10 @@ module Locomotive |
| Steam::UrlBuilderService.new(current_site, locale, request) | |
| end | |
| + | register :page_redirection do |
| + | Steam::PageRedirectionService.new(page_finder, url_builder) |
| + | end |
| + | |
| register :theme_asset_url do | |
| Steam::ThemeAssetUrlService.new(repositories.theme_asset, asset_host, configuration.theme_assets_checksum) | |
| end | |
locomotive/steam/services/action_service.rb b/lib/locomotive/steam/services/action_service.rb
+15
-2
| @@ | @@ -11,6 +11,8 @@ module Locomotive |
| class ActionService | |
| + | SERVICES = %w(content_entry api redirection) |
| + | |
| BUILT_IN_FUNCTIONS = %w( | |
| getProp | |
| setProp | |
| @@ | @@ -21,9 +23,10 @@ module Locomotive |
| findEntry | |
| createEntry | |
| updateEntry | |
| - | callAPI) |
| + | callAPI |
| + | redirectTo) |
| - | attr_accessor_initialize :site, :email, :content_entry_service, :api_service |
| + | attr_accessor_initialize :site, :email, :services |
| def run(script, params = {}, liquid_context) | |
| context = Duktape::Context.new | |
| @@ | @@ -39,6 +42,8 @@ module Locomotive |
| begin | |
| context.exec_string script | |
| context.call_prop('locomotiveAction', site.as_json, params) | |
| + | rescue Locomotive::Steam::RedirectionException |
| + | raise |
| rescue Exception => e | |
| raise Locomotive::Steam::ActionError.new(e, script) | |
| end | |
| @@ | @@ -46,6 +51,10 @@ module Locomotive |
| private | |
| + | SERVICES.each do |name| |
| + | define_method(:"#{name}_service") { self.services[:"#{name}"] } |
| + | end |
| + | |
| def define_built_in_functions(context, liquid_context) | |
| BUILT_IN_FUNCTIONS.each do |name| | |
| context.define_function name, &send(:"#{name.underscore}_lambda", liquid_context) | |
| @@ | @@ -92,6 +101,10 @@ module Locomotive |
| -> (method, url, options) { api_service.consume(url, (options || {}).with_indifferent_access.merge(method: method)) } | |
| end | |
| + | def redirect_to_lambda(liquid_context) |
| + | -> (page_handle, locale = nil) { redirection_service.redirect_to(page_handle, locale) } |
| + | end |
| + | |
| end | |
| end | |
locomotive/steam/services/page_redirection_service.rb b/lib/locomotive/steam/services/page_redirection_service.rb
+29
-0
| @@ | @@ -0,0 +1,29 @@ |
| + | module Locomotive |
| + | module Steam |
| + | |
| + | class PageRedirectionService |
| + | |
| + | attr_accessor_initialize :page_finder, :url_builder |
| + | |
| + | def redirect_to(handle, locale = nil) |
| + | if page_url = url_to(handle, locale) |
| + | raise Locomotive::Steam::RedirectionException.new(page_url) |
| + | else |
| + | false |
| + | end |
| + | end |
| + | |
| + | private |
| + | |
| + | def url_to(handle, locale) |
| + | if page = page_finder.by_handle(handle) |
| + | url = url_builder.url_for(page, locale) |
| + | else |
| + | false |
| + | end |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | end |
spec/unit/liquid/tags/authorize_spec.rb
+1
-1
| @@ | @@ -31,7 +31,7 @@ describe Locomotive::Steam::Liquid::Tags::Authorize do |
| context 'unauthenticated account' do | |
| it 'redirects to the sign in page' do | |
| - | expect { subject }.to raise_error(Locomotive::Steam::RedirectionException, '/me/sign_in') |
| + | expect { subject }.to raise_error(Locomotive::Steam::RedirectionException, 'Redirect to /me/sign_in') |
| end | |
| end | |
spec/unit/services/action_service_spec.rb
+13
-1
| @@ | @@ -7,7 +7,8 @@ describe Locomotive::Steam::ActionService do |
| let(:email_service) { instance_double('EmailService') } | |
| let(:entry_service) { instance_double('ContentService') } | |
| let(:api_service) { instance_double('ExternalAPIService') } | |
| - | let(:service) { described_class.new(site, email_service, entry_service, api_service) } |
| + | let(:redirection_service) { instance_double('PageRedirectionService') } |
| + | let(:service) { described_class.new(site, email_service, content_entry: entry_service, api: api_service, redirection: redirection_service) } |
| describe '#run' do | |
| @@ | @@ -210,6 +211,17 @@ describe Locomotive::Steam::ActionService do |
| end | |
| + | describe 'redirectTo' do |
| + | |
| + | let(:script) { "redirectTo('about-us');" } |
| + | |
| + | it 'stops the rendering process and redirects the user to another page' do |
| + | expect(redirection_service).to receive(:redirect_to).with('about-us', nil).and_raise(Locomotive::Steam::RedirectionException.new('/about-us')) |
| + | expect { subject }.to raise_exception(Locomotive::Steam::RedirectionException, 'Redirect to /about-us') |
| + | end |
| + | |
| + | end |
| + | |
| end | |
| end | |
spec/unit/services/page_redirection_service_spec.rb
+49
-0
| @@ | @@ -0,0 +1,49 @@ |
| + | require 'spec_helper' |
| + | |
| + | describe Locomotive::Steam::PageRedirectionService do |
| + | |
| + | let(:page_finder) { instance_double('PageFinder') } |
| + | let(:url_builder) { instance_double('UrlBuilder') } |
| + | let(:service) { described_class.new(page_finder, url_builder) } |
| + | |
| + | describe '#redirect_to' do |
| + | |
| + | let(:page) { instance_double('Page') } |
| + | |
| + | subject { service.redirect_to('about-us') } |
| + | |
| + | context 'the page exists' do |
| + | |
| + | before { expect(page_finder).to receive(:by_handle).with('about-us').and_return(page) } |
| + | |
| + | it 'raises an PageRedirectionException that will caught the appropriate middleware' do |
| + | expect(url_builder).to receive(:url_for).with(page, nil).and_return('/about-us') |
| + | expect { subject }.to raise_exception(Locomotive::Steam::RedirectionException, 'Redirect to /about-us') |
| + | end |
| + | |
| + | context 'passing a locale' do |
| + | |
| + | subject { service.redirect_to('about-us', 'fr') } |
| + | |
| + | it 'raises an PageRedirectionException that will caught the appropriate middleware' do |
| + | expect(url_builder).to receive(:url_for).with(page, 'fr').and_return('/a-notre-sujet') |
| + | expect { subject }.to raise_exception(Locomotive::Steam::RedirectionException, 'Redirect to /a-notre-sujet') |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | |
| + | context "the page doesn't exist" do |
| + | |
| + | before { expect(page_finder).to receive(:by_handle).with('about-us').and_return(nil) } |
| + | |
| + | it "returns false and doesn't raise a redirection exception" do |
| + | is_expected.to eq false |
| + | end |
| + | |
| + | end |
| + | |
| + | end |
| + | |
| + | end |