diff --git a/app/models/profile.rb b/app/models/profile.rb index 3da3062..fac0e08 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -3,6 +3,9 @@ # which by default is the one returned by VirtualCommunity:default. class Profile < ActiveRecord::Base + # Valid identifiers must match this format. + IDENTIFIER_FORMAT = /^[a-z][a-z0-9_]+[a-z0-9]$/ + # These names cannot be used as identifiers for Profiles RESERVED_IDENTIFIERS = %w[ admin @@ -17,10 +20,26 @@ class Profile < ActiveRecord::Base belongs_to :virtual_community belongs_to :user + + # Sets the identifier for this profile. Raises an exception when called on a + # existing profile (since profiles cannot be renamed) + def identifier=(value) + unless self.new_record? + raise ArgumentError.new(_('An existing profile cannot be renamed.')) + end + self[:identifier] = value + end + validates_presence_of :identifier - validates_format_of :identifier, :with => /^[a-z][a-z0-9_]+[a-z0-9]$/ + validates_format_of :identifier, :with => IDENTIFIER_FORMAT validates_exclusion_of :identifier, :in => RESERVED_IDENTIFIERS + # A user cannot have more than one profile, but many profiles can exist + # without being associated to a particular user. + validates_uniqueness_of :user_id, :if => (lambda do |profile| + ! profile.user_id.nil? + end) + # creates a new Profile. By default, it is attached to the default # VirtualCommunity (see VirtualCommunity#default), unless you tell it # otherwise diff --git a/app/models/user.rb b/app/models/user.rb index dce0d43..77b4156 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,5 @@ require 'digest/sha1' + class User < ActiveRecord::Base after_create do |user| @@ -10,6 +11,7 @@ class User < ActiveRecord::Base attr_accessor :password validates_presence_of :login, :email + validates_format_of :login, :with => Profile::IDENTIFIER_FORMAT validates_presence_of :password, :if => :password_required? validates_presence_of :password_confirmation, :if => :password_required? validates_length_of :password, :within => 4..40, :if => :password_required? diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb index d990ea9..10f15e7 100644 --- a/test/unit/profile_test.rb +++ b/test/unit/profile_test.rb @@ -50,4 +50,31 @@ class ProfileTest < Test::Unit::TestCase assert p.valid? end + def test_only_one_profile_per_user + p1 = profiles(:johndoe) + assert_equal users(:johndoe), p1.user + + p2 = Profile.new + p2.user = users(:johndoe) + assert !p2.valid? + assert p2.errors.invalid?(:user_id) + end + + def test_several_profiles_without_user + p1 = profiles(:john_and_joe) + assert p1.valid? + assert_nil p1.user + + p2 = Profile.new + assert !p2.valid? + assert !p2.errors.invalid?(:user_id) + end + + def test_cannot_rename + p1 = profiles(:johndoe) + assert_raise ArgumentError do + p1.identifier = 'bli' + end + end + end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index be238bc..12280a4 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -75,10 +75,37 @@ class UserTest < Test::Unit::TestCase user = User.create!(:login => 'new_user', :email => 'new_user@example.com', :password => 'test', :password_confirmation => 'test') assert Profile.exists?(['user_id = ?', user.id]) + assert_equal users_count + 1, User.count assert_equal profiles_count + 1, Profile.count end + def test_login_validation + u = User.new + u.valid? + assert u.errors.invalid?(:login) + + u.login = 'with space' + u.valid? + assert u.errors.invalid?(:login) + + u.login = 'áéíóú' + u.valid? + assert u.errors.invalid?(:login) + + u.login = 'rightformat2007' + u.valid? + assert ! u.errors.invalid?(:login) + + u.login = 'rightformat' + u.valid? + assert ! u.errors.invalid?(:login) + + u.login = 'right_format' + u.valid? + assert ! u.errors.invalid?(:login) + end + protected def create_user(options = {}) User.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) -- libgit2 0.21.2