Clone
require 'spec_helper'
describe Locomotive::Steam::ActionService do
let(:site_hash) { { 'name' => 'Acme Corp' } }
let(:site) { instance_double('Site', as_json: site_hash ) }
let(:email_service) { instance_double('EmailService') }
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) }
describe '#run' do
let(:script) { 'return 1 + 1;' }
let(:params) { {} }
let(:assigns) { {} }
let(:session) { {} }
let(:context) { ::Liquid::Context.new(assigns, {}, { session: session }) }
subject { service.run(script, params, context) }
it { is_expected.to eq 2.0 }
describe 'deal with exceptions' do
context 'wrong syntax' do
let(:script) { 'a +/ b * var;' }
it 'raises a meaningful exception' do
expect { subject }.to raise_error(Locomotive::Steam::ActionError, "eof or line terminator in regexp (line 2)")
end
end
context 'other error' do
let(:script) { 'a.b' }
it 'raises a meaningful exception' do
expect { subject }.to raise_error(Locomotive::Steam::ActionError, "identifier 'a' undefined")
end
end
end
describe 'with params' do
let(:params) { { 'foo' => 'hello' } }
let(:script) { "return params.foo + ' world';" }
it { is_expected.to eq 'hello world' }
describe "messing with params" do
let(:script) { "params.foo += ' world!';" }
it { is_expected.to eq nil }
it "can't change a param value" do
subject
expect(params['foo']).to eq 'hello'
end
end
end
describe 'built-in functions / getters / setters' do
describe 'site' do
let(:script) { 'return "Name: " + site.name;' }
it { is_expected.to eq 'Name: Acme Corp' }
end
describe 'getProp' do
let(:assigns) { { 'name' => 'John' } }
let(:script) { "return getProp('name');" }
it { is_expected.to eq 'John' }
end
describe 'setProp' do
let(:script) { "return setProp('done', true);" }
it { subject; expect(context['done']).to eq true }
end
describe 'getSessionProp' do
let(:session) { { name: 'John' } }
let(:script) { "return getSessionProp('name');" }
it { is_expected.to eq 'John' }
end
describe 'sendSessionProp' do
let(:script) { "return setSessionProp('done', true);" }
it { subject; expect(session[:done]).to eq true }
end
describe 'allEntries' do
let(:now) { Time.use_zone('America/Chicago') { Time.zone.local(2015, 'mar', 25, 10, 0) } }
let(:assigns) { { 'now' => now } }
let(:script) {
<<-JS
var entries = allEntries('bands', { 'created_at.lte': getProp('now'), published: true });
var names = []
for (var i = 0; i < entries.length; i++) {
names.push(entries[i].name)
}
return names.join(', ')
JS
}
before do
expect(entry_service).to receive(:all).with('bands', { "created_at.lte" => "2015-03-25T10:00:00.000-05:00", "published" => true }, true).and_return([
{ 'name' => 'Pearl Jam' },
{ 'name' => 'Nirvana' },
{ 'name' => 'Soundgarden' }
])
end
it { is_expected.to eq('Pearl Jam, Nirvana, Soundgarden') }
end
describe 'findEntry' do
let(:script) { "return findEntry('bands', '42').name;" }
before do
expect(entry_service).to receive(:find).with('bands', '42', true).and_return('name' => 'Pearl Jam')
end
it { is_expected.to eq('Pearl Jam') }
end
describe 'createEntry' do
let(:script) { "return createEntry('bands', { name: 'Pearl Jam'}).name;" }
before do
expect(entry_service).to receive(:create).with('bands', { 'name' => 'Pearl Jam' }, true).and_return('name' => 'Pearl Jam')
end
it { is_expected.to eq('Pearl Jam') }
end
describe 'updateEntry' do
let(:script) { "return updateEntry('bands', 'pearl-jam', { name: 'Pearl Jam'}).name;" }
before do
expect(entry_service).to receive(:update).with('bands', 'pearl-jam', { 'name' => 'Pearl Jam' }, true).and_return('name' => 'Pearl Jam')
end
it { is_expected.to eq('Pearl Jam') }
end
describe 'sendEmail' do
let(:params) { { 'to' => 'estelle@locomotivecms.com' } }
let(:script) { "sendEmail({ to: params.to, from: 'did@locomotivecms.com', subject: 'Happy Easter' })" }
it 'forwards the action to the email service' do
expect(email_service).to receive(:send_email).with({
'to' => 'estelle@locomotivecms.com',
'from' => 'did@locomotivecms.com',
'subject' => 'Happy Easter' }, context)
subject
end
end
describe 'callAPI' do
let(:script) { "callAPI('POST', 'https://api.stripe.com/v1/charges', { username: 'abcdefghij', data: { token: '123456789' } })" }
it 'forwards the action to the external api service' do
expect(api_service).to receive(:consume).with(
'https://api.stripe.com/v1/charges', {
method: 'POST',
username: 'abcdefghij',
data: {
token: '123456789'
}
}, true
)
subject
end
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
end