summaryrefslogtreecommitdiff
path: root/spec/models/concerns
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/concerns')
-rw-r--r--spec/models/concerns/counter_attribute_spec.rb44
-rw-r--r--spec/models/concerns/has_user_type_spec.rb3
-rw-r--r--spec/models/concerns/noteable_spec.rb76
-rw-r--r--spec/models/concerns/safely_change_column_default_spec.rb75
-rw-r--r--spec/models/concerns/sensitive_serializable_hash_spec.rb2
5 files changed, 198 insertions, 2 deletions
diff --git a/spec/models/concerns/counter_attribute_spec.rb b/spec/models/concerns/counter_attribute_spec.rb
index 1dd9b78d642..c8224c64ba2 100644
--- a/spec/models/concerns/counter_attribute_spec.rb
+++ b/spec/models/concerns/counter_attribute_spec.rb
@@ -37,6 +37,50 @@ RSpec.describe CounterAttribute, :counter_attribute, :clean_gitlab_redis_shared_
end
end
+ describe '#initiate_refresh!' do
+ context 'when counter attribute is enabled' do
+ let(:attribute) { :build_artifacts_size }
+
+ it 'initiates refresh on the BufferedCounter' do
+ expect_next_instance_of(Gitlab::Counters::BufferedCounter, model, attribute) do |counter|
+ expect(counter).to receive(:initiate_refresh!)
+ end
+
+ model.initiate_refresh!(attribute)
+ end
+ end
+
+ context 'when counter attribute is not enabled' do
+ let(:attribute) { :snippets_size }
+
+ it 'raises error' do
+ expect { model.initiate_refresh!(attribute) }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
+ describe '#finalize_refresh' do
+ let(:attribute) { :build_artifacts_size }
+
+ context 'when counter attribute is enabled' do
+ it 'initiates refresh on the BufferedCounter' do
+ expect_next_instance_of(Gitlab::Counters::BufferedCounter, model, attribute) do |counter|
+ expect(counter).to receive(:finalize_refresh)
+ end
+
+ model.finalize_refresh(attribute)
+ end
+ end
+
+ context 'when counter attribute is not enabled' do
+ let(:attribute) { :snippets_size }
+
+ it 'raises error' do
+ expect { model.finalize_refresh(attribute) }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
describe '#counter' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/models/concerns/has_user_type_spec.rb b/spec/models/concerns/has_user_type_spec.rb
index 462b28f99be..bd128112113 100644
--- a/spec/models/concerns/has_user_type_spec.rb
+++ b/spec/models/concerns/has_user_type_spec.rb
@@ -5,7 +5,8 @@ require 'spec_helper'
RSpec.describe User do
specify 'types consistency checks', :aggregate_failures do
expect(described_class::USER_TYPES.keys)
- .to match_array(%w[human ghost alert_bot project_bot support_bot service_user security_bot visual_review_bot migration_bot automation_bot admin_bot])
+ .to match_array(%w[human ghost alert_bot project_bot support_bot service_user security_bot visual_review_bot
+ migration_bot automation_bot admin_bot suggested_reviewers_bot])
expect(described_class::USER_TYPES).to include(*described_class::BOT_USER_TYPES)
expect(described_class::USER_TYPES).to include(*described_class::NON_INTERNAL_USER_TYPES)
expect(described_class::USER_TYPES).to include(*described_class::INTERNAL_USER_TYPES)
diff --git a/spec/models/concerns/noteable_spec.rb b/spec/models/concerns/noteable_spec.rb
index 82aca13c929..383ed68816e 100644
--- a/spec/models/concerns/noteable_spec.rb
+++ b/spec/models/concerns/noteable_spec.rb
@@ -63,6 +63,82 @@ RSpec.describe Noteable do
end
end
+ # rubocop:disable RSpec/MultipleMemoizedHelpers
+ describe '#commenters' do
+ shared_examples 'commenters' do
+ it 'does not automatically include the noteable author' do
+ expect(commenters).not_to include(noteable.author)
+ end
+
+ context 'with no user' do
+ it 'contains a distinct list of non-internal note authors' do
+ expect(commenters).to contain_exactly(commenter, another_commenter)
+ end
+ end
+
+ context 'with non project member' do
+ let(:current_user) { create(:user) }
+
+ it 'contains a distinct list of non-internal note authors' do
+ expect(commenters).to contain_exactly(commenter, another_commenter)
+ end
+
+ it 'does not include a commenter from another noteable' do
+ expect(commenters).not_to include(other_noteable_commenter)
+ end
+ end
+ end
+
+ let_it_be(:commenter) { create(:user) }
+ let_it_be(:another_commenter) { create(:user) }
+ let_it_be(:internal_commenter) { create(:user) }
+ let_it_be(:other_noteable_commenter) { create(:user) }
+
+ let(:current_user) {}
+ let(:commenters) { noteable.commenters(user: current_user) }
+
+ let!(:comments) { create_list(:note, 2, author: commenter, noteable: noteable, project: noteable.project) }
+ let!(:more_comments) { create_list(:note, 2, author: another_commenter, noteable: noteable, project: noteable.project) }
+
+ context 'when noteable is an issue' do
+ let(:noteable) { create(:issue) }
+
+ let!(:internal_comments) { create_list(:note, 2, author: internal_commenter, noteable: noteable, project: noteable.project, internal: true) }
+ let!(:other_noteable_comments) { create_list(:note, 2, author: other_noteable_commenter, noteable: create(:issue, project: noteable.project), project: noteable.project) }
+
+ it_behaves_like 'commenters'
+
+ context 'with reporter' do
+ let(:current_user) { create(:user) }
+
+ before do
+ noteable.project.add_reporter(current_user)
+ end
+
+ it 'contains a distinct list of non-internal note authors' do
+ expect(commenters).to contain_exactly(commenter, another_commenter, internal_commenter)
+ end
+
+ context 'with noteable author' do
+ let(:current_user) { noteable.author }
+
+ it 'contains a distinct list of non-internal note authors' do
+ expect(commenters).to contain_exactly(commenter, another_commenter, internal_commenter)
+ end
+ end
+ end
+ end
+
+ context 'when noteable is a merge request' do
+ let(:noteable) { create(:merge_request) }
+
+ let!(:other_noteable_comments) { create_list(:note, 2, author: other_noteable_commenter, noteable: create(:merge_request, source_project: noteable.project, source_branch: 'feat123'), project: noteable.project) }
+
+ it_behaves_like 'commenters'
+ end
+ end
+ # rubocop:enable RSpec/MultipleMemoizedHelpers
+
describe '#discussion_ids_relation' do
it 'returns ordered discussion_ids' do
discussion_ids = subject.discussion_ids_relation.pluck(:discussion_id)
diff --git a/spec/models/concerns/safely_change_column_default_spec.rb b/spec/models/concerns/safely_change_column_default_spec.rb
new file mode 100644
index 00000000000..36782170eaf
--- /dev/null
+++ b/spec/models/concerns/safely_change_column_default_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SafelyChangeColumnDefault, feature_category: :database do
+ include Gitlab::Database::DynamicModelHelpers
+ before do
+ ApplicationRecord.connection.execute(<<~SQL)
+ CREATE TABLE _test_gitlab_main_data(
+ id bigserial primary key not null,
+ value bigint default 1
+ );
+ SQL
+ end
+
+ let!(:model) do
+ define_batchable_model('_test_gitlab_main_data', connection: ApplicationRecord.connection).tap do |model|
+ model.include(described_class)
+ model.columns_changing_default(:value)
+ model.columns # Force the schema cache to populate
+ end
+ end
+
+ def alter_default(new_default)
+ ApplicationRecord.connection.execute(<<~SQL)
+ ALTER TABLE _test_gitlab_main_data ALTER COLUMN value SET DEFAULT #{new_default}
+ SQL
+ end
+
+ def recorded_insert_queries(&block)
+ recorder = ActiveRecord::QueryRecorder.new
+ recorder.record(&block)
+
+ recorder.log.select { |q| q.include?('INSERT INTO') }
+ end
+
+ def query_includes_value_column?(query)
+ parsed = PgQuery.parse(query)
+ parsed.tree.stmts.first.stmt.insert_stmt.cols.any? { |node| node.res_target.name == 'value' }
+ end
+
+ it 'forces the column to be written on a change' do
+ queries = recorded_insert_queries do
+ model.create!(value: 1)
+ end
+
+ expect(queries.length).to eq(1)
+
+ expect(query_includes_value_column?(queries.first)).to be_truthy
+ end
+
+ it 'does not write the column without a change' do
+ queries = recorded_insert_queries do
+ model.create!
+ end
+
+ expect(queries.length).to eq(1)
+ expect(query_includes_value_column?(queries.first)).to be_falsey
+ end
+
+ it 'does not send the old column value if the default has changed' do
+ alter_default(2)
+ model.create!
+
+ expect(model.pluck(:value)).to contain_exactly(2)
+ end
+
+ it 'prevents writing new default in place of the old default' do
+ alter_default(2)
+
+ model.create!(value: 1)
+
+ expect(model.pluck(:value)).to contain_exactly(1)
+ end
+end
diff --git a/spec/models/concerns/sensitive_serializable_hash_spec.rb b/spec/models/concerns/sensitive_serializable_hash_spec.rb
index 591a4383a03..0bfd2d6a7de 100644
--- a/spec/models/concerns/sensitive_serializable_hash_spec.rb
+++ b/spec/models/concerns/sensitive_serializable_hash_spec.rb
@@ -95,7 +95,7 @@ RSpec.describe SensitiveSerializableHash do
expect(model.attributes).to include(attribute) # double-check the attribute does exist
expect(model.serializable_hash).not_to include(attribute)
- expect(model.to_json).not_to include(attribute)
+ expect(model.to_json).not_to match(/\b#{attribute}\b/)
expect(model.as_json).not_to include(attribute)
end
end