ledermann-rails-settings 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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