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