diff --git a/core/app/helpers/spree/products_helper.rb b/core/app/helpers/spree/products_helper.rb new file mode 100644 index 00000000000..e227c3bfd33 --- /dev/null +++ b/core/app/helpers/spree/products_helper.rb @@ -0,0 +1,60 @@ +module Spree + module ProductsHelper + # returns the formatted price for the specified variant as a full price or a difference depending on configuration + def variant_price(variant) + if Spree::Config[:show_variant_full_price] + variant_full_price(variant) + else + variant_price_diff(variant) + end + end + + # returns the formatted price for the specified variant as a difference from product price + def variant_price_diff(variant) + variant_amount = variant.amount_in(current_currency) + product_amount = variant.product.amount_in(current_currency) + return if variant_amount == product_amount || product_amount.nil? + diff = variant.amount_in(current_currency) - product_amount + amount = Spree::Money.new(diff.abs, currency: current_currency).to_html + label = diff > 0 ? :add : :subtract + "(#{Spree.t(label)}: #{amount})".html_safe + end + + # returns the formatted full price for the variant, if at least one variant price differs from product price + def variant_full_price(variant) + product = variant.product + unless product.variants.active(current_currency).all? { |v| v.price == product.price } + Spree::Money.new(variant.price, { currency: current_currency }).to_html + end + end + + # converts line breaks in product description into

tags (for html display purposes) + def product_description(product) + if Spree::Config[:show_raw_product_description] + raw(product.description) + else + raw(product.description.gsub(/(.*?)\r?\n\r?\n/m, '

\1

')) + end + end + + def line_item_description(variant) + ActiveSupport::Deprecation.warn "line_item_description(variant) is deprecated and may be removed from future releases, use line_item_description_text(line_item.description) instead.", caller + + line_item_description_text(variant.product.description) + end + + def line_item_description_text description_text + if description_text.present? + truncate(strip_tags(description_text.gsub(' ', ' ')), length: 100) + else + Spree.t(:product_has_no_description) + end + end + + def cache_key_for_products + count = @products.count + max_updated_at = (@products.maximum(:updated_at) || Date.today).to_s(:number) + "#{I18n.locale}/#{current_currency}/spree/products/all-#{params[:page]}-#{max_updated_at}-#{count}" + end + end +end diff --git a/core/spec/helpers/products_helper_spec.rb b/core/spec/helpers/products_helper_spec.rb new file mode 100644 index 00000000000..6e2957be989 --- /dev/null +++ b/core/spec/helpers/products_helper_spec.rb @@ -0,0 +1,220 @@ +# encoding: utf-8 + +require 'spec_helper' + +module Spree + describe ProductsHelper, :type => :helper do + include ProductsHelper + + let(:product) { create(:product) } + let(:currency) { 'USD' } + + before do + allow(helper).to receive(:current_currency) { currency } + end + + context "#variant_price_diff" do + let(:product_price) { 10 } + let(:variant_price) { 10 } + + before do + @variant = create(:variant, :product => product) + product.price = 15 + @variant.price = 10 + allow(product).to receive(:amount_in) { product_price } + allow(@variant).to receive(:amount_in) { variant_price } + end + + subject { helper.variant_price(@variant) } + + context "when variant is same as master" do + it { is_expected.to be_nil } + end + + context "when the master has no price" do + let(:product_price) { nil } + + it { is_expected.to be_nil } + end + + context "when currency is default" do + context "when variant is more than master" do + let(:variant_price) { 15 } + + it { is_expected.to eq("(Add: $5.00)") } + # Regression test for #2737 + it { is_expected.to be_html_safe } + end + + context "when variant is less than master" do + let(:product_price) { 15 } + + it { is_expected.to eq("(Subtract: $5.00)") } + end + end + + context "when currency is JPY" do + let(:variant_price) { 100 } + let(:product_price) { 100 } + let(:currency) { 'JPY' } + + context "when variant is more than master" do + let(:variant_price) { 150 } + + it { is_expected.to eq("(Add: ¥50)") } + end + + context "when variant is less than master" do + let(:product_price) { 150 } + + it { is_expected.to eq("(Subtract: ¥50)") } + end + end + end + + context "#variant_price_full" do + before do + Spree::Config[:show_variant_full_price] = true + @variant1 = create(:variant, :product => product) + @variant2 = create(:variant, :product => product) + end + + context "when currency is default" do + it "should return the variant price if the price is different than master" do + product.price = 10 + @variant1.price = 15 + @variant2.price = 20 + expect(helper.variant_price(@variant1)).to eq("$15.00") + expect(helper.variant_price(@variant2)).to eq("$20.00") + end + end + + context "when currency is JPY" do + let(:currency) { 'JPY' } + + before do + product.variants.active.each do |variant| + variant.prices.each do |price| + price.currency = currency + price.save! + end + end + end + + it "should return the variant price if the price is different than master" do + product.price = 100 + @variant1.price = 150 + expect(helper.variant_price(@variant1)).to eq("¥150") + end + end + + it "should be nil when all variant prices are equal" do + product.price = 10 + @variant1.default_price.update_column(:amount, 10) + @variant2.default_price.update_column(:amount, 10) + expect(helper.variant_price(@variant1)).to be_nil + expect(helper.variant_price(@variant2)).to be_nil + end + end + + + context "#product_description" do + # Regression test for #1607 + it "renders a product description without excessive paragraph breaks" do + product.description = %Q{ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus a ligula leo. Proin eu arcu at ipsum dapibus ullamcorper. Pellentesque egestas orci nec magna condimentum luctus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut ac ante et mauris bibendum ultricies non sed massa. Fusce facilisis dui eget lacus scelerisque eget aliquam urna ultricies. Duis et rhoncus quam. Praesent tellus nisi, ultrices sed iaculis quis, euismod interdum ipsum.

+ + } + description = product_description(product) + expect(description.strip).to eq(product.description.strip) + end + + it "renders a product description with automatic paragraph breaks" do + product.description = %Q{ +THIS IS THE BEST PRODUCT EVER! + +"IT CHANGED MY LIFE" - Sue, MD} + + description = product_description(product) + expect(description.strip).to eq(%Q{

\nTHIS IS THE BEST PRODUCT EVER!

"IT CHANGED MY LIFE" - Sue, MD}) + end + + it "renders a product description without any formatting based on configuration" do + initialDescription = %Q{ +

hello world

+ +

tihs is completely awesome and it works

+ +

why so many spaces in the code. and why some more formatting afterwards?

+ } + + product.description = initialDescription + + Spree::Config[:show_raw_product_description] = true + description = product_description(product) + expect(description).to eq(initialDescription) + end + + end + + shared_examples_for "line item descriptions" do + context 'variant has a blank description' do + let(:description) { nil } + it { is_expected.to eq(Spree.t(:product_has_no_description)) } + end + context 'variant has a description' do + let(:description) { 'test_desc' } + it { is_expected.to eq(description) } + end + context 'description has nonbreaking spaces' do + let(:description) { 'test desc' } + it { is_expected.to eq('test desc') } + end + end + + context "#line_item_description" do + let(:variant) { create(:variant, :product => product, description: description) } + subject { line_item_description_text(variant.product.description) } + + it_should_behave_like "line item descriptions" + end + + context '#line_item_description_text' do + subject { line_item_description_text description } + + it_should_behave_like "line item descriptions" + end + + context '#cache_key_for_products' do + subject { helper.cache_key_for_products } + before(:each) do + @products = double('products collection') + allow(helper).to receive(:params) { {:page => 10} } + end + + context 'when there is a maximum updated date' do + let(:updated_at) { Date.new(2011, 12, 13) } + before :each do + allow(@products).to receive(:count) { 5 } + allow(@products).to receive(:maximum).with(:updated_at) { updated_at } + end + + it { is_expected.to eq('en/USD/spree/products/all-10-20111213-5') } + end + + context 'when there is no considered maximum updated date' do + let(:today) { Date.new(2013, 12, 11) } + before :each do + allow(@products).to receive(:count) { 1234567 } + allow(@products).to receive(:maximum).with(:updated_at) { nil } + allow(Date).to receive(:today) { today } + end + + it { is_expected.to eq('en/USD/spree/products/all-10-20131211-1234567') } + end + end + end +end diff --git a/frontend/app/views/spree/checkout/registration.html.erb b/frontend/app/views/spree/checkout/registration.html.erb deleted file mode 100755 index e3a8802c85e..00000000000 --- a/frontend/app/views/spree/checkout/registration.html.erb +++ /dev/null @@ -1,27 +0,0 @@ -<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @user } %> -

<%= Spree.t(:registration) %>

-
-
- <%= render :partial => 'new_user' %> -
- <% if Spree::Config[:allow_guest_checkout] %> -
-
-
-

<%= Spree.t(:guest_user_account) %>

-
-
- <% if flash[:registration_error] %> -
<%= flash[:registration_error] %>
- <% end %> - <%= form_for @order, :url => update_checkout_registration_path, :method => :put, :html => { :id => 'checkout_form_registration' } do |f| %> -

- <%= f.email_field :email, :class => 'form-control title', :placeholder => Spree.t(:email) %> -

-

<%= f.submit Spree.t(:continue), :class => 'btn btn-lg btn-success btn-block' %>

- <% end %> -
-
-
- <% end %> -
diff --git a/frontend/app/views/spree/shared/_user_form.html.erb b/frontend/app/views/spree/shared/_user_form.html.erb deleted file mode 100755 index 309a0f46728..00000000000 --- a/frontend/app/views/spree/shared/_user_form.html.erb +++ /dev/null @@ -1,13 +0,0 @@ -
-
- <%= f.email_field :email, :class => 'form-control', :placeholder => Spree.t(:email) %> -
-
-
- <%= f.password_field :password, :class => 'form-control', :placeholder => Spree.t(:password) %> -
-
- <%= f.password_field :password_confirmation, :class => 'form-control', :placeholder => Spree.t(:confirm_password) %> -
-
-
\ No newline at end of file diff --git a/frontend/app/views/spree/user_passwords/edit.html.erb b/frontend/app/views/spree/user_passwords/edit.html.erb deleted file mode 100755 index e486787c4e1..00000000000 --- a/frontend/app/views/spree/user_passwords/edit.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @spree_user } %> -
-
-
-

<%= Spree.t(:change_my_password) %>

-
-
- <%= form_for @spree_user, :as => :spree_user, :url => spree.update_password_path, :method => :put do |f| %> -

- <%= f.label :password, Spree.t(:password) %>
- <%= f.password_field :password, :class => "form-control" %>
-

-

- <%= f.label :password_confirmation, Spree.t(:confirm_password) %>
- <%= f.password_field :password_confirmation, :class => "form-control" %>
-

- <%= f.hidden_field :reset_password_token %> - <%= f.submit Spree.t(:update), :class => 'btn btn-lg btn-success btn-block' %> - <% end %> -
-
-
\ No newline at end of file diff --git a/frontend/app/views/spree/user_passwords/new.html.erb b/frontend/app/views/spree/user_passwords/new.html.erb deleted file mode 100755 index 38cdcd58798..00000000000 --- a/frontend/app/views/spree/user_passwords/new.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @spree_user } %> -
-
-
-

<%= Spree.t(:forgot_password) %>

-
-
-

<%= Spree.t(:instructions_to_reset_password) %>

- - <%= form_for Spree::User.new, :as => :spree_user, :url => spree.reset_password_path do |f| %> -

- <%= f.label :email, Spree.t(:email) %>
- <%= f.email_field :email, :class => "form-control" %> -

-

- <%= f.submit Spree.t(:reset_password), :class => 'btn btn-lg btn-success btn-block' %> -

- <% end %> -
-
-
diff --git a/frontend/app/views/spree/user_registrations/new.html.erb b/frontend/app/views/spree/user_registrations/new.html.erb deleted file mode 100755 index 5efc6d0866d..00000000000 --- a/frontend/app/views/spree/user_registrations/new.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<% @body_id = 'signup' %> -<%= render :partial => 'spree/shared/error_messages', :locals => { :target => @user } %> -
-
-
-

<%= Spree.t(:new_customer) %>

-
-
- <%= form_for resource, :as => :spree_user, :url => spree.registration_path(@user) do |f| %> -
- <%= render :partial => 'spree/shared/user_form', :locals => { :f => f } %> -

<%= f.submit Spree.t(:create), :class => 'btn btn-lg btn-success btn-block' %>

-
- <% end %> -
- <%= Spree.t(:or) %> - <%= link_to Spree.t(:login_as_existing), spree.login_path %> -
-
-
-
-
\ No newline at end of file diff --git a/frontend/app/views/spree/user_sessions/new.html.erb b/frontend/app/views/spree/user_sessions/new.html.erb deleted file mode 100755 index 550b6fb90ca..00000000000 --- a/frontend/app/views/spree/user_sessions/new.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -<% @body_id = 'login' %> -
"> -
-
-

<%= Spree.t(:login_as_existing) %>

-
-
- <% if flash[:alert] %> -
<%= flash[:alert] %>
- <% end %> - <%= render :partial => 'spree/shared/login' %> -
- <%= Spree.t(:or) %> - <%= link_to Spree.t(:create_a_new_account), spree.signup_path %> | - <%= link_to Spree.t(:forgot_password), spree.recover_password_path %> -
-
-
-
-
\ No newline at end of file diff --git a/frontend/app/views/spree/users/edit.html.erb b/frontend/app/views/spree/users/edit.html.erb deleted file mode 100755 index 7755c1499d1..00000000000 --- a/frontend/app/views/spree/users/edit.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -
-
-
-

<%= Spree.t(:editing_user) %>

-
-
- <%= render :partial => 'spree/shared/error_messages', :locals => { :target => @user } %> - - <%= form_for Spree::User.new, :as => @user, :url => spree.user_path(@user), :method => :put do |f| %> - <%= render :partial => 'spree/shared/user_form', :locals => { :f => f } %> -

- <%= f.submit Spree.t(:update), :class => 'btn btn-primary' %> -

- <% end %> -
-
-
\ No newline at end of file diff --git a/frontend/app/views/spree/users/show.html.erb b/frontend/app/views/spree/users/show.html.erb deleted file mode 100755 index ad184d1b77a..00000000000 --- a/frontend/app/views/spree/users/show.html.erb +++ /dev/null @@ -1,43 +0,0 @@ -

<%= accurate_title %>

- -
-
-
<%= Spree.t(:email) %>
-
<%= @user.email %> (<%= link_to Spree.t(:edit), spree.edit_account_path %>)
-
-
- -
- -

<%= Spree.t(:my_orders) %>

- <% if @orders.present? %> - - - - - - - - - - - - - <% @orders.each do |order| %> - - - - - - - - - <% end %> - -
<%= Spree.t(:order_number) %><%= Spree.t(:date) %><%= Spree.t(:status) %><%= Spree.t(:payment_state) %><%= Spree.t(:shipment_state) %><%= Spree.t(:total) %>
<%= link_to order.number, order_url(order) %><%= l order.completed_at.to_date %><%= Spree.t("order_state.#{order.state}").titleize %><%= Spree.t("payment_states.#{order.payment_state}").titleize if order.payment_state %><%= Spree.t("shipment_states.#{order.shipment_state}").titleize if order.shipment_state %><%= order.display_total %>
- <% else %> -
<%= Spree.t(:you_have_no_orders_yet) %>
- <% end %> -
- -