mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Basic Embedded Shopfronts
This commit is contained in:
committed by
Maikel Linke
parent
113f6565be
commit
782a812596
40
app/assets/stylesheets/darkswarm/embedded_shopfront.css.scss
Normal file
40
app/assets/stylesheets/darkswarm/embedded_shopfront.css.scss
Normal file
@@ -0,0 +1,40 @@
|
||||
body.embedded {
|
||||
nav.top-bar{
|
||||
ul.left, ul.center, ul.right li.current_hub {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul.right {
|
||||
width: auto !important;
|
||||
li {
|
||||
float: left;
|
||||
line-height: 4.6875rem;
|
||||
height: 4.6875rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
&.show-for-large-up {
|
||||
display: inherit !important;
|
||||
}
|
||||
&.show-for-medium-down {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
.footer-local {
|
||||
display: none;
|
||||
}
|
||||
.footer-global {
|
||||
padding-bottom: 0;
|
||||
|
||||
.row {
|
||||
display: none;
|
||||
}
|
||||
.row:first-of-type {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,28 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
def enable_embedded_styles
|
||||
session[:embedded_shopfront] = true
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
||||
def disable_embedded_styles
|
||||
session.delete :embedded_shopfront
|
||||
session.delete :shopfront_redirect
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def after_sign_in_path_for(resource_or_scope)
|
||||
return session[:shopfront_redirect] if session[:shopfront_redirect]
|
||||
stored_location_for(resource_or_scope) || signed_in_root_path(resource_or_scope)
|
||||
end
|
||||
|
||||
def after_sign_out_path_for(resource_or_scope)
|
||||
session[:shopfront_redirect] ? session[:shopfront_redirect] : root_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def restrict_iframes
|
||||
@@ -28,13 +50,32 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
|
||||
def enable_embedded_shopfront
|
||||
return unless Spree::Config[:enable_embedded_shopfronts]
|
||||
whitelist = Spree::Config[:embedded_shopfronts_whitelist]
|
||||
return unless Spree::Config[:enable_embedded_shopfronts] and whitelist.present?
|
||||
|
||||
@session_data = session
|
||||
|
||||
whitelist = Spree::Config[:embedded_shopfronts_whitelist] || "'none'"
|
||||
response.headers.delete 'X-Frame-Options'
|
||||
response.headers['Content-Security-Policy'] = "frame-ancestors #{whitelist}"
|
||||
|
||||
check_embedded_request
|
||||
set_embedded_layout
|
||||
end
|
||||
|
||||
def check_embedded_request
|
||||
return unless params[:embedded_shopfront]
|
||||
|
||||
# Show embedded shopfront CSS
|
||||
session[:embedded_shopfront] = true
|
||||
|
||||
# Get shopfront slug and set redirect path
|
||||
if params[:controller] == 'enterprises' and params[:action] == 'shop' and params[:id]
|
||||
slug = params[:id]
|
||||
session[:shopfront_redirect] = '/' + slug + '/shop?embedded_shopfront=true'
|
||||
end
|
||||
end
|
||||
|
||||
def set_embedded_layout
|
||||
return unless session[:embedded_shopfront]
|
||||
@shopfront_layout = 'embedded'
|
||||
end
|
||||
|
||||
def action
|
||||
|
||||
@@ -4,6 +4,5 @@ class ShopsController < BaseController
|
||||
before_filter :enable_embedded_shopfront
|
||||
|
||||
def index
|
||||
#@embeddable = "test"
|
||||
end
|
||||
end
|
||||
|
||||
29
app/views/layouts/_shopfront_script.html.haml
Normal file
29
app/views/layouts/_shopfront_script.html.haml
Normal file
@@ -0,0 +1,29 @@
|
||||
:javascript
|
||||
$(document).ready(function() {
|
||||
var in_iframe = function(){
|
||||
try {
|
||||
return window.self !== window.top;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
var embedded_styles_active = $('body.off-canvas').hasClass('embedded');
|
||||
|
||||
var set_shopfront_styles = function(state) {
|
||||
$.ajax({
|
||||
url: '/embedded_shopfront/'+state,
|
||||
type: 'POST'
|
||||
});
|
||||
};
|
||||
|
||||
if (in_iframe() && !embedded_styles_active){
|
||||
$('body.off-canvas').addClass('embedded');
|
||||
set_shopfront_styles('enable');
|
||||
}
|
||||
|
||||
if (!in_iframe() && embedded_styles_active) {
|
||||
$('body.off-canvas').removeClass('embedded');
|
||||
set_shopfront_styles('disable');
|
||||
}
|
||||
});
|
||||
@@ -21,11 +21,13 @@
|
||||
= render "layouts/bugherd_script"
|
||||
= csrf_meta_tags
|
||||
|
||||
%body.off-canvas{"ng-app" => "Darkswarm"}
|
||||
%body.off-canvas{class: @shopfront_layout, ng: {app: "Darkswarm"}}
|
||||
/ [if lte IE 8]
|
||||
= render partial: "shared/ie_warning"
|
||||
= javascript_include_tag "iehack"
|
||||
|
||||
= render "layouts/shopfront_script" if @shopfront_layout
|
||||
|
||||
= inject_current_hub
|
||||
= inject_json "user", "current_user"
|
||||
= inject_json "railsFlash", "flash"
|
||||
|
||||
@@ -57,6 +57,9 @@ Openfoodnetwork::Application.routes.draw do
|
||||
put '/checkout', :to => 'checkout#update' , :as => :update_checkout
|
||||
get '/checkout/paypal_payment/:order_id', to: 'checkout#paypal_payment', as: :paypal_payment
|
||||
|
||||
post 'embedded_shopfront/enable', to: 'application#enable_embedded_styles'
|
||||
post 'embedded_shopfront/disable', to: 'application#disable_embedded_styles'
|
||||
|
||||
resources :enterprises do
|
||||
collection do
|
||||
post :search
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
<head></head>
|
||||
<body>
|
||||
|
||||
<p>Iframe Test</p>
|
||||
|
||||
<iframe src="http://test.com/shops" name="test_iframe" id="test_iframe" style="width:100%;min-height:30em"></iframe>
|
||||
<iframe src="http://localhost:9999/test_enterprise/shop?embedded_shopfront=true" name="test_iframe" class="test_iframe" id="test_iframe" style="width:100%;min-height:35em"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -3,6 +3,11 @@ require 'spec_helper'
|
||||
feature "Using embedded shopfront functionality", js: true do
|
||||
include AuthenticationWorkflow
|
||||
include WebHelper
|
||||
include ShopWorkflow
|
||||
include CheckoutWorkflow
|
||||
include UIComponentHelper
|
||||
|
||||
Capybara.server_port = 9999
|
||||
|
||||
describe "enabling embedded shopfronts" do
|
||||
before do
|
||||
@@ -31,25 +36,118 @@ feature "Using embedded shopfront functionality", js: true do
|
||||
end
|
||||
end
|
||||
|
||||
describe "using iframes", js: true do
|
||||
describe "using iframes" do
|
||||
let(:distributor) { create(:distributor_enterprise, name: 'My Embedded Hub', permalink: 'test_enterprise', with_payment_and_shipping: true) }
|
||||
let(:supplier) { create(:supplier_enterprise) }
|
||||
let(:oc1) { create(:simple_order_cycle, distributors: [distributor], coordinator: create(:distributor_enterprise), orders_close_at: 2.days.from_now) }
|
||||
let(:product) { create(:simple_product, name: 'Framed Apples', supplier: supplier) }
|
||||
let(:variant) { create(:variant, product: product, price: 19.99) }
|
||||
let(:exchange) { Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
add_variant_to_order_cycle(exchange, variant)
|
||||
|
||||
Spree::Config[:enable_embedded_shopfronts] = true
|
||||
Spree::Config[:embedded_shopfronts_whitelist] = 'localhost'
|
||||
|
||||
page.driver.browser.js_errors = false
|
||||
Capybara.current_session.driver.visit('spec/dummy/iframe_test.html')
|
||||
end
|
||||
|
||||
after do
|
||||
Spree::Config[:enable_embedded_shopfronts] = false
|
||||
end
|
||||
|
||||
pending "displays iframe content" do
|
||||
Capybara.current_session.driver.visit('spec/dummy/iframe_test.html')
|
||||
|
||||
expect(page).to have_text 'Iframe Test'
|
||||
it "displays modified shopfront layout" do
|
||||
expect(page).to have_selector 'iframe#test_iframe'
|
||||
|
||||
within_frame 'test_iframe' do
|
||||
sleep 1
|
||||
expect(page).to have_content "OFN" # currently fails...
|
||||
within 'nav.top-bar' do
|
||||
expect(page).to have_selector 'ul.left', visible: false
|
||||
expect(page).to have_selector 'ul.center', visible: false
|
||||
end
|
||||
|
||||
expect(page).to have_content "My Embedded Hub"
|
||||
expect(page).to have_content "Framed Apples"
|
||||
end
|
||||
end
|
||||
|
||||
it "allows shopping and checkout" do
|
||||
within_frame 'test_iframe' do
|
||||
fill_in "variants[#{variant.id}]", with: 1
|
||||
wait_until_enabled 'input.add_to_cart'
|
||||
|
||||
first("input.add_to_cart:not([disabled='disabled'])").click
|
||||
|
||||
expect(page).to have_text 'Your shopping cart'
|
||||
find('a#checkout-link').click
|
||||
|
||||
expect(page).to have_text 'Checkout now'
|
||||
|
||||
click_button 'Login'
|
||||
login_with_modal
|
||||
|
||||
expect(page).to have_text 'Payment'
|
||||
|
||||
within "#details" do
|
||||
fill_in "First Name", with: "Some"
|
||||
fill_in "Last Name", with: "One"
|
||||
fill_in "Email", with: "test@example.com"
|
||||
fill_in "Phone", with: "0456789012"
|
||||
end
|
||||
|
||||
toggle_billing
|
||||
within "#billing" do
|
||||
fill_in "Address", with: "123 Street"
|
||||
select "Australia", from: "Country"
|
||||
select "Victoria", from: "State"
|
||||
fill_in "City", with: "Melbourne"
|
||||
fill_in "Postcode", with: "3066"
|
||||
end
|
||||
|
||||
toggle_shipping
|
||||
within "#shipping" do
|
||||
find('input[type="radio"]').trigger 'click'
|
||||
end
|
||||
|
||||
toggle_payment
|
||||
within "#payment" do
|
||||
find('input[type="radio"]').trigger 'click'
|
||||
end
|
||||
|
||||
place_order
|
||||
|
||||
expect(page).to have_content "Your order has been processed successfully"
|
||||
end
|
||||
end
|
||||
|
||||
it "redirects to embedded hub on logout when embedded" do
|
||||
within_frame 'test_iframe' do
|
||||
|
||||
find('ul.right li#login-link a').click
|
||||
login_with_modal
|
||||
|
||||
wait_until { page.find('ul.right li.has-dropdown').value.present? }
|
||||
logout_via_navigation
|
||||
|
||||
expect(page).to have_text 'My Embedded Hub'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def login_with_modal
|
||||
expect(page).to have_selector 'div.login-modal', visible: true
|
||||
|
||||
within 'div.login-modal' do
|
||||
fill_in "Email", with: user.email
|
||||
fill_in "Password", with: user.password
|
||||
find('input[type="submit"]').click
|
||||
end
|
||||
end
|
||||
|
||||
def logout_via_navigation
|
||||
first('ul.right li.has-dropdown a').click
|
||||
find('ul.right ul.dropdown li a[title="Logout"]').click
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user