diff options
Diffstat (limited to 'spec/support/shared_examples/models')
8 files changed, 71 insertions, 47 deletions
diff --git a/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb b/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb index a20bb794095..f98be12523d 100644 --- a/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/counter_attribute_shared_examples.rb @@ -14,13 +14,14 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| counter_attributes.each do |attribute| describe attribute do describe '#increment_counter', :redis do - let(:increment) { 10 } + let(:amount) { 10 } + let(:increment) { Gitlab::Counters::Increment.new(amount: amount) } let(:counter_key) { model.counter(attribute).key } subject { model.increment_counter(attribute, increment) } context 'when attribute is a counter attribute' do - where(:increment) { [10, -3] } + where(:amount) { [10, -3] } with_them do it 'increments the counter in Redis and logs it' do @@ -29,8 +30,8 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| message: 'Increment counter attribute', attribute: attribute, project_id: model.project_id, - increment: increment, - new_counter_value: 0 + increment, + increment: amount, + new_counter_value: 0 + amount, current_db_value: model.read_attribute(attribute), 'correlation_id' => an_instance_of(String), 'meta.feature_category' => 'test', @@ -42,7 +43,7 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| Gitlab::Redis::SharedState.with do |redis| counter = redis.get(counter_key) - expect(counter).to eq(increment.to_s) + expect(counter).to eq(amount.to_s) end end @@ -59,8 +60,8 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| end end - context 'when increment is 0' do - let(:increment) { 0 } + context 'when increment amount is 0' do + let(:amount) { 0 } it 'does nothing' do expect(FlushCounterIncrementsWorker).not_to receive(:perform_in) @@ -71,37 +72,49 @@ RSpec.shared_examples_for CounterAttribute do |counter_attributes| end end end - end - end - describe '#reset_counter!' do - let(:attribute) { counter_attributes.first } - let(:counter_key) { model.counter(attribute).key } + describe '#bulk_increment_counter', :redis do + let(:increments) { [Gitlab::Counters::Increment.new(amount: 10), Gitlab::Counters::Increment.new(amount: 5)] } + let(:total_amount) { increments.sum(&:amount) } + let(:counter_key) { model.counter(attribute).key } - before do - model.update!(attribute => 123) - model.increment_counter(attribute, 10) - end + subject { model.bulk_increment_counter(attribute, increments) } - subject { model.reset_counter!(attribute) } + context 'when attribute is a counter attribute' do + it 'increments the counter in Redis and logs it' do + expect(Gitlab::AppLogger).to receive(:info).with( + hash_including( + message: 'Increment counter attribute', + attribute: attribute, + project_id: model.project_id, + increment: total_amount, + new_counter_value: 0 + total_amount, + current_db_value: model.read_attribute(attribute), + 'correlation_id' => an_instance_of(String), + 'meta.feature_category' => 'test', + 'meta.caller_id' => 'caller' + ) + ) - it 'resets the attribute value to 0 and clears existing counter', :aggregate_failures do - expect { subject }.to change { model.reload.send(attribute) }.from(123).to(0) + subject - Gitlab::Redis::SharedState.with do |redis| - key_exists = redis.exists?(counter_key) - expect(key_exists).to be_falsey - end - end + Gitlab::Redis::SharedState.with do |redis| + counter = redis.get(counter_key) + expect(counter).to eq(total_amount.to_s) + end + end - it_behaves_like 'obtaining lease to update database' do - context 'when the execution raises error' do - before do - allow(model).to receive(:update!).and_raise(StandardError, 'Something went wrong') - end + it 'does not increment the counter for the record' do + expect { subject }.not_to change { model.reset.read_attribute(attribute) } + end - it 'reraises error' do - expect { subject }.to raise_error(StandardError, 'Something went wrong') + it 'schedules a worker to flush counter increments asynchronously' do + expect(FlushCounterIncrementsWorker).to receive(:perform_in) + .with(Gitlab::Counters::BufferedCounter::WORKER_DELAY, model.class.name, model.id, attribute) + .and_call_original + + subject + end end end end diff --git a/spec/support/shared_examples/models/concerns/integrations/reset_secret_fields_shared_examples.rb b/spec/support/shared_examples/models/concerns/integrations/reset_secret_fields_shared_examples.rb index 873f858e432..c51a6c4f6fd 100644 --- a/spec/support/shared_examples/models/concerns/integrations/reset_secret_fields_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/integrations/reset_secret_fields_shared_examples.rb @@ -42,7 +42,7 @@ RSpec.shared_examples Integrations::ResetSecretFields do # Treat values as persisted integration.reset_updated_properties - integration.instance_variable_set('@old_data_fields', nil) if integration.supports_data_fields? + integration.instance_variable_set(:@old_data_fields, nil) if integration.supports_data_fields? end context 'when an exposing field has changed' do diff --git a/spec/support/shared_examples/models/cycle_analytics_stage_shared_examples.rb b/spec/support/shared_examples/models/cycle_analytics_stage_shared_examples.rb index 457ee49938f..5eeefacdeb9 100644 --- a/spec/support/shared_examples/models/cycle_analytics_stage_shared_examples.rb +++ b/spec/support/shared_examples/models/cycle_analytics_stage_shared_examples.rb @@ -25,7 +25,7 @@ RSpec.shared_examples 'value stream analytics stage' do stage = described_class.new(valid_params.except(:parent)) expect(stage).to be_invalid - expect(stage.errors[parent_name]).to include("can't be blank") + expect(stage.errors[parent_name]).to include('must exist') end it 'validates presence of start_event_identifier' do diff --git a/spec/support/shared_examples/models/member_shared_examples.rb b/spec/support/shared_examples/models/member_shared_examples.rb index f8cff5c5558..7159c55e303 100644 --- a/spec/support/shared_examples/models/member_shared_examples.rb +++ b/spec/support/shared_examples/models/member_shared_examples.rb @@ -207,16 +207,14 @@ RSpec.shared_examples_for "member creation" do source.request_access(user) end - it 'does not add the requester as a regular member', :aggregate_failures do + it 'adds the requester as a member', :aggregate_failures do expect(source.users).not_to include(user) - expect(source.requesters.exists?(user_id: user)).to be_truthy + expect(source.requesters.exists?(user_id: user)).to eq(true) - expect do - described_class.add_member(source, user, :maintainer) - end.to raise_error(Gitlab::Access::AccessDeniedError) + described_class.add_member(source, user, :maintainer) - expect(source.users.reload).not_to include(user) - expect(source.requesters.reload.exists?(user_id: user)).to be_truthy + expect(source.users.reload).to include(user) + expect(source.requesters.reload.exists?(user_id: user)).to eq(false) end end diff --git a/spec/support/shared_examples/models/members_notifications_shared_example.rb b/spec/support/shared_examples/models/members_notifications_shared_example.rb index e74aab95e46..e28220334ac 100644 --- a/spec/support/shared_examples/models/members_notifications_shared_example.rb +++ b/spec/support/shared_examples/models/members_notifications_shared_example.rb @@ -51,7 +51,7 @@ RSpec.shared_examples 'members notifications' do |entity_type| it "calls NotificationService.new_#{entity_type}_member" do expect(notification_service).to receive(:"new_#{entity_type}_member").with(member) - member.accept_request + member.accept_request(create(:user)) end end diff --git a/spec/support/shared_examples/models/relative_positioning_shared_examples.rb b/spec/support/shared_examples/models/relative_positioning_shared_examples.rb index b8d12a6da59..2b46c8c8fb9 100644 --- a/spec/support/shared_examples/models/relative_positioning_shared_examples.rb +++ b/spec/support/shared_examples/models/relative_positioning_shared_examples.rb @@ -20,6 +20,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do let(:new_item) { create_item(relative_position: nil) } let(:set_size) { RelativePositioning.mover.context(item1).scoped_items.count } + let(:items_with_nil_position_sample_quantity) { 101 } def create_item(params = {}) create(factory, params.merge(default_params)) @@ -163,7 +164,7 @@ RSpec.shared_examples 'a class that supports relative positioning' do end it 'can move many nulls' do - nils = create_items_with_positions([nil] * 101) + nils = create_items_with_positions([nil] * items_with_nil_position_sample_quantity) described_class.move_nulls_to_end(nils) diff --git a/spec/support/shared_examples/models/resource_event_shared_examples.rb b/spec/support/shared_examples/models/resource_event_shared_examples.rb index 80806ee768a..8cab2de076d 100644 --- a/spec/support/shared_examples/models/resource_event_shared_examples.rb +++ b/spec/support/shared_examples/models/resource_event_shared_examples.rb @@ -161,3 +161,15 @@ RSpec.shared_examples 'a resource event for merge requests' do end end end + +RSpec.shared_examples 'a note for work item resource event' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:work_item) { create(:work_item, :task, project: project, author: user) } + + it 'builds synthetic note with correct synthetic_note_class' do + event = build(described_class.name.underscore.to_sym, issue: work_item) + + expect(event.work_item_synthetic_system_note.class.name).to eq(event.synthetic_note_class.name) + end +end diff --git a/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb b/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb index eb742921d35..5aaa93aecef 100644 --- a/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb +++ b/spec/support/shared_examples/models/update_project_statistics_shared_examples.rb @@ -60,8 +60,11 @@ RSpec.shared_examples 'UpdateProjectStatistics' do |with_counter_attribute| end it 'stores pending increments for async update' do + expected_increment = have_attributes(amount: delta, ref: subject.id) + expect(ProjectStatistics) .to receive(:increment_statistic) + .with(project, project_statistics_name, expected_increment) .and_call_original subject.write_attribute(statistic_attribute, read_attribute + delta) @@ -108,11 +111,8 @@ RSpec.shared_examples 'UpdateProjectStatistics' do |with_counter_attribute| end context 'when it is destroyed from the project level' do - it 'does not update the project statistics' do - expect(ProjectStatistics) - .not_to receive(:increment_statistic) - - expect(Projects::DestroyService.new(project, project.first_owner).execute).to eq(true) + it 'does not store pending increments for async update' do + expect { Projects::DestroyService.new(project, project.first_owner).execute }.not_to change { read_pending_increment } end it 'does not schedule a namespace statistics worker' do |