diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index de77e31cd8..a1825eba7d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -11,7 +11,6 @@ # AllowedMethods: enums Lint/ConstantDefinitionInBlock: Exclude: - - 'spec/models/spree/preferences/preferable_spec.rb' - 'spec/validators/date_time_string_validator_spec.rb' - 'spec/validators/integer_array_validator_spec.rb' diff --git a/spec/models/spree/preferences/preferable_spec.rb b/spec/models/spree/preferences/preferable_spec.rb index f350c1a891..4cf412c392 100644 --- a/spec/models/spree/preferences/preferable_spec.rb +++ b/spec/models/spree/preferences/preferable_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' describe Spree::Preferences::Preferable do - before :all do - class A + a_class = A = + Class.new do include Spree::Preferences::Preferable attr_reader :id @@ -15,16 +15,38 @@ describe Spree::Preferences::Preferable do preference :color, :string, default: 'green', description: "My Favorite Color" end - class B < A + b_class = B = + Class.new(a_class) do preference :flavor, :string end - end - before :each do - @a = A.new - allow(@a).to receive_messages(persisted?: true) - @b = B.new - allow(@b).to receive_messages(persisted?: true) + let(:a) { a_class.new } + let(:b) { b_class.new } + + create_pref_test = + Class.new(ActiveRecord::Migration[4.2]) do + def self.up + create_table :pref_tests do |t| + t.string :col + end + end + + def self.down + drop_table :pref_tests + end + end + + pref_test_class = + Class.new(ApplicationRecord) do + self.table_name = 'pref_tests' + + preference :pref_test_pref, :string, default: 'abc' + preference :pref_test_any, :any, default: [] + end + + before do + allow(a).to receive_messages(persisted?: true) + allow(b).to receive_messages(persisted?: true) # ensure we're persisting as that is the default # @@ -34,235 +56,213 @@ describe Spree::Preferences::Preferable do describe "preference definitions" do it "parent should not see child definitions" do - expect(@a.has_preference?(:color)).to be_truthy - expect(@a.has_preference?(:flavor)).not_to be_truthy + expect(a.has_preference?(:color)).to be_truthy + expect(a.has_preference?(:flavor)).not_to be_truthy end it "child should have parent and own definitions" do - expect(@b.has_preference?(:color)).to be_truthy - expect(@b.has_preference?(:flavor)).to be_truthy + expect(b.has_preference?(:color)).to be_truthy + expect(b.has_preference?(:flavor)).to be_truthy end it "instances have defaults" do - expect(@a.preferred_color).to eq 'green' - expect(@b.preferred_color).to eq 'green' - expect(@b.preferred_flavor).to be_nil + expect(a.preferred_color).to eq 'green' + expect(b.preferred_color).to eq 'green' + expect(b.preferred_flavor).to be_nil end it "can be asked if it has a preference definition" do - expect(@a.has_preference?(:color)).to be_truthy - expect(@a.has_preference?(:bad)).to be_falsy + expect(a.has_preference?(:color)).to be_truthy + expect(a.has_preference?(:bad)).to be_falsy end it "can be asked and raises" do expect { - @a.has_preference! :flavor + a.has_preference! :flavor }.to raise_error(NoMethodError, "flavor preference not defined") end it "has a type" do - expect(@a.preferred_color_type).to eq :string - expect(@a.preference_type(:color)).to eq :string + expect(a.preferred_color_type).to eq :string + expect(a.preference_type(:color)).to eq :string end it "has a default" do - expect(@a.preferred_color_default).to eq 'green' - expect(@a.preference_default(:color)).to eq 'green' + expect(a.preferred_color_default).to eq 'green' + expect(a.preference_default(:color)).to eq 'green' end it "has a description" do - expect(@a.preferred_color_description).to eq "My Favorite Color" - expect(@a.preference_description(:color)).to eq "My Favorite Color" + expect(a.preferred_color_description).to eq "My Favorite Color" + expect(a.preference_description(:color)).to eq "My Favorite Color" end it "raises if not defined" do expect { - @a.get_preference :flavor + a.get_preference :flavor }.to raise_error(NoMethodError, "flavor preference not defined") end end describe "preference access" do it "handles ghost methods for preferences" do - @a.preferred_color = 'blue' - expect(@a.preferred_color).to eq 'blue' + a.preferred_color = 'blue' + expect(a.preferred_color).to eq 'blue' - @a.prefers_color = 'green' - expect(@a.prefers_color?).to eq 'green' + a.prefers_color = 'green' + expect(a.prefers_color?).to eq 'green' end it "has genric readers" do - @a.preferred_color = 'red' - expect(@a.prefers?(:color)).to eq 'red' - expect(@a.preferred(:color)).to eq 'red' + a.preferred_color = 'red' + expect(a.prefers?(:color)).to eq 'red' + expect(a.preferred(:color)).to eq 'red' end it "parent and child instances have their own prefs" do - @a.preferred_color = 'red' - @b.preferred_color = 'blue' + a.preferred_color = 'red' + b.preferred_color = 'blue' - expect(@a.preferred_color).to eq 'red' - expect(@b.preferred_color).to eq 'blue' + expect(a.preferred_color).to eq 'red' + expect(b.preferred_color).to eq 'blue' end it "raises when preference not defined" do expect { - @a.set_preference(:bad, :bone) + a.set_preference(:bad, :bone) }.to raise_exception(NoMethodError, "bad preference not defined") end it "builds a hash of preferences" do - @b.preferred_flavor = :strawberry - expect(@b.preferences[:flavor]).to eq 'strawberry' - expect(@b.preferences[:color]).to eq 'green' # default from A + b.preferred_flavor = :strawberry + expect(b.preferences[:flavor]).to eq 'strawberry' + expect(b.preferences[:color]).to eq 'green' # default from A end context "database fallback" do before do - @a.instance_variable_set("@pending_preferences", {}) + a.instance_variable_set("@pending_preferences", {}) end it "retrieves a preference from the database before falling back to default" do preference = double(value: "chatreuse", key: 'a/color/123') expect(Spree::Preference).to receive(:find_by).and_return(preference) - expect(@a.preferred_color).to eq 'chatreuse' + expect(a.preferred_color).to eq 'chatreuse' end it "defaults if no database key exists" do expect(Spree::Preference).to receive(:find_by).and_return(nil) - expect(@a.preferred_color).to eq 'green' + expect(a.preferred_color).to eq 'green' end end context "converts integer preferences to integer values" do before do - A.preference :is_integer, :integer + a_class.preference :is_integer, :integer end it "with strings" do - @a.set_preference(:is_integer, '3') - expect(@a.preferences[:is_integer]).to eq 3 + a.set_preference(:is_integer, '3') + expect(a.preferences[:is_integer]).to eq 3 - @a.set_preference(:is_integer, '') - expect(@a.preferences[:is_integer]).to eq 0 + a.set_preference(:is_integer, '') + expect(a.preferences[:is_integer]).to eq 0 end end context "converts decimal preferences to BigDecimal values" do before do - A.preference :if_decimal, :decimal + a_class.preference :if_decimal, :decimal end it "returns a BigDecimal" do - @a.set_preference(:if_decimal, 3.3) - expect(@a.preferences[:if_decimal].class).to eq BigDecimal + a.set_preference(:if_decimal, 3.3) + expect(a.preferences[:if_decimal].class).to eq BigDecimal end it "with strings" do - @a.set_preference(:if_decimal, '3.3') - expect(@a.preferences[:if_decimal]).to eq 3.3 + a.set_preference(:if_decimal, '3.3') + expect(a.preferences[:if_decimal]).to eq 3.3 - @a.set_preference(:if_decimal, '') - expect(@a.preferences[:if_decimal]).to eq 0.0 + a.set_preference(:if_decimal, '') + expect(a.preferences[:if_decimal]).to eq 0.0 end context "when the value cannot be converted to BigDecimal" do it "returns the original value" do - @a.set_preference(:if_decimal, "invalid") - expect(@a.preferences[:if_decimal]).to eq "invalid" + a.set_preference(:if_decimal, "invalid") + expect(a.preferences[:if_decimal]).to eq "invalid" end end end context "converts boolean preferences to boolean values" do before do - A.preference :is_boolean, :boolean, default: true + a_class.preference :is_boolean, :boolean, default: true end it "with strings" do - @a.set_preference(:is_boolean, '0') - expect(@a.preferences[:is_boolean]).to be_falsy - @a.set_preference(:is_boolean, 'f') - expect(@a.preferences[:is_boolean]).to be_falsy - @a.set_preference(:is_boolean, 't') - expect(@a.preferences[:is_boolean]).to be_truthy + a.set_preference(:is_boolean, '0') + expect(a.preferences[:is_boolean]).to be_falsy + a.set_preference(:is_boolean, 'f') + expect(a.preferences[:is_boolean]).to be_falsy + a.set_preference(:is_boolean, 't') + expect(a.preferences[:is_boolean]).to be_truthy end it "with integers" do - @a.set_preference(:is_boolean, 0) - expect(@a.preferences[:is_boolean]).to be_falsy - @a.set_preference(:is_boolean, 1) - expect(@a.preferences[:is_boolean]).to be_truthy + a.set_preference(:is_boolean, 0) + expect(a.preferences[:is_boolean]).to be_falsy + a.set_preference(:is_boolean, 1) + expect(a.preferences[:is_boolean]).to be_truthy end it "with an empty string" do - @a.set_preference(:is_boolean, '') - expect(@a.preferences[:is_boolean]).to be_falsy + a.set_preference(:is_boolean, '') + expect(a.preferences[:is_boolean]).to be_falsy end it "with an empty hash" do - @a.set_preference(:is_boolean, []) - expect(@a.preferences[:is_boolean]).to be_falsy + a.set_preference(:is_boolean, []) + expect(a.preferences[:is_boolean]).to be_falsy end end context "converts any preferences to any values" do before do - A.preference :product_ids, :any, default: [] - A.preference :product_attributes, :any, default: {} + a_class.preference :product_ids, :any, default: [] + a_class.preference :product_attributes, :any, default: {} end it "with array" do - expect(@a.preferences[:product_ids]).to eq [] - @a.set_preference(:product_ids, [1, 2]) - expect(@a.preferences[:product_ids]).to eq [1, 2] + expect(a.preferences[:product_ids]).to eq [] + a.set_preference(:product_ids, [1, 2]) + expect(a.preferences[:product_ids]).to eq [1, 2] end it "with hash" do - expect(@a.preferences[:product_attributes]).to eq({}) - @a.set_preference(:product_attributes, { id: 1, name: 2 }) + expect(a.preferences[:product_attributes]).to eq({}) + a.set_preference(:product_attributes, { id: 1, name: 2 }) attributes_hash = { id: 1, name: 2 } - expect(@a.preferences[:product_attributes]).to eq attributes_hash + expect(a.preferences[:product_attributes]).to eq attributes_hash end end end describe "persisted preferables" do before(:all) do - class CreatePrefTest < ActiveRecord::Migration[4.2] - def self.up - create_table :pref_tests do |t| - t.string :col - end - end - - def self.down - drop_table :pref_tests - end - end - - @migration_verbosity = ActiveRecord::Migration.verbose ActiveRecord::Migration.verbose = false - CreatePrefTest.migrate(:up) - - class PrefTest < ApplicationRecord - preference :pref_test_pref, :string, default: 'abc' - preference :pref_test_any, :any, default: [] - end + create_pref_test.migrate(:up) end after(:all) do - CreatePrefTest.migrate(:down) - ActiveRecord::Migration.verbose = @migration_verbosity - end - - before(:each) do - @pt = PrefTest.create + create_pref_test.migrate(:down) + ActiveRecord::Migration.verbose = true end describe "pending preferences for new activerecord objects" do it "saves preferences after record is saved" do - pr = PrefTest.new + pr = pref_test_class.new pr.set_preference(:pref_test_pref, 'XXX') expect(pr.get_preference(:pref_test_pref)).to eq 'XXX' pr.save! @@ -270,7 +270,7 @@ describe Spree::Preferences::Preferable do end it "saves preferences for serialized object" do - pr = PrefTest.new + pr = pref_test_class.new pr.set_preference(:pref_test_any, [1, 2]) expect(pr.get_preference(:pref_test_any)).to eq [1, 2] pr.save! @@ -280,7 +280,7 @@ describe Spree::Preferences::Preferable do describe "requires a valid id" do it "for cache_key" do - pref_test = PrefTest.new + pref_test = pref_test_class.new expect(pref_test.preference_cache_key(:pref_test_pref)).to be_nil pref_test.save @@ -288,46 +288,48 @@ describe Spree::Preferences::Preferable do end it "but returns default values" do - pref_test = PrefTest.new + pref_test = pref_test_class.new expect(pref_test.get_preference(:pref_test_pref)).to eq 'abc' end it "adds prefs in a pending hash until after_create" do - pref_test = PrefTest.new + pref_test = pref_test_class.new expect(pref_test).to receive(:add_pending_preference).with(:pref_test_pref, 'XXX') pref_test.set_preference(:pref_test_pref, 'XXX') end end + let!(:pt) { pref_test_class.create } + it "clear preferences" do - @pt.set_preference(:pref_test_pref, 'xyz') - expect(@pt.preferred_pref_test_pref).to eq 'xyz' - @pt.clear_preferences - expect(@pt.preferred_pref_test_pref).to eq 'abc' + pt.set_preference(:pref_test_pref, 'xyz') + expect(pt.preferred_pref_test_pref).to eq 'xyz' + pt.clear_preferences + expect(pt.preferred_pref_test_pref).to eq 'abc' end it "clear preferences when record is deleted" do - @pt.save! - @pt.preferred_pref_test_pref = 'lmn' - @pt.save! - @pt.destroy - @pt1 = PrefTest.new(col: 'aaaa') - @pt1.id = @pt.id - @pt1.save! - expect(@pt1.get_preference(:pref_test_pref)).not_to eq 'lmn' - expect(@pt1.get_preference(:pref_test_pref)).to eq 'abc' + pt.save! + pt.preferred_pref_test_pref = 'lmn' + pt.save! + pt.destroy + pt1 = pref_test_class.new(col: 'aaaa') + pt1.id = pt.id + pt1.save! + expect(pt1.get_preference(:pref_test_pref)).not_to eq 'lmn' + expect(pt1.get_preference(:pref_test_pref)).to eq 'abc' end end it "builds cache keys" do - expect(@a.preference_cache_key(:color)).to match %r{a/color/\d+} + expect(a.preference_cache_key(:color)).to match %r{a/color/\d+} end it "can add and remove preferences" do - A.preference :test_temp, :boolean, default: true - expect(@a.preferred_test_temp).to be_truthy - A.remove_preference :test_temp - expect(@a.has_preference?(:test_temp)).to be_falsy - expect(@a.respond_to?(:preferred_test_temp)).to be_falsy + a_class.preference :test_temp, :boolean, default: true + expect(a.preferred_test_temp).to be_truthy + a_class.remove_preference :test_temp + expect(a.has_preference?(:test_temp)).to be_falsy + expect(a.respond_to?(:preferred_test_temp)).to be_falsy end end