From 1bf5bf9cdacc0e501d057d8484787a7025a974af Mon Sep 17 00:00:00 2001
From: Abdul Wadood <awadood@gitlab.com>
Date: Fri, 19 Jan 2024 01:37:27 +0000
Subject: [PATCH] Validate the presence of default User and UserPreference
 attributes

We want to make the columns with defaults not null in our database. As
the first step, we want to validate their presence in the models.
`before_validation`s have also been added to allow existing records
to update. Otherwise, new validation would have prevented them from
getting updated.
---
 app/models/user.rb                  |  4 ++++
 app/models/user_preference.rb       |  2 ++
 spec/models/user_preference_spec.rb | 17 ++++++++++-------
 spec/models/user_spec.rb            |  4 ++++
 4 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/app/models/user.rb b/app/models/user.rb
index c9873975cc932..e0868891172d0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -334,6 +334,10 @@ def update_tracked_fields!(request)
 
   validates :color_scheme_id, allow_nil: true, inclusion: { in: Gitlab::ColorSchemes.valid_ids,
                                                             message: ->(*) { _("%{placeholder} is not a valid color scheme") % { placeholder: '%{value}' } } }
+  validates :hide_no_ssh_key, allow_nil: false, inclusion: { in: [true, false] }
+  validates :hide_no_password, allow_nil: false, inclusion: { in: [true, false] }
+  validates :notified_of_own_activity, allow_nil: false, inclusion: { in: [true, false] }
+  validates :project_view, presence: true
 
   after_initialize :set_projects_limit
   before_validation :sanitize_attrs
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index 70ffe0c85f826..847249b22f8bc 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -25,6 +25,8 @@ class UserPreference < MainClusterwide::ApplicationRecord
     format: { with: ColorsHelper::HEX_COLOR_PATTERN },
     allow_blank: true
 
+  validates :time_display_relative, allow_nil: false, inclusion: { in: [true, false] }
+  validates :render_whitespace_in_code, allow_nil: false, inclusion: { in: [true, false] }
   validates :pass_user_identities_to_ci_jwt, allow_nil: false, inclusion: { in: [true, false] }
 
   validates :pinned_nav_items, json_schema: { filename: 'pinned_nav_items' }
diff --git a/spec/models/user_preference_spec.rb b/spec/models/user_preference_spec.rb
index ee3fbb97e472d..465590773396c 100644
--- a/spec/models/user_preference_spec.rb
+++ b/spec/models/user_preference_spec.rb
@@ -8,6 +8,16 @@
   let(:user_preference) { create(:user_preference, user: user) }
 
   describe 'validations' do
+    it { is_expected.to validate_inclusion_of(:time_display_relative).in_array([true, false]) }
+    it { is_expected.to validate_inclusion_of(:render_whitespace_in_code).in_array([true, false]) }
+
+    it do
+      is_expected.to validate_numericality_of(:tab_width)
+                       .only_integer
+                       .is_greater_than_or_equal_to(Gitlab::TabWidth::MIN)
+                       .is_less_than_or_equal_to(Gitlab::TabWidth::MAX)
+    end
+
     describe 'diffs_deletion_color and diffs_addition_color' do
       using RSpec::Parameterized::TableSyntax
 
@@ -163,13 +173,6 @@
 
       expect(pref.reload.tab_width).to eq(8)
     end
-
-    it do
-      is_expected.to validate_numericality_of(:tab_width)
-        .only_integer
-        .is_greater_than_or_equal_to(1)
-        .is_less_than_or_equal_to(12)
-    end
   end
 
   describe '#tab_width=' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 7014c9e685f15..a586f44d84332 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -728,6 +728,10 @@
     end
 
     it { is_expected.to validate_presence_of(:projects_limit) }
+    it { is_expected.to define_enum_for(:project_view).with_values(%i[readme activity files wiki]) }
+    it { is_expected.to validate_inclusion_of(:hide_no_ssh_key).in_array([true, false]) }
+    it { is_expected.to validate_inclusion_of(:hide_no_password).in_array([true, false]) }
+    it { is_expected.to validate_inclusion_of(:notified_of_own_activity).in_array([true, false]) }
     it { is_expected.to validate_numericality_of(:projects_limit) }
     it { is_expected.to allow_value(0).for(:projects_limit) }
     it { is_expected.not_to allow_value(-1).for(:projects_limit) }
-- 
GitLab