Commit 50c8896f958f1cb6de2b90a83e70f17495b857f8
1 parent
1a041f1c
Exists in
master
and in
29 other branches
ActionItem9: adding validations to user and profile models
git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@102 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
4 changed files
with
76 additions
and
1 deletions
Show diff stats
app/models/profile.rb
... | ... | @@ -3,6 +3,9 @@ |
3 | 3 | # which by default is the one returned by VirtualCommunity:default. |
4 | 4 | class Profile < ActiveRecord::Base |
5 | 5 | |
6 | + # Valid identifiers must match this format. | |
7 | + IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]+[a-z0-9]$/ | |
8 | + | |
6 | 9 | # These names cannot be used as identifiers for Profiles |
7 | 10 | RESERVED_IDENTIFIERS = %w[ |
8 | 11 | admin |
... | ... | @@ -17,10 +20,26 @@ class Profile < ActiveRecord::Base |
17 | 20 | belongs_to :virtual_community |
18 | 21 | belongs_to :user |
19 | 22 | |
23 | + | |
24 | + # Sets the identifier for this profile. Raises an exception when called on a | |
25 | + # existing profile (since profiles cannot be renamed) | |
26 | + def identifier=(value) | |
27 | + unless self.new_record? | |
28 | + raise ArgumentError.new(_('An existing profile cannot be renamed.')) | |
29 | + end | |
30 | + self[:identifier] = value | |
31 | + end | |
32 | + | |
20 | 33 | validates_presence_of :identifier |
21 | - validates_format_of :identifier, :with => /^[a-z][a-z0-9_]+[a-z0-9]$/ | |
34 | + validates_format_of :identifier, :with => IDENTIFIER_FORMAT | |
22 | 35 | validates_exclusion_of :identifier, :in => RESERVED_IDENTIFIERS |
23 | 36 | |
37 | + # A user cannot have more than one profile, but many profiles can exist | |
38 | + # without being associated to a particular user. | |
39 | + validates_uniqueness_of :user_id, :if => (lambda do |profile| | |
40 | + ! profile.user_id.nil? | |
41 | + end) | |
42 | + | |
24 | 43 | # creates a new Profile. By default, it is attached to the default |
25 | 44 | # VirtualCommunity (see VirtualCommunity#default), unless you tell it |
26 | 45 | # otherwise | ... | ... |
app/models/user.rb
1 | 1 | require 'digest/sha1' |
2 | + | |
2 | 3 | class User < ActiveRecord::Base |
3 | 4 | |
4 | 5 | after_create do |user| |
... | ... | @@ -10,6 +11,7 @@ class User < ActiveRecord::Base |
10 | 11 | attr_accessor :password |
11 | 12 | |
12 | 13 | validates_presence_of :login, :email |
14 | + validates_format_of :login, :with => Profile::IDENTIFIER_FORMAT | |
13 | 15 | validates_presence_of :password, :if => :password_required? |
14 | 16 | validates_presence_of :password_confirmation, :if => :password_required? |
15 | 17 | validates_length_of :password, :within => 4..40, :if => :password_required? | ... | ... |
test/unit/profile_test.rb
... | ... | @@ -50,4 +50,31 @@ class ProfileTest < Test::Unit::TestCase |
50 | 50 | assert p.valid? |
51 | 51 | end |
52 | 52 | |
53 | + def test_only_one_profile_per_user | |
54 | + p1 = profiles(:johndoe) | |
55 | + assert_equal users(:johndoe), p1.user | |
56 | + | |
57 | + p2 = Profile.new | |
58 | + p2.user = users(:johndoe) | |
59 | + assert !p2.valid? | |
60 | + assert p2.errors.invalid?(:user_id) | |
61 | + end | |
62 | + | |
63 | + def test_several_profiles_without_user | |
64 | + p1 = profiles(:john_and_joe) | |
65 | + assert p1.valid? | |
66 | + assert_nil p1.user | |
67 | + | |
68 | + p2 = Profile.new | |
69 | + assert !p2.valid? | |
70 | + assert !p2.errors.invalid?(:user_id) | |
71 | + end | |
72 | + | |
73 | + def test_cannot_rename | |
74 | + p1 = profiles(:johndoe) | |
75 | + assert_raise ArgumentError do | |
76 | + p1.identifier = 'bli' | |
77 | + end | |
78 | + end | |
79 | + | |
53 | 80 | end | ... | ... |
test/unit/user_test.rb
... | ... | @@ -75,10 +75,37 @@ class UserTest < Test::Unit::TestCase |
75 | 75 | user = User.create!(:login => 'new_user', :email => 'new_user@example.com', :password => 'test', :password_confirmation => 'test') |
76 | 76 | |
77 | 77 | assert Profile.exists?(['user_id = ?', user.id]) |
78 | + | |
78 | 79 | assert_equal users_count + 1, User.count |
79 | 80 | assert_equal profiles_count + 1, Profile.count |
80 | 81 | end |
81 | 82 | |
83 | + def test_login_validation | |
84 | + u = User.new | |
85 | + u.valid? | |
86 | + assert u.errors.invalid?(:login) | |
87 | + | |
88 | + u.login = 'with space' | |
89 | + u.valid? | |
90 | + assert u.errors.invalid?(:login) | |
91 | + | |
92 | + u.login = 'áéíóú' | |
93 | + u.valid? | |
94 | + assert u.errors.invalid?(:login) | |
95 | + | |
96 | + u.login = 'rightformat2007' | |
97 | + u.valid? | |
98 | + assert ! u.errors.invalid?(:login) | |
99 | + | |
100 | + u.login = 'rightformat' | |
101 | + u.valid? | |
102 | + assert ! u.errors.invalid?(:login) | |
103 | + | |
104 | + u.login = 'right_format' | |
105 | + u.valid? | |
106 | + assert ! u.errors.invalid?(:login) | |
107 | + end | |
108 | + | |
82 | 109 | protected |
83 | 110 | def create_user(options = {}) |
84 | 111 | User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) | ... | ... |