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,6 +3,9 @@ | ||
3 | # which by default is the one returned by VirtualCommunity:default. | 3 | # which by default is the one returned by VirtualCommunity:default. |
4 | class Profile < ActiveRecord::Base | 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 | # These names cannot be used as identifiers for Profiles | 9 | # These names cannot be used as identifiers for Profiles |
7 | RESERVED_IDENTIFIERS = %w[ | 10 | RESERVED_IDENTIFIERS = %w[ |
8 | admin | 11 | admin |
@@ -17,10 +20,26 @@ class Profile < ActiveRecord::Base | @@ -17,10 +20,26 @@ class Profile < ActiveRecord::Base | ||
17 | belongs_to :virtual_community | 20 | belongs_to :virtual_community |
18 | belongs_to :user | 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 | validates_presence_of :identifier | 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 | validates_exclusion_of :identifier, :in => RESERVED_IDENTIFIERS | 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 | # creates a new Profile. By default, it is attached to the default | 43 | # creates a new Profile. By default, it is attached to the default |
25 | # VirtualCommunity (see VirtualCommunity#default), unless you tell it | 44 | # VirtualCommunity (see VirtualCommunity#default), unless you tell it |
26 | # otherwise | 45 | # otherwise |
app/models/user.rb
1 | require 'digest/sha1' | 1 | require 'digest/sha1' |
2 | + | ||
2 | class User < ActiveRecord::Base | 3 | class User < ActiveRecord::Base |
3 | 4 | ||
4 | after_create do |user| | 5 | after_create do |user| |
@@ -10,6 +11,7 @@ class User < ActiveRecord::Base | @@ -10,6 +11,7 @@ class User < ActiveRecord::Base | ||
10 | attr_accessor :password | 11 | attr_accessor :password |
11 | 12 | ||
12 | validates_presence_of :login, :email | 13 | validates_presence_of :login, :email |
14 | + validates_format_of :login, :with => Profile::IDENTIFIER_FORMAT | ||
13 | validates_presence_of :password, :if => :password_required? | 15 | validates_presence_of :password, :if => :password_required? |
14 | validates_presence_of :password_confirmation, :if => :password_required? | 16 | validates_presence_of :password_confirmation, :if => :password_required? |
15 | validates_length_of :password, :within => 4..40, :if => :password_required? | 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,4 +50,31 @@ class ProfileTest < Test::Unit::TestCase | ||
50 | assert p.valid? | 50 | assert p.valid? |
51 | end | 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 | end | 80 | end |
test/unit/user_test.rb
@@ -75,10 +75,37 @@ class UserTest < Test::Unit::TestCase | @@ -75,10 +75,37 @@ class UserTest < Test::Unit::TestCase | ||
75 | user = User.create!(:login => 'new_user', :email => 'new_user@example.com', :password => 'test', :password_confirmation => 'test') | 75 | user = User.create!(:login => 'new_user', :email => 'new_user@example.com', :password => 'test', :password_confirmation => 'test') |
76 | 76 | ||
77 | assert Profile.exists?(['user_id = ?', user.id]) | 77 | assert Profile.exists?(['user_id = ?', user.id]) |
78 | + | ||
78 | assert_equal users_count + 1, User.count | 79 | assert_equal users_count + 1, User.count |
79 | assert_equal profiles_count + 1, Profile.count | 80 | assert_equal profiles_count + 1, Profile.count |
80 | end | 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 | protected | 109 | protected |
83 | def create_user(options = {}) | 110 | def create_user(options = {}) |
84 | User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) | 111 | User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) |