Completely remove option_values and option_types from the codebase

This commit is contained in:
Matt-Yorkley
2023-05-06 00:43:11 +01:00
parent 35b41fc7fe
commit a20277c3a7
61 changed files with 100 additions and 389 deletions

View File

@@ -173,8 +173,7 @@ class ProductsTableComponent < ViewComponentReflex::Component
:default_price,
:stock_locations,
:stock_items,
:variant_overrides,
{ option_values: :option_type }
:variant_overrides
]
]
end

View File

@@ -11,7 +11,7 @@ module Admin
@line_items = order_permissions.
editable_line_items.where(order_id: orders).
includes(variant: { option_values: :option_type }).
includes(:variant).
ransack(params[:q]).result.
reorder('spree_line_items.order_id ASC, spree_line_items.id ASC')

View File

@@ -29,7 +29,6 @@ module Admin
after_action :geocode_address_if_use_geocoder, only: [:create, :update]
helper 'spree/products'
include OrderCyclesHelper
def index
@@ -187,7 +186,7 @@ module Admin
if enterprises.present?
enterprises.includes(
supplied_products:
[:supplier, { master: [:images], variants: { option_values: :option_type } }]
[:supplier, :variants, { master: [:images] }]
)
end
when :index

View File

@@ -117,8 +117,7 @@ module Api
def product_query_includes
[
master: { images: { attachment_attachment: :blob } },
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides,
{ option_values: :option_type }]
variants: [:default_price, :stock_locations, :stock_items, :variant_overrides]
]
end

View File

@@ -9,12 +9,12 @@ module Api
before_action :product
def index
@variants = scope.includes(option_values: :option_type).ransack(params[:q]).result
@variants = scope.ransack(params[:q]).result
render json: @variants, each_serializer: Api::VariantSerializer
end
def show
@variant = scope.includes(option_values: :option_type).find(params[:id])
@variant = scope.find(params[:id])
render json: @variant, serializer: Api::VariantSerializer
end

View File

@@ -4,7 +4,6 @@ require 'open_food_network/enterprise_injection_data'
class EnterprisesController < BaseController
layout "darkswarm"
helper Spree::ProductsHelper
include OrderCyclesHelper
include SerializerHelper
include WhiteLabel

View File

@@ -7,7 +7,6 @@ require 'open_food_network/permissions'
module Spree
module Admin
class ProductsController < ::Admin::ResourceController
helper 'spree/products'
include OpenFoodNetwork::SpreeApiKeyLoader
include OrderCyclesHelper
include EnterprisesHelper
@@ -113,7 +112,6 @@ module Spree
def load_data
@taxons = Taxon.order(:name)
@option_types = OptionType.order(:name)
@tax_categories = TaxCategory.order(:name)
@shipping_categories = ShippingCategory.order(:name)
end
@@ -123,7 +121,7 @@ module Spree
end
def product_includes
[{ variants: [:images, { option_values: :option_type }] },
[{ variants: [:images] },
{ master: [:images, :default_price] }]
end

View File

@@ -5,7 +5,6 @@ require 'open_food_network/scope_variants_for_search'
module Spree
module Admin
class VariantsController < ::Admin::ResourceController
helper 'spree/products'
belongs_to 'spree/product', find_by: :permalink
before_action :assign_default_attributes, only: :new
@@ -81,8 +80,6 @@ module Spree
end
def create_before
option_values = params[:new_variant]
option_values&.each_value { |id| @object.option_values << OptionValue.find(id) }
@object.save
end

View File

@@ -10,7 +10,7 @@ module Spree
layout 'darkswarm'
rescue_from ActiveRecord::RecordNotFound, with: :render_404
helper 'spree/products', 'spree/orders'
helper 'spree/orders'
respond_to :html, :json

View File

@@ -60,7 +60,7 @@ class ProducerMailer < ApplicationMailer
def line_items_from(order_cycle, producer)
@line_items ||= Spree::LineItem.
includes(:option_values, variant: [:product, { option_values: :option_type }]).
includes(variant: [:product]).
from_order_cycle(order_cycle).
sorted_by_name_and_unit_value.
merge(Spree::Product.with_deleted.in_supplier(producer)).

View File

@@ -22,8 +22,6 @@ module Spree
can :manage, :all
else
can [:index, :read], Country
can [:index, :read], OptionType
can [:index, :read], OptionValue
can :create, Order
can :read, Order do |order, token|
order.user == user || order.token && token == order.token

View File

@@ -9,7 +9,7 @@ module Spree
include LineItemStockChanges
searchable_attributes :price, :quantity, :order_id, :variant_id, :tax_category_id
searchable_associations :order, :order_cycle, :variant, :product, :supplier, :tax_category, :option_values
searchable_associations :order, :order_cycle, :variant, :product, :supplier, :tax_category
searchable_scopes :with_tax, :without_tax
belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items
@@ -22,9 +22,6 @@ module Spree
has_many :adjustments, as: :adjustable, dependent: :destroy
has_and_belongs_to_many :option_values, join_table: 'spree_option_values_line_items',
class_name: 'Spree::OptionValue'
before_validation :adjust_quantity
before_validation :copy_price
before_validation :copy_tax_category

View File

@@ -1,18 +0,0 @@
# frozen_string_literal: true
module Spree
class OptionType < ApplicationRecord
has_many :option_values, -> { order(:position) }, dependent: :destroy
has_many :product_option_types, dependent: :destroy
has_many :products, through: :product_option_types
validates :name, :presentation, presence: true
default_scope -> { order("#{table_name}.position") }
accepts_nested_attributes_for :option_values,
reject_if: lambda { |ov|
ov[:name].blank? || ov[:presentation].blank?
},
allow_destroy: true
end
end

View File

@@ -1,12 +0,0 @@
# frozen_string_literal: true
module Spree
class OptionValue < ApplicationRecord
belongs_to :option_type
acts_as_list scope: :option_type
has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants',
class_name: "Spree::Variant"
validates :name, :presentation, presence: true
end
end

View File

@@ -1,8 +0,0 @@
# frozen_string_literal: true
module Spree
class OptionValuesLineItem < ApplicationRecord
belongs_to :line_item, class_name: 'Spree::LineItem'
belongs_to :option_value, class_name: 'Spree::OptionValue'
end
end

View File

@@ -11,7 +11,6 @@ require 'concerns/product_stock'
#
# MASTER VARIANT
# Every product has one master variant, which stores master price and sku, size and weight, etc.
# The master variant does not have option values associated with it.
# Price, SKU, size, weight, etc. are all delegated to the master variant.
# Contains on_hand inventory levels only when there are no variants for the product.
#
@@ -33,11 +32,6 @@ module Spree
searchable_associations :supplier, :properties, :primary_taxon, :variants, :master
searchable_scopes :active, :with_properties
has_many :product_option_types, dependent: :destroy
# We have an after_destroy callback on Spree::ProductOptionType. However, if we
# don't specify dependent => destroy on this association, it is not called. See:
# https://github.com/rails/rails/issues/7618
has_many :option_types, through: :product_option_types, dependent: :destroy
has_many :product_properties, dependent: :destroy
has_many :properties, through: :product_properties

View File

@@ -1,18 +0,0 @@
# frozen_string_literal: true
module Spree
class ProductOptionType < ApplicationRecord
after_destroy :remove_option_values
belongs_to :product, class_name: 'Spree::Product'
belongs_to :option_type, class_name: 'Spree::OptionType'
acts_as_list scope: :product
def remove_option_values
product.variants_including_master.each do |variant|
option_values = variant.option_values.where(option_type_id: option_type)
variant.option_values.destroy(*option_values)
end
end
end
end

View File

@@ -14,7 +14,7 @@ module Spree
acts_as_paranoid
searchable_attributes :sku, :display_as, :display_name
searchable_associations :product, :option_values, :default_price
searchable_associations :product, :default_price
searchable_scopes :active, :deleted
NAME_FIELDS = ["display_name", "display_as", "weight", "unit_value", "unit_description"].freeze
@@ -31,9 +31,6 @@ module Spree
has_many :stock_items, dependent: :destroy, inverse_of: :variant
has_many :stock_locations, through: :stock_items
has_many :stock_movements
has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
has_many :images, -> { order(:position) }, as: :viewable,
dependent: :destroy,
class_name: "Spree::Image"
@@ -181,10 +178,6 @@ module Spree
order_cycle).fees_name_by_type_for self
end
def option_value(opt_name)
option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
end
def price_in(currency)
prices.select{ |price| price.currency == currency }.first ||
Spree::Price.new(variant_id: id, currency: currency)

View File

@@ -36,7 +36,7 @@ module VariantUnits
end
def option_value_value_unit
if @nameable.unit_value.present?
if @nameable.unit_value.present? && @nameable.product.persisted?
if %w(weight volume).include? @nameable.product.variant_unit
value, unit_name = option_value_value_unit_scaled
else

View File

@@ -69,7 +69,7 @@ module VariantUnits
end
def weight_from_unit_value
(unit_value || 0) / 1000 if variant_unit == 'weight'
(unit_value || 0) / 1000 if product.variant_unit == 'weight'
end
private

View File

@@ -1,7 +1,7 @@
%tr{id: "#{spree_dom_id(f.object)}", class: "#{cycle('odd', 'even')}"}
%td
= f.object.variant.product.name
= "(#{f.object.full_name})" unless f.object.variant.option_values.empty?
= "(#{f.object.full_name})"
%td.price.align-center
= f.object.single_display_amount
%td.qty

View File

@@ -18,15 +18,6 @@
= f.text_field :unit_description, class: "fullwidth", placeholder: t('admin.products.unit_name_placeholder')
%div
- @product.option_types.each do |option_type|
- unless variant_unit_option_type?(option_type)
.field
= label :new_variant, option_type.presentation
- if @variant.new_record?
= select(:new_variant, option_type.presentation, option_type.option_values.collect {|ov| [ ov.presentation, ov.id ] }, {}, {class: 'select2 fullwidth'})
- else
- if opt = @variant.option_values.detect {|o| o.option_type == option_type }.try(:presentation)
= text_field(:new_variant, option_type.presentation, value: opt, disabled: 'disabled', class: 'fullwidth')
.field
= f.label :sku, t('.sku')
= f.text_field :sku, class: 'fullwidth'

View File

@@ -12,14 +12,14 @@ module OrderManagement
let!(:product2) { create(:product, supplier: shop) }
let!(:product3) { create(:product, supplier: shop) }
let!(:variant1) {
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
create(:variant, product: product1, unit_value: '100', price: 12.00)
}
let!(:variant2) {
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
create(:variant, product: product2, unit_value: '1000', price: 6.00)
}
let!(:variant3) {
create(:variant, product: product2, unit_value: '1000',
price: 2.50, option_values: [], on_hand: 1)
price: 2.50, on_hand: 1)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle1) {

View File

@@ -34,7 +34,6 @@ module OpenFoodNetwork
def query_scope
Spree::Variant.where(is_master: false).
includes(option_values: :option_type).
ransack(search_params.merge(m: 'or')).
result.
order("spree_products.name, display_name, display_as, spree_products.variant_unit_name").

View File

@@ -40,13 +40,6 @@ module Reporting
def joins_order_bill_address
reflect query.join(association(Spree::Order, :bill_address, bill_address_alias))
end
def join_line_item_option_values
reflect query.
join(association(Spree::LineItem, :option_values)).
join(association(Spree::OptionValuesLineItem, :option_value)
)
end
end
end
end

View File

@@ -65,7 +65,7 @@ module Reporting
def variant_full_name
display_name = variant_table[:display_name]
display_as = variant_table[:display_as]
options_text = option_value_table[:presentation]
options_text = variant_table[:unit_presentation]
unit_to_display = coalesce(nullify_empty_strings(display_as), options_text)
combined_description = sql_concat(display_name, raw("' ('"), unit_to_display, raw("')'"))

View File

@@ -39,10 +39,6 @@ module Reporting
Spree::Order.arel_table.alias(:managed_orders)
end
def option_value_table
Spree::OptionValue.arel_table
end
def shipping_category_table
Spree::ShippingCategory.arel_table
end

View File

@@ -22,9 +22,8 @@ module Reporting
[
{
order: [:bill_address],
variant: [{ option_values: :option_type }, { product: :supplier }]
},
:option_values
variant: { product: :supplier }
}
]
end

View File

@@ -91,7 +91,7 @@ module Reporting
end
def line_item_includes
[{ variant: [{ option_values: :option_type }, { product: :supplier }],
[{ variant: { product: :supplier },
order: [:bill_address, :ship_address, :order_cycle, :adjustments, :payments,
:user, :distributor, :shipments] }]
end

View File

@@ -40,7 +40,7 @@ module Reporting
:adjustments,
{ shipments: { shipping_rates: :shipping_method } }
],
variant: [{ option_values: :option_type }, { product: :supplier }]
variant: { product: :supplier }
}]
end
end

View File

@@ -36,7 +36,7 @@ module Reporting
end
def line_item_includes
[{ variant: [{ option_values: :option_type }, { product: :supplier }] }]
[{ variant: { product: :supplier } }]
end
def query_result

View File

@@ -41,7 +41,7 @@ module Reporting
def line_item_includes
[{ order: :distributor,
variant: [{ option_values: :option_type }, { product: :supplier }] }]
variant: { product: :supplier } }]
end
end
end

View File

@@ -20,7 +20,6 @@ module Reporting
joins_variant_product.
joins_product_supplier.
joins_product_shipping_category.
join_line_item_option_values.
selecting(select_fields).
ordered_by(ordering_fields)
end

View File

@@ -34,7 +34,6 @@ module Reporting
def child_variants
Spree::Variant.
where(is_master: false).
includes(option_values: :option_type).
joins(:product).
merge(visible_products).
order('spree_products.name')

View File

@@ -62,7 +62,7 @@ module Reporting
def line_item_includes
[:bill_address, :adjustments,
{ line_items: { variant: [{ option_values: :option_type }, { product: :supplier }] } }]
{ line_items: { variant: { product: :supplier } } }]
end
def detail_rows_for_order(order, invoice_number, opts)

View File

@@ -11,8 +11,6 @@ module Spree
def duplicate
new_product = duplicate_product
new_product.option_types = product.option_types
new_product.save!
new_product
end

View File

@@ -27,11 +27,9 @@ class RemoveTransientData
merge(orders_without_payments)
old_cart_line_items = Spree::LineItem.where(order_id: old_carts)
old_line_item_options = Spree::OptionValuesLineItem.where(line_item_id: old_cart_line_items)
old_cart_adjustments = Spree::Adjustment.where(order_id: old_carts)
old_cart_adjustments.delete_all
old_line_item_options.delete_all
old_cart_line_items.delete_all
old_carts.delete_all
end

View File

@@ -11,7 +11,7 @@ describe Admin::SubscriptionLineItemsController, type: :controller do
let(:unmanaged_shop) { create(:enterprise) }
let!(:product) { create(:product) }
let!(:variant) {
create(:variant, product: product, unit_value: '100', price: 15.00, option_values: [])
create(:variant, product: product, unit_value: '100', price: 15.00)
}
let!(:outgoing_exchange) {
order_cycle.exchanges.create(sender: shop, receiver: shop, variants: [variant],

View File

@@ -262,7 +262,7 @@ describe Admin::SubscriptionsController, type: :controller do
let!(:customer) { create(:customer, enterprise: shop) }
let!(:product1) { create(:product, supplier: shop) }
let!(:variant1) {
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
create(:variant, product: product1, unit_value: '100', price: 12.00)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle) {
@@ -373,7 +373,7 @@ describe Admin::SubscriptionsController, type: :controller do
context 'with subscription_line_items params' do
let!(:product2) { create(:product) }
let!(:variant2) {
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
create(:variant, product: product2, unit_value: '1000', price: 6.00)
}
before do

View File

@@ -61,7 +61,7 @@ describe Api::V0::ProductsController, type: :controller do
api_get :show, id: product.to_param
expect(json_response["permalink_live"]).to match(/and-1-ways/)
product.destroy
product.reload.destroy
api_get :show, id: other_product.id
expect(json_response["permalink_live"]).to match(/droids/)

View File

@@ -24,7 +24,6 @@ describe Api::V0::VariantsController, type: :controller do
let!(:product) { create(:product) }
let!(:variant) do
variant = product.master
variant.option_values << create(:option_value)
variant
end
@@ -46,17 +45,18 @@ describe Api::V0::VariantsController, type: :controller do
# Regression test for spree#2141
context "a deleted variant" do
before do
expect(Spree::Variant.count).to eq 11
variant.update_column(:deleted_at, Time.zone.now)
end
it "is not returned in the results" do
api_get :index
expect(json_response.count).to eq(10) # there are 11 variants
expect(json_response.count).to eq(10)
end
it "is not returned even when show_deleted is passed" do
api_get :index, show_deleted: true
expect(json_response.count).to eq(10) # there are 11 variants
expect(json_response.count).to eq(10)
end
end

View File

@@ -1,17 +0,0 @@
# frozen_string_literal: true
FactoryBot.define do
factory :option_value, class: Spree::OptionValue do
name { 'Size' }
presentation { 'S' }
option_type
end
factory :option_type, class: Spree::OptionType do
name { 'foo-size' }
presentation { 'Size' }
# Prevent inconsistent ordering in specs when all option types have the same (0) position
sequence(:position)
end
end

View File

@@ -34,10 +34,7 @@ FactoryBot.define do
after(:create) do |product, evaluator|
product.master.on_hand = evaluator.on_hand
product.variants.first.on_hand = evaluator.on_hand
end
factory :product_with_option_types do
after(:create) { |product| create(:product_option_type, product: product) }
product.reload
end
end
end
@@ -60,6 +57,7 @@ FactoryBot.define do
product.master.on_hand = evaluator.on_hand
product.variants.first.on_demand = evaluator.on_demand
product.variants.first.on_hand = evaluator.on_hand
product.reload
end
end

View File

@@ -1,8 +0,0 @@
# frozen_string_literal: true
FactoryBot.define do
factory :product_option_type, class: Spree::ProductOptionType do
product
option_type
end
end

View File

@@ -12,7 +12,6 @@ FactoryBot.define do
depth { generate(:random_float) }
product { |p| p.association(:base_product) }
option_values { [create(:option_value)] }
# ensure stock item will be created for this variant
before(:create) { create(:stock_location) if Spree::StockLocation.count.zero? }

View File

@@ -1,2 +1,2 @@
Hub,Customer,Email,Phone,Producer,Product,Variant,Quantity,Item ($),Item + Fees ($),Admin & Handling ($),Ship ($),Pay fee ($),Total ($),Paid?,Shipping,Delivery?,Ship Street,Ship Street 2,Ship City,Ship Postcode,Ship State,Comments,SKU,Order Cycle,Payment Method,Customer Code,Tags,Billing Street,Billing Street 2,Billing City,Billing Postcode,Billing State,Order number,Date
Apple Market,John Doe,john@example.net,123-456-7890,Apple Farmer,Apples,"1g, S",1,10.0,10.0,"","","","",false,UPS Ground,true,10 Lovely Street,Northwest,Herndon,20170,Victoria,"",APP,,,JHN,"",10 Lovely Street,Northwest,Herndon,20170,Victoria,R644360121,2022-05-26 00:00:00
Apple Market,John Doe,john@example.net,123-456-7890,Apple Farmer,Apples,1g,1,10.0,10.0,"","","","",false,UPS Ground,true,10 Lovely Street,Northwest,Herndon,20170,Victoria,"",APP,,,JHN,"",10 Lovely Street,Northwest,Herndon,20170,Victoria,R644360121,2022-05-26 00:00:00
1 Hub Customer Email Phone Producer Product Variant Quantity Item ($) Item + Fees ($) Admin & Handling ($) Ship ($) Pay fee ($) Total ($) Paid? Shipping Delivery? Ship Street Ship Street 2 Ship City Ship Postcode Ship State Comments SKU Order Cycle Payment Method Customer Code Tags Billing Street Billing Street 2 Billing City Billing Postcode Billing State Order number Date
2 Apple Market John Doe john@example.net 123-456-7890 Apple Farmer Apples 1g, S 1g 1 10.0 10.0 false UPS Ground true 10 Lovely Street Northwest Herndon 20170 Victoria APP JHN 10 Lovely Street Northwest Herndon 20170 Victoria R644360121 2022-05-26 00:00:00

View File

@@ -9,8 +9,7 @@ describe Spree::Core::ProductDuplicator do
taxons: [],
product_properties: [property],
master: master_variant,
variants: [variant],
option_types: []
variants: [variant]
end
let(:new_product) do
@@ -89,7 +88,6 @@ describe Spree::Core::ProductDuplicator do
expect(new_product).to receive(:updated_at=).with(nil)
expect(new_product).to receive(:deleted_at=).with(nil)
expect(new_product).to receive(:master=).with(new_master_variant)
expect(new_product).to receive(:option_types=).with([])
expect(new_product).to receive(:variants=).with([new_variant])
expect(new_master_variant).to receive(:sku=).with("")

View File

@@ -63,13 +63,6 @@ describe RemoveTransientData do
expect{ old_line_item.reload }.to raise_error ActiveRecord::RecordNotFound
expect{ old_adjustment.reload }.to raise_error ActiveRecord::RecordNotFound
end
it "removes any defunct line item option value records" do
line_item.delete
expect{ RemoveTransientData.new.call }.
to change{ Spree::OptionValuesLineItem.count }.by(-1)
end
end
end
end

View File

@@ -71,20 +71,6 @@ describe Spree::Ability do
end
end
context 'for OptionType' do
let(:resource) { Spree::OptionType.new }
context 'requested by any user' do
it_should_behave_like 'read only'
end
end
context 'for OptionValue' do
let(:resource) { Spree::OptionType.new }
context 'requested by any user' do
it_should_behave_like 'read only'
end
end
context 'for Order' do
let(:resource) { Spree::Order.new }

View File

@@ -178,12 +178,12 @@ module Spree
before do
li1
li2
li2.reload
li1.adjustments << adjustment1
end
it "finds line items with tax" do
expect(LineItem.with_tax).to eq([li1])
expect(LineItem.with_tax.to_a).to eq([li1])
end
it "finds line items without tax" do
@@ -708,47 +708,41 @@ module Spree
end
end
context "when the line_item already has a final_weight_volume set (and all required option values do not exist)" do
context "when the line_item has a final_weight_volume set" do
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v) { create(:variant, product: p0, unit_value: 10, unit_description: 'bar') }
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:li) { create(:line_item, product: p, final_weight_volume: 5) }
it "removes the old option value and assigns the new one" do
ov_orig = li.option_values.last
ov_var = v.option_values.last
it "assigns the new value" do
expect(li.unit_presentation).to eq "5g"
expect(v.unit_presentation).to eq "10g bar"
allow(li).to receive(:unit_description) { 'foo' }
expect {
li.update_attribute(:final_weight_volume, 10)
}.to change(Spree::OptionValue, :count).by(1)
li.update_attribute(:final_weight_volume, 10)
expect(li.option_values).not_to include ov_orig
expect(li.option_values).not_to include ov_var
ov = li.option_values.last
expect(ov.name).to eq("10g foo")
expect(li.unit_presentation).to eq "10g foo"
end
end
context "when the variant already has a value set (and all required option values exist)" do
context "when the variant already has a value set" do
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v) { create(:variant, product: p0, unit_value: 10, unit_description: 'bar') }
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:li) { create(:line_item, product: p, final_weight_volume: 5) }
it "removes the old option value and assigns the new one" do
ov_orig = li.option_values.last
ov_new = v.option_values.last
it "assigns the new value" do
expect(li.unit_presentation).to eq "5g"
expect(v.unit_presentation).to eq "10g bar"
allow(li).to receive(:unit_description) { 'bar' }
expect {
li.update_attribute(:final_weight_volume, 10)
}.to change(Spree::OptionValue, :count).by(0)
li.update_attribute(:final_weight_volume, 10)
expect(li.option_values).not_to include ov_orig
expect(li.option_values).to include ov_new
expect(li.unit_presentation).to eq "10g bar"
end
end
@@ -792,24 +786,6 @@ module Spree
end
end
describe "deleting unit option values" do
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:ot) { Spree::OptionType.find_by name: 'unit_weight' }
let!(:li) { create(:line_item, product: p) }
it "removes option value associations for unit option types" do
expect {
li.delete_unit_option_values
}.to change(li.option_values, :count).by(-1)
end
it "does not delete option values" do
expect {
li.delete_unit_option_values
}.to change(Spree::OptionValue, :count).by(0)
end
end
describe "when the associated variant is soft-deleted" do
let!(:variant) { create(:variant) }
let!(:line_item) { create(:line_item, variant: variant) }

View File

@@ -881,7 +881,7 @@ module Spree
end
describe "variant units" do
context "when the product already has a variant unit set (and all required option types exist)" do
context "when the product already has a variant unit set" do
let!(:p) {
create(:simple_product,
variant_unit: 'weight',
@@ -889,75 +889,27 @@ module Spree
variant_unit_name: nil)
}
let!(:ot_volume) { create(:option_type, name: 'unit_volume', presentation: 'Volume') }
it "removes the old option type and assigns the new one" do
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
expect(p.option_types).to eq([ot_volume])
end
it "does not remove and re-add the option type if it is not changed" do
expect(p.option_types).to receive(:delete).never
p.update!(name: 'foo')
end
it "removes the related option values from all its variants and replaces them" do
ot = Spree::OptionType.find_by name: 'unit_weight'
it "updates its variants unit values" do
v = create(:variant, unit_value: 1, product: p)
p.reload
expect(v.option_values.map(&:name).include?("1L")).to eq(false)
expect(v.option_values.map(&:name).include?("1g")).to eq(true)
expect {
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
}.to change(p.master.option_values.reload, :count).by(0)
v.reload
expect(v.option_values.map(&:name).include?("1L")).to eq(true)
expect(v.option_values.map(&:name).include?("1g")).to eq(false)
expect(v.unit_presentation).to eq "1g"
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
expect(v.reload.unit_presentation).to eq "1L"
end
it "removes the related option values from its master variant and replaces them" do
ot = Spree::OptionType.find_by name: 'unit_weight'
it "updates its master variant's unit values" do
p.master.update!(unit_value: 1)
p.reload
expect(p.master.option_values.map(&:name).include?("1L")).to eq(false)
expect(p.master.option_values.map(&:name).include?("1g")).to eq(true)
expect {
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
}.to change(p.master.option_values.reload, :count).by(0)
expect(p.master.unit_presentation).to eq "1g"
p.update!(variant_unit: 'volume', variant_unit_scale: 0.001)
p.reload
expect(p.master.option_values.map(&:name).include?("1L")).to eq(true)
expect(p.master.option_values.map(&:name).include?("1g")).to eq(false)
end
end
end
describe "option types" do
describe "removing an option type" do
it "removes the associated option values from all variants" do
# Given a product with a variant unit option type and values
p = create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1)
v1 = create(:variant, product: p, unit_value: 100, option_values: [])
v2 = create(:variant, product: p, unit_value: 200, option_values: [])
# And a custom option type and values
ot = create(:option_type, name: 'foo', presentation: 'foo')
p.option_types << ot
ov1 = create(:option_value, option_type: ot, name: 'One', presentation: 'One')
ov2 = create(:option_value, option_type: ot, name: 'Two', presentation: 'Two')
v1.option_values << ov1
v2.option_values << ov2
# When we remove the custom option type
p.option_type_ids = p.option_type_ids.reject { |id| id == ot.id }
# Then the associated option values should have been removed from the variants
expect(v1.option_values.reload).not_to include ov1
expect(v2.option_values.reload).not_to include ov2
# And the option values themselves should still exist
expect(Spree::OptionValue.where(id: [ov1.id, ov2.id]).count).to eq(2)
expect(p.master.unit_presentation).to eq "1L"
end
end
end

View File

@@ -48,7 +48,7 @@ describe Spree::Shipment do
context "manifest" do
let(:order) { Spree::Order.create }
let(:variant) { create(:variant) }
let!(:variant) { create(:variant) }
let!(:line_item) { order.contents.add variant }
let!(:shipment) { order.create_proposed_shipments.first }

View File

@@ -567,8 +567,7 @@ describe Spree::Variant do
end
describe "unit value/description" do
let(:v) { Spree::Variant.new(option_values: [option_value]) }
let(:option_value) { build(:option_value, presentation: "small") }
let(:v) { Spree::Variant.new(unit_presentation: "small" ) }
describe "generating the full name" do
it "returns unit_to_display when display_name is blank" do
@@ -583,7 +582,7 @@ describe Spree::Variant do
it "returns unit_to_display when it contains display_name" do
v.display_name = "small"
v.option_values[0].presentation = "small size"
v.unit_presentation = "small size"
expect(v.full_name).to eq "small size"
end
@@ -594,7 +593,7 @@ describe Spree::Variant do
it "is resilient to regex chars" do
v.display_name = ")))"
v.option_values[0].presentation = ")))"
v.unit_presentation = ")))"
expect(v.full_name).to eq(")))")
end
end
@@ -665,38 +664,16 @@ describe Spree::Variant do
end
end
context "when the variant already has a value set (and all required option values do not exist)" do
context "when the variant already has a value set" do
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v) { create(:variant, product: p, unit_value: 5, unit_description: 'bar') }
it "removes the old option value and assigns the new one" do
ov_orig = v.option_values.last
it "assigns the new option value" do
expect(v.unit_presentation).to eq "5g bar"
expect {
v.update!(unit_value: 10, unit_description: 'foo')
}.to change(Spree::OptionValue, :count).by(1)
v.update!(unit_value: 10, unit_description: 'foo')
expect(v.option_values).not_to include ov_orig
end
end
context "when the variant already has a value set (and all required option values exist)" do
let!(:p0) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v0) { create(:variant, product: p0, unit_value: 10, unit_description: 'foo') }
let!(:p) { create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1) }
let!(:v) { create(:variant, product: p, unit_value: 5, unit_description: 'bar') }
it "removes the old option value and assigns the new one" do
ov_orig = v.option_values.last
ov_new = v0.option_values.last
expect {
v.update!(unit_value: 10, unit_description: 'foo')
}.to change(Spree::OptionValue, :count).by(0)
expect(v.option_values).not_to include ov_orig
expect(v.option_values).to include ov_new
expect(v.unit_presentation).to eq "10g foo"
end
end
@@ -706,11 +683,10 @@ describe Spree::Variant do
create(:variant, product: p, unit_value: 5, unit_description: 'bar', display_as: '')
}
it "requests the name of the new option_value from OptionValueName" do
it "requests the new value from OptionValueName" do
expect_any_instance_of(VariantUnits::OptionValueNamer).to receive(:name).exactly(1).times.and_call_original
v.update(unit_value: 10, unit_description: 'foo')
ov = v.option_values.last
expect(ov.name).to eq("10g foo")
expect(v.unit_presentation).to eq "10g foo"
end
end
@@ -720,35 +696,14 @@ describe Spree::Variant do
create(:variant, product: p, unit_value: 5, unit_description: 'bar', display_as: 'FOOS!')
}
it "does not request the name of the new option_value from OptionValueName" do
it "does not request the new value from OptionValueName" do
expect_any_instance_of(VariantUnits::OptionValueNamer).not_to receive(:name)
v.update!(unit_value: 10, unit_description: 'foo')
ov = v.option_values.last
expect(ov.name).to eq("FOOS!")
expect(v.unit_presentation).to eq("FOOS!")
end
end
end
describe "deleting unit option values" do
before do
p = create(:simple_product, variant_unit: 'weight', variant_unit_scale: 1)
ot = Spree::OptionType.find_by name: 'unit_weight'
@v = create(:variant, product: p)
end
it "removes option value associations for unit option types" do
expect {
@v.delete_unit_option_values
}.to change(@v.option_values, :count).by(-1)
end
it "does not delete option values" do
expect {
@v.delete_unit_option_values
}.to change(Spree::OptionValue, :count).by(0)
end
end
context "extends LocalizedNumber" do
subject! { build_stubbed(:variant) }

View File

@@ -6,34 +6,35 @@ module VariantUnits
describe OptionValueNamer do
describe "generating option value name" do
let(:v) { Spree::Variant.new }
let(:subject) { OptionValueNamer.new }
let(:p) { Spree::Product.new }
let(:subject) { OptionValueNamer.new(v) }
it "when description is blank" do
allow(v).to receive(:unit_description) { nil }
allow(subject).to receive(:value_scaled?) { true }
allow(subject).to receive(:option_value_value_unit) { %w(value unit) }
expect(subject.name(v)).to eq("valueunit")
expect(subject.name).to eq("valueunit")
end
it "when description is present" do
allow(v).to receive(:unit_description) { 'desc' }
allow(subject).to receive(:option_value_value_unit) { %w(value unit) }
allow(subject).to receive(:value_scaled?) { true }
expect(subject.name(v)).to eq("valueunit desc")
expect(subject.name).to eq("valueunit desc")
end
it "when value is blank and description is present" do
allow(v).to receive(:unit_description) { 'desc' }
allow(subject).to receive(:option_value_value_unit) { [nil, nil] }
allow(subject).to receive(:value_scaled?) { true }
expect(subject.name(v)).to eq("desc")
expect(subject.name).to eq("desc")
end
it "spaces value and unit when value is unscaled" do
allow(v).to receive(:unit_description) { nil }
allow(subject).to receive(:option_value_value_unit) { %w(value unit) }
allow(subject).to receive(:value_scaled?) { false }
expect(subject.name(v)).to eq("value unit")
expect(subject.name).to eq("value unit")
end
end

View File

@@ -249,7 +249,7 @@ describe '
}
let!(:li1) { create(:line_item_with_shipment, order: o1) }
let!(:li2) {
create(:line_item_with_shipment, order: o2, product: create(:product_with_option_types) )
create(:line_item_with_shipment, order: o2, product: create(:product) )
}
before :each do
@@ -428,8 +428,8 @@ describe '
end
let!(:p1) {
create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000,
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
create(:product, group_buy: true, group_buy_unit_size: 5000,
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
}
let!(:v1) { p1.variants.first }
let!(:o1) {
@@ -1068,8 +1068,8 @@ describe '
let!(:li1) { create(:line_item_with_shipment, order: o1 ) }
let!(:li2) { create(:line_item_with_shipment, order: o2 ) }
let!(:p3) {
create(:product_with_option_types, group_buy: true, group_buy_unit_size: 5000,
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
create(:product, group_buy: true, group_buy_unit_size: 5000,
variant_unit: "weight", variants: [create(:variant, unit_value: 1000)] )
}
let!(:v3) { p3.variants.first }
let!(:o3) {

View File

@@ -113,8 +113,7 @@ describe '
expect(product.shipping_category).to eq(shipping_category)
expect(product.description).to eq("<p>A description...</p>")
expect(product.group_buy).to be_falsey
expect(product.master.option_values.map(&:name)).to eq(['5kg'])
expect(product.master.options_text).to eq("5kg")
expect(product.master.unit_presentation).to eq("5kg")
end
it "creating an on-demand product" do

View File

@@ -237,12 +237,12 @@ describe "Orders And Fulfillment" do
table = rows.map { |r| r.all("td").map { |c| c.text.strip } }
expect(table).to include [
"Supplier Name", "Baked Beans", "1g Big, S",
"Supplier Name", "Baked Beans", "1g Big",
"3", "0.003", "10.0", "30.0"
]
expect(table).to include [
"Supplier Name", "Baked Beans", "1g Small, S",
"Supplier Name", "Baked Beans", "1g Small",
"7", "0.007", "10.0", "70.0"
]
expect(table[2]).to eq [

View File

@@ -380,8 +380,6 @@ describe '
variant2.update!(sku: "sku2")
variant3.on_hand = 9
variant3.update!(sku: "")
variant1.option_values = [create(:option_value, presentation: "Test")]
variant2.option_values = [create(:option_value, presentation: "Something")]
end
it "shows products and inventory report" do
@@ -399,12 +397,12 @@ describe '
expect(page).to have_table_row [product1.supplier.name, product1.supplier.address.city,
"Product Name",
product1.properties.map(&:presentation).join(", "),
product1.primary_taxon.name, "Test", "100.0",
product1.primary_taxon.name, "1g", "100.0",
"none", "", "sku1"]
expect(page).to have_table_row [product1.supplier.name, product1.supplier.address.city,
"Product Name",
product1.properties.map(&:presentation).join(", "),
product1.primary_taxon.name, "Something", "80.0",
product1.primary_taxon.name, "1g", "80.0",
"none", "", "sku2"]
expect(page).to have_table_row [product2.supplier.name, product1.supplier.address.city,
"Product 2",

View File

@@ -209,11 +209,11 @@ describe 'Subscriptions' do
}
let!(:test_product) { create(:product, supplier: shop) }
let!(:test_variant) {
create(:variant, product: test_product, unit_value: "100", price: 12.00, option_values: [])
create(:variant, product: test_product, unit_value: "100", price: 12.00)
}
let!(:shop_product) { create(:product, supplier: shop) }
let!(:shop_variant) {
create(:variant, product: shop_product, unit_value: "1000", price: 6.00, option_values: [])
create(:variant, product: shop_product, unit_value: "1000", price: 6.00)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle) {
@@ -453,13 +453,13 @@ describe 'Subscriptions' do
let!(:product2) { create(:product, supplier: shop) }
let!(:product3) { create(:product, supplier: shop) }
let!(:variant1) {
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
create(:variant, product: product1, unit_value: '100', price: 12.00)
}
let!(:variant2) {
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
create(:variant, product: product2, unit_value: '1000', price: 6.00)
}
let!(:variant3) {
create(:variant, product: product3, unit_value: '10000', price: 22.00, option_values: [])
create(:variant, product: product3, unit_value: '10000', price: 22.00)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle) {
@@ -606,10 +606,10 @@ describe 'Subscriptions' do
let!(:product1) { create(:product, supplier: shop) }
let!(:product2) { create(:product, supplier: shop) }
let!(:variant1) {
create(:variant, product: product1, unit_value: '100', price: 12.00, option_values: [])
create(:variant, product: product1, unit_value: '100', price: 12.00)
}
let!(:variant2) {
create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: [])
create(:variant, product: product2, unit_value: '1000', price: 6.00)
}
let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) }
let!(:order_cycle) {

View File

@@ -74,11 +74,6 @@ describe "
let!(:product_unrelated) { create(:simple_product, supplier: producer_unrelated) }
before do
# Remove 'S' option value
variant.option_values.first.destroy
end
context "when a hub is selected" do
before do
visit '/admin/inventory'

View File

@@ -127,9 +127,6 @@ describe '
variant = product.variants.first
variant.update( unit_value: 1, unit_description: 'foo' )
# And the product has option types for the unit-related and non-unit-related option values
product.option_types << variant.option_values.first.option_type
# When I view the variant
login_as_admin
visit spree.admin_product_variants_path product