From c207b4bb330463c39c202d1c66e2447b55332093 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Jun 2017 15:22:01 +0200 Subject: [PATCH] Fix db:seed - only run some validations when the field was changed (#3592) * Fix db:seed - only run some validations when the field was changed * Add tests --- app/models/account.rb | 12 ++++++++---- app/models/user.rb | 2 +- db/seeds.rb | 3 ++- spec/models/account_spec.rb | 6 ++++++ spec/models/user_spec.rb | 6 ++++++ 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index 918d5b0f1c..214d3b9fd6 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -52,13 +52,17 @@ class Account < ApplicationRecord has_one :user, inverse_of: :account validates :username, presence: true - validates :username, uniqueness: { scope: :domain, case_sensitive: true }, unless: :local? + + # Remote user validations + with_options unless: :local? do + validates :username, uniqueness: { scope: :domain, case_sensitive: true }, if: :username_changed? + end # Local user validations with_options if: :local? do - validates :username, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, unreserved: true - validates :display_name, length: { maximum: 30 } - validates :note, length: { maximum: 160 } + validates :username, format: { with: /\A[a-z0-9_]+\z/i }, uniqueness: { scope: :domain, case_sensitive: false }, length: { maximum: 30 }, unreserved: true, if: :username_changed? + validates :display_name, length: { maximum: 30 }, if: :display_name_changed? + validates :note, length: { maximum: 160 }, if: :note_changed? end # Timelines diff --git a/app/models/user.rb b/app/models/user.rb index c0600fe75f..0fd3983b48 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -47,7 +47,7 @@ class User < ApplicationRecord accepts_nested_attributes_for :account validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale? - validates :email, email: true + validates :email, email: true, if: :email_changed? scope :recent, -> { order(id: :desc) } scope :admins, -> { where(admin: true) } diff --git a/db/seeds.rb b/db/seeds.rb index cdce04994d..6adfeed8d3 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -2,6 +2,7 @@ Doorkeeper::Application.create!(name: 'Web', superapp: true, redirect_uri: Doork if Rails.env.development? domain = ENV['LOCAL_DOMAIN'] || Rails.configuration.x.local_domain - admin = Account.where(username: 'admin').first_or_create!(username: 'admin') + admin = Account.where(username: 'admin').first_or_initialize(username: 'admin') + admin.save(validate: false) User.where(email: "admin@#{domain}").first_or_initialize(email: "admin@#{domain}", password: 'mastodonadmin', password_confirmation: 'mastodonadmin', confirmed_at: Time.now.utc, admin: true, account: admin).save! end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index ab4de9aa12..73ae34f8e5 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -387,6 +387,12 @@ RSpec.describe Account, type: :model do expect(account).to model_have_error_on_field(:username) end + it 'is valid when username is reserved but record has already been created' do + account = Fabricate.build(:account, username: 'support') + account.save(validate: false) + expect(account.valid?).to be true + end + context 'when is local' do it 'is invalid if the username doesn\'t only contains letters, numbers and underscores' do account = Fabricate.build(:account, username: 'the-doctor') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 13a60f6681..a6df3fb262 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -34,6 +34,12 @@ RSpec.describe User, type: :model do expect(user).to model_have_error_on_field(:email) end + it 'is valid with an invalid e-mail that has already been saved' do + user = Fabricate.build(:user, email: 'invalid-email') + user.save(validate: false) + expect(user.valid?).to be true + end + it 'cleans out empty string from languages' do user = Fabricate.build(:user, filtered_languages: ['']) user.valid?