diff --git a/core/lib/spree/core/engine.rb b/core/lib/spree/core/engine.rb index d78893395f9..a3375ceaf31 100644 --- a/core/lib/spree/core/engine.rb +++ b/core/lib/spree/core/engine.rb @@ -87,6 +87,7 @@ class Engine < ::Rails::Engine config.after_initialize do Spree::Config.check_load_defaults_called('Spree::Config') + Spree::Config.static_model_preferences.validate! end config.after_initialize do diff --git a/core/lib/spree/preferences/static_model_preferences.rb b/core/lib/spree/preferences/static_model_preferences.rb index 6b213d801a6..0b0b5e782f3 100644 --- a/core/lib/spree/preferences/static_model_preferences.rb +++ b/core/lib/spree/preferences/static_model_preferences.rb @@ -7,13 +7,8 @@ class Definition attr_reader :preferences def initialize(klass, hash) - hash = hash.symbolize_keys - hash.keys.each do |key| - if !klass.defined_preferences.include?(key) - raise "Preference #{key.inspect} is not defined on #{klass}" - end - end - @preferences = hash + @klass = klass + @preferences = hash.symbolize_keys end def fetch(key, &block) @@ -27,20 +22,39 @@ def []=(key, value) def to_hash @preferences.deep_dup end + + delegate :keys, to: :@preferences end def initialize - @store = Hash.new do |data, klass| - data[klass] = {} - end + @store = {} end def add(klass, name, preferences) - @store[klass.to_s][name] = Definition.new(klass, preferences) + @store[klass.to_s] ||= {} + @store[klass.to_s][name] = Definition.new(klass.to_s, preferences) end def for_class(klass) - @store[klass.to_s] + @store[klass.to_s] || {} + end + + def validate! + @store.keys.map(&:constantize).each do |klass| + validate_for_class!(klass) + end + end + + private + + def validate_for_class!(klass) + for_class(klass).each do |name, preferences| + klass_keys = klass.defined_preferences.map(&:to_s) + extra_keys = preferences.keys.map(&:to_s) - klass_keys + next if extra_keys.empty? + + raise "Unexpected keys found for #{klass} under #{name}: #{extra_keys.to_sentence} (expected keys: #{klass_keys.to_sentence})" + end end end end diff --git a/core/spec/models/spree/preferences/static_model_preferences_spec.rb b/core/spec/models/spree/preferences/static_model_preferences_spec.rb index 9781a12d0f6..4628d9990bf 100644 --- a/core/spec/models/spree/preferences/static_model_preferences_spec.rb +++ b/core/spec/models/spree/preferences/static_model_preferences_spec.rb @@ -31,12 +31,6 @@ module Spree expect(definitions['my_definition'].fetch(:color)).to eq("blue") end - it "errors assigning invalid preferences" do - expect { - subject.add(preference_class, 'my_definition', { ice_cream: 'chocolate' }) - }.to raise_error(/\APreference :ice_cream is not defined/) - end - context "with stored definitions" do before do subject.add(preference_class, 'light', { color: 'white' }) @@ -83,5 +77,17 @@ module Spree expect(subject.for_class(other_class)).to be_empty end end + + describe '.validate!' do + it "errors assigning invalid preferences" do + subject.add(preference_class, 'my_definition', { ice_cream: 'chocolate' }) + + expect { + subject.validate! + }.to raise_error( + /\AUnexpected keys found for #{Regexp.escape preference_class.to_s} under my_definition: ice_cream \(expected keys: color\)/ + ) + end + end end end