Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

V1.4.x.shopinvader cookie backport #2

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/locomotive/steam/middlewares/default_env.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def call(env)
env['steam.request'] = request
env['steam.services'] = build_services(request)
env['steam.liquid_assigns'] = {}
env['steam.cookies'] = {}

app.call(env)
end
Expand Down
15 changes: 13 additions & 2 deletions lib/locomotive/steam/middlewares/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,26 @@ def json?
#= Helper methods

def render_response(content, code = 200, type = nil)
@next_response = [code, { 'Content-Type' => type || 'text/html' }, [content]]
headers = { 'Content-Type' => type || 'text/html' }
inject_cookies(headers)
@next_response = [code, headers, [content]]
end

def redirect_to(location, type = 301)
_location = mounted_on && !location.starts_with?(mounted_on) && (location =~ Locomotive::Steam::IsHTTP).nil? ? "#{mounted_on}#{location}" : location

self.log "Redirected to #{_location}".blue

@next_response = [type, { 'Content-Type' => 'text/html', 'Location' => _location }, []]
headers = { 'Content-Type' => 'text/html', 'Location' => _location }
inject_cookies(headers)

@next_response = [type, headers, []]
end

def inject_cookies(headers)
request.env['steam.cookies'].each do |key, vals|
Rack::Utils.set_cookie_header!(headers, key, vals.symbolize_keys!)
end
end

def modify_path(path = nil, &block)
Expand Down
23 changes: 14 additions & 9 deletions lib/locomotive/steam/middlewares/locale.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Middlewares
# /index => locale = :en (default one)
#
# /en/index?locale=fr => locale = :fr
# /index => redirection to /en if the locale in session is :en
# /index => redirection to /en if the locale in cookie is :en
#
class Locale < ThreadSafe

Expand All @@ -19,7 +19,9 @@ class Locale < ThreadSafe
def _call
env['steam.path'] = request.path_info

env['steam.locale'] = session[session_key_name] = services.locale = extract_locale
env['steam.locale'] = services.locale = extract_locale

set_locale_cookie

log "Locale used: #{locale.upcase}"

Expand All @@ -34,7 +36,7 @@ def extract_locale
# Regarding the index page (basically, "/"), we've to see if we could
# guess the locale from the headers the browser sends to us.
locale = if is_index_page?
locale_from_params || locale_from_session || locale_from_header
locale_from_params || locale_from_cookie || locale_from_header
else
locale_from_path || locale_from_params
end
Expand Down Expand Up @@ -75,20 +77,23 @@ def locale_from_header
end
end

def locale_from_session
if locale = session[session_key_name]
env['steam.locale_in_session'] = true
def locale_from_cookie
if locale = services.cookie.get(cookie_key_name)

log 'Locale extracted from the session'
log 'Locale extracted from the cookie'

locale.to_sym
end
end

# The preview urls for all the sites share the same domain, so session[:locale]
def set_locale_cookie
services.cookie.set(cookie_key_name, {'value': locale, 'path': '/', 'max_age': 1.year})
end

# The preview urls for all the sites share the same domain, so cookie[:locale]
# would be the same for all the preview urls and this is not good.
# This is why we need to use a different key.
def session_key_name
def cookie_key_name
live_editing? ? "steam-locale-#{site.handle}" : 'steam-locale'
end

Expand Down
6 changes: 5 additions & 1 deletion lib/locomotive/steam/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Instance
end

register :action do
Steam::ActionService.new(current_site, email, content_entry: content_entry, api: external_api, redirection: page_redirection)
Steam::ActionService.new(current_site, email, content_entry: content_entry, api: external_api, redirection: page_redirection, cookie: cookie)
end

register :content_entry do
Expand Down Expand Up @@ -130,6 +130,10 @@ class Instance
Steam::NoCacheService.new
end

register :cookie do
Steam::CookieService.new(request)
end

register :configuration do
Locomotive::Steam.configuration
end
Expand Down
6 changes: 3 additions & 3 deletions lib/locomotive/steam/services/action_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module Steam

class ActionService

SERVICES = %w(content_entry api redirection)
SERVICES = %w(content_entry api redirection cookie)

BUILT_IN_FUNCTIONS = %w(
getProp
Expand Down Expand Up @@ -84,11 +84,11 @@ def set_session_prop_lambda(liquid_context)
end

def get_cookies_prop_lambda(liquid_context)
-> (name) { liquid_context.registers[:cookies][name.to_s].as_json }
-> (name) { cookie_service.get(name.to_s) }
end

def set_cookies_prop_lambda(liquid_context)
-> (name, value) { liquid_context.registers[:cookies][name.to_s] = value.to_s }
-> (name, values) { cookie_service.set(name.to_s, values) }
end

def all_entries_lambda(liquid_context)
Expand Down
25 changes: 25 additions & 0 deletions lib/locomotive/steam/services/cookie_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Locomotive
module Steam

class CookieService

def initialize(request)
@request = request
@cookies = request.env['steam.cookies']
end

def set(key, vals)
@cookies[key] = vals
end

def get(key)
if @cookies.include?(key)
@cookies[key]['value']
else
@request.cookies[key]
end
end

end
end
end
54 changes: 41 additions & 13 deletions spec/unit/middlewares/locale_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@
let(:site) { instance_double('Site', default_locale: :de, locales: [:de, :fr, :en]) }
let(:url) { 'http://models.example.com' }
let(:app) { ->(env) { [200, env, 'app'] } }
let(:services) { instance_double('Services', :locale= => 'en') }
let(:cookie_lang) { nil }
let(:cookie_service) { instance_double('Cookie Service', :get => cookie_lang) }
let(:services) { instance_double('Services', :locale= => 'en', :cookie => cookie_service) }
let(:middleware) { Locomotive::Steam::Middlewares::Locale.new(app) }
let(:session) { {} }
let(:cookie) { {} }
let(:accept_language) { '' }
let(:expected_lang) { :de }
let(:cookie) { { value: expected_lang, path: '/', max_age: 1.year } }

subject do
env = env_for(
url,
'steam.site' => site,
'rack.session' => session,
'HTTP_ACCEPT_LANGUAGE' => accept_language)
env['steam.request'] = Rack::Request.new(env)
env['steam.services'] = services
code, env = middleware.call(env)
[env['steam.locale'], session['steam-locale']&.to_sym]
env['steam.locale']
end

describe 'no locale defined in the path' do
Expand All @@ -32,33 +35,48 @@

context 'without accept-language header' do

it { is_expected.to eq [:de, :de] }
it 'should use default language' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

end

context 'with accept-language header' do

let(:accept_language) { 'fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7' }
let(:expected_lang) { :fr }

it { is_expected.to eq [:fr, :fr] }
it 'should use "fr" in header' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

context 'with url path' do

let(:url) { 'http://models.example.com/werkzeug' }
let(:expected_lang) { :de }

it { is_expected.to eq [:de, :de] }
it 'should use "de" in path' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

end

end

end

context 'user with session, use it' do
context 'user with cookie, use it' do

let(:session) { {'steam-locale' => 'en'} }
let(:cookie_lang) { 'en' }
let(:expected_lang) { :en }

it { is_expected.to eq [:en, :en] }
it 'should use "en" in cookie' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

end

Expand All @@ -70,23 +88,33 @@

let(:url) { 'http://models.example.com?locale=' }

it { is_expected.to eq [:de, :de] }
it 'should use default locale "de"' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

end

context 'the locale exists' do

let(:url) { 'http://models.example.com?locale=en' }
let(:expected_lang) { :en }

it { is_expected.to eq [:en, :en] }
it 'should use existing locale "en"' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

end

context 'the locale is unknown' do

let(:url) { 'http://models.example.com?locale=onload' }

it { is_expected.to eq [:de, :de] }
it 'should use default locale "de"' do
expect(cookie_service).to receive(:set).with('steam-locale', cookie).and_return(nil)
is_expected.to eq expected_lang
end

end

Expand Down
24 changes: 12 additions & 12 deletions spec/unit/services/action_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
let(:entry_service) { instance_double('ContentService') }
let(:api_service) { instance_double('ExternalAPIService') }
let(:redirection_service) { instance_double('PageRedirectionService') }
let(:service) { described_class.new(site, email_service, content_entry: entry_service, api: api_service, redirection: redirection_service) }
let(:cookie_service) { instance_double('CookieService') }
let(:service) { described_class.new(site, email_service, content_entry: entry_service, api: api_service, redirection: redirection_service, cookie: cookie_service) }

describe '#run' do

Expand Down Expand Up @@ -113,20 +114,19 @@
end

describe 'getCookiesProp' do

let(:cookie) { { name: 'John' } }
let(:script) { "return getCookiesProp('name');" }

it { is_expected.to eq 'John' }

before do
expect(cookie_service).to receive(:get).with('name').and_return('John')
end
it { is_expected.to eq('John') }
end

describe 'sendCookiesProp' do

let(:script) { "return setCookiesProp('done', true);" }

it { subject; expect(cookies[:done]).to eq true }

describe 'setCookiesProp' do
let(:script) { "return setCookiesProp('done', {'value': true});" }
before do
expect(cookie_service).to receive(:set).with('done', {'value' => true})
end
it { is_expected.to eq(nil) }
end

describe 'allEntries' do
Expand Down
38 changes: 38 additions & 0 deletions spec/unit/services/cookie_service_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'spec_helper'

describe Locomotive::Steam::CookieService do

let(:steam_cookies) { {} }
let(:request_cookies) { {} }
let(:request) { instance_double('Request', env: { 'steam.cookies' => steam_cookies }, cookies: request_cookies) }
let(:cookie) { {'value' => 'bar2'} }
let(:service) { described_class.new(request)}

describe '#get cookies from request' do

let(:request_cookies) { {'foo' => 'bar'} }
subject { service.get('foo') }

context 'from request' do
it { is_expected.to eq 'bar' }
end

context 'from response' do
let(:steam_cookies) { {'foo' => {'value' => 'bar2'}} }
it { is_expected.to eq 'bar2' }
end

end

describe '#set cookies from response' do

subject { service.set('foo', cookie) }

it 'set the cookies into steam' do
is_expected.to eq cookie
expect(steam_cookies).to eq({'foo' => cookie})
end

end

end