pluginaweek-preferences 0.3.1

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,43 @@
1
+ module Preferences
2
+ # Represents the definition of a preference for a particular model
3
+ class PreferenceDefinition
4
+ def initialize(name, *args) #:nodoc:
5
+ options = args.extract_options!
6
+ options.assert_valid_keys(:default)
7
+
8
+ @type = args.first ? args.first.to_s : 'boolean'
9
+
10
+ # Create a column that will be responsible for typecasting
11
+ @column = ActiveRecord::ConnectionAdapters::Column.new(name.to_s, options[:default], @type == 'any' ? nil : @type)
12
+ end
13
+
14
+ # The name of the preference
15
+ def name
16
+ @column.name
17
+ end
18
+
19
+ # The default value to use for the preference in case none have been
20
+ # previously defined
21
+ def default_value
22
+ @column.default
23
+ end
24
+
25
+ # Typecasts the value based on the type of preference that was defined.
26
+ # This uses ActiveRecord's typecast functionality so the same rules for
27
+ # typecasting a model's columns apply here.
28
+ def type_cast(value)
29
+ @type == 'any' ? value : @column.type_cast(value)
30
+ end
31
+
32
+ # Typecasts the value to true/false depending on the type of preference
33
+ def query(value)
34
+ if !(value = type_cast(value))
35
+ false
36
+ elsif @column.number?
37
+ !value.zero?
38
+ else
39
+ !value.blank?
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,2 @@
1
+ class Car < ActiveRecord::Base
2
+ end
@@ -0,0 +1,2 @@
1
+ class Employee < ActiveRecord::Base
2
+ end
@@ -0,0 +1,3 @@
1
+ class Manager < Employee
2
+ preference :health_insurance
3
+ end
@@ -0,0 +1,7 @@
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'
7
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :login, :null => false
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :users
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class CreateCars < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :cars do |t|
4
+ t.string :name, :null => false
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :cars
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class CreateEmployees < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :employees do |t|
4
+ t.string :name, :null => false
5
+ t.string :type
6
+ end
7
+ end
8
+
9
+ def self.down
10
+ drop_table :employees
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class MigratePreferencesToVersion1 < ActiveRecord::Migration
2
+ def self.up
3
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
4
+ migration.migrate(:up)
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
10
+ migration.migrate(:down)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,65 @@
1
+ module Factory
2
+ # Build actions for the model
3
+ def self.build(model, &block)
4
+ name = model.to_s.underscore
5
+
6
+ define_method("#{name}_attributes", block)
7
+ define_method("valid_#{name}_attributes") {|*args| valid_attributes_for(model, *args)}
8
+ define_method("new_#{name}") {|*args| new_record(model, *args)}
9
+ define_method("create_#{name}") {|*args| create_record(model, *args)}
10
+ end
11
+
12
+ # Get valid attributes for the model
13
+ def valid_attributes_for(model, attributes = {})
14
+ name = model.to_s.underscore
15
+ send("#{name}_attributes", attributes)
16
+ attributes.stringify_keys!
17
+ attributes
18
+ end
19
+
20
+ # Build an unsaved record
21
+ def new_record(model, *args)
22
+ attributes = valid_attributes_for(model, *args)
23
+ record = model.new(attributes)
24
+ attributes.each {|attr, value| record.send("#{attr}=", value) if model.accessible_attributes && !model.accessible_attributes.include?(attr) || model.protected_attributes && model.protected_attributes.include?(attr)}
25
+ record
26
+ end
27
+
28
+ # Build and save/reload a record
29
+ def create_record(model, *args)
30
+ record = new_record(model, *args)
31
+ record.save!
32
+ record.reload
33
+ record
34
+ end
35
+
36
+ build Car do |attributes|
37
+ attributes.reverse_merge!(
38
+ :name => 'Porsche'
39
+ )
40
+ end
41
+
42
+ build Employee do |attributes|
43
+ attributes.reverse_merge!(
44
+ :name => 'John Smith'
45
+ )
46
+ end
47
+
48
+ build Manager do |attributes|
49
+ valid_employee_attributes(attributes)
50
+ end
51
+
52
+ build Preference do |attributes|
53
+ attributes[:owner] = create_user unless attributes.include?(:owner)
54
+ attributes.reverse_merge!(
55
+ :name => 'notifications',
56
+ :value => false
57
+ )
58
+ end
59
+
60
+ build User do |attributes|
61
+ attributes.reverse_merge!(
62
+ :login => 'admin'
63
+ )
64
+ end
65
+ end
@@ -0,0 +1,426 @@
1
+ require "#{File.dirname(__FILE__)}/../test_helper"
2
+
3
+ class PreferencesTest < ActiveSupport::TestCase
4
+ def setup
5
+ User.preference :notifications, :boolean
6
+
7
+ @user = User.new
8
+ end
9
+
10
+ def test_should_raise_exception_if_invalid_options_specified
11
+ assert_raise(ArgumentError) {User.preference :notifications, :invalid => true}
12
+ assert_raise(ArgumentError) {User.preference :notifications, :boolean, :invalid => true}
13
+ end
14
+
15
+ def test_should_create_preferred_query_method
16
+ assert @user.respond_to?(:preferred_notifications?)
17
+ end
18
+
19
+ def test_should_create_prefers_query_method
20
+ assert @user.respond_to?(:prefers_notifications?)
21
+ end
22
+
23
+ def test_should_create_preferred_reader
24
+ assert @user.respond_to?(:preferred_notifications)
25
+ end
26
+
27
+ def test_should_create_prefers_reader
28
+ assert @user.respond_to?(:prefers_notifications)
29
+ end
30
+
31
+ def test_should_create_preferred_writer
32
+ assert @user.respond_to?(:preferred_notifications=)
33
+ end
34
+
35
+ def test_should_create_prefers_writer
36
+ assert @user.respond_to?(:prefers_notifications=)
37
+ end
38
+
39
+ def test_should_create_preference_definitions
40
+ assert User.respond_to?(:preference_definitions)
41
+ end
42
+
43
+ def test_should_create_default_preferences
44
+ assert User.respond_to?(:default_preferences)
45
+ end
46
+
47
+ def test_should_include_new_definitions_in_preference_definitions
48
+ assert_not_nil User.preference_definitions['notifications']
49
+ end
50
+
51
+ def teardown
52
+ User.preference_definitions.delete('notifications')
53
+ User.default_preferences.delete('notifications')
54
+ end
55
+ end
56
+
57
+ class UserByDefaultTest < ActiveSupport::TestCase
58
+ def setup
59
+ @user = User.new
60
+ end
61
+
62
+ def test_should_not_prefer_hot_salsa
63
+ assert_nil @user.preferred_hot_salsa
64
+ assert_nil @user.prefers_hot_salsa
65
+ end
66
+
67
+ def test_should_prefer_dark_chocolate
68
+ assert_equal true, @user.preferred_dark_chocolate
69
+ assert_equal true, @user.prefers_dark_chocolate
70
+ end
71
+
72
+ def test_should_not_have_a_preferred_color
73
+ assert_nil @user.preferred_color
74
+ end
75
+
76
+ def test_should_not_have_a_preferred_car
77
+ assert_nil @user.preferred_car
78
+ end
79
+
80
+ def test_should_have_a_preferred_language
81
+ assert_equal 'English', @user.preferred_language
82
+ end
83
+
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
94
+ end
95
+ end
96
+
97
+ class UserTest < ActiveSupport::TestCase
98
+ def setup
99
+ @user = new_user
100
+ end
101
+
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?
108
+ end
109
+
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?
116
+ end
117
+
118
+ def test_should_be_able_to_change_color_preference
119
+ @user.preferred_color = 'blue'
120
+ assert_equal 'blue', @user.preferred_color
121
+ end
122
+
123
+ def test_should_be_able_to_change_car_preference
124
+ @user.preferred_car = 1
125
+ assert_equal 1, @user.preferred_car
126
+ end
127
+
128
+ def test_should_be_able_to_change_language_preference
129
+ @user.preferred_language = 'Latin'
130
+ assert_equal 'Latin', @user.preferred_language
131
+ end
132
+
133
+ def test_should_be_able_to_use_generic_preferred_query_method
134
+ @user.prefers_hot_salsa = true
135
+ assert @user.preferred?(:hot_salsa)
136
+ end
137
+
138
+ def test_should_be_able_to_use_generic_prefers_query_method
139
+ @user.prefers_hot_salsa = true
140
+ assert @user.prefers?(:hot_salsa)
141
+ end
142
+
143
+ def test_should_be_able_to_use_generic_preferred_method
144
+ @user.preferred_color = 'blue'
145
+ assert_equal 'blue', @user.preferred(:color)
146
+ end
147
+
148
+ def test_should_be_able_to_use_generic_prefers_method
149
+ @user.preferred_color = 'blue'
150
+ assert_equal 'blue', @user.prefers(:color)
151
+ end
152
+
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)
156
+ end
157
+
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?
162
+ end
163
+ end
164
+
165
+ class UserAfterBeingCreatedTest < ActiveSupport::TestCase
166
+ def setup
167
+ @user = create_user
168
+ end
169
+
170
+ def test_should_not_have_any_stored_preferences
171
+ assert @user.stored_preferences.empty?
172
+ end
173
+ end
174
+
175
+ class UserWithoutStoredPreferencesTest < ActiveSupport::TestCase
176
+ def setup
177
+ @user = create_user
178
+ end
179
+
180
+ def test_should_not_prefer_hot_salsa
181
+ assert_nil @user.preferred_hot_salsa
182
+ end
183
+
184
+ def test_should_prefer_dark_chocolate
185
+ assert_equal true, @user.preferred_dark_chocolate
186
+ end
187
+
188
+ def test_should_not_have_a_preferred_color
189
+ assert_nil @user.preferred_color
190
+ end
191
+
192
+ def test_should_not_have_a_preferred_car
193
+ assert_nil @user.preferred_car
194
+ end
195
+
196
+ def test_should_have_a_preferred_language
197
+ assert_equal 'English', @user.preferred_language
198
+ end
199
+
200
+ def test_should_not_save_record_after_changing_preference
201
+ @user.preferred_language = 'Latin'
202
+
203
+ user = User.find(@user.id)
204
+ assert_equal 'English', user.preferred_language
205
+ assert user.stored_preferences.empty?
206
+ end
207
+ end
208
+
209
+ class UserWithStoredPreferencesTest < ActiveSupport::TestCase
210
+ def setup
211
+ @user = create_user
212
+ @user.preferred_language = 'Latin'
213
+ @user.save!
214
+ end
215
+
216
+ def test_should_have_stored_preferences
217
+ assert_equal 1, @user.stored_preferences.size
218
+ end
219
+
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
+ }
228
+
229
+ assert_equal expected, @user.preferences
230
+ end
231
+
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
+ }
240
+
241
+ assert_equal expected, @user.prefs
242
+ end
243
+
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
249
+ end
250
+
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
256
+ end
257
+
258
+ def test_should_not_save_preference_if_model_is_not_saved
259
+ @user.preferred_language = 'English'
260
+
261
+ user = User.find(@user.id)
262
+ assert_equal 'Latin', user.preferred_language
263
+ end
264
+
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
272
+ end
273
+
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
281
+ end
282
+ end
283
+
284
+ class UserWithStoredPreferencesForBasicGroupsTest < ActiveSupport::TestCase
285
+ def setup
286
+ @user = create_user
287
+ @user.preferred_color = 'red', 'cars'
288
+ @user.save!
289
+ end
290
+
291
+ def test_should_have_stored_preferences
292
+ assert_equal 1, @user.stored_preferences.size
293
+ end
294
+
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
+ }
310
+
311
+ assert_equal expected, @user.preferences
312
+ end
313
+
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
+ }
322
+
323
+ assert_equal expected, @user.preferences(nil)
324
+ end
325
+
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
+ }
334
+
335
+ assert_equal expected, @user.preferences('cars')
336
+ end
337
+
338
+ def test_should_not_have_preference_without_group
339
+ assert_nil @user.preferred_color
340
+ end
341
+
342
+ def test_should_have_preference_with_group
343
+ assert_equal 'red', @user.preferred_color('cars')
344
+ end
345
+
346
+ def test_should_modify_existing_preferences_when_saved
347
+ @user.preferred_color = 'blue', 'cars'
348
+ assert @user.save
349
+
350
+ @user.reload
351
+ assert_equal 'blue', @user.preferred_color('cars')
352
+ assert_equal 1, @user.stored_preferences.size
353
+ end
354
+
355
+ def test_should_be_able_to_differentiate_between_groups
356
+ @user.preferred_color = 'blue', 'boats'
357
+ assert @user.save
358
+
359
+ @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
363
+ end
364
+ end
365
+
366
+ class UserWithStoredPreferencesForActiveRecordGroupsTest < ActiveSupport::TestCase
367
+ def setup
368
+ @car = create_car
369
+
370
+ @user = create_user
371
+ @user.preferred_color = 'red', @car
372
+ @user.save!
373
+ end
374
+
375
+ def test_should_have_stored_preferences
376
+ assert_equal 1, @user.stored_preferences.size
377
+ end
378
+
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
+ }
394
+
395
+ assert_equal expected, @user.preferences
396
+ end
397
+
398
+ def test_should_not_have_preference_without_group
399
+ assert_nil @user.preferred_color
400
+ end
401
+
402
+ def test_should_have_preference_with_group
403
+ assert_equal 'red', @user.preferred_color(@car)
404
+ end
405
+
406
+ def test_should_modify_existing_preferences_when_saved
407
+ @user.preferred_color = 'blue', @car
408
+ assert @user.save
409
+
410
+ @user.reload
411
+ assert_equal 'blue', @user.preferred_color(@car)
412
+ assert_equal 1, @user.stored_preferences.size
413
+ end
414
+
415
+ def test_should_be_able_to_differentiate_between_groups
416
+ @different_car = create_car
417
+
418
+ @user.preferred_color = 'blue', @different_car
419
+ assert @user.save
420
+
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
425
+ end
426
+ end