summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-31 12:10:34 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-31 12:10:34 +0000
commit7dc0a21702cd9345eeee385d8ce20002d9c9fb36 (patch)
treea369b90331ed6f61a37477e5e5713fcccfd45b4c /spec
parente5f7ee6673f47290d860565f13a5a26391822260 (diff)
downloadgitlab-ce-7dc0a21702cd9345eeee385d8ce20002d9c9fb36.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/boards/components/board_form_spec.js20
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js11
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js6
-rw-r--r--spec/lib/banzai/reference_parser/commit_parser_spec.rb4
-rw-r--r--spec/lib/banzai/reference_parser/merge_request_parser_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/parsers/test/junit_spec.rb29
-rw-r--r--spec/lib/gitlab/usage/metric_definition_spec.rb16
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb2
-rw-r--r--spec/support/capybara.rb1
-rw-r--r--spec/support/helpers/reference_parser_helpers.rb15
13 files changed, 90 insertions, 49 deletions
diff --git a/spec/frontend/boards/components/board_form_spec.js b/spec/frontend/boards/components/board_form_spec.js
index 24fcdd528d5..80d740458dc 100644
--- a/spec/frontend/boards/components/board_form_spec.js
+++ b/spec/frontend/boards/components/board_form_spec.js
@@ -9,14 +9,12 @@ import createBoardMutation from '~/boards/graphql/board_create.mutation.graphql'
import destroyBoardMutation from '~/boards/graphql/board_destroy.mutation.graphql';
import updateBoardMutation from '~/boards/graphql/board_update.mutation.graphql';
import { createStore } from '~/boards/stores';
-import { deprecatedCreateFlash as createFlash } from '~/flash';
import { visitUrl } from '~/lib/utils/url_utility';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn().mockName('visitUrlMock'),
stripFinalUrlSegment: jest.requireActual('~/lib/utils/url_utility').stripFinalUrlSegment,
}));
-jest.mock('~/flash');
const currentBoard = {
id: 1,
@@ -194,9 +192,11 @@ describe('BoardForm', () => {
expect(visitUrl).toHaveBeenCalledWith('test-path');
});
- it('shows an error flash if GraphQL mutation fails', async () => {
+ it('shows a GlAlert if GraphQL mutation fails', async () => {
mutate = jest.fn().mockRejectedValue('Houston, we have a problem');
createComponent({ canAdminBoard: true, currentPage: formType.new });
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
+
fillForm();
await waitForPromises();
@@ -205,7 +205,7 @@ describe('BoardForm', () => {
await waitForPromises();
expect(visitUrl).not.toHaveBeenCalled();
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
});
@@ -290,9 +290,11 @@ describe('BoardForm', () => {
expect(visitUrl).toHaveBeenCalledWith('test-path?group_by=epic');
});
- it('shows an error flash if GraphQL mutation fails', async () => {
+ it('shows a GlAlert if GraphQL mutation fails', async () => {
mutate = jest.fn().mockRejectedValue('Houston, we have a problem');
createComponent({ canAdminBoard: true, currentPage: formType.edit });
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
+
findInput().trigger('keyup.enter', { metaKey: true });
await waitForPromises();
@@ -301,7 +303,7 @@ describe('BoardForm', () => {
await waitForPromises();
expect(visitUrl).not.toHaveBeenCalled();
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
@@ -335,9 +337,11 @@ describe('BoardForm', () => {
expect(visitUrl).toHaveBeenCalledWith('root');
});
- it('shows an error flash if GraphQL mutation fails', async () => {
+ it('dispatches `setError` action when GraphQL mutation fails', async () => {
mutate = jest.fn().mockRejectedValue('Houston, we have a problem');
createComponent({ canAdminBoard: true, currentPage: formType.delete });
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
+
findModal().vm.$emit('primary');
await waitForPromises();
@@ -346,7 +350,7 @@ describe('BoardForm', () => {
await waitForPromises();
expect(visitUrl).not.toHaveBeenCalled();
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
index 8fd178a0856..2f91beda275 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
@@ -3,15 +3,12 @@ import { shallowMount } from '@vue/test-utils';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import BoardSidebarDueDate from '~/boards/components/sidebar/board_sidebar_due_date.vue';
import { createStore } from '~/boards/stores';
-import createFlash from '~/flash';
const TEST_DUE_DATE = '2020-02-20';
const TEST_FORMATTED_DUE_DATE = 'Feb 20, 2020';
const TEST_PARSED_DATE = new Date(2020, 1, 20);
const TEST_ISSUE = { id: 'gid://gitlab/Issue/1', iid: 9, dueDate: null, referencePath: 'h/b#2' };
-jest.mock('~/flash');
-
describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
let wrapper;
let store;
@@ -124,6 +121,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
throw new Error(['failed mutation']);
});
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
findDatePicker().vm.$emit('input', 'Invalid date');
await wrapper.vm.$nextTick();
});
@@ -131,7 +129,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
it('collapses sidebar and renders former issue due date', () => {
expect(findCollapsed().isVisible()).toBe(true);
expect(findCollapsed().text()).toContain(TEST_FORMATTED_DUE_DATE);
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
index ad682774ee6..8992a5780f3 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
@@ -9,11 +9,8 @@ import {
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue';
import { createStore } from '~/boards/stores';
-import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-jest.mock('~/flash');
-
const TEST_LABELS_PAYLOAD = TEST_LABELS.map((label) => ({ ...label, set: true }));
const TEST_LABELS_TITLES = TEST_LABELS.map((label) => label.title);
@@ -154,6 +151,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
jest.spyOn(wrapper.vm, 'setActiveBoardItemLabels').mockImplementation(() => {
throw new Error(['failed mutation']);
});
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
findLabelsSelect().vm.$emit('updateSelectedLabels', [{ id: '?' }]);
await wrapper.vm.$nextTick();
});
@@ -161,7 +159,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
it('collapses sidebar and renders former issue weight', () => {
expect(findCollapsed().isVisible()).toBe(true);
expect(findLabelsTitles()).toEqual(TEST_LABELS_TITLES);
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
index 8706424a296..6cf750be972 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
@@ -4,12 +4,9 @@ import { mockMilestone as TEST_MILESTONE } from 'jest/boards/mock_data';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import BoardSidebarMilestoneSelect from '~/boards/components/sidebar/board_sidebar_milestone_select.vue';
import { createStore } from '~/boards/stores';
-import createFlash from '~/flash';
const TEST_ISSUE = { id: 'gid://gitlab/Issue/1', iid: 9, referencePath: 'h/b#2' };
-jest.mock('~/flash');
-
describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () => {
let wrapper;
let store;
@@ -165,6 +162,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => {
throw new Error(['failed mutation']);
});
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
findDropdownItem().vm.$emit('click');
await wrapper.vm.$nextTick();
});
@@ -172,7 +170,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
it('collapses sidebar and renders former milestone', () => {
expect(findCollapsed().isVisible()).toBe(true);
expect(findCollapsed().text()).toContain(testMilestone.title);
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
index 7976e73ff2f..8847f626c1f 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
@@ -5,11 +5,8 @@ import Vuex from 'vuex';
import BoardSidebarSubscription from '~/boards/components/sidebar/board_sidebar_subscription.vue';
import { createStore } from '~/boards/stores';
import * as types from '~/boards/stores/mutation_types';
-import createFlash from '~/flash';
import { mockActiveIssue } from '../../mock_data';
-jest.mock('~/flash.js');
-
Vue.use(Vuex);
describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () => {
@@ -153,13 +150,15 @@ describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () =
jest.spyOn(wrapper.vm, 'setActiveItemSubscribed').mockImplementation(async () => {
throw new Error();
});
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
findToggle().trigger('click');
await wrapper.vm.$nextTick();
- expect(createFlash).toHaveBeenNthCalledWith(1, {
- message: wrapper.vm.$options.i18n.updateSubscribedErrorMessage,
- });
+ expect(wrapper.vm.setError).toHaveBeenCalled();
+ expect(wrapper.vm.setError.mock.calls[0][0].message).toBe(
+ wrapper.vm.$options.i18n.updateSubscribedErrorMessage,
+ );
});
});
});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js
index c8ccd4c88a5..4a8eda298f2 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_title_spec.js
@@ -3,7 +3,6 @@ import { shallowMount } from '@vue/test-utils';
import BoardEditableItem from '~/boards/components/sidebar/board_editable_item.vue';
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
import { createStore } from '~/boards/stores';
-import createFlash from '~/flash';
const TEST_TITLE = 'New item title';
const TEST_ISSUE_A = {
@@ -19,8 +18,6 @@ const TEST_ISSUE_B = {
referencePath: 'h/b#2',
};
-jest.mock('~/flash');
-
describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
let wrapper;
let store;
@@ -168,6 +165,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
jest.spyOn(wrapper.vm, 'setActiveItemTitle').mockImplementation(() => {
throw new Error(['failed mutation']);
});
+ jest.spyOn(wrapper.vm, 'setError').mockImplementation(() => {});
findFormInput().vm.$emit('input', 'Invalid title');
findForm().vm.$emit('submit', { preventDefault: () => {} });
await wrapper.vm.$nextTick();
@@ -176,7 +174,7 @@ describe('~/boards/components/sidebar/board_sidebar_title.vue', () => {
it('collapses sidebar and renders former item title', () => {
expect(findCollapsed().isVisible()).toBe(true);
expect(findTitle().text()).toContain(TEST_ISSUE_B.title);
- expect(createFlash).toHaveBeenCalled();
+ expect(wrapper.vm.setError).toHaveBeenCalled();
});
});
});
diff --git a/spec/lib/banzai/reference_parser/commit_parser_spec.rb b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
index 612ce6b93f1..31cece108bf 100644
--- a/spec/lib/banzai/reference_parser/commit_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/commit_parser_spec.rb
@@ -130,11 +130,11 @@ RSpec.describe Banzai::ReferenceParser::CommitParser do
end
context 'when checking commits on another projects' do
- let(:control_links) do
+ let!(:control_links) do
[commit_link]
end
- let(:actual_links) do
+ let!(:actual_links) do
control_links + [commit_link, commit_link]
end
diff --git a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
index a57e4e52501..04c35c8b082 100644
--- a/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
+++ b/spec/lib/banzai/reference_parser/merge_request_parser_spec.rb
@@ -18,10 +18,19 @@ RSpec.describe Banzai::ReferenceParser::MergeRequestParser do
context 'when the link has a data-issue attribute' do
before do
project.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
+ link['data-project'] = merge_request.project_id.to_s
link['data-merge-request'] = merge_request.id.to_s
end
it_behaves_like "referenced feature visibility", "merge_requests"
+
+ context 'when optimize_merge_request_parser feature flag is off' do
+ before do
+ stub_feature_flags(optimize_merge_request_parser: false)
+ end
+
+ it_behaves_like "referenced feature visibility", "merge_requests"
+ end
end
end
@@ -29,6 +38,7 @@ RSpec.describe Banzai::ReferenceParser::MergeRequestParser do
describe 'when the link has a data-merge-request attribute' do
context 'using an existing merge request ID' do
it 'returns an Array of merge requests' do
+ link['data-project'] = merge_request.project_id.to_s
link['data-merge-request'] = merge_request.id.to_s
expect(subject.referenced_by([link])).to eq([merge_request])
@@ -37,6 +47,7 @@ RSpec.describe Banzai::ReferenceParser::MergeRequestParser do
context 'using a non-existing merge request ID' do
it 'returns an empty Array' do
+ link['data-project'] = merge_request.project_id.to_s
link['data-merge-request'] = ''
expect(subject.referenced_by([link])).to eq([])
@@ -49,16 +60,16 @@ RSpec.describe Banzai::ReferenceParser::MergeRequestParser do
let(:other_project) { create(:project, :public) }
let(:other_merge_request) { create(:merge_request, source_project: other_project) }
- let(:control_links) do
+ let!(:control_links) do
[merge_request_link(other_merge_request)]
end
- let(:actual_links) do
+ let!(:actual_links) do
control_links + [merge_request_link(create(:merge_request, :conflict, source_project: other_project))]
end
def merge_request_link(merge_request)
- Nokogiri::HTML.fragment(%Q{<a data-merge-request="#{merge_request.id}"></a>}).children[0]
+ Nokogiri::HTML.fragment(%Q{<a data-project="#{merge_request.project_id}" data-merge-request="#{merge_request.id}"></a>}).children[0]
end
before do
diff --git a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
index 7da602251a5..644379d7289 100644
--- a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
@@ -8,8 +8,14 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
let(:test_suite) { Gitlab::Ci::Reports::TestSuite.new('rspec') }
let(:test_cases) { flattened_test_cases(test_suite) }
- let(:job) { double(max_test_cases_per_report: max_test_cases) }
+ let(:variables) { [{ key: 'CI_PROJECT_DIR', value: '/builds/group/project' }] }
let(:max_test_cases) { 0 }
+ let(:job) do
+ double(
+ max_test_cases_per_report: max_test_cases,
+ variables: Gitlab::Ci::Variables::Collection.new.concat(variables)
+ )
+ end
context 'when data is JUnit style XML' do
context 'when there are no <testcases> in <testsuite>' do
@@ -417,6 +423,27 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
end
end
+ context 'when paths contains the build group project path' do
+ let(:junit) do
+ <<~EOF
+ <testsuites>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'>
+ <failure>Some failure</failure>
+ <system-out>[[ATTACHMENT|/builds/group/project/some/path.png]]</system-out>
+ </testcase>
+ </testsuite>
+ </testsuites>
+ EOF
+ end
+
+ it 'removes the builds group project path prefix' do
+ expect { subject }.not_to raise_error
+
+ expect(test_cases[0].attachment).to eq("/some/path.png")
+ end
+ end
+
private
def flattened_test_cases(test_suite)
diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb
index 92e51b8ea23..e6b9351858b 100644
--- a/spec/lib/gitlab/usage/metric_definition_spec.rb
+++ b/spec/lib/gitlab/usage/metric_definition_spec.rb
@@ -73,6 +73,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
:distribution | 'test'
:tier | %w(test ee)
:name | 'count_<adjective_describing>_boards'
+ :repair_issue_url | nil
:instrumentation_class | 'Metric_Class'
:instrumentation_class | 'metricClass'
@@ -103,6 +104,19 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
end
end
end
+
+ context 'conditional validations' do
+ context 'when metric has broken status' do
+ it 'has to have repair issue url provided' do
+ attributes[:status] = 'broken'
+ attributes.delete(:repair_issue_url)
+
+ expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::Metric::InvalidMetricError))
+
+ described_class.new(path, attributes).validate!
+ end
+ end
+ end
end
describe 'statuses' do
@@ -153,7 +167,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
is_expected.to be_one
end
- it 'when the same meric is defined multiple times raises exception' do
+ it 'when the same metric is defined multiple times raises exception' do
write_metric(metric1, path, yaml_content)
write_metric(metric2, path, yaml_content)
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 5ddbc98a172..dde6b4c91cb 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -576,7 +576,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
expect(count_data[:projects_with_tracing_enabled]).to eq(1)
expect(count_data[:projects_with_enabled_alert_integrations]).to eq(1)
- expect(count_data[:projects_with_prometheus_alerts]).to eq(2)
+ expect(count_data[:projects_with_prometheus_alerts]).to eq(Gitlab::UsageData::DEPRECATED_VALUE)
expect(count_data[:projects_with_terraform_reports]).to eq(2)
expect(count_data[:projects_with_terraform_states]).to eq(2)
expect(count_data[:projects_with_alerts_created]).to eq(1)
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index f9a28c8e40b..e751c060145 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -177,7 +177,6 @@ RSpec.configure do |config|
config.append_after do |example|
if example.metadata[:screenshot]
screenshot = example.metadata[:screenshot][:image] || example.metadata[:screenshot][:html]
- screenshot&.delete_prefix!(ENV.fetch('CI_PROJECT_DIR', ''))
example.metadata[:stdout] = %{[[ATTACHMENT|#{screenshot}]]}
end
end
diff --git a/spec/support/helpers/reference_parser_helpers.rb b/spec/support/helpers/reference_parser_helpers.rb
index f42410d8102..a6a7948d9d9 100644
--- a/spec/support/helpers/reference_parser_helpers.rb
+++ b/spec/support/helpers/reference_parser_helpers.rb
@@ -11,25 +11,20 @@ module ReferenceParserHelpers
end
RSpec.shared_examples 'no project N+1 queries' do
- it 'avoids N+1 queries in #nodes_visible_to_user', :request_store do
+ it 'avoids N+1 queries in #nodes_visible_to_user' do
context = Banzai::RenderContext.new(project, user)
- record_queries = lambda do |links|
- ActiveRecord::QueryRecorder.new do
- described_class.new(context).nodes_visible_to_user(user, links)
- end
+ request = lambda do |links|
+ described_class.new(context).nodes_visible_to_user(user, links)
end
- control = record_queries.call(control_links)
+ control = ActiveRecord::QueryRecorder.new { request.call(control_links) }
create(:group_member, group: project.group) if project.group
create(:project_member, project: project)
create(:project_group_link, project: project)
- actual = record_queries.call(actual_links)
-
- expect(actual.count).to be <= control.count
- expect(actual.cached_count).to be <= control.cached_count
+ expect { request.call(actual_links) }.not_to exceed_query_limit(control)
end
end