summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-04 15:10:36 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-04 15:10:36 +0000
commitbe4b3134a282f7a8812306777abd2d3150deecdc (patch)
tree0563327ce590b415047686c6feff43496742b49a /spec
parent998adcc422d4161515bf2960ef4dce71258f69a3 (diff)
downloadgitlab-ce-be4b3134a282f7a8812306777abd2d3150deecdc.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/concerns/graceful_timeout_handling_spec.rb2
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb2
-rw-r--r--spec/features/merge_request/user_resolves_conflicts_spec.rb2
-rw-r--r--spec/features/runners_spec.rb67
-rw-r--r--spec/frontend/issuable_list/components/issuable_item_spec.js26
-rw-r--r--spec/frontend/issues_list/components/issues_list_app_spec.js44
-rw-r--r--spec/frontend/issues_list/utils_spec.js34
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js32
-rw-r--r--spec/frontend/jobs/components/table/jobs_table_empty_state_spec.js37
-rw-r--r--spec/frontend/jobs/mock_data.js8
-rw-r--r--spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js12
-rw-r--r--spec/frontend/sidebar/components/date/sidebar_date_widget_spec.js8
-rw-r--r--spec/lib/gitlab/alert_management/payload/base_spec.rb6
-rw-r--r--spec/lib/gitlab/database_spec.rb2
-rw-r--r--spec/lib/gitlab/external_authorization/access_spec.rb2
-rw-r--r--spec/lib/gitlab/external_authorization/client_spec.rb2
-rw-r--r--spec/lib/gitlab/git/wraps_gitaly_errors_spec.rb2
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb2
-rw-r--r--spec/models/namespace/traversal_hierarchy_spec.rb2
-rw-r--r--spec/requests/api/api_guard/admin_mode_middleware_spec.rb2
-rw-r--r--spec/requests/api/helpers_spec.rb2
-rw-r--r--spec/requests/api/releases_spec.rb70
-rw-r--r--spec/services/alert_management/process_prometheus_alert_service_spec.rb2
-rw-r--r--spec/services/auto_merge/base_service_spec.rb8
-rw-r--r--spec/services/branches/delete_service_spec.rb2
-rw-r--r--spec/services/ci/parse_dotenv_artifact_service_spec.rb2
-rw-r--r--spec/services/merge_requests/merge_to_ref_service_spec.rb2
-rw-r--r--spec/support/helpers/board_helpers.rb1
-rw-r--r--spec/support/helpers/dns_helpers.rb2
-rw-r--r--spec/support/helpers/next_found_instance_of.rb2
-rw-r--r--spec/support/helpers/redis_without_keys.rb4
-rw-r--r--spec/support/helpers/require_migration.rb2
-rw-r--r--spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb64
-rw-r--r--spec/support/shared_examples/services/alert_management_shared_examples.rb20
-rw-r--r--spec/support/stored_repositories.rb2
35 files changed, 350 insertions, 129 deletions
diff --git a/spec/controllers/concerns/graceful_timeout_handling_spec.rb b/spec/controllers/concerns/graceful_timeout_handling_spec.rb
index cece36f06b2..e496d12856b 100644
--- a/spec/controllers/concerns/graceful_timeout_handling_spec.rb
+++ b/spec/controllers/concerns/graceful_timeout_handling_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe GracefulTimeoutHandling, type: :controller do
skip_before_action :authenticate_user!
def index
- raise ActiveRecord::QueryCanceled.new
+ raise ActiveRecord::QueryCanceled
end
end
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index 081927ea73c..776ed9774b1 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -201,7 +201,7 @@ RSpec.describe Projects::LabelsController do
context 'service raising InvalidRecord' do
before do
expect_any_instance_of(Labels::PromoteService).to receive(:execute) do |label|
- raise ActiveRecord::RecordInvalid.new(label_1)
+ raise ActiveRecord::RecordInvalid, label_1
end
end
diff --git a/spec/features/merge_request/user_resolves_conflicts_spec.rb b/spec/features/merge_request/user_resolves_conflicts_spec.rb
index 1b1152897fc..d9e3bfd6a9c 100644
--- a/spec/features/merge_request/user_resolves_conflicts_spec.rb
+++ b/spec/features/merge_request/user_resolves_conflicts_spec.rb
@@ -173,7 +173,7 @@ RSpec.describe 'Merge request > User resolves conflicts', :js do
end
it "renders bad name without xss issues" do
- expect(find('.resolve-conflicts-form .resolve-info')).to have_content(bad_branch_name)
+ expect(find('[data-testid="resolve-info"]')).to have_content(bad_branch_name)
end
end
end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index acfb7c2602a..64250931006 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -160,18 +160,67 @@ RSpec.describe 'Runners' do
end
end
- context 'when application settings have shared_runners_text' do
- let(:shared_runners_text) { 'custom **shared** runners description' }
- let(:shared_runners_html) { 'custom shared runners description' }
+ context 'shared runner text' do
+ context 'when application settings have no shared_runners_text' do
+ it 'user sees default shared runners description' do
+ visit project_runners_path(project)
- before do
- stub_application_setting(shared_runners_text: shared_runners_text)
+ page.within("[data-testid='shared-runners-description']") do
+ expect(page).to have_content('The same shared runner executes code from multiple projects')
+ end
+ end
end
- it 'user sees shared runners description' do
- visit project_runners_path(project)
+ context 'when application settings have shared_runners_text' do
+ let(:shared_runners_text) { 'custom **shared** runners description' }
+ let(:shared_runners_html) { 'custom shared runners description' }
+
+ before do
+ stub_application_setting(shared_runners_text: shared_runners_text)
+ end
+
+ it 'user sees shared runners description' do
+ visit project_runners_path(project)
+
+ page.within("[data-testid='shared-runners-description']") do
+ expect(page).not_to have_content('The same shared runner executes code from multiple projects')
+ expect(page).to have_content(shared_runners_html)
+ end
+ end
+ end
+
+ context 'when application settings have an unsafe link in shared_runners_text' do
+ let(:shared_runners_text) { '<a href="javascript:alert(\'xss\')">link</a>' }
+
+ before do
+ stub_application_setting(shared_runners_text: shared_runners_text)
+ end
+
+ it 'user sees no link' do
+ visit project_runners_path(project)
+
+ page.within("[data-testid='shared-runners-description']") do
+ expect(page).to have_content('link')
+ expect(page).not_to have_link('link')
+ end
+ end
+ end
- expect(page.find('.shared-runners-description')).to have_content(shared_runners_html)
+ context 'when application settings have an unsafe image in shared_runners_text' do
+ let(:shared_runners_text) { '<img src="404.png" onerror="alert(\'xss\')"/>' }
+
+ before do
+ stub_application_setting(shared_runners_text: shared_runners_text)
+ end
+
+ it 'user sees image safely' do
+ visit project_runners_path(project)
+
+ page.within("[data-testid='shared-runners-description']") do
+ expect(page).to have_css('img')
+ expect(page).not_to have_css('img[onerror]')
+ end
+ end
end
end
end
@@ -190,7 +239,7 @@ RSpec.describe 'Runners' do
click_on 'Enable shared runners'
- expect(page.find('.shared-runners-description')).to have_content('Disable shared runners')
+ expect(page.find("[data-testid='shared-runners-description']")).to have_content('Disable shared runners')
expect(page).not_to have_selector('#toggle-shared-runners-form')
end
end
diff --git a/spec/frontend/issuable_list/components/issuable_item_spec.js b/spec/frontend/issuable_list/components/issuable_item_spec.js
index 7281d2fde1d..e324f071966 100644
--- a/spec/frontend/issuable_list/components/issuable_item_spec.js
+++ b/spec/frontend/issuable_list/components/issuable_item_spec.js
@@ -453,5 +453,31 @@ describe('IssuableItem', () => {
expect(updatedAtEl.find('span').attributes('title')).toBe('Sep 10, 2020 11:41am GMT+0000');
expect(updatedAtEl.text()).toBe(wrapper.vm.updatedAt);
});
+
+ describe('when issuable is closed', () => {
+ it('renders issuable card with a closed style', () => {
+ wrapper = createComponent({ issuable: { ...mockIssuable, closedAt: '2020-12-10' } });
+
+ expect(wrapper.classes()).toContain('closed');
+ });
+ });
+
+ describe('when issuable was created within the past 24 hours', () => {
+ it('renders issuable card with a recently-created style', () => {
+ wrapper = createComponent({
+ issuable: { ...mockIssuable, createdAt: '2020-12-10T12:34:56' },
+ });
+
+ expect(wrapper.classes()).toContain('today');
+ });
+ });
+
+ describe('when issuable was created earlier than the past 24 hours', () => {
+ it('renders issuable card without a recently-created style', () => {
+ wrapper = createComponent({ issuable: { ...mockIssuable, createdAt: '2020-12-09' } });
+
+ expect(wrapper.classes()).not.toContain('today');
+ });
+ });
});
});
diff --git a/spec/frontend/issues_list/components/issues_list_app_spec.js b/spec/frontend/issues_list/components/issues_list_app_spec.js
index 9a4c2edc01a..c0b3ad0f21f 100644
--- a/spec/frontend/issues_list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues_list/components/issues_list_app_spec.js
@@ -15,10 +15,10 @@ import {
PAGE_SIZE,
PAGE_SIZE_MANUAL,
RELATIVE_POSITION_ASC,
- sortOptions,
sortParams,
} from '~/issues_list/constants';
import eventHub from '~/issues_list/eventhub';
+import { getSortOptions } from '~/issues_list/utils';
import axios from '~/lib/utils/axios_utils';
import { setUrlParams } from '~/lib/utils/url_utility';
@@ -35,7 +35,9 @@ describe('IssuesListApp component', () => {
emptyStateSvgPath: 'empty-state.svg',
endpoint: 'api/endpoint',
exportCsvPath: 'export/csv/path',
+ hasBlockedIssuesFeature: true,
hasIssues: true,
+ hasIssueWeightsFeature: true,
isSignedIn: false,
issuesPath: 'path/to/issues',
jiraIntegrationPath: 'jira/integration/path',
@@ -43,7 +45,6 @@ describe('IssuesListApp component', () => {
projectLabelsPath: 'project/labels/path',
projectPath: 'path/to/project',
rssPath: 'rss/path',
- showImportButton: true,
showNewIssueLink: true,
signInPath: 'sign/in/path',
};
@@ -105,7 +106,7 @@ describe('IssuesListApp component', () => {
namespace: defaultProvide.projectPath,
recentSearchesStorageKey: 'issues',
searchInputPlaceholder: 'Search or filter results…',
- sortOptions,
+ sortOptions: getSortOptions(true, true),
initialSortBy: CREATED_DESC,
tabs: IssuableListTabs,
currentTab: IssuableStates.Opened,
@@ -142,18 +143,33 @@ describe('IssuesListApp component', () => {
});
});
- it('renders csv import/export component', async () => {
- const search = '?page=1&search=refactor&state=opened&order_by=created_at&sort=desc';
+ describe('csv import/export component', () => {
+ describe('when user is signed in', () => {
+ it('renders', async () => {
+ const search = '?page=1&search=refactor&state=opened&order_by=created_at&sort=desc';
- global.jsdom.reconfigure({ url: `${TEST_HOST}${search}` });
+ global.jsdom.reconfigure({ url: `${TEST_HOST}${search}` });
- wrapper = mountComponent({ mountFn: mount });
+ wrapper = mountComponent({
+ provide: { ...defaultProvide, isSignedIn: true },
+ mountFn: mount,
+ });
- await waitForPromises();
+ await waitForPromises();
- expect(findCsvImportExportButtons().props()).toMatchObject({
- exportCsvPath: `${defaultProvide.exportCsvPath}${search}`,
- issuableCount: xTotal,
+ expect(findCsvImportExportButtons().props()).toMatchObject({
+ exportCsvPath: `${defaultProvide.exportCsvPath}${search}`,
+ issuableCount: xTotal,
+ });
+ });
+ });
+
+ describe('when user is not signed in', () => {
+ it('does not render', () => {
+ wrapper = mountComponent({ provide: { ...defaultProvide, isSignedIn: false } });
+
+ expect(findCsvImportExportButtons().exists()).toBe(false);
+ });
});
});
@@ -369,11 +385,11 @@ describe('IssuesListApp component', () => {
it('shows Jira integration information', () => {
const paragraphs = wrapper.findAll('p');
- expect(paragraphs.at(2).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
- expect(paragraphs.at(3).text()).toContain(
+ expect(paragraphs.at(1).text()).toContain(IssuesListApp.i18n.jiraIntegrationTitle);
+ expect(paragraphs.at(2).text()).toContain(
'Enable the Jira integration to view your Jira issues in GitLab.',
);
- expect(paragraphs.at(4).text()).toContain(
+ expect(paragraphs.at(3).text()).toContain(
IssuesListApp.i18n.jiraIntegrationSecondaryMessage,
);
expect(findGlLink().text()).toBe('Enable the Jira integration');
diff --git a/spec/frontend/issues_list/utils_spec.js b/spec/frontend/issues_list/utils_spec.js
index fbd0a535174..00b387263ea 100644
--- a/spec/frontend/issues_list/utils_spec.js
+++ b/spec/frontend/issues_list/utils_spec.js
@@ -6,6 +6,7 @@ import {
convertToUrlParams,
getFilterTokens,
getSortKey,
+ getSortOptions,
} from '~/issues_list/utils';
describe('getSortKey', () => {
@@ -15,6 +16,39 @@ describe('getSortKey', () => {
});
});
+describe('getSortOptions', () => {
+ describe.each`
+ hasIssueWeightsFeature | hasBlockedIssuesFeature | length | containsWeight | containsBlocking
+ ${false} | ${false} | ${8} | ${false} | ${false}
+ ${true} | ${false} | ${9} | ${true} | ${false}
+ ${false} | ${true} | ${9} | ${false} | ${true}
+ ${true} | ${true} | ${10} | ${true} | ${true}
+ `(
+ 'when hasIssueWeightsFeature=$hasIssueWeightsFeature and hasBlockedIssuesFeature=$hasBlockedIssuesFeature',
+ ({
+ hasIssueWeightsFeature,
+ hasBlockedIssuesFeature,
+ length,
+ containsWeight,
+ containsBlocking,
+ }) => {
+ const sortOptions = getSortOptions(hasIssueWeightsFeature, hasBlockedIssuesFeature);
+
+ it('returns the correct length of sort options', () => {
+ expect(sortOptions).toHaveLength(length);
+ });
+
+ it(`${containsWeight ? 'contains' : 'does not contain'} weight option`, () => {
+ expect(sortOptions.some((option) => option.title === 'Weight')).toBe(containsWeight);
+ });
+
+ it(`${containsBlocking ? 'contains' : 'does not contain'} blocking option`, () => {
+ expect(sortOptions.some((option) => option.title === 'Blocking')).toBe(containsBlocking);
+ });
+ },
+ );
+});
+
describe('getFilterTokens', () => {
it('returns filtered tokens given "window.location.search"', () => {
expect(getFilterTokens(locationSearch)).toEqual(filteredTokens);
diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js
index 3f91b44ae5a..9d1135e26c8 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -1,5 +1,5 @@
-import { GlSkeletonLoader, GlAlert } from '@gitlab/ui';
-import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { GlSkeletonLoader, GlAlert, GlEmptyState } from '@gitlab/ui';
+import { createLocalVue, mount, shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -7,7 +7,7 @@ import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
-import { mockJobsQueryResponse } from '../../mock_data';
+import { mockJobsQueryResponse, mockJobsQueryEmptyResponse } from '../../mock_data';
const projectPath = 'gitlab-org/gitlab';
const localVue = createLocalVue();
@@ -18,11 +18,13 @@ describe('Job table app', () => {
const successHandler = jest.fn().mockResolvedValue(mockJobsQueryResponse);
const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+ const emptyHandler = jest.fn().mockResolvedValue(mockJobsQueryEmptyResponse);
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findTable = () => wrapper.findComponent(JobsTable);
const findTabs = () => wrapper.findComponent(JobsTableTabs);
const findAlert = () => wrapper.findComponent(GlAlert);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const createMockApolloProvider = (handler) => {
const requestHandlers = [[getJobsQuery, handler]];
@@ -30,8 +32,8 @@ describe('Job table app', () => {
return createMockApollo(requestHandlers);
};
- const createComponent = (handler = successHandler) => {
- wrapper = shallowMount(JobsTableApp, {
+ const createComponent = (handler = successHandler, mountFn = shallowMount) => {
+ wrapper = mountFn(JobsTableApp, {
provide: {
projectPath,
},
@@ -85,4 +87,24 @@ describe('Job table app', () => {
expect(findAlert().exists()).toBe(true);
});
});
+
+ describe('empty state', () => {
+ it('should display empty state if there are no jobs and tab scope is null', async () => {
+ createComponent(emptyHandler, mount);
+
+ await waitForPromises();
+
+ expect(findEmptyState().exists()).toBe(true);
+ expect(findTable().exists()).toBe(false);
+ });
+
+ it('should not display empty state if there are jobs and tab scope is not null', async () => {
+ createComponent(successHandler, mount);
+
+ await waitForPromises();
+
+ expect(findEmptyState().exists()).toBe(false);
+ expect(findTable().exists()).toBe(true);
+ });
+ });
});
diff --git a/spec/frontend/jobs/components/table/jobs_table_empty_state_spec.js b/spec/frontend/jobs/components/table/jobs_table_empty_state_spec.js
new file mode 100644
index 00000000000..05b066a9edc
--- /dev/null
+++ b/spec/frontend/jobs/components/table/jobs_table_empty_state_spec.js
@@ -0,0 +1,37 @@
+import { GlEmptyState } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import JobsTableEmptyState from '~/jobs/components/table/jobs_table_empty_state.vue';
+
+describe('Jobs table empty state', () => {
+ let wrapper;
+
+ const pipelineEditorPath = '/root/project/-/ci/editor';
+ const emptyStateSvgPath = 'assets/jobs-empty-state.svg';
+
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+
+ const createComponent = () => {
+ wrapper = shallowMount(JobsTableEmptyState, {
+ provide: {
+ pipelineEditorPath,
+ emptyStateSvgPath,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('displays empty state', () => {
+ expect(findEmptyState().exists()).toBe(true);
+ });
+
+ it('links to the pipeline editor', () => {
+ expect(findEmptyState().props('primaryButtonLink')).toBe(pipelineEditorPath);
+ });
+
+ it('shows an empty state image', () => {
+ expect(findEmptyState().props('svgPath')).toBe(emptyStateSvgPath);
+ });
+});
diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js
index bdedbffff22..d2c065a3aba 100644
--- a/spec/frontend/jobs/mock_data.js
+++ b/spec/frontend/jobs/mock_data.js
@@ -1501,3 +1501,11 @@ export const mockJobsQueryResponse = {
},
},
};
+
+export const mockJobsQueryEmptyResponse = {
+ data: {
+ project: {
+ jobs: [],
+ },
+ },
+};
diff --git a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
index d175b541edb..a09edb50f20 100644
--- a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
+++ b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
@@ -82,20 +82,20 @@ describe('Merge Conflict Resolver App', () => {
const interactiveButton = findFileInteractiveButton(findFiles().at(0));
const inlineButton = findFileInlineButton(findFiles().at(0));
- expect(interactiveButton.classes('active')).toBe(true);
- expect(inlineButton.classes('active')).toBe(false);
+ expect(interactiveButton.props('selected')).toBe(true);
+ expect(inlineButton.props('selected')).toBe(false);
});
it('clicking inline set inline as default', async () => {
mountComponent();
const inlineButton = findFileInlineButton(findFiles().at(0));
- expect(inlineButton.classes('active')).toBe(false);
+ expect(inlineButton.props('selected')).toBe(false);
- inlineButton.trigger('click');
+ inlineButton.vm.$emit('click');
await wrapper.vm.$nextTick();
- expect(inlineButton.classes('active')).toBe(true);
+ expect(inlineButton.props('selected')).toBe(true);
});
it('inline mode shows a inline-conflict-lines', () => {
@@ -110,7 +110,7 @@ describe('Merge Conflict Resolver App', () => {
it('parallel mode shows a parallel-conflict-lines', async () => {
mountComponent();
- findSideBySideButton().trigger('click');
+ findSideBySideButton().vm.$emit('click');
await wrapper.vm.$nextTick();
const parallelConflictLinesComponent = findParallelConflictLines(findFiles().at(0));
diff --git a/spec/frontend/sidebar/components/date/sidebar_date_widget_spec.js b/spec/frontend/sidebar/components/date/sidebar_date_widget_spec.js
index d4e2483b765..273235fe197 100644
--- a/spec/frontend/sidebar/components/date/sidebar_date_widget_spec.js
+++ b/spec/frontend/sidebar/components/date/sidebar_date_widget_spec.js
@@ -1,3 +1,4 @@
+import { GlDatepicker } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
@@ -23,6 +24,7 @@ describe('Sidebar date Widget', () => {
const findEditableItem = () => wrapper.findComponent(SidebarEditableItem);
const findPopoverIcon = () => wrapper.find('[data-testid="inherit-date-popover"]');
+ const findDatePicker = () => wrapper.find(GlDatepicker);
const createComponent = ({
dueDateQueryHandler = jest.fn().mockResolvedValue(issuableDueDateResponse()),
@@ -50,6 +52,7 @@ describe('Sidebar date Widget', () => {
},
stubs: {
SidebarEditableItem,
+ GlDatepicker,
},
});
};
@@ -109,6 +112,11 @@ describe('Sidebar date Widget', () => {
it('emits `dueDateUpdated` event with the date payload', () => {
expect(wrapper.emitted('dueDateUpdated')).toEqual([[date]]);
});
+
+ it('uses a correct prop to set the initial date for GlDatePicker', () => {
+ expect(findDatePicker().props('value')).toBe(null);
+ expect(findDatePicker().props('defaultDate')).toEqual(wrapper.vm.parsedDate);
+ });
});
it.each`
diff --git a/spec/lib/gitlab/alert_management/payload/base_spec.rb b/spec/lib/gitlab/alert_management/payload/base_spec.rb
index e093b3587c2..d3c1a96253c 100644
--- a/spec/lib/gitlab/alert_management/payload/base_spec.rb
+++ b/spec/lib/gitlab/alert_management/payload/base_spec.rb
@@ -89,6 +89,12 @@ RSpec.describe Gitlab::AlertManagement::Payload::Base do
it { is_expected.to be_nil }
end
+
+ context 'with time in seconds' do
+ let(:raw_payload) { { 'test' => 1618877936 } }
+
+ it { is_expected.to be_nil }
+ end
end
context 'with an integer type provided' do
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index b735ac7940b..cc9f005b189 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -176,7 +176,7 @@ RSpec.describe Gitlab::Database do
closed_pool = pool
- raise error.new('boom')
+ raise error, 'boom'
end
rescue error
end
diff --git a/spec/lib/gitlab/external_authorization/access_spec.rb b/spec/lib/gitlab/external_authorization/access_spec.rb
index a6773cc19e1..812ef2b54e9 100644
--- a/spec/lib/gitlab/external_authorization/access_spec.rb
+++ b/spec/lib/gitlab/external_authorization/access_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache
context 'when the request fails' do
before do
allow(fake_client).to receive(:request_access) do
- raise ::Gitlab::ExternalAuthorization::RequestFailed.new('Service unavailable')
+ raise ::Gitlab::ExternalAuthorization::RequestFailed, 'Service unavailable'
end
end
diff --git a/spec/lib/gitlab/external_authorization/client_spec.rb b/spec/lib/gitlab/external_authorization/client_spec.rb
index c08da382486..b907b0bb262 100644
--- a/spec/lib/gitlab/external_authorization/client_spec.rb
+++ b/spec/lib/gitlab/external_authorization/client_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
end
it 'wraps exceptions if the request fails' do
- expect(Gitlab::HTTP).to receive(:post) { raise Gitlab::HTTP::BlockedUrlError.new('the request broke') }
+ expect(Gitlab::HTTP).to receive(:post) { raise Gitlab::HTTP::BlockedUrlError, 'the request broke' }
expect { client.request_access }
.to raise_error(::Gitlab::ExternalAuthorization::RequestFailed)
diff --git a/spec/lib/gitlab/git/wraps_gitaly_errors_spec.rb b/spec/lib/gitlab/git/wraps_gitaly_errors_spec.rb
index e448277b307..2c9da0f6606 100644
--- a/spec/lib/gitlab/git/wraps_gitaly_errors_spec.rb
+++ b/spec/lib/gitlab/git/wraps_gitaly_errors_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Gitlab::Git::WrapsGitalyErrors do
mapping.each do |grpc_error, error|
it "wraps #{grpc_error} in a #{error}" do
- expect { wrapper.wrapped_gitaly_errors { raise grpc_error.new('wrapped') } }
+ expect { wrapper.wrapped_gitaly_errors { raise grpc_error, 'wrapped' } }
.to raise_error(error)
end
end
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index 3e5fbbfe823..028208a56f1 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -178,7 +178,7 @@ RSpec.describe Ci::PipelineSchedule do
context 'when record is invalid' do
before do
- allow(pipeline_schedule).to receive(:save!) { raise ActiveRecord::RecordInvalid.new(pipeline_schedule) }
+ allow(pipeline_schedule).to receive(:save!) { raise ActiveRecord::RecordInvalid, pipeline_schedule }
end
it 'nullifies the next run at' do
diff --git a/spec/models/namespace/traversal_hierarchy_spec.rb b/spec/models/namespace/traversal_hierarchy_spec.rb
index b166d541171..baefc161691 100644
--- a/spec/models/namespace/traversal_hierarchy_spec.rb
+++ b/spec/models/namespace/traversal_hierarchy_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe Namespace::TraversalHierarchy, type: :model do
connection_double = double(:connection)
allow(Namespace).to receive(:connection).and_return(connection_double)
- allow(connection_double).to receive(:exec_query) { raise ActiveRecord::Deadlocked.new }
+ allow(connection_double).to receive(:exec_query) { raise ActiveRecord::Deadlocked }
end
it { expect { subject }.to raise_error(ActiveRecord::Deadlocked) }
diff --git a/spec/requests/api/api_guard/admin_mode_middleware_spec.rb b/spec/requests/api/api_guard/admin_mode_middleware_spec.rb
index 63bcec4b52a..ba7a01a2cd9 100644
--- a/spec/requests/api/api_guard/admin_mode_middleware_spec.rb
+++ b/spec/requests/api/api_guard/admin_mode_middleware_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe API::APIGuard::AdminModeMiddleware, :request_store do
let(:app) do
Class.new(API::API) do
get 'willfail' do
- raise StandardError.new('oh noes!')
+ raise StandardError, 'oh noes!'
end
end
end
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index 8160a94aef2..ce0018d6d0d 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe API::Helpers do
end
def error!(message, status, header)
- raise StandardError.new("#{status} - #{message}")
+ raise StandardError, "#{status} - #{message}"
end
def set_param(key, value)
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index dcef0653ec0..f3d100449a1 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe API::Releases do
project.add_developer(developer)
end
- describe 'GET /projects/:id/releases' do
+ describe 'GET /projects/:id/releases', :use_clean_rails_redis_caching do
context 'when there are two releases' do
let!(:release_1) do
create(:release,
@@ -147,6 +147,60 @@ RSpec.describe API::Releases do
end.not_to exceed_all_query_limit(control_count)
end
+ it 'serializes releases for the first time and read cached data from the second time' do
+ create_list(:release, 2, project: project)
+
+ expect(API::Entities::Release)
+ .to receive(:represent).with(instance_of(Release), any_args)
+ .twice
+
+ 5.times { get api("/projects/#{project.id}/releases", maintainer) }
+ end
+
+ it 'increments the cache key when link is updated' do
+ releases = create_list(:release, 2, project: project)
+
+ expect(API::Entities::Release)
+ .to receive(:represent).with(instance_of(Release), any_args)
+ .exactly(4).times
+
+ 2.times { get api("/projects/#{project.id}/releases", maintainer) }
+
+ releases.each { |release| create(:release_link, release: release) }
+
+ 3.times { get api("/projects/#{project.id}/releases", maintainer) }
+ end
+
+ it 'increments the cache key when evidence is updated' do
+ releases = create_list(:release, 2, project: project)
+
+ expect(API::Entities::Release)
+ .to receive(:represent).with(instance_of(Release), any_args)
+ .exactly(4).times
+
+ 2.times { get api("/projects/#{project.id}/releases", maintainer) }
+
+ releases.each { |release| create(:evidence, release: release) }
+
+ 3.times { get api("/projects/#{project.id}/releases", maintainer) }
+ end
+
+ context 'when api_caching_releases feature flag is disabled' do
+ before do
+ stub_feature_flags(api_caching_releases: false)
+ end
+
+ it 'serializes releases everytime' do
+ create_list(:release, 2, project: project)
+
+ expect(API::Entities::Release)
+ .to receive(:represent).with(kind_of(ActiveRecord::Relation), any_args)
+ .exactly(5).times
+
+ 5.times { get api("/projects/#{project.id}/releases", maintainer) }
+ end
+ end
+
context 'when tag does not exist in git repository' do
let!(:release) { create(:release, project: project, tag: 'v1.1.5') }
@@ -230,6 +284,20 @@ RSpec.describe API::Releases do
end
end
end
+
+ context 'when releases are public and request user is absent' do
+ let(:project) { create(:project, :repository, :public) }
+
+ it 'returns the releases' do
+ create(:release, project: project, tag: 'v0.1')
+
+ get api("/projects/#{project.id}/releases")
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.count).to eq(1)
+ expect(json_response.first['tag_name']).to eq('v0.1')
+ end
+ end
end
describe 'GET /projects/:id/releases/:tag_name' do
diff --git a/spec/services/alert_management/process_prometheus_alert_service_spec.rb b/spec/services/alert_management/process_prometheus_alert_service_spec.rb
index 84c64508a8d..86a6cdee52d 100644
--- a/spec/services/alert_management/process_prometheus_alert_service_spec.rb
+++ b/spec/services/alert_management/process_prometheus_alert_service_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe AlertManagement::ProcessPrometheusAlertService do
context 'with resolving payload' do
let(:prometheus_status) { 'resolved' }
- it_behaves_like 'processes prometheus recovery alert'
+ it_behaves_like 'processes recovery alert'
end
context 'environment given' do
diff --git a/spec/services/auto_merge/base_service_spec.rb b/spec/services/auto_merge/base_service_spec.rb
index 1d33dc15838..3f535b83788 100644
--- a/spec/services/auto_merge/base_service_spec.rb
+++ b/spec/services/auto_merge/base_service_spec.rb
@@ -84,7 +84,7 @@ RSpec.describe AutoMerge::BaseService do
context 'when failed to save merge request' do
before do
- allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid }
end
it 'does not yield block' do
@@ -195,7 +195,7 @@ RSpec.describe AutoMerge::BaseService do
context 'when failed to save' do
before do
- allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid }
end
it 'does not yield block' do
@@ -213,7 +213,7 @@ RSpec.describe AutoMerge::BaseService do
context 'when failed to save merge request' do
before do
- allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid }
end
it 'returns error status' do
@@ -260,7 +260,7 @@ RSpec.describe AutoMerge::BaseService do
context 'when failed to save' do
before do
- allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid.new }
+ allow(merge_request).to receive(:save!) { raise ActiveRecord::RecordInvalid }
end
it 'returns error status' do
diff --git a/spec/services/branches/delete_service_spec.rb b/spec/services/branches/delete_service_spec.rb
index 291431c1723..727cadc5a50 100644
--- a/spec/services/branches/delete_service_spec.rb
+++ b/spec/services/branches/delete_service_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe Branches::DeleteService do
context 'when Gitlab::Git::CommandError is raised' do
before do
allow(repository).to receive(:rm_branch) do
- raise Gitlab::Git::CommandError.new('Could not update patch')
+ raise Gitlab::Git::CommandError, 'Could not update patch'
end
end
diff --git a/spec/services/ci/parse_dotenv_artifact_service_spec.rb b/spec/services/ci/parse_dotenv_artifact_service_spec.rb
index 8a96479bc6f..7536e04f2de 100644
--- a/spec/services/ci/parse_dotenv_artifact_service_spec.rb
+++ b/spec/services/ci/parse_dotenv_artifact_service_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
context 'when parse error happens' do
before do
- allow(service).to receive(:scan_line!) { raise described_class::ParserError.new('Invalid Format') }
+ allow(service).to receive(:scan_line!) { raise described_class::ParserError, 'Invalid Format' }
end
it 'returns error' do
diff --git a/spec/services/merge_requests/merge_to_ref_service_spec.rb b/spec/services/merge_requests/merge_to_ref_service_spec.rb
index 938165a807c..01dce0dfbce 100644
--- a/spec/services/merge_requests/merge_to_ref_service_spec.rb
+++ b/spec/services/merge_requests/merge_to_ref_service_spec.rb
@@ -94,7 +94,7 @@ RSpec.describe MergeRequests::MergeToRefService do
it 'returns an error when Gitlab::Git::CommandError is raised during merge' do
allow(project.repository).to receive(:merge_to_ref) do
- raise Gitlab::Git::CommandError.new('Failed to create merge commit')
+ raise Gitlab::Git::CommandError, 'Failed to create merge commit'
end
result = service.execute(merge_request)
diff --git a/spec/support/helpers/board_helpers.rb b/spec/support/helpers/board_helpers.rb
index 6e145fed733..dff3f9d976c 100644
--- a/spec/support/helpers/board_helpers.rb
+++ b/spec/support/helpers/board_helpers.rb
@@ -4,6 +4,7 @@ module BoardHelpers
def click_card(card)
within card do
first('.board-card-number').click
+ wait_for_requests
end
end
end
diff --git a/spec/support/helpers/dns_helpers.rb b/spec/support/helpers/dns_helpers.rb
index 1795b0a9ac3..ba32ccbb6f1 100644
--- a/spec/support/helpers/dns_helpers.rb
+++ b/spec/support/helpers/dns_helpers.rb
@@ -18,7 +18,7 @@ module DnsHelpers
def stub_invalid_dns!
allow(Addrinfo).to receive(:getaddrinfo).with(/\Afoobar\.\w|(\d{1,3}\.){4,}\d{1,3}\z/i, anything, nil, :STREAM) do
- raise SocketError.new("getaddrinfo: Name or service not known")
+ raise SocketError, "getaddrinfo: Name or service not known"
end
end
diff --git a/spec/support/helpers/next_found_instance_of.rb b/spec/support/helpers/next_found_instance_of.rb
index feb63f90211..c8cdbaf2c5d 100644
--- a/spec/support/helpers/next_found_instance_of.rb
+++ b/spec/support/helpers/next_found_instance_of.rb
@@ -22,7 +22,7 @@ module NextFoundInstanceOf
private
def check_if_active_record!(klass)
- raise ArgumentError.new(ERROR_MESSAGE) unless klass < ActiveRecord::Base
+ raise ArgumentError, ERROR_MESSAGE unless klass < ActiveRecord::Base
end
def stub_allocate(target, klass)
diff --git a/spec/support/helpers/redis_without_keys.rb b/spec/support/helpers/redis_without_keys.rb
index e030f1028f7..ff64a3cf08e 100644
--- a/spec/support/helpers/redis_without_keys.rb
+++ b/spec/support/helpers/redis_without_keys.rb
@@ -4,7 +4,7 @@ class Redis
ForbiddenCommand = Class.new(StandardError)
def keys(*args)
- raise ForbiddenCommand.new("Don't use `Redis#keys` as it iterates over all "\
- "keys in redis. Use `Redis#scan_each` instead.")
+ raise ForbiddenCommand, "Don't use `Redis#keys` as it iterates over all "\
+ "keys in redis. Use `Redis#scan_each` instead."
end
end
diff --git a/spec/support/helpers/require_migration.rb b/spec/support/helpers/require_migration.rb
index c2902aa4ec7..b5313e78f5d 100644
--- a/spec/support/helpers/require_migration.rb
+++ b/spec/support/helpers/require_migration.rb
@@ -20,7 +20,7 @@ class RequireMigration
class << self
def require_migration!(file_name)
file_paths = search_migration_file(file_name)
- raise AutoLoadError.new(file_name) unless file_paths.first
+ raise AutoLoadError, file_name unless file_paths.first
require file_paths.first
end
diff --git a/spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb b/spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb
index e299a83cf97..86e7da5bcbe 100644
--- a/spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb
+++ b/spec/support/shared_examples/services/alert_management/alert_processing/alert_recovery_shared_examples.rb
@@ -111,67 +111,3 @@ RSpec.shared_examples 'processes recovery alert' do
end
end
end
-
-RSpec.shared_examples 'processes prometheus recovery alert' do
- context 'seen for the first time' do
- it_behaves_like 'does not create an alert management alert'
- it_behaves_like 'does not send alert notification emails'
- it_behaves_like 'does not process incident issues'
- end
-
- context 'for an existing alert with the same fingerprint' do
- let_it_be(:gitlab_fingerprint) { Digest::SHA1.hexdigest(fingerprint) }
-
- context 'which is triggered' do
- let_it_be(:alert) { create(:alert_management_alert, :triggered, project: project, fingerprint: gitlab_fingerprint, monitoring_tool: source) }
-
- it_behaves_like 'resolves an existing alert management alert'
- it_behaves_like 'creates expected system notes for alert', :recovery_alert, :resolve_alert
- it_behaves_like 'sends alert notification emails if enabled'
- it_behaves_like 'closes related incident if enabled'
- it_behaves_like 'writes a warning to the log for a failed alert status update'
-
- it_behaves_like 'does not create an alert management alert'
- it_behaves_like 'does not process incident issues'
- it_behaves_like 'does not add an alert management alert event'
- end
-
- context 'which is ignored' do
- let_it_be(:alert) { create(:alert_management_alert, :ignored, project: project, fingerprint: gitlab_fingerprint, monitoring_tool: source) }
-
- it_behaves_like 'resolves an existing alert management alert'
- it_behaves_like 'creates expected system notes for alert', :recovery_alert, :resolve_alert
- it_behaves_like 'sends alert notification emails if enabled'
- it_behaves_like 'closes related incident if enabled'
- it_behaves_like 'writes a warning to the log for a failed alert status update'
-
- it_behaves_like 'does not create an alert management alert'
- it_behaves_like 'does not process incident issues'
- it_behaves_like 'does not add an alert management alert event'
- end
-
- context 'which is acknowledged' do
- let_it_be(:alert) { create(:alert_management_alert, :acknowledged, project: project, fingerprint: gitlab_fingerprint, monitoring_tool: source) }
-
- it_behaves_like 'resolves an existing alert management alert'
- it_behaves_like 'creates expected system notes for alert', :recovery_alert, :resolve_alert
- it_behaves_like 'sends alert notification emails if enabled'
- it_behaves_like 'closes related incident if enabled'
- it_behaves_like 'writes a warning to the log for a failed alert status update'
-
- it_behaves_like 'does not create an alert management alert'
- it_behaves_like 'does not process incident issues'
- it_behaves_like 'does not add an alert management alert event'
- end
-
- context 'which is resolved' do
- let_it_be(:alert) { create(:alert_management_alert, :resolved, project: project, fingerprint: gitlab_fingerprint, monitoring_tool: source) }
-
- it_behaves_like 'does not create an alert management alert'
- it_behaves_like 'does not send alert notification emails'
- it_behaves_like 'does not change the alert end time'
- it_behaves_like 'does not process incident issues'
- it_behaves_like 'does not add an alert management alert event'
- end
- end
-end
diff --git a/spec/support/shared_examples/services/alert_management_shared_examples.rb b/spec/support/shared_examples/services/alert_management_shared_examples.rb
index a0e084967e5..827ae42f970 100644
--- a/spec/support/shared_examples/services/alert_management_shared_examples.rb
+++ b/spec/support/shared_examples/services/alert_management_shared_examples.rb
@@ -48,9 +48,19 @@ end
RSpec.shared_examples 'processes never-before-seen recovery alert' do
it_behaves_like 'creates an alert management alert or errors'
- it_behaves_like 'creates expected system notes for alert', :new_alert
+ it_behaves_like 'creates expected system notes for alert', :new_alert, :recovery_alert, :resolve_alert
it_behaves_like 'sends alert notification emails if enabled'
- it_behaves_like 'processes incident issues if enabled'
+ it_behaves_like 'does not process incident issues'
+ it_behaves_like 'writes a warning to the log for a failed alert status update' do
+ let(:alert) { nil } # Ensure the next alert id is used
+ end
+
+ it 'resolves the alert' do
+ subject
+
+ expect(AlertManagement::Alert.last.ended_at).to be_present
+ expect(AlertManagement::Alert.last.resolved?).to be(true)
+ end
end
RSpec.shared_examples 'processes one firing and one resolved prometheus alerts' do
@@ -58,10 +68,10 @@ RSpec.shared_examples 'processes one firing and one resolved prometheus alerts'
expect(Gitlab::AppLogger).not_to receive(:warn)
expect { subject }
- .to change(AlertManagement::Alert, :count).by(1)
- .and change(Note, :count).by(1)
+ .to change(AlertManagement::Alert, :count).by(2)
+ .and change(Note, :count).by(4)
end
it_behaves_like 'processes incident issues'
- it_behaves_like 'sends alert notification emails', count: 1
+ it_behaves_like 'sends alert notification emails', count: 2
end
diff --git a/spec/support/stored_repositories.rb b/spec/support/stored_repositories.rb
index 95f0f971787..84396c675b9 100644
--- a/spec/support/stored_repositories.rb
+++ b/spec/support/stored_repositories.rb
@@ -3,7 +3,7 @@
RSpec.configure do |config|
config.before(:each, :broken_storage) do
allow(Gitlab::GitalyClient).to receive(:call) do
- raise GRPC::Unavailable.new('Gitaly broken in this spec')
+ raise GRPC::Unavailable, 'Gitaly broken in this spec'
end
end
end