ledermann-rails-settings 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'scopes' do
4
+ let!(:user1) { User.create! :name => 'Mr. White' do |user| user.settings(:dashboard).theme = 'white' end }
5
+ let!(:user2) { User.create! :name => 'Mr. Blue' }
6
+
7
+ it "should find objects with existing settings" do
8
+ User.with_settings.should eq([user1])
9
+ end
10
+
11
+ it "should find objects with settings for key" do
12
+ User.with_settings_for(:dashboard).should eq([user1])
13
+ User.with_settings_for(:foo).should eq([])
14
+ end
15
+
16
+ it "should records without settings" do
17
+ User.without_settings.should eq([user2])
18
+ end
19
+
20
+ it "should records without settings for key" do
21
+ User.without_settings_for(:foo).should eq([user1, user2])
22
+ User.without_settings_for(:dashboard).should eq([user2])
23
+ end
24
+
25
+ it "should require symbol as key" do
26
+ [ nil, "string", 42 ].each do |invalid_key|
27
+ expect { User.without_settings_for(invalid_key) }.to raise_error(ArgumentError)
28
+ expect { User.with_settings_for(invalid_key) }.to raise_error(ArgumentError)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Serialization" do
4
+ let!(:user) do
5
+ User.create! :name => 'Mr. White' do |user|
6
+ user.settings(:dashboard).theme = 'white'
7
+ user.settings(:calendar).scope = 'all'
8
+ end
9
+ end
10
+
11
+ describe 'created settings' do
12
+ it 'should be serialized' do
13
+ user.reload
14
+
15
+ dashboard_settings = user.setting_objects.where(:var => 'dashboard').first
16
+ calendar_settings = user.setting_objects.where(:var => 'calendar').first
17
+
18
+ dashboard_settings.var.should == 'dashboard'
19
+ dashboard_settings.value.should eq({'theme' => 'white'})
20
+
21
+ calendar_settings.var.should == 'calendar'
22
+ calendar_settings.value.should eq({'scope' => 'all'})
23
+ end
24
+ end
25
+
26
+ describe 'updated settings' do
27
+ it 'should be serialized' do
28
+ user.settings(:dashboard).update_attributes! :smart => true
29
+
30
+ dashboard_settings = user.setting_objects.where(:var => 'dashboard').first
31
+ calendar_settings = user.setting_objects.where(:var => 'calendar').first
32
+
33
+ dashboard_settings.var.should == 'dashboard'
34
+ dashboard_settings.value.should eq({'theme' => 'white', 'smart' => true})
35
+
36
+ calendar_settings.var.should == 'calendar'
37
+ calendar_settings.value.should eq({'scope' => 'all'})
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsSettings::SettingObject do
4
+ let(:user) { User.create! :name => 'Mr. Pink' }
5
+ let(:new_setting_object) { user.setting_objects.build :var => 'dashboard' }
6
+ let(:saved_setting_object) { user.setting_objects.create! :var => 'dashboard', :value => { 'theme' => 'pink', 'filter' => true } }
7
+
8
+ describe "Getter and Setter" do
9
+ context "on unsaved settings" do
10
+ it "should respond to setters" do
11
+ new_setting_object.should respond_to(:foo=)
12
+ new_setting_object.should respond_to(:bar=)
13
+ end
14
+
15
+ it "should not respond to some getters" do
16
+ expect { new_setting_object.foo! }.to raise_error(NoMethodError)
17
+ expect { new_setting_object.foo? }.to raise_error(NoMethodError)
18
+ end
19
+
20
+ it "should not respond if a block is given" do
21
+ expect {
22
+ new_setting_object.foo do
23
+ end
24
+ }.to raise_error(NoMethodError)
25
+ end
26
+
27
+ it "should not respond if params are given" do
28
+ expect { new_setting_object.foo(42) }.to raise_error(NoMethodError)
29
+ expect { new_setting_object.foo(42,43) }.to raise_error(NoMethodError)
30
+ end
31
+
32
+ it "should return nil for unknown attribute" do
33
+ new_setting_object.foo.should eq(nil)
34
+ new_setting_object.bar.should eq(nil)
35
+ end
36
+
37
+ it "should return defaults" do
38
+ new_setting_object.theme.should eq('blue')
39
+ new_setting_object.view.should eq('monthly')
40
+ new_setting_object.filter.should eq(false)
41
+ end
42
+
43
+ it "should store to value hash" do
44
+ new_setting_object.foo = 42
45
+ new_setting_object.bar = 'hello'
46
+
47
+ new_setting_object.value.should eq({'foo' => 42, 'bar' => 'hello'})
48
+ end
49
+
50
+ it "should set and return attributes" do
51
+ new_setting_object.theme = 'pink'
52
+ new_setting_object.foo = 42
53
+ new_setting_object.bar = 'hello'
54
+
55
+ new_setting_object.theme.should eq('pink')
56
+ new_setting_object.foo.should eq(42)
57
+ new_setting_object.bar.should eq('hello')
58
+ end
59
+
60
+ it "should set dirty trackers on change" do
61
+ new_setting_object.theme = 'pink'
62
+ new_setting_object.should be_value_changed
63
+ new_setting_object.should be_changed
64
+ end
65
+ end
66
+
67
+ context "on saved settings" do
68
+ it "should not set dirty trackers on setting same value" do
69
+ saved_setting_object.theme = 'pink'
70
+ saved_setting_object.should_not be_value_changed
71
+ saved_setting_object.should_not be_changed
72
+ end
73
+
74
+ it "should delete key on assigning nil" do
75
+ saved_setting_object.theme = nil
76
+ saved_setting_object.value.should == { 'filter' => true }
77
+ end
78
+ end
79
+ end
80
+
81
+ describe "update_attributes" do
82
+ it 'should save' do
83
+ new_setting_object.update_attributes(:foo => 42, :bar => 'string').should be_true
84
+ new_setting_object.reload
85
+
86
+ new_setting_object.foo.should eq(42)
87
+ new_setting_object.bar.should eq('string')
88
+ new_setting_object.should_not be_new_record
89
+ new_setting_object.id.should_not be_zero
90
+ end
91
+
92
+ it 'should not save blank hash' do
93
+ new_setting_object.update_attributes({}).should be_false
94
+ end
95
+ end
96
+
97
+ describe "save" do
98
+ it "should save" do
99
+ new_setting_object.foo = 42
100
+ new_setting_object.bar = 'string'
101
+ new_setting_object.save.should be_true
102
+ new_setting_object.reload
103
+
104
+ new_setting_object.foo.should eq(42)
105
+ new_setting_object.bar.should eq('string')
106
+ new_setting_object.should_not be_new_record
107
+ new_setting_object.id.should_not be_zero
108
+ end
109
+ end
110
+
111
+ describe "validation" do
112
+ it "should not validate for unknown var" do
113
+ new_setting_object.var = "unknown-var"
114
+
115
+ new_setting_object.should_not be_valid
116
+ new_setting_object.errors[:var].should be_present
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,206 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Defaults" do
4
+ it "should be stored for simple class" do
5
+ Account.default_settings.should eq(:portal => {})
6
+ end
7
+
8
+ it "should be stored for parent class" do
9
+ User.default_settings.should eq(:dashboard => { 'theme' => 'blue', 'view' => 'monthly', 'filter' => false },
10
+ :calendar => { 'scope' => 'company'})
11
+ end
12
+
13
+ it "should be stored for child class" do
14
+ GuestUser.default_settings.should eq(:dashboard => { 'theme' => 'red', 'view' => 'monthly', 'filter' => false })
15
+ end
16
+ end
17
+
18
+ describe "Getter/Setter" do
19
+ let(:account) { Account.new :subdomain => 'foo' }
20
+
21
+ it "should handle method syntax" do
22
+ account.settings(:portal).enabled = true
23
+ account.settings(:portal).template = 'black'
24
+
25
+ account.settings(:portal).enabled.should eq(true)
26
+ account.settings(:portal).template.should eq('black')
27
+ end
28
+
29
+ it "should return nil for not existing key" do
30
+ account.settings(:portal).foo.should eq(nil)
31
+ end
32
+ end
33
+
34
+ describe 'Objects' do
35
+ context 'without defaults' do
36
+ let(:account) { Account.new :subdomain => 'foo' }
37
+
38
+ it 'should have blank settings' do
39
+ account.settings(:portal).value.should eq({})
40
+ end
41
+
42
+ it 'should not add settings on saving' do
43
+ account.save!
44
+ RailsSettings::SettingObject.count.should eq(0)
45
+ end
46
+
47
+ it "should save object with settings" do
48
+ account.settings(:portal).premium = true
49
+ account.settings(:portal).fee = 42.5
50
+ account.save!
51
+
52
+ account.reload
53
+ account.settings(:portal).premium.should eq(true)
54
+ account.settings(:portal).fee.should eq(42.5)
55
+
56
+ RailsSettings::SettingObject.count.should eq(1)
57
+ RailsSettings::SettingObject.first.value.should == { 'premium' => true, 'fee' => 42.5 }
58
+ end
59
+
60
+ it "should save settings separated" do
61
+ account.save!
62
+
63
+ settings = account.settings(:portal)
64
+ settings.enabled = true
65
+ settings.template = 'black'
66
+ settings.save!
67
+
68
+ account.reload
69
+ account.settings(:portal).enabled.should eq(true)
70
+ account.settings(:portal).template.should eq('black')
71
+ end
72
+ end
73
+
74
+ context 'with defaults' do
75
+ let(:user) { User.new :name => 'Mr. Brown' }
76
+
77
+ it 'should have default settings' do
78
+ user.settings(:dashboard).theme.should eq('blue')
79
+ user.settings(:dashboard).view.should eq('monthly')
80
+ user.settings(:dashboard).filter.should eq(false)
81
+ user.settings(:calendar).scope.should eq('company')
82
+ end
83
+
84
+ it 'should have default settings after changing one' do
85
+ user.settings(:dashboard).theme = 'gray'
86
+
87
+ user.settings(:dashboard).theme.should eq('gray')
88
+ user.settings(:dashboard).view.should eq('monthly')
89
+ user.settings(:dashboard).filter.should eq(false)
90
+ user.settings(:calendar).scope.should eq('company')
91
+ end
92
+
93
+ it "should overwrite settings" do
94
+ user.settings(:dashboard).theme = 'brown'
95
+ user.settings(:dashboard).filter = true
96
+ user.save!
97
+
98
+ user.reload
99
+ user.settings(:dashboard).theme.should eq('brown')
100
+ user.settings(:dashboard).filter.should eq(true)
101
+ RailsSettings::SettingObject.count.should eq(1)
102
+ RailsSettings::SettingObject.first.value.should == { 'theme' => 'brown', 'filter' => true }
103
+ end
104
+
105
+ it "should merge settings with defaults" do
106
+ user.settings(:dashboard).theme = 'brown'
107
+ user.save!
108
+
109
+ user.reload
110
+ user.settings(:dashboard).theme.should eq('brown')
111
+ user.settings(:dashboard).filter.should eq(false)
112
+ RailsSettings::SettingObject.count.should eq(1)
113
+ RailsSettings::SettingObject.first.value.should == { 'theme' => 'brown' }
114
+ end
115
+ end
116
+ end
117
+
118
+ describe "Object without settings" do
119
+ let!(:user) { User.create! :name => 'Mr. White' }
120
+
121
+ it "should respond to #settings?" do
122
+ user.settings?.should eq(false)
123
+ user.settings?(:dashboard).should eq(false)
124
+ end
125
+
126
+ it "should have no setting objects" do
127
+ RailsSettings::SettingObject.count.should eq(0)
128
+ end
129
+
130
+ it "should add settings" do
131
+ user.settings(:dashboard).update_attributes! :smart => true
132
+
133
+ user.reload
134
+ user.settings(:dashboard).smart.should eq(true)
135
+ end
136
+
137
+ it "should not save settings if assigned nil" do
138
+ expect {
139
+ user.settings = nil
140
+ user.save!
141
+ }.to_not change(RailsSettings::SettingObject, :count)
142
+ end
143
+ end
144
+
145
+ describe "Object with settings" do
146
+ let!(:user) do
147
+ User.create! :name => 'Mr. White' do |user|
148
+ user.settings(:dashboard).theme = 'white'
149
+ user.settings(:calendar).scope = 'all'
150
+ end
151
+ end
152
+
153
+ it "should respond to #settings?" do
154
+ user.settings?.should eq(true)
155
+
156
+ user.settings?(:dashboard).should eq(true)
157
+ user.settings?(:calendar).should eq(true)
158
+ end
159
+
160
+ it "should have two setting objects" do
161
+ RailsSettings::SettingObject.count.should eq(2)
162
+ end
163
+
164
+ it "should update settings" do
165
+ user.settings(:dashboard).update_attributes! :smart => true
166
+ user.reload
167
+
168
+ user.settings(:dashboard).smart.should eq(true)
169
+ user.settings(:dashboard).theme.should eq('white')
170
+ user.settings(:calendar).scope.should eq('all')
171
+ end
172
+
173
+ it "should update settings by saving object" do
174
+ user.settings(:dashboard).smart = true
175
+ user.save!
176
+
177
+ user.reload
178
+ user.settings(:dashboard).smart.should eq(true)
179
+ end
180
+
181
+ it "should destroy settings with nil" do
182
+ expect {
183
+ user.settings = nil
184
+ user.save!
185
+ }.to change(RailsSettings::SettingObject, :count).by(-2)
186
+
187
+ user.settings?.should == false
188
+ end
189
+ end
190
+
191
+ describe "Customized SettingObject" do
192
+ let(:project) { Project.create! :name => 'Heist' }
193
+
194
+ it "should not accept invalid attributes" do
195
+ project.settings(:info).owner_name = 42
196
+ project.settings(:info).should_not be_valid
197
+
198
+ project.settings(:info).owner_name = ''
199
+ project.settings(:info).should_not be_valid
200
+ end
201
+
202
+ it "should accept valid attributes" do
203
+ project.settings(:info).owner_name = 'Mr. Brown'
204
+ project.settings(:info).should be_valid
205
+ end
206
+ end
@@ -0,0 +1,90 @@
1
+ # Requires supporting ruby files with custom matchers and macros, etc,
2
+ # in spec/support/ and its subdirectories.
3
+ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}
4
+
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # Require this file using `require "spec_helper"` to ensure that it is only
8
+ # loaded once.
9
+ #
10
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
11
+ RSpec.configure do |config|
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ # config.order = 'random'
17
+
18
+ config.before(:each) do
19
+ clear_db
20
+ end
21
+ end
22
+
23
+ require 'active_record'
24
+ require 'rails-settings'
25
+
26
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
27
+ ActiveRecord::Migration.verbose = false
28
+
29
+ class User < ActiveRecord::Base
30
+ has_settings do |s|
31
+ s.key :dashboard, :defaults => { :theme => 'blue', :view => 'monthly', :filter => false }
32
+ s.key :calendar, :defaults => { :scope => 'company'}
33
+ end
34
+ end
35
+
36
+ class GuestUser < User
37
+ has_settings do |s|
38
+ s.key :dashboard, :defaults => { :theme => 'red', :view => 'monthly', :filter => false }
39
+ end
40
+ end
41
+
42
+ class Account < ActiveRecord::Base
43
+ has_settings :portal
44
+ end
45
+
46
+ class Project < ActiveRecord::Base
47
+ has_settings :info, :class_name => 'ProjectSettingObject'
48
+ end
49
+
50
+ class ProjectSettingObject < RailsSettings::SettingObject
51
+ validate do
52
+ unless self.owner_name.present? && self.owner_name.is_a?(String)
53
+ errors.add(:base, "Owner name is missing")
54
+ end
55
+ end
56
+ end
57
+
58
+ def setup_db
59
+ ActiveRecord::Schema.define(:version => 1) do
60
+ create_table :settings do |t|
61
+ t.string :var, :null => false
62
+ t.text :value, :null => false
63
+ t.references :target, :null => false, :polymorphic => true
64
+ t.timestamps
65
+ end
66
+ add_index :settings, [ :target_type, :target_id, :var ], :unique => true
67
+
68
+ create_table :users do |t|
69
+ t.string :type
70
+ t.string :name
71
+ end
72
+
73
+ create_table :accounts do |t|
74
+ t.string :subdomain
75
+ end
76
+
77
+ create_table :projects do |t|
78
+ t.string :name
79
+ end
80
+ end
81
+ end
82
+
83
+ def clear_db
84
+ User.delete_all
85
+ Account.delete_all
86
+ RailsSettings::SettingObject.delete_all
87
+ end
88
+
89
+ puts "Testing with ActiveRecord #{ActiveRecord::VERSION::STRING}"
90
+ setup_db