diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-22 21:10:13 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-22 21:10:13 +0300 |
commit | 0a5e00b6914944295b31ce10ffd5429cbe9fae89 (patch) | |
tree | 580508961eaa268b13df3eafe6f373b5b500d8c5 /spec | |
parent | 5f5f492fe278f3322e9533b617522321e2ccafcc (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
15 files changed, 197 insertions, 236 deletions
diff --git a/spec/factories/alert_management/alerts.rb b/spec/factories/alert_management/alerts.rb index ee1225b9542..0131eca68a1 100644 --- a/spec/factories/alert_management/alerts.rb +++ b/spec/factories/alert_management/alerts.rb @@ -109,6 +109,20 @@ FactoryBot.define do end end + trait :cilium do + monitoring_tool { Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:cilium] } + payload do + { + annotations: { + title: 'This is a cilium alert', + summary: 'Summary of the alert', + description: 'Description of the alert' + }, + startsAt: started_at + }.with_indifferent_access + end + end + trait :all_fields do with_issue with_assignee diff --git a/spec/finders/packages/maven/package_finder_spec.rb b/spec/finders/packages/maven/package_finder_spec.rb index ca144292501..9a6bb675248 100644 --- a/spec/finders/packages/maven/package_finder_spec.rb +++ b/spec/finders/packages/maven/package_finder_spec.rb @@ -47,23 +47,7 @@ RSpec.describe ::Packages::Maven::PackageFinder do context 'within a group' do let(:param_group) { group } - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - expect(finder).to receive(:packages_visible_to_user).with(user, within_group: group).and_call_original - end - - it_behaves_like 'handling valid and invalid paths' - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - expect(finder).not_to receive(:packages_visible_to_user) - end - - it_behaves_like 'handling valid and invalid paths' - end + it_behaves_like 'handling valid and invalid paths' end context 'across all projects' do @@ -93,38 +77,14 @@ RSpec.describe ::Packages::Maven::PackageFinder do create(:package_file, :xml, package: package2) end - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - expect(finder).not_to receive(:versionless_package?) - end - - context 'without order by package file' do - it { is_expected.to eq(package3) } - end - - context 'with order by package file' do - let(:param_order_by_package_file) { true } - - it { is_expected.to eq(package2) } - end + context 'without order by package file' do + it { is_expected.to eq(package3) } end - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - expect(finder).to receive(:versionless_package?).and_call_original - end + context 'with order by package file' do + let(:param_order_by_package_file) { true } - context 'without order by package file' do - it { is_expected.to eq(package2) } - end - - context 'with order by package file' do - let(:param_order_by_package_file) { true } - - it { is_expected.to eq(package2) } - end + it { is_expected.to eq(package2) } end end end diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml new file mode 100644 index 00000000000..c51b5bf6e01 --- /dev/null +++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_ee.yml @@ -0,0 +1,19 @@ +--- +key_path: counts_weekly.test_metric +name: test metric name +description: +product_section: +product_stage: +product_group: +product_category: +value_type: number +status: implemented +milestone: "13.9" +introduced_by_url: +time_frame: 7d +data_source: +distribution: +- ee +tier: +#- premium +- ultimate diff --git a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml index 47fc1d7e376..c1ed9783308 100644 --- a/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml +++ b/spec/fixtures/lib/generators/gitlab/usage_metric_definition_generator/sample_metric_with_name_suggestions.yml @@ -15,8 +15,8 @@ time_frame: 7d data_source: distribution: - ce -# Add here corresponding tiers -# tier: -# - free -# - premium -# - ultimate +- ee +tier: +- free +- premium +- ultimate diff --git a/spec/frontend/pipelines/test_reports/empty_state_spec.js b/spec/frontend/pipelines/test_reports/empty_state_spec.js new file mode 100644 index 00000000000..ee0f8a90a11 --- /dev/null +++ b/spec/frontend/pipelines/test_reports/empty_state_spec.js @@ -0,0 +1,45 @@ +import { GlEmptyState } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import EmptyState, { i18n } from '~/pipelines/components/test_reports/empty_state.vue'; + +describe('Test report empty state', () => { + let wrapper; + + const findEmptyState = () => wrapper.findComponent(GlEmptyState); + + const createComponent = ({ hasTestReport = true } = {}) => { + wrapper = shallowMount(EmptyState, { + provide: { + emptyStateImagePath: '/image/path', + hasTestReport, + }, + stubs: { + GlEmptyState, + }, + }); + }; + + describe('when pipeline has a test report', () => { + it('should render empty test report message', () => { + createComponent(); + + expect(findEmptyState().props()).toMatchObject({ + primaryButtonText: i18n.noTestsButton, + description: i18n.noTestsDescription, + title: i18n.noTestsTitle, + }); + }); + }); + + describe('when pipeline does not have a test report', () => { + it('should render no test report message', () => { + createComponent({ hasTestReport: false }); + + expect(findEmptyState().props()).toMatchObject({ + primaryButtonText: i18n.noReportsButton, + description: i18n.noReportsDescription, + title: i18n.noReportsTitle, + }); + }); + }); +}); diff --git a/spec/frontend/pipelines/test_reports/test_reports_spec.js b/spec/frontend/pipelines/test_reports/test_reports_spec.js index da5763ddf8e..34bbe7cc0e1 100644 --- a/spec/frontend/pipelines/test_reports/test_reports_spec.js +++ b/spec/frontend/pipelines/test_reports/test_reports_spec.js @@ -2,6 +2,8 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { shallowMount, createLocalVue } from '@vue/test-utils'; import Vuex from 'vuex'; import { getJSONFixture } from 'helpers/fixtures'; +import { extendedWrapper } from 'helpers/vue_test_utils_helper'; +import EmptyState from '~/pipelines/components/test_reports/empty_state.vue'; import TestReports from '~/pipelines/components/test_reports/test_reports.vue'; import TestSummary from '~/pipelines/components/test_reports/test_summary.vue'; import TestSummaryTable from '~/pipelines/components/test_reports/test_summary_table.vue'; @@ -16,11 +18,11 @@ describe('Test reports app', () => { const testReports = getJSONFixture('pipelines/test_report.json'); - const loadingSpinner = () => wrapper.find(GlLoadingIcon); - const testsDetail = () => wrapper.find('[data-testid="tests-detail"]'); - const noTestsToShow = () => wrapper.find('[data-testid="no-tests-to-show"]'); - const testSummary = () => wrapper.find(TestSummary); - const testSummaryTable = () => wrapper.find(TestSummaryTable); + const loadingSpinner = () => wrapper.findComponent(GlLoadingIcon); + const testsDetail = () => wrapper.findByTestId('tests-detail'); + const emptyState = () => wrapper.findComponent(EmptyState); + const testSummary = () => wrapper.findComponent(TestSummary); + const testSummaryTable = () => wrapper.findComponent(TestSummaryTable); const actionSpies = { fetchTestSuite: jest.fn(), @@ -29,7 +31,7 @@ describe('Test reports app', () => { removeSelectedSuiteIndex: jest.fn(), }; - const createComponent = (state = {}) => { + const createComponent = ({ state = {}, hasTestReport = true } = {}) => { store = new Vuex.Store({ state: { isLoading: false, @@ -41,10 +43,15 @@ describe('Test reports app', () => { getters, }); - wrapper = shallowMount(TestReports, { - store, - localVue, - }); + wrapper = extendedWrapper( + shallowMount(TestReports, { + store, + localVue, + provide: { + hasTestReport, + }, + }), + ); }; afterEach(() => { @@ -52,33 +59,34 @@ describe('Test reports app', () => { }); describe('when component is created', () => { - beforeEach(() => { + it('should call fetchSummary when pipeline has test report', () => { createComponent(); - }); - it('should call fetchSummary', () => { expect(actionSpies.fetchSummary).toHaveBeenCalled(); }); + + it('should not call fetchSummary when pipeline does not have test report', () => { + createComponent({ state: {}, hasTestReport: false }); + + expect(actionSpies.fetchSummary).not.toHaveBeenCalled(); + }); }); describe('when loading', () => { - beforeEach(() => createComponent({ isLoading: true })); + beforeEach(() => createComponent({ state: { isLoading: true } })); it('shows the loading spinner', () => { - expect(noTestsToShow().exists()).toBe(false); + expect(emptyState().exists()).toBe(false); expect(testsDetail().exists()).toBe(false); expect(loadingSpinner().exists()).toBe(true); }); }); describe('when the api returns no data', () => { - beforeEach(() => createComponent({ testReports: {} })); - - it('displays that there are no tests to show', () => { - const noTests = noTestsToShow(); + it('displays empty state component', () => { + createComponent({ state: { testReports: {} } }); - expect(noTests.exists()).toBe(true); - expect(noTests.text()).toBe('There are no tests to show.'); + expect(emptyState().exists()).toBe(true); }); }); @@ -97,7 +105,7 @@ describe('Test reports app', () => { describe('when a suite is clicked', () => { beforeEach(() => { - createComponent({ hasFullReport: true }); + createComponent({ state: { hasFullReport: true } }); testSummaryTable().vm.$emit('row-click', 0); }); @@ -109,7 +117,7 @@ describe('Test reports app', () => { describe('when clicking back to summary', () => { beforeEach(() => { - createComponent({ selectedSuiteIndex: 0 }); + createComponent({ state: { selectedSuiteIndex: 0 } }); testSummary().vm.$emit('on-back-click'); }); diff --git a/spec/frontend/whats_new/utils/notification_spec.js b/spec/frontend/whats_new/utils/notification_spec.js index e1de65df30f..c361f934e59 100644 --- a/spec/frontend/whats_new/utils/notification_spec.js +++ b/spec/frontend/whats_new/utils/notification_spec.js @@ -33,19 +33,6 @@ describe('~/whats_new/utils/notification', () => { expect(notificationEl.classList).toContain('with-notifications'); }); - it('removes class and count element when legacy storage key is false', () => { - const notificationEl = findNotificationEl(); - notificationEl.classList.add('with-notifications'); - localStorage.setItem('display-whats-new-notification-13.10', 'false'); - - expect(findNotificationCountEl()).toExist(); - - subject(); - - expect(findNotificationCountEl()).not.toExist(); - expect(notificationEl.classList).not.toContain('with-notifications'); - }); - it('removes class and count element when storage key has current digest', () => { const notificationEl = findNotificationEl(); notificationEl.classList.add('with-notifications'); diff --git a/spec/lib/generators/gitlab/usage_metric_definition_generator_spec.rb b/spec/lib/generators/gitlab/usage_metric_definition_generator_spec.rb index f8c055ae111..74aaf34e82c 100644 --- a/spec/lib/generators/gitlab/usage_metric_definition_generator_spec.rb +++ b/spec/lib/generators/gitlab/usage_metric_definition_generator_spec.rb @@ -20,20 +20,37 @@ RSpec.describe Gitlab::UsageMetricDefinitionGenerator do end describe 'Creating metric definition file' do + let(:sample_metric) { load_sample_metric_definition(filename: sample_filename) } + # Stub version so that `milestone` key remains constant between releases to prevent flakiness. before do stub_const('Gitlab::VERSION', '13.9.0') allow(::Gitlab::Usage::Metrics::NamesSuggestions::Generator).to receive(:generate).and_return('test metric name') end - let(:sample_metric) { load_sample_metric_definition(filename: 'sample_metric_with_name_suggestions.yml') } + context 'without ee option' do + let(:sample_filename) { 'sample_metric_with_name_suggestions.yml' } + let(:metric_definition_path) { Dir.glob(File.join(temp_dir, 'metrics/counts_7d/*_test_metric.yml')).first } - it 'creates a metric definition file using the template' do - described_class.new([key_path], { 'dir' => dir }).invoke_all + it 'creates a metric definition file using the template' do + described_class.new([key_path], { 'dir' => dir }).invoke_all + expect(YAML.safe_load(File.read(metric_definition_path))).to eq(sample_metric) + end + end - metric_definition_path = Dir.glob(File.join(temp_dir, 'metrics/counts_7d/*_test_metric.yml')).first + context 'with ee option' do + let(:sample_filename) { 'sample_metric_with_ee.yml' } + let(:metric_definition_path) { Dir.glob(File.join(temp_dir, 'ee/config/metrics/counts_7d/*_test_metric.yml')).first } - expect(YAML.safe_load(File.read(metric_definition_path))).to eq(sample_metric) + before do + stub_const("#{described_class}::TOP_LEVEL_DIR", 'config') + stub_const("#{described_class}::TOP_LEVEL_DIR_EE", File.join(temp_dir, 'ee')) + end + + it 'creates a metric definition file using the template' do + described_class.new([key_path], { 'dir' => dir, 'ee': true }).invoke_all + expect(YAML.safe_load(File.read(metric_definition_path))).to eq(sample_metric) + end end end diff --git a/spec/lib/gitlab/database/migration_helpers/cascading_namespace_settings_spec.rb b/spec/lib/gitlab/database/migration_helpers/cascading_namespace_settings_spec.rb new file mode 100644 index 00000000000..e11ffe53c61 --- /dev/null +++ b/spec/lib/gitlab/database/migration_helpers/cascading_namespace_settings_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Database::MigrationHelpers::CascadingNamespaceSettings do + let(:migration) do + ActiveRecord::Migration.new.extend(described_class) + end + + describe '#add_cascading_namespace_setting' do + it 'creates the required columns', :aggregate_failures do + expect(migration).to receive(:add_column).with(:namespace_settings, :some_setting, :integer, null: true, default: nil) + expect(migration).to receive(:add_column).with(:namespace_settings, :lock_some_setting, :boolean, null: false, default: false) + + expect(migration).to receive(:add_column).with(:application_settings, :some_setting, :integer, null: false, default: 5) + expect(migration).to receive(:add_column).with(:application_settings, :lock_some_setting, :boolean, null: false, default: false) + + migration.add_cascading_namespace_setting(:some_setting, :integer, null: false, default: 5) + end + + context 'when columns already exist' do + before do + migration.add_column(:namespace_settings, :cascading_setting, :integer) + migration.add_column(:application_settings, :lock_cascading_setting, :boolean) + end + + it 'raises an error when some columns already exist' do + expect do + migration.add_cascading_namespace_setting(:cascading_setting, :integer) + end.to raise_error %r/Existing columns: namespace_settings.cascading_setting, application_settings.lock_cascading_setting/ + end + end + end + + describe '#remove_cascading_namespace_setting' do + before do + allow(migration).to receive(:column_exists?).and_return(true) + end + + it 'removes the columns', :aggregate_failures do + expect(migration).to receive(:remove_column).with(:namespace_settings, :some_setting) + expect(migration).to receive(:remove_column).with(:namespace_settings, :lock_some_setting) + + expect(migration).to receive(:remove_column).with(:application_settings, :some_setting) + expect(migration).to receive(:remove_column).with(:application_settings, :lock_some_setting) + + migration.remove_cascading_namespace_setting(:some_setting) + end + end +end diff --git a/spec/lib/gitlab/usage_data_queries_spec.rb b/spec/lib/gitlab/usage_data_queries_spec.rb index 6a529328cde..695859c8e6e 100644 --- a/spec/lib/gitlab/usage_data_queries_spec.rb +++ b/spec/lib/gitlab/usage_data_queries_spec.rb @@ -63,7 +63,7 @@ RSpec.describe Gitlab::UsageDataQueries do it 'returns the histogram sql' do expect(described_class.histogram(AlertManagement::HttpIntegration.active, :project_id, buckets: 1..2, bucket_size: 101)) - .to eq('WITH "count_cte" AS (SELECT COUNT(*) AS count_grouped FROM "alert_management_http_integrations" WHERE "alert_management_http_integrations"."active" = TRUE GROUP BY "alert_management_http_integrations"."project_id") SELECT WIDTH_BUCKET("count_cte"."count_grouped", 1, 2, 100) AS buckets, "count_cte"."count" FROM "count_cte" GROUP BY buckets ORDER BY buckets') + .to match(/^WITH "count_cte" AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported}/) end end diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb index 23ca5c6e3e6..d03a2a4992f 100644 --- a/spec/models/packages/package_spec.rb +++ b/spec/models/packages/package_spec.rb @@ -114,18 +114,6 @@ RSpec.describe Packages::Package, type: :model do expect(subject).to match_array([package1, package2]) end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it 'returns package1 and package2' do - expect(projects).to receive(:any?).and_call_original - - expect(subject).to match_array([package1, package2]) - end - end end describe 'validations' do diff --git a/spec/models/wiki_page/meta_spec.rb b/spec/models/wiki_page/meta_spec.rb index 24906d4fb79..42ec98c3491 100644 --- a/spec/models/wiki_page/meta_spec.rb +++ b/spec/models/wiki_page/meta_spec.rb @@ -124,6 +124,7 @@ RSpec.describe WikiPage::Meta do context 'the slug is already in the DB (but not canonical)' do let_it_be(:slug_record) { create(:wiki_page_slug, wiki_page_meta: meta) } + let(:slug) { slug_record.slug } let(:query_limit) { 4 } @@ -132,6 +133,7 @@ RSpec.describe WikiPage::Meta do context 'the slug is already in the DB (and canonical)' do let_it_be(:slug_record) { create(:wiki_page_slug, :canonical, wiki_page_meta: meta) } + let(:slug) { slug_record.slug } let(:query_limit) { 4 } diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index be94eca550c..44014f93444 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -640,6 +640,7 @@ RSpec.describe WikiPage do let_it_be(:existing_page) { create_wiki_page(title: 'test page') } let_it_be(:directory_page) { create_wiki_page(title: 'parent directory/child page') } let_it_be(:page_with_special_characters) { create_wiki_page(title: 'test+page') } + let(:untitled_page) { described_class.new(wiki) } where(:page, :title, :changed) do diff --git a/spec/requests/api/maven_packages_spec.rb b/spec/requests/api/maven_packages_spec.rb index 3a015e98fb1..1416d35d9d1 100644 --- a/spec/requests/api/maven_packages_spec.rb +++ b/spec/requests/api/maven_packages_spec.rb @@ -299,22 +299,6 @@ RSpec.describe API::MavenPackages do end end - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - end - - it_behaves_like 'handling all conditions' - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it_behaves_like 'handling all conditions' - end - context 'with check_maven_path_first enabled' do before do stub_feature_flags(check_maven_path_first: true) @@ -346,22 +330,6 @@ RSpec.describe API::MavenPackages do it_behaves_like 'processing HEAD requests', instance_level: true - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - end - - it_behaves_like 'processing HEAD requests', instance_level: true - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it_behaves_like 'processing HEAD requests', instance_level: true - end - context 'with check_maven_path_first enabled' do before do stub_feature_flags(check_maven_path_first: true) @@ -468,8 +436,7 @@ RSpec.describe API::MavenPackages do subject - status = Feature.enabled?(:maven_packages_group_level_improvements, default_enabled: :yaml) ? :not_found : :forbidden - expect(response).to have_gitlab_http_status(status) + expect(response).to have_gitlab_http_status(:not_found) end it 'denies download when no private token' do @@ -594,22 +561,6 @@ RSpec.describe API::MavenPackages do end end - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - end - - it_behaves_like 'handling all conditions' - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it_behaves_like 'handling all conditions' - end - context 'with check_maven_path_first enabled' do before do stub_feature_flags(check_maven_path_first: true) @@ -639,22 +590,6 @@ RSpec.describe API::MavenPackages do let(:path) { package.maven_metadatum.path } let(:url) { "/groups/#{group.id}/-/packages/maven/#{path}/#{package_file.file_name}" } - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - end - - it_behaves_like 'processing HEAD requests' - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it_behaves_like 'processing HEAD requests' - end - context 'with check_maven_path_first enabled' do before do stub_feature_flags(check_maven_path_first: true) @@ -743,22 +678,6 @@ RSpec.describe API::MavenPackages do end end - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - end - - it_behaves_like 'handling all conditions' - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it_behaves_like 'handling all conditions' - end - context 'with check_maven_path_first enabled' do before do stub_feature_flags(check_maven_path_first: true) @@ -789,22 +708,6 @@ RSpec.describe API::MavenPackages do let(:path) { package.maven_metadatum.path } let(:url) { "/projects/#{project.id}/packages/maven/#{path}/#{package_file.file_name}" } - context 'with maven_packages_group_level_improvements enabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: true) - end - - it_behaves_like 'processing HEAD requests' - end - - context 'with maven_packages_group_level_improvements disabled' do - before do - stub_feature_flags(maven_packages_group_level_improvements: false) - end - - it_behaves_like 'processing HEAD requests' - end - context 'with check_maven_path_first enabled' do before do stub_feature_flags(check_maven_path_first: true) diff --git a/spec/serializers/member_serializer_spec.rb b/spec/serializers/member_serializer_spec.rb index f7415214e95..687d69f86ea 100644 --- a/spec/serializers/member_serializer_spec.rb +++ b/spec/serializers/member_serializer_spec.rb @@ -30,39 +30,6 @@ RSpec.describe MemberSerializer do .from(nil).to(true) .and change(group_member, :last_blocked_owner).from(nil).to(false) end - - context "with LastGroupOwnerAssigner query improvements" do - it "avoids N+1 database queries for last group owner assignment in MembersPresenter" do - group_member = create(:group_member, group: group) - control_count = ActiveRecord::QueryRecorder.new { member_last_owner_with_preload([group_member]) }.count - group_members = create_list(:group_member, 3, group: group) - - expect { member_last_owner_with_preload(group_members) }.not_to exceed_query_limit(control_count) - end - - it "avoids N+1 database queries for last blocked owner assignment in MembersPresenter" do - group_member = create(:group_member, group: group) - control_count = ActiveRecord::QueryRecorder.new { member_last_blocked_owner_with_preload([group_member]) }.count - group_members = create_list(:group_member, 3, group: group) - - expect { member_last_blocked_owner_with_preload(group_members) }.not_to exceed_query_limit(control_count) - end - - def member_last_owner_with_preload(members) - assigner_with_preload(members) - members.map { |m| group.member_last_owner?(m) } - end - - def member_last_blocked_owner_with_preload(members) - assigner_with_preload(members) - members.map { |m| group.member_last_blocked_owner?(m) } - end - - def assigner_with_preload(members) - MembersPreloader.new(members).preload_all - Members::LastGroupOwnerAssigner.new(group, members).execute - end - end end context 'project member' do |