spree_variant_options 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +12 -4
- data/Versionfile +2 -1
- data/app/controllers/admin/option_values_controller.rb +14 -0
- data/app/models/option_value_decorator.rb +24 -0
- data/app/views/admin/option_types/_option_value_fields.html.erb +8 -0
- data/app/views/admin/option_types/edit.html.erb +33 -0
- data/app/views/products/_variant_options.html.erb +2 -2
- data/config/routes.rb +13 -0
- data/features/admin_option_types.feature +44 -0
- data/features/step_definitions/option_values.rb +64 -0
- data/features/step_definitions/variant_options.rb +11 -0
- data/features/step_definitions/web_steps.rb +6 -3
- data/features/support/env.rb +5 -1
- data/features/support/paths.rb +1 -36
- data/features/support/selectors.rb +1 -39
- data/features/variant_options.feature +11 -3
- data/lib/generators/spree_variant_options/install_generator.rb +30 -0
- data/lib/generators/templates/db/migrate/add_image_to_option_values.rb +14 -0
- data/lib/spree_variant_options/version.rb +1 -1
- data/public/stylesheets/variant_options.css +6 -0
- data/spree_variant_options.gemspec +3 -2
- data/test/dummy_hooks/before_migrate.rb +3 -0
- data/{features → test}/support/factories.rb +0 -0
- data/{features → test}/support/helper_methods.rb +0 -2
- data/test/support/paperclip.rb +18 -0
- data/test/test_helper.rb +2 -1
- data/test/unit/option_value_test.rb +57 -0
- metadata +37 -13
data/README.md
CHANGED
@@ -24,7 +24,7 @@ If you don't already have an existing Spree site, [click here](https://gist.gith
|
|
24
24
|
|
25
25
|
To install Spree Variant Options, just add the following to your Gemfile:
|
26
26
|
|
27
|
-
gem 'spree_variant_options', '0.
|
27
|
+
gem 'spree_variant_options', '0.2.0'
|
28
28
|
|
29
29
|
|
30
30
|
Now, bundle up with:
|
@@ -32,7 +32,13 @@ Now, bundle up with:
|
|
32
32
|
bundle
|
33
33
|
|
34
34
|
|
35
|
-
|
35
|
+
Next, run the install generator to copy the necessary migration to your project and migrate your database:
|
36
|
+
|
37
|
+
rails g spree_variant_options:install
|
38
|
+
rake db:migrate
|
39
|
+
|
40
|
+
|
41
|
+
Finally, you'll need include `app/views/products/_variant_options.html.erb` in your `products#show` view...
|
36
42
|
|
37
43
|
If you don't have a custom version of `_cart_form.html.erb` in your application, then don't worry about a thing, spree_variant_options will include the partial for you. Otherwise, just replace the entire `<% if @product.has_variants? %>` block with:
|
38
44
|
|
@@ -46,7 +52,7 @@ To tie spree_variant_options in with your product photos just delete your local
|
|
46
52
|
Versions
|
47
53
|
--------
|
48
54
|
|
49
|
-
Spree Variant Options works on Spree 0.30.x
|
55
|
+
Spree Variant Options works on Spree 0.30.x through 0.60.x. 0.70.x compatibility is just around the corner... Please let me know if you run into any issues.
|
50
56
|
|
51
57
|
|
52
58
|
Testing
|
@@ -124,7 +130,9 @@ You can easily use the test/dummy app as a demo of spree_variant_options. Just `
|
|
124
130
|
Contributors
|
125
131
|
------------
|
126
132
|
|
127
|
-
|
133
|
+
* Spencer Steffen ([@citrus](https://github.com/citrus))
|
134
|
+
* Richard Brown ([@rbrown](https://github.com/rbrown))
|
135
|
+
* [@baracek](https://github.com/baracek)
|
128
136
|
|
129
137
|
If you'd like to help out feel free to fork and send me pull requests!
|
130
138
|
|
data/Versionfile
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
class Admin::OptionValuesController < Admin::BaseController
|
2
|
+
|
3
|
+
def update_positions
|
4
|
+
params[:positions].each do |id, index|
|
5
|
+
OptionValue.update_all(['position=?', index], ['id=?', id])
|
6
|
+
end
|
7
|
+
|
8
|
+
respond_to do |format|
|
9
|
+
format.html { redirect_to edit_admin_option_type_url(params[:id]) }
|
10
|
+
format.js { render :text => 'Ok' }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
OptionValue.class_eval do
|
2
|
+
|
3
|
+
default_scope order(:position)
|
4
|
+
|
5
|
+
if defined?(SpreeHeroku)
|
6
|
+
has_attached_file :image,
|
7
|
+
:styles => { :small => '40x30#', :large => '140x110#' },
|
8
|
+
:default_style => :small,
|
9
|
+
:path => "assets/option_values/:id/:style/:basename.:extension",
|
10
|
+
:storage => "s3",
|
11
|
+
:s3_credentials => "#{Rails.root}/config/s3.yml"
|
12
|
+
else
|
13
|
+
has_attached_file :image,
|
14
|
+
:styles => { :small => '40x30#', :large => '140x110#' },
|
15
|
+
:default_style => :small,
|
16
|
+
:url => "/assets/option_values/:id/:style/:basename.:extension",
|
17
|
+
:path => ":rails_root/public/assets/option_values/:id/:style/:basename.:extension"
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_image?
|
21
|
+
image_file_name && !image_file_name.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<tr class="option_value fields" id="<%= dom_id(f.object) %>">
|
2
|
+
<td><span class="handle"></span></td>
|
3
|
+
<td><%= f.text_field :name %></td>
|
4
|
+
<td><%= f.text_field :presentation %></td>
|
5
|
+
<td><%= image_tag f.object.image.url(:small) if f.object.has_image? %></td>
|
6
|
+
<td><%= f.file_field :image %></td>
|
7
|
+
<td class="actions"><%= link_to_remove_fields t("remove"), f %></td>
|
8
|
+
</tr>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<%= render :partial => 'admin/shared/product_sub_menu' %>
|
2
|
+
<h1><%= t("editing_option_type") %></h1>
|
3
|
+
<%= render 'shared/error_messages', :target => @option_type %>
|
4
|
+
<%= form_for(@option_type, :url => object_url, :html => { :method => :put, :multipart => true }) do |f| %>
|
5
|
+
<fieldset>
|
6
|
+
<legend><%= t("editing_option_type") %></legend>
|
7
|
+
<%= render :partial => "form", :locals => { :f => f } %>
|
8
|
+
<h3><%= t("option_values") %></h3>
|
9
|
+
<table class="index sortable">
|
10
|
+
<thead>
|
11
|
+
<tr>
|
12
|
+
<th colspan="2"><%= t("name") %></th>
|
13
|
+
<th><%= t("display") %></th>
|
14
|
+
<th><%= t("preview") %></th>
|
15
|
+
<th><%= t("image") %></th>
|
16
|
+
<th></th>
|
17
|
+
</tr>
|
18
|
+
</thead>
|
19
|
+
<tbody id="option_values">
|
20
|
+
<% if @option_type.option_values.empty? %>
|
21
|
+
<tr id="none">
|
22
|
+
<td colspan="6"><%= @option_type.option_values.empty? ? t("none") : "" %></td>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
<%= f.fields_for :option_values do |option_value_form| %>
|
26
|
+
<%= render "option_value_fields", :f => option_value_form %>
|
27
|
+
<% end %>
|
28
|
+
</tbody>
|
29
|
+
</table>
|
30
|
+
<%= link_to_add_fields t("add_option_value"), "tbody#option_values", f, :option_values %>
|
31
|
+
<%= render :partial => 'admin/shared/edit_resource_links' %>
|
32
|
+
</fieldset>
|
33
|
+
<% end %>
|
@@ -17,8 +17,8 @@
|
|
17
17
|
<% classes << ( Spree::Config[:allow_backorders] || variants.sum(&:count_on_hand) > 0 ? "in-stock" : "out-of-stock" ) %>
|
18
18
|
<% end %>
|
19
19
|
<% end %>
|
20
|
-
<li>
|
21
|
-
<%= link_to content_tag(:span, value.presentation), "#", :title => value.presentation, :class => classes.join(" "), :rel => "#{type.id}-#{value.id}" %>
|
20
|
+
<li>
|
21
|
+
<%= link_to value.has_image? ? image_tag(value.image.url, :alt => value.presentation) : content_tag(:span, value.presentation), "#", :title => value.presentation, :class => classes.join(" "), :rel => "#{type.id}-#{value.id}" %>
|
22
22
|
</li>
|
23
23
|
<% end %>
|
24
24
|
<li class="clear-option"><%= link_to "X", "#clear", :class => "clear-button clear-index-#{index}" %></li>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
@javascript @admin
|
2
|
+
Feature: Admin option type values
|
3
|
+
|
4
|
+
In order to make selectable options
|
5
|
+
As an admin
|
6
|
+
I want to manage option type values
|
7
|
+
|
8
|
+
Background:
|
9
|
+
Given I have a product with variants
|
10
|
+
|
11
|
+
Scenario: Index option values
|
12
|
+
Given I'm on the edit admin option type page for option type "Size"
|
13
|
+
Then I should see option values for small, medium, large and x-large
|
14
|
+
|
15
|
+
Scenario: Create a new option values
|
16
|
+
Given I'm on the edit admin option type page for option type "Size"
|
17
|
+
Then I follow "Add Option Value"
|
18
|
+
And I fill in the option value fields for the new option value
|
19
|
+
When I press "Update"
|
20
|
+
Then I should see option values for small, medium, large, x-large and xxx-large
|
21
|
+
And I should see image "spree.jpg"
|
22
|
+
|
23
|
+
Scenario: Update an existing option value
|
24
|
+
Given I'm on the edit admin option type page for option type "Size"
|
25
|
+
When I fill in the option value fields for option value "Medium"
|
26
|
+
And I press "Update"
|
27
|
+
Then I should see option values for small, large, x-large and xxx-large
|
28
|
+
And I should see image "spree.jpg"
|
29
|
+
|
30
|
+
Scenario: Delete an existing option value
|
31
|
+
Given I'm on the edit admin option type page for option type "Size"
|
32
|
+
When I follow "Remove" for option type "Small"
|
33
|
+
And I press "Update"
|
34
|
+
Then I should see option values for medium, large and x-large
|
35
|
+
|
36
|
+
# Can't get capybara to play nicely with sortables...
|
37
|
+
#@wip
|
38
|
+
#Scenario: Sort existing option values
|
39
|
+
# Given I'm on the edit admin option type page for option type "Size"
|
40
|
+
# When I drag option value "Large" to the top
|
41
|
+
# And I reload the page
|
42
|
+
# Then I should see "Large" as the first option value
|
43
|
+
|
44
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
Then /^I should see option values for (.*)$/ do |value_string|
|
2
|
+
values = value_string.gsub(" and ", ", ").split(", ")
|
3
|
+
within "table.index.sortable" do
|
4
|
+
values.each do |value|
|
5
|
+
assert has_xpath?("//input[@value='#{value}']")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^I fill in the option value fields for (.*)$/ do |parent|
|
11
|
+
if parent == 'the new option value'
|
12
|
+
parent = "tr#new_option_value"
|
13
|
+
else
|
14
|
+
matches = parent.match(/([^"]*)"$/)
|
15
|
+
ov = OptionValue.find_by_presentation(matches[matches.length - 1])
|
16
|
+
parent = "tr#option_value_#{ov.id}"
|
17
|
+
end
|
18
|
+
within parent do
|
19
|
+
%w(name presentation).each do |name|
|
20
|
+
find(:xpath, ".//input[contains(@name, '[#{name}]')]").set('xxx-large')
|
21
|
+
end
|
22
|
+
find(:xpath, ".//input[contains(@name, '[image]')]").set(Rails.root.join("public/images/spree.jpg"))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
Then /^I should see image "([^"]*)"$/ do |source|
|
28
|
+
within "table.index" do
|
29
|
+
assert has_xpath?(".//img[contains(@src, '#{source}')]")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
When /^I follow "([^"]*)" for option type "([^"]*)"$/ do |link_text, value_string|
|
34
|
+
ov = OptionValue.find_by_presentation(value_string)
|
35
|
+
within "tr#option_value_#{ov.id}" do
|
36
|
+
click_link link_text
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
#============================================================
|
41
|
+
# Attempts at sortables...
|
42
|
+
|
43
|
+
#When /^I drag option value "([^"]*)" to the top$/ do |value_string|
|
44
|
+
# ov = OptionValue.find_by_presentation(value_string)
|
45
|
+
# page.driver.browser.drag_and_drop("#option_value_#{ov.id} span.handle", "0,-100")
|
46
|
+
#end
|
47
|
+
|
48
|
+
#When /^I drag option value "([^"]*)" to the top$/ do |value_string|
|
49
|
+
# ov = OptionValue.find_by_presentation(value_string)
|
50
|
+
# from = find("#option_value_#{ov.id} span.handle")
|
51
|
+
# to = find("table.index tr:first")
|
52
|
+
# from.drag_to(to)
|
53
|
+
#end
|
54
|
+
#
|
55
|
+
#When /^I reload the page$/ do
|
56
|
+
# visit current_path
|
57
|
+
#end
|
58
|
+
#
|
59
|
+
#Then /^I should see "([^"]*)" as the first option value$/ do |value_string|
|
60
|
+
# ov = OptionValue.find_by_presentation(value_string)
|
61
|
+
# #assert_equal 1, ov.position
|
62
|
+
# #assert_equal find("table.index tr:first"), find("#option_value_#{ov.id}")
|
63
|
+
#end
|
64
|
+
|
@@ -36,7 +36,18 @@ Given /^I have a product( with variants)?( and images)?$/ do |has_variants, has_
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
Given /^the first option type has an option value with image "([^"]*)"$/ do |source|
|
40
|
+
flunk unless @product
|
41
|
+
@product.option_types.first.option_values.first.update_attributes(:image => File.open(Rails.root.join("public/images/#{source}")))
|
42
|
+
end
|
39
43
|
|
44
|
+
Then /^I should see image "([^"]*)" within the first option value$/ do |source|
|
45
|
+
ot = @product.option_types.first
|
46
|
+
ov = ot.option_values.first
|
47
|
+
within ".variant-options a[rel='#{ot.id}-#{ov.id}']" do
|
48
|
+
assert_match "/assets/option_values/#{ov.id}/small/#{source}", find("img").native.attribute("src")
|
49
|
+
end
|
50
|
+
end
|
40
51
|
|
41
52
|
Given /^the "([^"]*)" variant is out of stock$/ do |descriptor|
|
42
53
|
flunk unless @product
|
@@ -28,15 +28,18 @@ Given /^I'm on the ((?!page).*) page$/ do |path|
|
|
28
28
|
end
|
29
29
|
|
30
30
|
Given /^I'm on the ((?!page).*) page for (.*)$/ do |path, id|
|
31
|
-
case id
|
31
|
+
id = case id
|
32
32
|
when "the first product"
|
33
|
-
|
33
|
+
@product ||= Product.last
|
34
|
+
when 'option type "Size"'
|
35
|
+
@option_type = OptionType.find_by_presentation!("Size")
|
36
|
+
else id
|
34
37
|
end
|
35
38
|
path = "#{path.downcase.gsub(/\s/, '_')}_path".to_sym
|
36
39
|
begin
|
37
40
|
visit send(path, id)
|
38
41
|
rescue
|
39
|
-
puts "#{path} could not be found!"
|
42
|
+
puts "#{path}(#{id.to_param}) could not be found!"
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
data/features/support/env.rb
CHANGED
@@ -5,8 +5,10 @@ require 'spork'
|
|
5
5
|
|
6
6
|
Spork.prefork do
|
7
7
|
require 'cucumber/rails'
|
8
|
+
require 'selenium/webdriver'
|
8
9
|
require 'factory_girl'
|
9
10
|
|
11
|
+
|
10
12
|
I18n.reload!
|
11
13
|
|
12
14
|
ActionController::Base.allow_rescue = false
|
@@ -18,10 +20,12 @@ Spork.prefork do
|
|
18
20
|
DatabaseCleaner.strategy = :transaction
|
19
21
|
|
20
22
|
Spree::Config.set(:random => rand(1000))
|
23
|
+
|
21
24
|
end
|
22
25
|
|
23
26
|
Spork.each_run do
|
24
27
|
|
25
28
|
Dir["#{File.expand_path("../../../", __FILE__)}/test/support/**/*.rb"].each { |f| require f }
|
26
|
-
|
29
|
+
World(HelperMethods)
|
30
|
+
|
27
31
|
end
|
data/features/support/paths.rb
CHANGED
@@ -1,36 +1 @@
|
|
1
|
-
|
2
|
-
# Maps a name to a path. Used by the
|
3
|
-
#
|
4
|
-
# When /^I go to (.+)$/ do |page_name|
|
5
|
-
#
|
6
|
-
# step definition in web_steps.rb
|
7
|
-
#
|
8
|
-
def path_to(page_name)
|
9
|
-
case page_name
|
10
|
-
|
11
|
-
when /the home\s?page/
|
12
|
-
'/'
|
13
|
-
when /the new post page/
|
14
|
-
new_post_path
|
15
|
-
|
16
|
-
|
17
|
-
# Add more mappings here.
|
18
|
-
# Here is an example that pulls values out of the Regexp:
|
19
|
-
#
|
20
|
-
# when /^(.*)'s profile page$/i
|
21
|
-
# user_profile_path(User.find_by_login($1))
|
22
|
-
|
23
|
-
else
|
24
|
-
begin
|
25
|
-
page_name =~ /the (.*) page/
|
26
|
-
path_components = $1.split(/\s+/)
|
27
|
-
self.send(path_components.push('path').join('_').to_sym)
|
28
|
-
rescue Object => e
|
29
|
-
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
30
|
-
"Now, go and add a mapping in #{__FILE__}"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
World(NavigationHelpers)
|
1
|
+
# unused
|
@@ -1,39 +1 @@
|
|
1
|
-
|
2
|
-
# Maps a name to a selector. Used primarily by the
|
3
|
-
#
|
4
|
-
# When /^(.+) within (.+)$/ do |step, scope|
|
5
|
-
#
|
6
|
-
# step definitions in web_steps.rb
|
7
|
-
#
|
8
|
-
def selector_for(locator)
|
9
|
-
case locator
|
10
|
-
|
11
|
-
when /the page/
|
12
|
-
"html > body"
|
13
|
-
|
14
|
-
# Add more mappings here.
|
15
|
-
# Here is an example that pulls values out of the Regexp:
|
16
|
-
#
|
17
|
-
# when /the (notice|error|info) flash/
|
18
|
-
# ".flash.#{$1}"
|
19
|
-
|
20
|
-
# You can also return an array to use a different selector
|
21
|
-
# type, like:
|
22
|
-
#
|
23
|
-
# when /the header/
|
24
|
-
# [:xpath, "//header"]
|
25
|
-
|
26
|
-
# This allows you to provide a quoted selector as the scope
|
27
|
-
# for "within" steps as was previously the default for the
|
28
|
-
# web steps:
|
29
|
-
when /"(.+)"/
|
30
|
-
$1
|
31
|
-
|
32
|
-
else
|
33
|
-
raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
|
34
|
-
"Now, go and add a mapping in #{__FILE__}"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
World(HtmlSelectorsHelpers)
|
1
|
+
# unused
|
@@ -1,8 +1,10 @@
|
|
1
|
-
@
|
1
|
+
@javascript
|
2
2
|
Feature: Products should have variant options
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
In order to purchase a product
|
5
|
+
As a customer
|
6
|
+
I want to select a variant
|
7
|
+
|
6
8
|
Scenario: Display options when visiting a product
|
7
9
|
Given I have a product with variants
|
8
10
|
And I'm on the product page for the first product
|
@@ -12,6 +14,12 @@ Feature: Products should have variant options
|
|
12
14
|
And I should have a hidden input for the selected variant
|
13
15
|
And the add to cart button should be disabled
|
14
16
|
|
17
|
+
Scenario: Display option images when visiting a product
|
18
|
+
Given I have a product with variants
|
19
|
+
And the first option type has an option value with image "spree.jpg"
|
20
|
+
And I'm on the product page for the first product
|
21
|
+
Then I should see image "spree.jpg" within the first option value
|
22
|
+
|
15
23
|
Scenario: Interact with options for a product
|
16
24
|
Given I have a product with variants
|
17
25
|
And I'm on the product page for the first product
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module SpreeVariantOptions
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
|
7
|
+
def self.count!
|
8
|
+
@count ||= 0
|
9
|
+
(@count += 1) * 3
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.next_migration_number(path)
|
13
|
+
@time ||= Time.new.utc
|
14
|
+
if ActiveRecord::Base.timestamped_migrations
|
15
|
+
(@time + self.count!).strftime("%Y%m%d%H%M%S")
|
16
|
+
else
|
17
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Installs required migrations for spree_essentials"
|
22
|
+
source_root File.expand_path("../../templates", __FILE__)
|
23
|
+
|
24
|
+
def copy_migrations
|
25
|
+
migration_template "db/migrate/add_image_to_option_values.rb", "db/migrate/add_image_to_option_values.rb"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AddImageToOptionValues < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :option_values, :image_file_name, :string
|
4
|
+
add_column :option_values, :image_content_type, :string
|
5
|
+
add_column :option_values, :image_file_size, :integer
|
6
|
+
add_column :option_values, :image_updated_at, :datetime
|
7
|
+
end
|
8
|
+
def self.down
|
9
|
+
remove_column :option_values, :image_file_name
|
10
|
+
remove_column :option_values, :image_content_type
|
11
|
+
remove_column :option_values, :image_file_size
|
12
|
+
remove_column :option_values, :image_updated_at
|
13
|
+
end
|
14
|
+
end
|
@@ -26,11 +26,12 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_development_dependency('spree_sample', '>= 0.30.1')
|
27
27
|
s.add_development_dependency('dummier', '>= 0.2.0')
|
28
28
|
s.add_development_dependency('shoulda', '>= 2.11.3')
|
29
|
-
s.add_development_dependency('factory_girl', '>= 2.0.
|
29
|
+
s.add_development_dependency('factory_girl', '>= 2.0.4')
|
30
30
|
s.add_development_dependency('cucumber-rails', '>= 1.0.2')
|
31
31
|
s.add_development_dependency('database_cleaner', '>= 0.6.7')
|
32
|
-
s.add_development_dependency('sqlite3', '>= 1.3.
|
32
|
+
s.add_development_dependency('sqlite3', '>= 1.3.4')
|
33
33
|
s.add_development_dependency('spork', '>= 0.9.0.rc9')
|
34
34
|
s.add_development_dependency('spork-testunit', '>= 0.0.5')
|
35
|
+
s.add_development_dependency('turn', '>= 0.8.2')
|
35
36
|
|
36
37
|
end
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Test::Unit::TestCase
|
2
|
+
def self.should_have_attached_file(attachment)
|
3
|
+
klass = self.name.gsub(/Test$/, '').constantize
|
4
|
+
|
5
|
+
context "To support a paperclip attachment named #{attachment}, #{klass}" do
|
6
|
+
should have_db_column("#{attachment}_file_name").of_type(:string)
|
7
|
+
should have_db_column("#{attachment}_content_type").of_type(:string)
|
8
|
+
should have_db_column("#{attachment}_file_size").of_type(:integer)
|
9
|
+
should have_db_column("#{attachment}_updated_at").of_type(:datetime)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "have a paperclip attachment named ##{attachment}" do
|
13
|
+
assert klass.new.respond_to?(attachment.to_sym), "@#{klass.name.underscore} doesn't have a paperclip field named #{attachment}"
|
14
|
+
assert_equal Paperclip::Attachment, klass.new.send(attachment.to_sym).class
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -10,6 +10,7 @@ Spork.prefork do
|
|
10
10
|
require "factory_girl"
|
11
11
|
require "sqlite3"
|
12
12
|
require "faker"
|
13
|
+
require "turn"
|
13
14
|
|
14
15
|
# Run any available migration if needed
|
15
16
|
ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
|
@@ -17,6 +18,6 @@ end
|
|
17
18
|
|
18
19
|
Spork.each_run do
|
19
20
|
|
20
|
-
|
21
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
21
22
|
|
22
23
|
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
class OptionValueTest < ActiveSupport::TestCase
|
4
|
+
|
5
|
+
setup do
|
6
|
+
@images = Dir[File.expand_path("../../dummy/db/sample/assets/*", __FILE__)]
|
7
|
+
end
|
8
|
+
|
9
|
+
should_have_attached_file :image
|
10
|
+
|
11
|
+
context "a new option value" do
|
12
|
+
|
13
|
+
setup do
|
14
|
+
@option_value = OptionValue.new
|
15
|
+
end
|
16
|
+
|
17
|
+
should "not have an image" do
|
18
|
+
assert !@option_value.has_image?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
context "an existing option value" do
|
24
|
+
|
25
|
+
setup do
|
26
|
+
@option_value = Factory.create(:option_value)
|
27
|
+
end
|
28
|
+
|
29
|
+
should "not have an image" do
|
30
|
+
assert !@option_value.has_image?
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with an image" do
|
34
|
+
|
35
|
+
setup do
|
36
|
+
@path = @images.shuffle.first
|
37
|
+
file = File.open(@path)
|
38
|
+
@option_value.update_attributes(:image => file)
|
39
|
+
file.close
|
40
|
+
end
|
41
|
+
|
42
|
+
should "have an image" do
|
43
|
+
assert @option_value.has_image?
|
44
|
+
end
|
45
|
+
|
46
|
+
should "have small large and original images" do
|
47
|
+
dir = File.expand_path("../../dummy/public/assets/option_values/#{@option_value.id}", __FILE__)
|
48
|
+
%w(small large original).each do |size|
|
49
|
+
assert File.exists?(File.join(dir, size, File.basename(@path)))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: spree_variant_options
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Spencer Steffen
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-08-17 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: spree_core
|
@@ -64,7 +63,7 @@ dependencies:
|
|
64
63
|
requirements:
|
65
64
|
- - ">="
|
66
65
|
- !ruby/object:Gem::Version
|
67
|
-
version: 2.0.
|
66
|
+
version: 2.0.4
|
68
67
|
type: :development
|
69
68
|
prerelease: false
|
70
69
|
version_requirements: *id005
|
@@ -97,7 +96,7 @@ dependencies:
|
|
97
96
|
requirements:
|
98
97
|
- - ">="
|
99
98
|
- !ruby/object:Gem::Version
|
100
|
-
version: 1.3.
|
99
|
+
version: 1.3.4
|
101
100
|
type: :development
|
102
101
|
prerelease: false
|
103
102
|
version_requirements: *id008
|
@@ -123,6 +122,17 @@ dependencies:
|
|
123
122
|
type: :development
|
124
123
|
prerelease: false
|
125
124
|
version_requirements: *id010
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: turn
|
127
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
128
|
+
none: false
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 0.8.2
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: *id011
|
126
136
|
description: Spree Variant Options is a simple spree extension that replaces the radio-button variant selection with groups of option types and values. Please see the documentation for more details.
|
127
137
|
email:
|
128
138
|
- spencer@citrusme.com
|
@@ -139,18 +149,25 @@ files:
|
|
139
149
|
- README.md
|
140
150
|
- Rakefile
|
141
151
|
- Versionfile
|
152
|
+
- app/controllers/admin/option_values_controller.rb
|
153
|
+
- app/models/option_value_decorator.rb
|
142
154
|
- app/models/product_decorator.rb
|
155
|
+
- app/views/admin/option_types/_option_value_fields.html.erb
|
156
|
+
- app/views/admin/option_types/edit.html.erb
|
143
157
|
- app/views/products/_cart_form.html.erb
|
144
158
|
- app/views/products/_variant_options.html.erb
|
145
159
|
- config/cucumber.yml
|
160
|
+
- config/routes.rb
|
161
|
+
- features/admin_option_types.feature
|
162
|
+
- features/step_definitions/option_values.rb
|
146
163
|
- features/step_definitions/variant_options.rb
|
147
164
|
- features/step_definitions/web_steps.rb
|
148
165
|
- features/support/env.rb
|
149
|
-
- features/support/factories.rb
|
150
|
-
- features/support/helper_methods.rb
|
151
166
|
- features/support/paths.rb
|
152
167
|
- features/support/selectors.rb
|
153
168
|
- features/variant_options.feature
|
169
|
+
- lib/generators/spree_variant_options/install_generator.rb
|
170
|
+
- lib/generators/templates/db/migrate/add_image_to_option_values.rb
|
154
171
|
- lib/spree_variant_options.rb
|
155
172
|
- lib/spree_variant_options/version.rb
|
156
173
|
- public/images/out-of-stock.png
|
@@ -160,9 +177,12 @@ files:
|
|
160
177
|
- spree_variant_options.gemspec
|
161
178
|
- test/dummy_hooks/after_migrate.rb.sample
|
162
179
|
- test/dummy_hooks/before_migrate.rb
|
180
|
+
- test/support/factories.rb
|
181
|
+
- test/support/helper_methods.rb
|
182
|
+
- test/support/paperclip.rb
|
163
183
|
- test/test_helper.rb
|
184
|
+
- test/unit/option_value_test.rb
|
164
185
|
- test/unit/product_test.rb
|
165
|
-
has_rdoc: true
|
166
186
|
homepage: https://github.com/citrus/spree_variant_options
|
167
187
|
licenses: []
|
168
188
|
|
@@ -176,7 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
196
|
requirements:
|
177
197
|
- - ">="
|
178
198
|
- !ruby/object:Gem::Version
|
179
|
-
hash:
|
199
|
+
hash: 2340832333583009512
|
180
200
|
segments:
|
181
201
|
- 0
|
182
202
|
version: "0"
|
@@ -185,27 +205,31 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
185
205
|
requirements:
|
186
206
|
- - ">="
|
187
207
|
- !ruby/object:Gem::Version
|
188
|
-
hash:
|
208
|
+
hash: 2340832333583009512
|
189
209
|
segments:
|
190
210
|
- 0
|
191
211
|
version: "0"
|
192
212
|
requirements: []
|
193
213
|
|
194
214
|
rubyforge_project: spree_variant_options
|
195
|
-
rubygems_version: 1.
|
215
|
+
rubygems_version: 1.8.8
|
196
216
|
signing_key:
|
197
217
|
specification_version: 3
|
198
218
|
summary: Spree Variant Options is a simple spree extension that replaces the radio-button variant selection with groups of option types and values.
|
199
219
|
test_files:
|
220
|
+
- features/admin_option_types.feature
|
221
|
+
- features/step_definitions/option_values.rb
|
200
222
|
- features/step_definitions/variant_options.rb
|
201
223
|
- features/step_definitions/web_steps.rb
|
202
224
|
- features/support/env.rb
|
203
|
-
- features/support/factories.rb
|
204
|
-
- features/support/helper_methods.rb
|
205
225
|
- features/support/paths.rb
|
206
226
|
- features/support/selectors.rb
|
207
227
|
- features/variant_options.feature
|
208
228
|
- test/dummy_hooks/after_migrate.rb.sample
|
209
229
|
- test/dummy_hooks/before_migrate.rb
|
230
|
+
- test/support/factories.rb
|
231
|
+
- test/support/helper_methods.rb
|
232
|
+
- test/support/paperclip.rb
|
210
233
|
- test/test_helper.rb
|
234
|
+
- test/unit/option_value_test.rb
|
211
235
|
- test/unit/product_test.rb
|