Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #23 from sbounmy/allow_select_out_of_stock

Allow select out of stock - thanks @sbounmy
  • Loading branch information...
commit 136f03a77d4f47a7d05e1fd9e8153d174744b7ec 2 parents d2d9a2b + d0012cf
@citrus authored
View
1  .gitignore
@@ -6,3 +6,4 @@ pkg/*
public/tmp.html
test/dummy_hooks/after_migrate.rb
test/dummy
+capybara-*.html
View
22 app/assets/javascripts/store/variant_options.js
@@ -30,13 +30,14 @@ if (!Array.find_matches) Array.find_matches = function(a) {
return m;
}
-function VariantOptions(options, allow_backorders) {
+function VariantOptions(options, allow_backorders, allow_select_outofstock) {
var options = options;
var allow_backorders = allow_backorders;
+ var allow_select_outofstock = allow_select_outofstock;
var variant, divs, parent, index = 0;
var selection = [];
- var buttons;
+ var buttons;
function init() {
divs = $('#product-variants .variant-options');
@@ -63,14 +64,17 @@ function VariantOptions(options, allow_backorders) {
}
function enable(btns) {
- return btns.not('.unavailable').removeClass('locked').unbind('click').filter('.in-stock').click(handle_click).filter('.auto-click').removeClass('auto-click').click();
+ bt = btns.not('.unavailable').removeClass('locked').unbind('click')
+ if (!allow_select_outofstock)
+ bt = bt.filter('.in-stock')
+ return bt.click(handle_click).filter('.auto-click').removeClass('auto-click').click();
}
function advance() {
index++
update();
inventory(buttons.removeClass('locked'));
- enable(buttons.filter('.in-stock'));
+ enable(buttons);
}
function inventory(btns) {
@@ -161,17 +165,19 @@ function VariantOptions(options, allow_backorders) {
function toggle() {
if (variant) {
- $('#variant_id').val(variant.id);
+ $('#variant_id, form[data-form-type="variant"] input[name$="[variant_id]"]').val(variant.id);
$('#product-price .price').removeClass('unselected').text(variant.price);
- $('#cart-form button[type=submit]').attr('disabled', false).fadeTo(100, 1);
+ if (variant.count > 0)
+ $('#cart-form button[type=submit]').attr('disabled', false).fadeTo(100, 1);
+ $('form[data-form-type="variant"] button[type=submit]').attr('disabled', false).fadeTo(100, 1);
try {
show_variant_images(variant.id);
} catch(error) {
// depends on modified version of product.js
}
} else {
- $('#variant_id').val('');
- $('#cart-form button[type=submit]').attr('disabled', true).fadeTo(0, 0.5);
+ $('#variant_id, form[data-form-type="variant"] input[name$="[variant_id]"]').val('');
+ $('#cart-form button[type=submit], form[data-form-type="variant"] button[type=submit]').attr('disabled', true).fadeTo(0, 0.5);
price = $('#product-price .price').addClass('unselected')
// Replace product price by "(select)" only when there are at least 1 variant not out-of-stock
variants = $("div.variant-options.index-0")
View
5 app/models/spree/app_configuration/variant_configuration.rb
@@ -0,0 +1,5 @@
+module SpreeVariantOptions
+ class VariantConfiguration < Spree::Preferences::Configuration
+ preference :allow_select_outofstock, :boolean, :default => false
+ end
+end
View
4 app/views/spree/products/_variant_options.html.erb
@@ -22,8 +22,8 @@
<%= hidden_field_tag "products[#{@product.id}]", "", :id => "variant_id", :class => "hidden" %>
<script type="text/javascript">
//<![CDATA[
- var variant_options = new VariantOptions(<%== @product.variant_options_hash.to_json %>, <%== !!Spree::Config[:allow_backorders] %>);
+ var variant_options = new VariantOptions(<%== @product.variant_options_hash.to_json %>, <%== !!Spree::Config[:allow_backorders] %>, <%== !!SpreeVariantOptions::VariantConfig[:allow_select_outofstock] %>);
//]]>
- </script>
+ </script>
</div>
<% end%>
View
19 lib/spree_variant_options/engine.rb
@@ -1,12 +1,12 @@
module SpreeVariantOptions
class Engine < Rails::Engine
-
+ isolate_namespace SpreeVariantOptions
engine_name "spree_variant_options"
-
+
config.to_prepare do
#loads application's model / class decorators
- Dir.glob File.expand_path("../../../app/**/*_decorator.rb", __FILE__) do |c|
- Rails.configuration.cache_classes ? require(c) : load(c)
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/**/*_decorator*.rb")) do |c|
+ Rails.application.config.cache_classes ? require(c) : load(c)
end
#loads application's deface view overrides
@@ -14,6 +14,15 @@ class Engine < Rails::Engine
Rails.application.config.cache_classes ? require(c) : load(c)
end
end
-
+
+ initializer "spree_variant_options.environment", :before => :load_config_initializers, :after => "spree.environment" do |app|
+ Dir.glob(File.join(File.dirname(__FILE__), "../../app/models/spree/app_configuration/*.rb")) do |c|
+ Rails.application.config.cache_classes ? require(c) : load(c)
+ end
+ app.config.spree.add_class('variant_preferences')
+ app.config.spree.variant_preferences = SpreeVariantOptions::VariantConfiguration.new
+
+ SpreeVariantOptions::VariantConfig = app.config.spree.variant_preferences
+ end
end
end
View
12 spree_variant_options.gemspec
@@ -18,10 +18,10 @@ Gem::Specification.new do |s|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
-
+
# Runtime
s.add_dependency('spree_core', '~> 1.0')
-
+
# Development
s.add_development_dependency('spree_sample', '~> 1.0')
s.add_development_dependency('dummier', '~> 0.3')
@@ -30,5 +30,13 @@ Gem::Specification.new do |s|
s.add_development_dependency('cucumber-rails', '~> 1.2')
s.add_development_dependency('database_cleaner', '~> 0.6')
s.add_development_dependency('sqlite3', '~> 1.3')
+ s.add_development_dependency('capybara')
+ s.add_development_dependency('launchy')
+ s.add_development_dependency('database_cleaner')
+ if RUBY_VERSION < "1.9"
+ s.add_development_dependency "ruby-debug"
+ else
+ s.add_development_dependency "ruby-debug19"
+ end
end
View
106 test/integration/variant_test.rb
@@ -0,0 +1,106 @@
+require 'test_helper'
+
+module Spree
+ class WishedProduct
+ include ActiveModel::Conversion
+ extend ActiveModel::Naming
+
+ attr_accessor :variant_id
+
+ def persisted?
+ false
+ end
+ end
+end
+
+class ProductTest < ActionDispatch::IntegrationTest
+
+ setup do
+ Spree::Config[:allow_backorders] = false
+ @product = Factory(:product)
+ @size = Factory(:option_type)
+ @color = Factory(:option_type, :name => "Color")
+ @s = Factory(:option_value, :presentation => "S", :option_type => @size)
+ @m = Factory(:option_value, :presentation => "M", :option_type => @size)
+ @red = Factory(:option_value, :name => "Color", :presentation => "Red", :option_type => @color)
+ @green = Factory(:option_value, :name => "Color", :presentation => "Green", :option_type => @color)
+ @variant1 = Factory(:variant, :product => @product, :option_values => [@s, @red], :on_hand => 0)
+ @variant2 = Factory(:variant, :product => @product, :option_values => [@s, @green], :on_hand => 0)
+ @variant3 = Factory(:variant, :product => @product, :option_values => [@m, @red], :on_hand => 0)
+ @variant4 = Factory(:variant, :product => @product, :option_values => [@m, @green], :on_hand => 1)
+
+ Deface::Override.new( :virtual_path => "spree/products/show",
+ :name => "add_other_form_to_spree_variant_options",
+ :insert_after => "div#cart-form",
+ :text => %q{
+ <div id="wishlist-form">
+ <%= form_for Spree::WishedProduct.new, :url => "foo", :html => {:"data-form-type" => "variant"} do |f| %>
+ <%= f.hidden_field :variant_id, :value => @product.master.id %>
+ <button type="submit">
+ <%= t(:add_to_wishlist) %>
+ </button>
+ <% end %>
+ </div>
+ }
+ )
+ end
+
+ test 'disallow choose out of stock variants' do
+
+ SpreeVariantOptions::VariantConfig.allow_select_outofstock = false
+
+ visit spree.product_path(@product)
+
+ # variant options are not selectable
+ within("#product-variants") do
+ size = find_link('S')
+ size.click
+ assert !size["class"].include?("selected")
+ color = find_link('Green')
+ color.click
+ assert !color["class"].include?("selected")
+ end
+
+ # add to cart button is still disabled
+ assert_equal "true", find_button("Add To Cart")["disabled"]
+ # add to wishlist button is still disabled
+ assert_equal "true", find_button("Add To Wishlist")["disabled"]
+ end
+
+ test 'allow choose out of stock variants' do
+ SpreeVariantOptions::VariantConfig.allow_select_outofstock = true
+
+ visit spree.product_path(@product)
+
+ # variant options are selectable
+ within("#product-variants") do
+ size = find_link('S')
+ size.click
+ assert size["class"].include?("selected")
+ color = find_link('Green')
+ color.click
+ assert color["class"].include?("selected")
+ end
+ # add to cart button is still disabled
+ assert_equal "true", find_button("Add To Cart")["disabled"]
+ # add to wishlist button is enabled
+ assert_equal "false", find_button("Add To Wishlist")["disabled"]
+ end
+
+ test "choose in stock variant" do
+ visit spree.product_path(@product)
+ within("#product-variants") do
+ size = find_link('M')
+ size.click
+ assert size["class"].include?("selected")
+ color = find_link('Green')
+ color.click
+ assert color["class"].include?("selected")
+ end
+ # add to cart button is enabled
+ assert_equal "false", find_button("Add To Wishlist")["disabled"]
+ # add to wishlist button is enabled
+ assert_equal "false", find_button("Add To Wishlist")["disabled"]
+ end
+
+ end
View
6 test/support/preferences.rb
@@ -0,0 +1,6 @@
+def reset_spree_preferences
+ Spree::Preferences::Store.instance.persistence = true
+ config = Rails.application.config.spree.preferences
+ config.reset
+ yield(config) if block_given?
+end
View
13 test/support/shared_connection.rb
@@ -0,0 +1,13 @@
+# Using databasecleaner until we solve reset_preferences issue
+# class ActiveRecord::Base
+# mattr_accessor :shared_connection
+# @@shared_connection = nil
+#
+# def self.connection
+# @@shared_connection || retrieve_connection
+# end
+# end
+#
+# # Forces all threads to share the same connection. This works on
+# # Capybara because it starts the web server in a thread.
+# ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
View
7 test/support/url_helpers.rb
@@ -0,0 +1,7 @@
+module Spree
+ module UrlHelpers
+ def spree
+ Spree::Core::Engine.routes.url_helpers
+ end
+ end
+end
View
27 test/test_helper.rb
@@ -1,11 +1,36 @@
# Configure Rails Envinronment
ENV["RAILS_ENV"] = "test"
-
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
require "rails/test_help"
require "shoulda"
require "factory_girl"
require "sqlite3"
+if RUBY_VERSION < "1.9"
+ require "ruby-debug"
+else
+ require "ruby-debug19"
+end
begin; require "turn"; rescue LoadError; end
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
+
+require 'capybara/rails'
+require 'database_cleaner'
+DatabaseCleaner.strategy = :truncation
+Capybara.default_driver = :selenium
+
+class ActionDispatch::IntegrationTest
+ # Make the Capybara DSL available in all integration tests
+ include Capybara::DSL
+ include Spree::UrlHelpers
+
+ # Stop ActiveRecord from wrapping tests in transactions
+ self.use_transactional_fixtures = false
+
+ teardown do
+ DatabaseCleaner.clean # Truncate the database
+ Capybara.reset_sessions! # Forget the (simulated) browser state
+ Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.