preferences 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,14 +1,17 @@
1
1
  module Preferences
2
2
  # Represents the definition of a preference for a particular model
3
3
  class PreferenceDefinition
4
+ # The data type for the content stored in this preference type
5
+ attr_reader :type
6
+
4
7
  def initialize(name, *args) #:nodoc:
5
8
  options = args.extract_options!
6
9
  options.assert_valid_keys(:default)
7
10
 
8
- @type = args.first ? args.first.to_s : 'boolean'
11
+ @type = args.first ? args.first.to_sym : :boolean
9
12
 
10
13
  # Create a column that will be responsible for typecasting
11
- @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == 'any' ? nil : @type)
14
+ @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == :any ? nil : @type.to_s)
12
15
  end
13
16
 
14
17
  # The name of the preference
@@ -22,18 +25,23 @@ module Preferences
22
25
  @column.default
23
26
  end
24
27
 
28
+ # Determines whether column backing this preference stores numberic values
29
+ def number?
30
+ @column.number?
31
+ end
32
+
25
33
  # Typecasts the value based on the type of preference that was defined.
26
34
  # This uses ActiveRecord's typecast functionality so the same rules for
27
35
  # typecasting a model's columns apply here.
28
36
  def type_cast(value)
29
- @type == 'any' ? value : @column.type_cast(value)
37
+ @type == :any ? value : @column.type_cast(value)
30
38
  end
31
39
 
32
40
  # Typecasts the value to true/false depending on the type of preference
33
41
  def query(value)
34
42
  if !(value = type_cast(value))
35
43
  false
36
- elsif @column.number?
44
+ elsif number?
37
45
  !value.zero?
38
46
  else
39
47
  !value.blank?
@@ -1,7 +1,8 @@
1
1
  class User < ActiveRecord::Base
2
- preference :hot_salsa
3
- preference :dark_chocolate, :default => true
4
- preference :color, :string
5
- preference :car, :integer
6
- preference :language, :string, :default => 'English'
2
+ # preference :hot_salsa
3
+ # preference :dark_chocolate, :default => true
4
+ # preference :color, :string
5
+ # preference :car, :integer
6
+ # preference :language, :string, :default => 'English'
7
+ # preference :data, :any
7
8
  end
@@ -1,12 +1,12 @@
1
1
  class MigratePreferencesToVersion1 < ActiveRecord::Migration
2
2
  def self.up
3
- ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
3
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../generators/preferences/templates", 0).migrations.each do |migration|
4
4
  migration.migrate(:up)
5
5
  end
6
6
  end
7
7
 
8
8
  def self.down
9
- ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
9
+ ActiveRecord::Migrator.new(:down, "#{Rails.root}/../../generators/preferences/templates", 0).migrations.each do |migration|
10
10
  migration.migrate(:down)
11
11
  end
12
12
  end
@@ -1,10 +1,62 @@
1
- require "#{File.dirname(__FILE__)}/../test_helper"
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
2
 
3
- class PreferencesTest < ActiveSupport::TestCase
3
+ class ModelPreferenceTest < ActiveRecord::TestCase
4
+ def default_test
5
+ end
6
+
7
+ def teardown
8
+ User.preference_definitions.clear
9
+ User.default_preferences.clear
10
+ end
11
+ end
12
+
13
+ class ModelWithoutPreferencesTest < ActiveRecord::TestCase
14
+ def test_should_not_create_preference_definitions
15
+ assert !Car.respond_to?(:preference_definitions)
16
+ end
17
+
18
+ def test_should_not_create_default_preferences
19
+ assert !Car.respond_to?(:default_preferences)
20
+ end
21
+
22
+ def test_should_not_create_stored_preferences_association
23
+ assert !Car.new.respond_to?(:stored_preferences)
24
+ end
25
+
26
+ def test_should_not_create_preference_scopes
27
+ assert !Car.respond_to?(:with_preferences)
28
+ assert !Car.respond_to?(:without_preferences)
29
+ end
30
+ end
31
+
32
+ class PreferencesAfterFirstBeingDefinedTest < ModelPreferenceTest
4
33
  def setup
5
- User.preference :notifications, :boolean
6
-
7
- @user = User.new
34
+ User.preference :notifications
35
+ @user = new_user
36
+ end
37
+
38
+ def test_should_create_preference_definitions
39
+ assert User.respond_to?(:preference_definitions)
40
+ end
41
+
42
+ def test_should_create_default_preferences
43
+ assert User.respond_to?(:default_preferences)
44
+ end
45
+
46
+ def test_should_create_preference_scopes
47
+ assert User.respond_to?(:with_preferences)
48
+ assert User.respond_to?(:without_preferences)
49
+ end
50
+
51
+ def test_should_create_stored_preferences_associations
52
+ assert @user.respond_to?(:stored_preferences)
53
+ end
54
+ end
55
+
56
+ class PreferencesAfterBeingDefinedTest < ModelPreferenceTest
57
+ def setup
58
+ @definition = User.preference :notifications
59
+ @user = new_user
8
60
  end
9
61
 
10
62
  def test_should_raise_exception_if_invalid_options_specified
@@ -12,6 +64,11 @@ class PreferencesTest < ActiveSupport::TestCase
12
64
  assert_raise(ArgumentError) {User.preference :notifications, :boolean, :invalid => true}
13
65
  end
14
66
 
67
+ def test_should_create_definition
68
+ assert_not_nil @definition
69
+ assert_equal 'notifications', @definition.name
70
+ end
71
+
15
72
  def test_should_create_preferred_query_method
16
73
  assert @user.respond_to?(:preferred_notifications?)
17
74
  end
@@ -36,134 +93,167 @@ class PreferencesTest < ActiveSupport::TestCase
36
93
  assert @user.respond_to?(:prefers_notifications=)
37
94
  end
38
95
 
39
- def test_should_create_preference_definitions
40
- assert User.respond_to?(:preference_definitions)
96
+ def test_should_create_preferred_changed_query
97
+ assert @user.respond_to?(:preferred_notifications_changed?)
41
98
  end
42
99
 
43
- def test_should_create_default_preferences
44
- assert User.respond_to?(:default_preferences)
100
+ def test_should_create_prefers_changed_query
101
+ assert @user.respond_to?(:prefers_notifications_changed?)
102
+ end
103
+
104
+ def test_should_create_preferred_was
105
+ assert @user.respond_to?(:preferred_notifications_was)
106
+ end
107
+
108
+ def test_should_create_prefers_was
109
+ assert @user.respond_to?(:prefers_notifications_was)
110
+ end
111
+
112
+ def test_should_create_preferred_change
113
+ assert @user.respond_to?(:preferred_notifications_change)
114
+ end
115
+
116
+ def test_should_create_prefers_change
117
+ assert @user.respond_to?(:prefers_notifications_change)
118
+ end
119
+
120
+ def test_should_create_preferred_will_change
121
+ assert @user.respond_to?(:preferred_notifications_will_change!)
122
+ end
123
+
124
+ def test_should_create_prefers_will_change
125
+ assert @user.respond_to?(:prefers_notifications_will_change!)
126
+ end
127
+
128
+ def test_should_create_preferred_reset
129
+ assert @user.respond_to?(:reset_preferred_notifications!)
130
+ end
131
+
132
+ def test_should_create_prefers_reset
133
+ assert @user.respond_to?(:reset_prefers_notifications!)
45
134
  end
46
135
 
47
136
  def test_should_include_new_definitions_in_preference_definitions
48
- assert_not_nil User.preference_definitions['notifications']
137
+ assert_equal e = {'notifications' => @definition}, User.preference_definitions
49
138
  end
50
139
 
51
- def teardown
52
- User.preference_definitions.delete('notifications')
53
- User.default_preferences.delete('notifications')
140
+ def test_should_include_default_value_in_default_preferences
141
+ assert_equal e = {'notifications' => nil}, User.default_preferences
54
142
  end
55
143
  end
56
144
 
57
- class UserByDefaultTest < ActiveSupport::TestCase
145
+ class PreferencesByDefaultTest < ModelPreferenceTest
58
146
  def setup
59
- @user = User.new
147
+ @definition = User.preference :notifications
148
+ @user = new_user
60
149
  end
61
150
 
62
- def test_should_not_prefer_hot_salsa
63
- assert_nil @user.preferred_hot_salsa
64
- assert_nil @user.prefers_hot_salsa
151
+ def test_should_have_boolean_type
152
+ assert_equal :boolean, @definition.type
65
153
  end
66
154
 
67
- def test_should_prefer_dark_chocolate
68
- assert_equal true, @user.preferred_dark_chocolate
69
- assert_equal true, @user.prefers_dark_chocolate
155
+ def test_should_not_have_default_value
156
+ assert_nil @definition.default_value
70
157
  end
71
158
 
72
- def test_should_not_have_a_preferred_color
73
- assert_nil @user.preferred_color
159
+ def test_should_include_in_default_preferences
160
+ assert_equal e = {'notifications' => nil}, User.default_preferences
74
161
  end
75
162
 
76
- def test_should_not_have_a_preferred_car
77
- assert_nil @user.preferred_car
163
+ def test_should_only_have_default_preferences
164
+ assert_equal e = {'notifications' => nil}, @user.preferences
78
165
  end
79
166
 
80
- def test_should_have_a_preferred_language
81
- assert_equal 'English', @user.preferred_language
167
+ def test_should_not_query_preferences_changed
168
+ assert_equal false, @user.preferences_changed?
82
169
  end
83
170
 
84
- def test_should_have_only_default_preferences
85
- expected = {
86
- 'hot_salsa' => nil,
87
- 'dark_chocolate' => true,
88
- 'color' => nil,
89
- 'car' => nil,
90
- 'language' => 'English'
91
- }
92
-
93
- assert_equal expected, @user.preferences
171
+ def test_should_not_query_group_preferences_changed
172
+ assert_equal false, @user.preferences_changed?(:chat)
173
+ end
174
+
175
+ def test_should_not_have_preferences_changed
176
+ assert_equal [], @user.preferences_changed
177
+ end
178
+
179
+ def test_should_not_have_group_preferences_changed
180
+ assert_equal [], @user.preferences_changed(:chat)
181
+ end
182
+
183
+ def test_should_not_have_preference_changes
184
+ assert_equal e = {}, @user.preference_changes
185
+ end
186
+
187
+ def test_should_not_have_group_preference_changes
188
+ assert_equal e = {}, @user.preference_changes(:chat)
94
189
  end
95
190
  end
96
191
 
97
- class UserTest < ActiveSupport::TestCase
192
+ class PreferencesWithCustomTypeTest < ModelPreferenceTest
98
193
  def setup
194
+ @definition = User.preference :vehicle_id, :integer
99
195
  @user = new_user
100
196
  end
101
197
 
102
- def test_should_be_able_to_change_hot_salsa_preference
103
- @user.prefers_hot_salsa = false
104
- assert_equal false, @user.prefers_hot_salsa?
105
-
106
- @user.prefers_hot_salsa = true
107
- assert_equal true, @user.prefers_hot_salsa?
198
+ def test_should_have_boolean_type
199
+ assert_equal :integer, @definition.type
108
200
  end
109
201
 
110
- def test_should_be_able_to_change_dark_chocolate_preference
111
- @user.prefers_dark_chocolate = false
112
- assert_equal false, @user.prefers_dark_chocolate?
113
-
114
- @user.prefers_dark_chocolate = true
115
- assert_equal true, @user.prefers_dark_chocolate?
202
+ def test_should_not_have_default_value
203
+ assert_nil @definition.default_value
116
204
  end
117
205
 
118
- def test_should_be_able_to_change_color_preference
119
- @user.preferred_color = 'blue'
120
- assert_equal 'blue', @user.preferred_color
206
+ def test_should_include_in_default_preferences
207
+ assert_equal e = {'vehicle_id' => nil}, User.default_preferences
121
208
  end
122
209
 
123
- def test_should_be_able_to_change_car_preference
124
- @user.preferred_car = 1
125
- assert_equal 1, @user.preferred_car
210
+ def test_should_only_have_default_preferences
211
+ assert_equal e = {'vehicle_id' => nil}, @user.preferences
126
212
  end
127
-
128
- def test_should_be_able_to_change_language_preference
129
- @user.preferred_language = 'Latin'
130
- assert_equal 'Latin', @user.preferred_language
213
+ end
214
+
215
+ class PreferencesWithCustomDefaultTest < ModelPreferenceTest
216
+ def setup
217
+ @definition = User.preference :color, :string, :default => 'red'
218
+ @user = new_user
131
219
  end
132
220
 
133
- def test_should_be_able_to_use_generic_preferred_query_method
134
- @user.prefers_hot_salsa = true
135
- assert @user.preferred?(:hot_salsa)
221
+ def test_should_have_boolean_type
222
+ assert_equal :string, @definition.type
136
223
  end
137
224
 
138
- def test_should_be_able_to_use_generic_prefers_query_method
139
- @user.prefers_hot_salsa = true
140
- assert @user.prefers?(:hot_salsa)
225
+ def test_should_have_default_value
226
+ assert_equal 'red', @definition.default_value
141
227
  end
142
228
 
143
- def test_should_be_able_to_use_generic_preferred_method
144
- @user.preferred_color = 'blue'
145
- assert_equal 'blue', @user.preferred(:color)
229
+ def test_should_include_in_default_preferences
230
+ assert_equal e = {'color' => 'red'}, User.default_preferences
146
231
  end
147
232
 
148
- def test_should_be_able_to_use_generic_prefers_method
149
- @user.preferred_color = 'blue'
150
- assert_equal 'blue', @user.prefers(:color)
233
+ def test_should_only_have_default_preferences
234
+ assert_equal e = {'color' => 'red'}, @user.preferences
235
+ end
236
+ end
237
+
238
+ class PreferencesWithMultipleDefinitionsTest < ModelPreferenceTest
239
+ def setup
240
+ User.preference :notifications, :default => true
241
+ User.preference :color, :string, :default => 'red'
242
+ @user = new_user
151
243
  end
152
244
 
153
- def test_should_be_able_to_use_generic_set_preference_method
154
- @user.set_preference(:color, 'blue')
155
- assert_equal 'blue', @user.preferred(:color)
245
+ def test_should_include_all_in_default_preferences
246
+ assert_equal e = {'notifications' => true, 'color' => 'red'}, User.default_preferences
156
247
  end
157
248
 
158
- def test_should_still_be_new_record_after_changing_preference
159
- @user.preferred_color = 'blue'
160
- assert @user.new_record?
161
- assert @user.stored_preferences.empty?
249
+ def test_should_only_have_default_preferences
250
+ assert_equal e = {'notifications' => true, 'color' => 'red'}, @user.preferences
162
251
  end
163
252
  end
164
253
 
165
- class UserAfterBeingCreatedTest < ActiveSupport::TestCase
254
+ class PreferencesAfterBeingCreatedTest < ModelPreferenceTest
166
255
  def setup
256
+ User.preference :notifications, :default => true
167
257
  @user = create_user
168
258
  end
169
259
 
@@ -172,255 +262,1096 @@ class UserAfterBeingCreatedTest < ActiveSupport::TestCase
172
262
  end
173
263
  end
174
264
 
175
- class UserWithoutStoredPreferencesTest < ActiveSupport::TestCase
265
+ class PreferencesReaderTest < ModelPreferenceTest
176
266
  def setup
267
+ User.preference :notifications, :default => true
177
268
  @user = create_user
178
269
  end
179
270
 
180
- def test_should_not_prefer_hot_salsa
181
- assert_nil @user.preferred_hot_salsa
271
+ def test_should_raise_exception_if_invalid_preference_read
272
+ exception = assert_raise(ArgumentError) { @user.preferred(:invalid) }
273
+ assert_equal 'Unknown preference: invalid', exception.message
182
274
  end
183
275
 
184
- def test_should_prefer_dark_chocolate
185
- assert_equal true, @user.preferred_dark_chocolate
276
+ def test_use_default_value_if_not_stored
277
+ assert_equal true, @user.preferred(:notifications)
186
278
  end
187
279
 
188
- def test_should_not_have_a_preferred_color
189
- assert_nil @user.preferred_color
280
+ def test_should_use_stored_value_if_stored
281
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
282
+ assert_equal false, @user.preferred(:notifications)
190
283
  end
191
284
 
192
- def test_should_not_have_a_preferred_car
193
- assert_nil @user.preferred_car
285
+ def test_should_type_cast_based_on_preference_definition
286
+ @user.write_preference(:notifications, 'false')
287
+ assert_equal false, @user.preferred(:notifications)
194
288
  end
195
289
 
196
- def test_should_have_a_preferred_language
197
- assert_equal 'English', @user.preferred_language
290
+ def test_should_cache_stored_values
291
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
292
+ assert_queries(1) { @user.preferred(:notifications) }
293
+ assert_queries(0) { @user.preferred(:notifications) }
198
294
  end
199
295
 
200
- def test_should_not_save_record_after_changing_preference
201
- @user.preferred_language = 'Latin'
296
+ def test_should_not_query_if_preferences_already_loaded
297
+ @user.preferences
298
+ assert_queries(0) { @user.preferred(:notifications) }
299
+ end
300
+
301
+ def test_should_use_value_from_preferences_lookup
302
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
303
+ @user.preferences
202
304
 
203
- user = User.find(@user.id)
204
- assert_equal 'English', user.preferred_language
205
- assert user.stored_preferences.empty?
305
+ assert_queries(0) { assert_equal false, @user.preferred(:notifications) }
306
+ end
307
+
308
+ def test_should_be_able_to_use_prefers_reader
309
+ assert_equal true, @user.prefers_notifications
310
+ end
311
+
312
+ def test_should_be_able_to_use_preferred_reader
313
+ assert_equal true, @user.preferred_notifications
206
314
  end
207
315
  end
208
316
 
209
- class UserWithStoredPreferencesTest < ActiveSupport::TestCase
317
+ class PreferencesGroupReaderTest < ModelPreferenceTest
210
318
  def setup
319
+ User.preference :notifications, :default => true
211
320
  @user = create_user
212
- @user.preferred_language = 'Latin'
213
- @user.save!
214
321
  end
215
322
 
216
- def test_should_have_stored_preferences
217
- assert_equal 1, @user.stored_preferences.size
323
+ def test_use_default_value_if_not_stored
324
+ assert_equal true, @user.preferred(:notifications, :chat)
325
+ end
326
+
327
+ def test_should_use_stored_value_if_stored
328
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
329
+ assert_equal false, @user.preferred(:notifications, :chat)
330
+ end
331
+
332
+ def test_should_cache_stored_values
333
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
334
+ assert_queries(1) { @user.preferred(:notifications, :chat) }
335
+ assert_queries(0) { @user.preferred(:notifications, :chat) }
336
+ end
337
+
338
+ def test_should_not_query_if_preferences_already_loaded
339
+ @user.preferences(:chat)
340
+ assert_queries(0) { @user.preferred(:notifications, :chat) }
218
341
  end
219
342
 
220
- def test_should_include_custom_and_default_preferences_in_preferences
221
- expected = {
222
- 'hot_salsa' => nil,
223
- 'dark_chocolate' => true,
224
- 'color' => nil,
225
- 'car' => nil,
226
- 'language' => 'Latin'
227
- }
343
+ def test_should_use_value_from_preferences_lookup
344
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
345
+ @user.preferences(:chat)
228
346
 
229
- assert_equal expected, @user.preferences
347
+ assert_queries(0) { assert_equal false, @user.preferred(:notifications, :chat) }
230
348
  end
231
349
 
232
- def test_should_use_preferences_for_prefs
233
- expected = {
234
- 'hot_salsa' => nil,
235
- 'dark_chocolate' => true,
236
- 'color' => nil,
237
- 'car' => nil,
238
- 'language' => 'Latin'
239
- }
350
+ def test_should_be_able_to_use_prefers_reader
351
+ assert_equal true, @user.prefers_notifications(:chat)
352
+ end
353
+
354
+ def test_should_be_able_to_use_preferred_reader
355
+ assert_equal true, @user.preferred_notifications(:chat)
356
+ end
357
+ end
358
+
359
+ class PreferencesARGroupReaderTest < ModelPreferenceTest
360
+ def setup
361
+ @car = create_car
240
362
 
241
- assert_equal expected, @user.prefs
363
+ User.preference :notifications, :default => true
364
+ @user = create_user
242
365
  end
243
366
 
244
- def test_should_not_remove_preference_if_set_to_default
245
- @user.preferred_language = 'English'
246
- @user.save!
247
- @user.reload
248
- assert_equal 1, @user.stored_preferences.size
367
+ def test_use_default_value_if_not_stored
368
+ assert_equal true, @user.preferred(:notifications, @car)
249
369
  end
250
370
 
251
- def test_should_not_remove_preference_if_set_to_nil
252
- @user.preferred_language = nil
253
- @user.save!
254
- @user.reload
255
- assert_equal 1, @user.stored_preferences.size
371
+ def test_should_use_stored_value_if_stored
372
+ create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false)
373
+ assert_equal false, @user.preferred(:notifications, @car)
256
374
  end
257
375
 
258
- def test_should_not_save_preference_if_model_is_not_saved
259
- @user.preferred_language = 'English'
376
+ def test_should_use_value_from_preferences_lookup
377
+ create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false)
378
+ @user.preferences(@car)
260
379
 
261
- user = User.find(@user.id)
262
- assert_equal 'Latin', user.preferred_language
380
+ assert_queries(0) { assert_equal false, @user.preferred(:notifications, @car) }
263
381
  end
264
382
 
265
- def test_should_modify_existing_preferences_when_saved
266
- @user.preferred_language = 'Spanish'
267
- assert @user.save
268
-
269
- @user.reload
270
- assert_equal 'Spanish', @user.preferred_language
271
- assert_equal 1, @user.stored_preferences.size
383
+ def test_should_be_able_to_use_prefers_reader
384
+ assert_equal true, @user.prefers_notifications(@car)
272
385
  end
273
386
 
274
- def test_should_add_new_preferences_when_saved
275
- @user.preferred_color = 'blue'
276
- assert @user.save
277
-
278
- @user.reload
279
- assert_equal 'blue', @user.preferred_color
280
- assert_equal 2, @user.stored_preferences.size
387
+ def test_should_be_able_to_use_preferred_reader
388
+ assert_equal true, @user.preferred_notifications(@car)
281
389
  end
282
390
  end
283
391
 
284
- class UserWithStoredPreferencesForBasicGroupsTest < ActiveSupport::TestCase
392
+ class PreferencesQueryTest < ModelPreferenceTest
285
393
  def setup
394
+ User.preference :language, :string
286
395
  @user = create_user
287
- @user.preferred_color = 'red', 'cars'
288
- @user.save!
289
396
  end
290
397
 
291
- def test_should_have_stored_preferences
292
- assert_equal 1, @user.stored_preferences.size
398
+ def test_should_raise_exception_if_invalid_preference_queried
399
+ exception = assert_raise(ArgumentError) { @user.preferred?(:invalid) }
400
+ assert_equal 'Unknown preference: invalid', exception.message
401
+ end
402
+
403
+ def test_should_be_true_if_present
404
+ @user.preferred_language = 'English'
405
+ assert_equal true, @user.preferred?(:language)
406
+ end
407
+
408
+ def test_should_be_false_if_not_present
409
+ assert_equal false, @user.preferred?(:language)
410
+ end
411
+
412
+ def test_should_use_stored_value_if_stored
413
+ create_preference(:owner => @user, :name => 'language', :value => 'English')
414
+ assert_equal true, @user.preferred?(:language)
293
415
  end
294
416
 
295
- def test_should_include_group_in_preferences
296
- expected = {
297
- 'hot_salsa' => nil,
298
- 'dark_chocolate' => true,
299
- 'color' => nil,
300
- 'car' => nil,
301
- 'language' => 'English',
302
- 'cars' => {
303
- 'hot_salsa' => nil,
304
- 'dark_chocolate' => true,
305
- 'color' => 'red',
306
- 'car' => nil,
307
- 'language' => 'English'
308
- }
309
- }
417
+ def test_should_cache_stored_values
418
+ create_preference(:owner => @user, :name => 'language', :value => 'English')
419
+ assert_queries(1) { @user.preferred?(:language) }
420
+ assert_queries(0) { @user.preferred?(:language) }
421
+ end
422
+
423
+ def test_should_be_able_to_use_prefers_reader
424
+ assert_equal false, @user.prefers_language?
425
+ end
426
+
427
+ def test_should_be_able_to_use_preferred_reader
428
+ assert_equal false, @user.preferred_language?
429
+ end
430
+ end
431
+
432
+ class PreferencesGroupQueryTest < ModelPreferenceTest
433
+ def setup
434
+ User.preference :language, :string
435
+ @user = create_user
436
+ end
437
+
438
+ def test_should_be_true_if_present
439
+ @user.preferred_language = 'English', :chat
440
+ assert_equal true, @user.preferred?(:language, :chat)
441
+ end
442
+
443
+ def test_should_be_false_if_not_present
444
+ assert_equal false, @user.preferred?(:language, :chat)
445
+ end
446
+
447
+ def test_should_use_stored_value_if_stored
448
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'language', :value => 'English')
449
+ assert_equal true, @user.preferred?(:language, :chat)
450
+ end
451
+
452
+ def test_should_cache_stored_values
453
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'language', :value => 'English')
454
+ assert_queries(1) { @user.preferred?(:language, :chat) }
455
+ assert_queries(0) { @user.preferred?(:language, :chat) }
456
+ end
457
+
458
+ def test_should_be_able_to_use_prefers_reader
459
+ assert_equal false, @user.prefers_language?(:chat)
460
+ end
461
+
462
+ def test_should_be_able_to_use_preferred_reader
463
+ assert_equal false, @user.preferred_language?(:chat)
464
+ end
465
+ end
466
+
467
+ class PreferencesARGroupQueryTest < ModelPreferenceTest
468
+ def setup
469
+ @car = create_car
470
+
471
+ User.preference :language, :string
472
+ @user = create_user
473
+ end
474
+
475
+ def test_should_be_true_if_present
476
+ @user.preferred_language = 'English', @car
477
+ assert_equal true, @user.preferred?(:language, @car)
478
+ end
479
+
480
+ def test_should_be_false_if_not_present
481
+ assert_equal false, @user.preferred?(:language, @car)
482
+ end
483
+
484
+ def test_should_use_stored_value_if_stored
485
+ create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'language', :value => 'English')
486
+ assert_equal true, @user.preferred?(:language, @car)
487
+ end
488
+
489
+ def test_should_be_able_to_use_prefers_reader
490
+ assert_equal false, @user.prefers_language?(@car)
491
+ end
492
+
493
+ def test_should_be_able_to_use_preferred_reader
494
+ assert_equal false, @user.preferred_language?(@car)
495
+ end
496
+ end
497
+
498
+ class PreferencesWriterTest < ModelPreferenceTest
499
+ def setup
500
+ User.preference :notifications, :boolean, :default => true
501
+ User.preference :language, :string, :default => 'English'
502
+ @user = create_user(:login => 'admin')
503
+ end
504
+
505
+ def test_should_raise_exception_if_invalid_preference_written
506
+ exception = assert_raise(ArgumentError) { @user.write_preference(:invalid, true) }
507
+ assert_equal 'Unknown preference: invalid', exception.message
508
+ end
509
+
510
+ def test_should_have_same_value_if_not_changed
511
+ @user.write_preference(:notifications, true)
512
+ assert_equal true, @user.preferred(:notifications)
513
+ end
514
+
515
+ def test_should_use_new_value_if_changed
516
+ @user.write_preference(:notifications, false)
517
+ assert_equal false, @user.preferred(:notifications)
518
+ end
519
+
520
+ def test_should_not_save_record_after_changing_preference
521
+ @user.login = 'test'
522
+ @user.write_preference(:notifications, false)
523
+
524
+ assert_equal 'admin', User.find(@user.id).login
525
+ end
526
+
527
+ def test_should_not_create_stored_preferences_immediately
528
+ @user.write_preference(:notifications, false)
529
+ assert @user.stored_preferences.empty?
530
+ end
531
+
532
+ def test_should_not_create_stored_preference_if_value_not_changed
533
+ @user.write_preference(:notifications, true)
534
+ @user.save!
310
535
 
311
- assert_equal expected, @user.preferences
536
+ assert_equal 0, @user.stored_preferences.count
312
537
  end
313
538
 
314
- def test_should_be_able_to_show_all_preferences_just_for_the_owner
315
- expected = {
316
- 'hot_salsa' => nil,
317
- 'dark_chocolate' => true,
318
- 'color' => nil,
319
- 'car' => nil,
320
- 'language' => 'English'
321
- }
539
+ def test_should_not_create_stored_integer_preference_if_typecast_not_changed
540
+ User.preference :age, :integer
541
+
542
+ @user.write_preference(:age, '')
543
+ @user.save!
322
544
 
323
- assert_equal expected, @user.preferences(nil)
545
+ assert_equal 0, @user.stored_preferences.count
324
546
  end
325
547
 
326
- def test_should_be_able_to_show_all_preferences_for_a_single_group
327
- expected = {
328
- 'hot_salsa' => nil,
329
- 'dark_chocolate' => true,
330
- 'color' => 'red',
331
- 'car' => nil,
332
- 'language' => 'English'
333
- }
548
+ def test_should_create_stored_integer_preference_if_typecast_changed
549
+ User.preference :age, :integer, :default => 0
334
550
 
335
- assert_equal expected, @user.preferences('cars')
551
+ @user.write_preference(:age, '')
552
+ @user.save!
553
+
554
+ assert_nil @user.preferred(:age)
555
+ assert_equal 1, @user.stored_preferences.count
336
556
  end
337
557
 
338
- def test_should_not_have_preference_without_group
339
- assert_nil @user.preferred_color
558
+ def test_should_create_stored_preference_if_value_changed
559
+ @user.write_preference(:notifications, false)
560
+ @user.save!
561
+
562
+ assert_equal 1, @user.stored_preferences.count
340
563
  end
341
564
 
342
- def test_should_have_preference_with_group
343
- assert_equal 'red', @user.preferred_color('cars')
565
+ def test_should_overwrite_existing_stored_preference_if_value_changed
566
+ preference = create_preference(:owner => @user, :name => 'notifications', :value => true)
567
+
568
+ @user.write_preference(:notifications, false)
569
+ @user.save!
570
+
571
+ preference.reload
572
+ assert_equal false, preference.value
344
573
  end
345
574
 
346
- def test_should_modify_existing_preferences_when_saved
347
- @user.preferred_color = 'blue', 'cars'
348
- assert @user.save
575
+ def test_should_not_remove_preference_if_set_to_default
576
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
349
577
 
578
+ @user.write_preference(:notifications, true)
579
+ @user.save!
350
580
  @user.reload
351
- assert_equal 'blue', @user.preferred_color('cars')
581
+
352
582
  assert_equal 1, @user.stored_preferences.size
583
+ preference = @user.stored_preferences.first
584
+ assert_equal true, preference.value
353
585
  end
354
586
 
355
- def test_should_be_able_to_differentiate_between_groups
356
- @user.preferred_color = 'blue', 'boats'
357
- assert @user.save
587
+ def test_should_not_remove_preference_if_set_to_nil
588
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
358
589
 
590
+ @user.write_preference(:notifications, nil)
591
+ @user.save!
359
592
  @user.reload
360
- assert_equal 'red', @user.preferred_color('cars')
361
- assert_equal 'blue', @user.preferred_color('boats')
362
- assert_equal 2, @user.stored_preferences.size
593
+
594
+ assert_equal 1, @user.stored_preferences.size
595
+ preference = @user.stored_preferences.first
596
+ assert_nil preference.value
597
+ end
598
+
599
+ def test_should_not_query_for_old_value_if_preferences_loaded
600
+ @user.preferences
601
+
602
+ assert_queries(0) { @user.write_preference(:notifications, false) }
363
603
  end
364
604
  end
365
605
 
366
- class UserWithStoredPreferencesForActiveRecordGroupsTest < ActiveSupport::TestCase
606
+ class PreferencesGroupWriterTest < ModelPreferenceTest
367
607
  def setup
368
- @car = create_car
608
+ User.preference :notifications, :boolean, :default => true
609
+ User.preference :language, :string, :default => 'English'
610
+ @user = create_user(:login => 'admin')
611
+ end
612
+
613
+ def test_should_have_same_value_if_not_changed
614
+ @user.write_preference(:notifications, true, :chat)
615
+ assert_equal true, @user.preferred(:notifications, :chat)
616
+ end
617
+
618
+ def test_should_use_new_value_if_changed
619
+ @user.write_preference(:notifications, false, :chat)
620
+ assert_equal false, @user.preferred(:notifications, :chat)
621
+ end
622
+
623
+ def test_should_not_create_stored_preference_if_value_not_changed
624
+ @user.write_preference(:notifications, true, :chat)
625
+ @user.save!
369
626
 
370
- @user = create_user
371
- @user.preferred_color = 'red', @car
627
+ assert_equal 0, @user.stored_preferences.count
628
+ end
629
+
630
+ def test_should_create_stored_preference_if_value_changed
631
+ @user.write_preference(:notifications, false, :chat)
372
632
  @user.save!
633
+
634
+ assert_equal 1, @user.stored_preferences.count
373
635
  end
374
636
 
375
- def test_should_have_stored_preferences
376
- assert_equal 1, @user.stored_preferences.size
637
+ def test_should_set_group_attributes_on_stored_preferences
638
+ @user.write_preference(:notifications, false, :chat)
639
+ @user.save!
640
+
641
+ preference = @user.stored_preferences.first
642
+ assert_equal 'chat', preference.group_type
643
+ assert_nil preference.group_id
377
644
  end
378
645
 
379
- def test_should_have_preferences_for_group
380
- expected = {
381
- 'hot_salsa' => nil,
382
- 'dark_chocolate' => true,
383
- 'color' => nil,
384
- 'car' => nil,
385
- 'language' => 'English',
386
- @car => {
387
- 'hot_salsa' => nil,
388
- 'dark_chocolate' => true,
389
- 'color' => 'red',
390
- 'car' => nil,
391
- 'language' => 'English'
392
- }
393
- }
646
+ def test_should_overwrite_existing_stored_preference_if_value_changed
647
+ preference = create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => true)
648
+
649
+ @user.write_preference(:notifications, false, :chat)
650
+ @user.save!
651
+
652
+ preference.reload
653
+ assert_equal false, preference.value
654
+ end
655
+ end
656
+
657
+ class PreferencesARGroupWriterTest < ModelPreferenceTest
658
+ def setup
659
+ @car = create_car
394
660
 
395
- assert_equal expected, @user.preferences
661
+ User.preference :notifications, :boolean, :default => true
662
+ User.preference :language, :string, :default => 'English'
663
+ @user = create_user(:login => 'admin')
396
664
  end
397
665
 
398
- def test_should_not_have_preference_without_group
399
- assert_nil @user.preferred_color
666
+ def test_should_have_same_value_if_not_changed
667
+ @user.write_preference(:notifications, true, @car)
668
+ assert_equal true, @user.preferred(:notifications, @car)
400
669
  end
401
670
 
402
- def test_should_have_preference_with_group
403
- assert_equal 'red', @user.preferred_color(@car)
671
+ def test_should_use_new_value_if_changed
672
+ @user.write_preference(:notifications, false, @car)
673
+ assert_equal false, @user.preferred(:notifications, @car)
404
674
  end
405
675
 
406
- def test_should_modify_existing_preferences_when_saved
407
- @user.preferred_color = 'blue', @car
408
- assert @user.save
676
+ def test_should_not_create_stored_preference_if_value_not_changed
677
+ @user.write_preference(:notifications, true, @car)
678
+ @user.save!
409
679
 
410
- @user.reload
411
- assert_equal 'blue', @user.preferred_color(@car)
412
- assert_equal 1, @user.stored_preferences.size
680
+ assert_equal 0, @user.stored_preferences.count
413
681
  end
414
682
 
415
- def test_should_be_able_to_differentiate_between_groups
416
- @different_car = create_car
683
+ def test_should_create_stored_preference_if_value_changed
684
+ @user.write_preference(:notifications, false, @car)
685
+ @user.save!
417
686
 
418
- @user.preferred_color = 'blue', @different_car
419
- assert @user.save
687
+ assert_equal 1, @user.stored_preferences.count
688
+ end
689
+
690
+ def test_should_set_group_attributes_on_stored_preferences
691
+ @user.write_preference(:notifications, false, @car)
692
+ @user.save!
420
693
 
421
- @user.reload
422
- assert_equal 'red', @user.preferred_color(@car)
423
- assert_equal 'blue', @user.preferred_color(@different_car)
424
- assert_equal 2, @user.stored_preferences.size
694
+ preference = @user.stored_preferences.first
695
+ assert_equal 'Car', preference.group_type
696
+ assert_equal @car.id, preference.group_id
697
+ end
698
+ end
699
+
700
+ class PreferencesAfterChangingPreferenceTest < ModelPreferenceTest
701
+ def setup
702
+ User.preference :notifications, :boolean, :default => true
703
+ User.preference :language, :string, :default => 'English'
704
+ @user = create_user
705
+
706
+ @user.write_preference(:notifications, false)
707
+ end
708
+
709
+ def test_should_query_preferences_changed
710
+ assert_equal true, @user.preferences_changed?
711
+ end
712
+
713
+ def test_should_query_preference_changed
714
+ assert_equal true, @user.prefers_notifications_changed?
715
+ end
716
+
717
+ def test_should_not_query_preferences_changed_for_group
718
+ assert_equal false, @user.preferences_changed?(:chat)
719
+ end
720
+
721
+ def test_should_not_query_preference_changed_for_group
722
+ assert_equal false, @user.prefers_notifications_changed?(:chat)
723
+ end
724
+
725
+ def test_should_have_preferences_changed
726
+ assert_equal ['notifications'], @user.preferences_changed
727
+ end
728
+
729
+ def test_should_not_build_same_preferences_changed_result
730
+ assert_not_same @user.preferences_changed, @user.preferences_changed
731
+ end
732
+
733
+ def test_should_not_have_preferences_changed_for_group
734
+ assert_equal [], @user.preferences_changed(:chat)
735
+ end
736
+
737
+ def test_should_track_multiple_preferences_changed
738
+ @user.write_preference(:language, 'Latin')
739
+ assert_equal ['language', 'notifications'], @user.preferences_changed.sort
740
+ end
741
+
742
+ def test_should_have_preference_changes
743
+ assert_equal e = {'notifications' => [true, false]}, @user.preference_changes
744
+ end
745
+
746
+ def test_should_not_build_same_preference_changes_result
747
+ assert_not_same @user.preference_changes, @user.preference_changes
748
+ end
749
+
750
+ def test_should_have_preference_change
751
+ assert_equal [true, false], @user.prefers_notifications_change
752
+ end
753
+
754
+ def test_should_have_preference_was
755
+ assert_equal true, @user.prefers_notifications_was
756
+ end
757
+
758
+ def test_should_not_have_preference_changes_for_group
759
+ assert_equal e = {}, @user.preference_changes(:chat)
760
+ end
761
+
762
+ def test_should_not_have_preference_change_for_group
763
+ assert_nil @user.prefers_notifications_change(:chat)
764
+ end
765
+
766
+ def test_should_have_preference_was_for_group
767
+ assert_equal true, @user.prefers_notifications_was(:chat)
768
+ end
769
+
770
+ def test_should_use_latest_value_for_preference_changes
771
+ @user.write_preference(:notifications, nil)
772
+ assert_equal e = {'notifications' => [true, nil]}, @user.preference_changes
773
+ end
774
+
775
+ def test_should_use_cloned_old_value_for_preference_changes
776
+ old_value = @user.preferred(:language)
777
+ @user.write_preference(:language, 'Latin')
778
+
779
+ tracked_old_value = @user.preference_changes['language'][0]
780
+ assert_equal old_value, tracked_old_value
781
+ assert_not_same old_value, tracked_old_value
782
+ end
783
+
784
+ def test_should_track_multiple_preference_changes
785
+ @user.write_preference(:language, 'Latin')
786
+ assert_equal e = {'notifications' => [true, false], 'language' => ['English', 'Latin']}, @user.preference_changes
787
+ end
788
+ end
789
+
790
+ class PreferencesAfterChangingGroupPreferenceTest < ModelPreferenceTest
791
+ def setup
792
+ User.preference :notifications, :boolean, :default => true
793
+ User.preference :language, :string, :default => 'English'
794
+ @user = create_user
795
+
796
+ @user.write_preference(:notifications, false, :chat)
797
+ end
798
+
799
+ def test_should_not_query_preferences_changed
800
+ assert_equal false, @user.preferences_changed?
801
+ end
802
+
803
+ def test_not_should_query_preference_changed
804
+ assert_equal false, @user.prefers_notifications_changed?
805
+ end
806
+
807
+ def test_should_query_preferences_changed_for_group
808
+ assert_equal true, @user.preferences_changed?(:chat)
809
+ end
810
+
811
+ def test_should_query_preference_changed_for_group
812
+ assert_equal true, @user.prefers_notifications_changed?(:chat)
813
+ end
814
+
815
+ def test_should_have_preferences_changed
816
+ assert_equal [], @user.preferences_changed
817
+ end
818
+
819
+ def test_should_not_have_preferences_changed_for_group
820
+ assert_equal ['notifications'], @user.preferences_changed(:chat)
821
+ end
822
+
823
+ def test_should_have_preference_changes
824
+ assert_equal e = {}, @user.preference_changes
825
+ end
826
+
827
+ def test_should_not_have_preference_change
828
+ assert_nil @user.prefers_notifications_change
829
+ end
830
+
831
+ def test_should_have_preference_was
832
+ assert_equal true, @user.prefers_notifications_was
833
+ end
834
+
835
+ def test_should_not_have_preference_changes_for_group
836
+ assert_equal e = {'notifications' => [true, false]}, @user.preference_changes(:chat)
837
+ end
838
+
839
+ def test_should_have_preference_change_for_group
840
+ assert_equal [true, false], @user.prefers_notifications_change(:chat)
841
+ end
842
+
843
+ def test_should_have_preference_was_for_group
844
+ assert_equal true, @user.prefers_notifications_was(:chat)
845
+ end
846
+ end
847
+
848
+ class PreferencesAfterRevertPreferenceChangeTest < ModelPreferenceTest
849
+ def setup
850
+ User.preference :notifications, :boolean, :default => true
851
+
852
+ @user = create_user
853
+ @user.write_preference(:notifications, false)
854
+ @user.write_preference(:notifications, true)
855
+ end
856
+
857
+ def test_should_not_query_preferences_changed
858
+ assert_equal false, @user.preferences_changed?
859
+ end
860
+
861
+ def test_should_not_have_preferences_changed
862
+ assert_equal [], @user.preferences_changed
863
+ end
864
+
865
+ def test_should_not_have_preference_changes
866
+ assert_equal e = {}, @user.preference_changes
867
+ end
868
+ end
869
+
870
+ class PreferencesAfterForcingChangeTest < ModelPreferenceTest
871
+ def setup
872
+ User.preference :notifications, :boolean, :default => true
873
+
874
+ @user = create_user
875
+ @user.prefers_notifications_will_change!
876
+ @user.save
877
+ end
878
+
879
+ def test_should_store_preference
880
+ assert_equal 1, @user.stored_preferences.count
881
+
882
+ preference = @user.stored_preferences.first
883
+ assert_equal nil, preference.group_type
884
+ assert_equal nil, preference.group_id
885
+ assert_equal true, preference.value
886
+ end
887
+ end
888
+
889
+ class PreferencesAfterForcingChangeForGroupTest < ModelPreferenceTest
890
+ def setup
891
+ User.preference :notifications, :boolean, :default => true
892
+ User.preference :language, :string, :default => 'English'
893
+
894
+ @user = create_user
895
+ @user.prefers_notifications_will_change!(:chat)
896
+ @user.save
897
+ end
898
+
899
+ def test_should_store_preference
900
+ assert_equal 1, @user.stored_preferences.count
901
+
902
+ preference = @user.stored_preferences.first
903
+ assert_equal 'chat', preference.group_type
904
+ assert_equal nil, preference.group_id
905
+ assert_equal true, preference.value
906
+ end
907
+
908
+ def test_should_use_cloned_value_for_tracking_old_value
909
+ old_value = @user.preferred(:language)
910
+ @user.preferred_language_will_change!
911
+
912
+ tracked_old_value = @user.preferred_language_was
913
+ assert_equal old_value, tracked_old_value
914
+ assert_not_same old_value, tracked_old_value
915
+ end
916
+ end
917
+
918
+ class PreferencesAfterResettingPreferenceTest < ModelPreferenceTest
919
+ def setup
920
+ User.preference :notifications, :boolean, :default => true
921
+
922
+ @user = create_user
923
+ @user.write_preference(:notifications, false)
924
+ @user.write_preference(:notifications, false, :chat)
925
+ @user.reset_prefers_notifications!
926
+ end
927
+
928
+ def test_should_revert_to_original_value
929
+ assert_equal true, @user.preferred(:notifications)
930
+ end
931
+
932
+ def test_should_not_reset_groups
933
+ assert_equal true, @user.preferred(:notifications, :chat)
934
+ end
935
+ end
936
+
937
+ class PreferencesAfterResettingPreferenceTest < ModelPreferenceTest
938
+ def setup
939
+ User.preference :notifications, :boolean, :default => true
940
+
941
+ @user = create_user
942
+ @user.write_preference(:notifications, false)
943
+ @user.write_preference(:notifications, false, :chat)
944
+ @user.reset_prefers_notifications!(:chat)
945
+ end
946
+
947
+ def test_should_revert_to_original_value
948
+ assert_equal true, @user.preferred(:notifications, :chat)
949
+ end
950
+
951
+ def test_should_not_reset_default_group
952
+ assert_equal false, @user.preferred(:notifications)
953
+ end
954
+ end
955
+
956
+ class PreferencesLookupTest < ModelPreferenceTest
957
+ def setup
958
+ User.preference :notifications, :boolean, :default => true
959
+ User.preference :language, :string, :default => 'English'
960
+
961
+ @user = create_user
962
+ end
963
+
964
+ def test_should_only_have_defaults_if_nothing_customized
965
+ assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences
966
+ end
967
+
968
+ def test_should_merge_defaults_with_unsaved_changes
969
+ @user.write_preference(:notifications, false)
970
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences
971
+ end
972
+
973
+ def test_should_merge_defaults_with_saved_changes
974
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
975
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences
976
+ end
977
+
978
+ def test_should_merge_stored_preferences_with_unsaved_changes
979
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
980
+ @user.write_preference(:language, 'Latin')
981
+ assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences
982
+ end
983
+
984
+ def test_should_use_unsaved_changes_over_stored_preferences
985
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
986
+ @user.write_preference(:notifications, true)
987
+ assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences
988
+ end
989
+
990
+ def test_should_cache_results
991
+ assert_queries(1) { @user.preferences }
992
+ assert_queries(0) { @user.preferences }
993
+ end
994
+
995
+ def test_should_not_query_if_stored_preferences_eager_loaded
996
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
997
+ user = User.find(@user.id, :include => :stored_preferences)
998
+
999
+ assert_queries(0) do
1000
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, user.preferences
1001
+ end
1002
+ end
1003
+
1004
+ def test_should_not_generate_same_object_twice
1005
+ assert_not_same @user.preferences, @user.preferences
1006
+ end
1007
+
1008
+ def test_should_use_preferences_for_prefs
1009
+ assert_equal @user.preferences, @user.prefs
1010
+ end
1011
+ end
1012
+
1013
+ class PreferencesGroupLookupTest < ModelPreferenceTest
1014
+ def setup
1015
+ User.preference :notifications, :boolean, :default => true
1016
+ User.preference :language, :string, :default => 'English'
1017
+
1018
+ @user = create_user
1019
+ end
1020
+
1021
+ def test_should_only_have_defaults_if_nothing_customized
1022
+ assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences(:chat)
1023
+ end
1024
+
1025
+ def test_should_merge_defaults_with_unsaved_changes
1026
+ @user.write_preference(:notifications, false, :chat)
1027
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(:chat)
1028
+ end
1029
+
1030
+ def test_should_merge_defaults_with_saved_changes
1031
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
1032
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(:chat)
1033
+ end
1034
+
1035
+ def test_should_merge_stored_preferences_with_unsaved_changes
1036
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
1037
+ @user.write_preference(:language, 'Latin', :chat)
1038
+ assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(:chat)
1039
+ end
1040
+
1041
+ def test_should_cache_results
1042
+ assert_queries(1) { @user.preferences(:chat) }
1043
+ assert_queries(0) { @user.preferences(:chat) }
1044
+ end
1045
+
1046
+ def test_should_not_query_if_all_preferences_individually_loaded
1047
+ @user.preferred(:notifications, :chat)
1048
+ @user.preferred(:language, :chat)
1049
+
1050
+ assert_queries(0) { @user.preferences(:chat) }
1051
+ end
1052
+
1053
+ def test_should_not_generate_same_object_twice
1054
+ assert_not_same @user.preferences(:chat), @user.preferences(:chat)
1055
+ end
1056
+ end
1057
+
1058
+ class PreferencesARGroupLookupTest < ModelPreferenceTest
1059
+ def setup
1060
+ @car = create_car
1061
+
1062
+ User.preference :notifications, :boolean, :default => true
1063
+ User.preference :language, :string, :default => 'English'
1064
+
1065
+ @user = create_user
1066
+ end
1067
+
1068
+ def test_should_only_have_defaults_if_nothing_customized
1069
+ assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences(@car)
1070
+ end
1071
+
1072
+ def test_should_merge_defaults_with_unsaved_changes
1073
+ @user.write_preference(:notifications, false, @car)
1074
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(@car)
1075
+ end
1076
+
1077
+ def test_should_merge_defaults_with_saved_changes
1078
+ create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false)
1079
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(@car)
1080
+ end
1081
+
1082
+ def test_should_merge_stored_preferences_with_unsaved_changes
1083
+ create_preference(:owner => @user, :group_type => 'Car', :group_id => @car.id, :name => 'notifications', :value => false)
1084
+ @user.write_preference(:language, 'Latin', @car)
1085
+ assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(@car)
1086
+ end
1087
+ end
1088
+
1089
+ class PreferencesNilGroupLookupTest < ModelPreferenceTest
1090
+ def setup
1091
+ @car = create_car
1092
+
1093
+ User.preference :notifications, :boolean, :default => true
1094
+ User.preference :language, :string, :default => 'English'
1095
+
1096
+ @user = create_user
1097
+ end
1098
+
1099
+ def test_should_only_have_defaults_if_nothing_customized
1100
+ assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences(nil)
1101
+ end
1102
+
1103
+ def test_should_merge_defaults_with_unsaved_changes
1104
+ @user.write_preference(:notifications, false)
1105
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(nil)
1106
+ end
1107
+
1108
+ def test_should_merge_defaults_with_saved_changes
1109
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
1110
+ assert_equal e = {'notifications' => false, 'language' => 'English'}, @user.preferences(nil)
1111
+ end
1112
+
1113
+ def test_should_merge_stored_preferences_with_unsaved_changes
1114
+ create_preference(:owner => @user, :name => 'notifications', :value => false)
1115
+ @user.write_preference(:language, 'Latin')
1116
+ assert_equal e = {'notifications' => false, 'language' => 'Latin'}, @user.preferences(nil)
1117
+ end
1118
+ end
1119
+
1120
+ class PreferencesLookupWithGroupsTest < ModelPreferenceTest
1121
+ def setup
1122
+ User.preference :notifications, :boolean, :default => true
1123
+ User.preference :language, :string, :default => 'English'
1124
+
1125
+ @user = create_user
1126
+ create_preference(:owner => @user, :group_type => 'chat', :name => 'notifications', :value => false)
1127
+ end
1128
+
1129
+ def test_not_include_group_preferences_by_default
1130
+ assert_equal e = {'notifications' => true, 'language' => 'English'}, @user.preferences
1131
+ end
1132
+ end
1133
+
1134
+ class PreferencesAfterBeingReloadedTest < ModelPreferenceTest
1135
+ def setup
1136
+ User.preference :notifications, :boolean, :default => true
1137
+
1138
+ @user = create_user
1139
+ @user.write_preference(:notifications, false)
1140
+ @user.reload
1141
+ end
1142
+
1143
+ def test_should_reset_unsaved_preferences
1144
+ assert_equal true, @user.preferred(:notifications)
1145
+ end
1146
+
1147
+ def test_should_not_save_reset_preferences
1148
+ @user.save!
1149
+ assert @user.stored_preferences.empty?
1150
+ end
1151
+
1152
+ def test_should_reset_preferences
1153
+ assert_equal e = {'notifications' => true}, @user.preferences
1154
+ end
1155
+
1156
+ def test_should_clear_query_cache_for_preferences
1157
+ assert_queries(1) { @user.preferences }
1158
+ end
1159
+
1160
+ def test_should_reset_preferences_changed_query
1161
+ assert_equal false, @user.preferences_changed?
1162
+ end
1163
+
1164
+ def test_should_reset_preferences_changed
1165
+ assert_equal [], @user.preferences_changed
1166
+ end
1167
+
1168
+ def test_should_reset_preference_changes
1169
+ assert_equal e = {}, @user.preference_changes
1170
+ end
1171
+ end
1172
+
1173
+ class PreferencesForGroupAfterBeingReloadedTest < ModelPreferenceTest
1174
+ def setup
1175
+ User.preference :notifications, :boolean, :default => true
1176
+
1177
+ @user = create_user
1178
+ @user.write_preference(:notifications, false, :chat)
1179
+ @user.reload
1180
+ end
1181
+
1182
+ def test_should_reset_unsaved_preferences
1183
+ assert_equal true, @user.preferred(:notifications, :chat)
1184
+ end
1185
+
1186
+ def test_should_reset_preferences
1187
+ assert_equal e = {'notifications' => true}, @user.preferences(:chat)
1188
+ end
1189
+
1190
+ def test_should_clear_query_cache_for_preferences
1191
+ assert_queries(1) { @user.preferences(:chat) }
1192
+ end
1193
+
1194
+ def test_should_reset_preferences_changed_query
1195
+ assert_equal false, @user.preferences_changed?(:chat)
1196
+ end
1197
+
1198
+ def test_should_reset_preferences_changed
1199
+ assert_equal [], @user.preferences_changed(:chat)
1200
+ end
1201
+
1202
+ def test_should_reset_preference_changes
1203
+ assert_equal e = {}, @user.preference_changes(:chat)
1204
+ end
1205
+ end
1206
+
1207
+ class PreferencesWithScopeTest < ModelPreferenceTest
1208
+ def setup
1209
+ User.preference :notifications
1210
+ User.preference :language, :string, :default => 'English'
1211
+ User.preference :color, :string, :default => 'red'
1212
+
1213
+ @user = create_user
1214
+ @customized_user = create_user(:login => 'customized',
1215
+ :prefers_notifications => false,
1216
+ :preferred_language => 'Latin'
1217
+ )
1218
+ @customized_user.prefers_notifications = false, :chat
1219
+ @customized_user.preferred_language = 'Latin', :chat
1220
+ @customized_user.save!
1221
+ end
1222
+
1223
+ def test_should_not_find_if_no_preference_matched
1224
+ assert_equal [], User.with_preferences(:language => 'Italian')
1225
+ end
1226
+
1227
+ def test_should_find_with_null_preference
1228
+ assert_equal [@user], User.with_preferences(:notifications => nil)
1229
+ end
1230
+
1231
+ def test_should_find_with_default_preference
1232
+ assert_equal [@user], User.with_preferences(:language => 'English')
1233
+ end
1234
+
1235
+ def test_should_find_with_multiple_default_preferences
1236
+ assert_equal [@user], User.with_preferences(:notifications => nil, :language => 'English')
1237
+ end
1238
+
1239
+ def test_should_find_with_custom_preference
1240
+ assert_equal [@customized_user], User.with_preferences(:language => 'Latin')
1241
+ end
1242
+
1243
+ def test_should_find_with_multiple_custom_preferences
1244
+ assert_equal [@customized_user], User.with_preferences(:notifications => false, :language => 'Latin')
1245
+ end
1246
+
1247
+ def test_should_find_with_mixed_default_and_custom_preferences
1248
+ assert_equal [@customized_user], User.with_preferences(:color => 'red', :language => 'Latin')
1249
+ end
1250
+
1251
+ def test_should_find_with_default_group_preference
1252
+ assert_equal [@user], User.with_preferences(:chat => {:language => 'English'})
1253
+ end
1254
+
1255
+ def test_should_find_with_multiple_default_group_preferences
1256
+ assert_equal [@user], User.with_preferences(:chat => {:notifications => nil, :language => 'English'})
1257
+ end
1258
+
1259
+ def test_should_find_with_custom_group_preference
1260
+ assert_equal [@customized_user], User.with_preferences(:chat => {:language => 'Latin'})
1261
+ end
1262
+
1263
+ def test_should_find_with_multiple_custom_group_preferences
1264
+ assert_equal [@customized_user], User.with_preferences(:chat => {:notifications => false, :language => 'Latin'})
1265
+ end
1266
+
1267
+ def test_should_find_with_mixed_default_and_custom_group_preferences
1268
+ assert_equal [@customized_user], User.with_preferences(:chat => {:color => 'red', :language => 'Latin'})
1269
+ end
1270
+
1271
+ def test_should_find_with_mixed_basic_and_group_preferences
1272
+ @customized_user.preferred_language = 'English'
1273
+ @customized_user.save!
1274
+
1275
+ assert_equal [@customized_user], User.with_preferences(:language => 'English', :chat => {:language => 'Latin'})
1276
+ end
1277
+
1278
+ def test_should_allow_chaining
1279
+ assert_equal [@user], User.with_preferences(:language => 'English').with_preferences(:color => 'red')
1280
+ end
1281
+ end
1282
+
1283
+ class PreferencesWithoutScopeTest < ModelPreferenceTest
1284
+ def setup
1285
+ User.preference :notifications
1286
+ User.preference :language, :string, :default => 'English'
1287
+ User.preference :color, :string, :default => 'red'
1288
+
1289
+ @user = create_user
1290
+ @customized_user = create_user(:login => 'customized',
1291
+ :prefers_notifications => false,
1292
+ :preferred_language => 'Latin'
1293
+ )
1294
+ @customized_user.prefers_notifications = false, :chat
1295
+ @customized_user.preferred_language = 'Latin', :chat
1296
+ @customized_user.save!
1297
+ end
1298
+
1299
+ def test_should_not_find_if_no_preference_matched
1300
+ assert_equal [], User.without_preferences(:color => 'red')
1301
+ end
1302
+
1303
+ def test_should_find_with_null_preference
1304
+ assert_equal [@user], User.without_preferences(:notifications => false)
1305
+ end
1306
+
1307
+ def test_should_find_with_default_preference
1308
+ assert_equal [@user], User.without_preferences(:language => 'Latin')
1309
+ end
1310
+
1311
+ def test_should_find_with_multiple_default_preferences
1312
+ assert_equal [@user], User.without_preferences(:language => 'Latin', :notifications => false)
1313
+ end
1314
+
1315
+ def test_should_find_with_custom_preference
1316
+ assert_equal [@customized_user], User.without_preferences(:language => 'English')
1317
+ end
1318
+
1319
+ def test_should_find_with_multiple_custom_preferences
1320
+ assert_equal [@customized_user], User.without_preferences(:language => 'English', :notifications => nil)
1321
+ end
1322
+
1323
+ def test_should_find_with_mixed_default_and_custom_preferences
1324
+ assert_equal [@customized_user], User.without_preferences(:language => 'English', :color => 'blue')
1325
+ end
1326
+
1327
+ def test_should_find_with_default_group_preference
1328
+ assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin'})
1329
+ end
1330
+
1331
+ def test_should_find_with_multiple_default_group_preferences
1332
+ assert_equal [@user], User.without_preferences(:chat => {:language => 'Latin', :notifications => false})
1333
+ end
1334
+
1335
+ def test_should_find_with_custom_group_preference
1336
+ assert_equal [@customized_user], User.without_preferences(:chat => {:language => 'English'})
1337
+ end
1338
+
1339
+ def test_should_find_with_multiple_custom_group_preferences
1340
+ assert_equal [@customized_user], User.without_preferences(:chat => {:language => 'English', :notifications => nil})
1341
+ end
1342
+
1343
+ def test_should_find_with_mixed_default_and_custom_group_preferences
1344
+ assert_equal [@customized_user], User.without_preferences(:chat => {:language => 'English', :color => 'blue'})
1345
+ end
1346
+
1347
+ def test_should_find_with_mixed_basic_and_group_preferences
1348
+ @customized_user.preferred_language = 'English'
1349
+ @customized_user.save!
1350
+
1351
+ assert_equal [@customized_user], User.without_preferences(:language => 'Latin', :chat => {:language => 'English'})
1352
+ end
1353
+
1354
+ def test_should_allow_chaining
1355
+ assert_equal [@user], User.without_preferences(:language => 'Latin').without_preferences(:color => 'blue')
425
1356
  end
426
1357
  end