diff options
Diffstat (limited to 'spec/models/concerns')
-rw-r--r-- | spec/models/concerns/counter_attribute_spec.rb | 44 | ||||
-rw-r--r-- | spec/models/concerns/has_user_type_spec.rb | 3 | ||||
-rw-r--r-- | spec/models/concerns/noteable_spec.rb | 76 | ||||
-rw-r--r-- | spec/models/concerns/safely_change_column_default_spec.rb | 75 | ||||
-rw-r--r-- | spec/models/concerns/sensitive_serializable_hash_spec.rb | 2 |
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 |