Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-03 21:08:55 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-03 21:08:55 +0300
commit8f9307985ea047abb5b8a7c6c56bb644e0b7c363 (patch)
tree474c91c280b903c345bd94f4842abf481c535656 /spec
parent3cda3d43aef1e92e2eedf7383122c6db9c61149f (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/profiles_controller_spec.rb10
-rw-r--r--spec/finders/ci/freeze_periods_finder_spec.rb2
-rw-r--r--spec/frontend/api/groups_api_spec.js28
-rw-r--r--spec/frontend/api/projects_api_spec.js26
-rw-r--r--spec/frontend/commit/commit_box_pipeline_mini_graph_spec.js10
-rw-r--r--spec/frontend/commit/mock_data.js42
-rw-r--r--spec/frontend/issues/list/components/issue_card_time_info_spec.js6
-rw-r--r--spec/frontend/issues/show/components/app_spec.js24
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js10
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js2
-rw-r--r--spec/frontend/search/mock_data.js31
-rw-r--r--spec/frontend/search/sidebar/components/app_spec.js69
-rw-r--r--spec/frontend/search/sidebar/components/checkbox_filter_spec.js85
-rw-r--r--spec/frontend/search/sidebar/components/language_filters_spec.js152
-rw-r--r--spec/frontend/search/sidebar/utils_spec.js10
-rw-r--r--spec/haml_lint/linter/documentation_links_spec.rb13
-rw-r--r--spec/helpers/application_helper_spec.rb17
-rw-r--r--spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb102
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb47
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb27
-rw-r--r--spec/migrations/sanitize_confidential_note_todos_spec.rb33
-rw-r--r--spec/models/user_detail_spec.rb31
-rw-r--r--spec/models/user_spec.rb3
-rw-r--r--spec/models/wiki_directory_spec.rb2
-rw-r--r--spec/models/wiki_page_spec.rb2
-rw-r--r--spec/rubocop/cop/migration/prevent_single_statement_with_disable_ddl_transaction_spec.rb2
-rw-r--r--spec/views/shared/wikis/_sidebar.html.haml_spec.rb6
27 files changed, 586 insertions, 206 deletions
diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb
index aa92ff6be33..daf0f36c28b 100644
--- a/spec/controllers/profiles_controller_spec.rb
+++ b/spec/controllers/profiles_controller_spec.rb
@@ -126,6 +126,16 @@ RSpec.describe ProfilesController, :request_store do
expect(user.reload.pronunciation).to eq(pronunciation)
expect(response).to have_gitlab_http_status(:found)
end
+
+ it 'allows updating user specified Discord User ID', :aggregate_failures do
+ discord_user_id = '1234567890123456789'
+ sign_in(user)
+
+ put :update, params: { user: { discord: discord_user_id } }
+
+ expect(user.reload.discord).to eq(discord_user_id)
+ expect(response).to have_gitlab_http_status(:found)
+ end
end
describe 'GET audit_log' do
diff --git a/spec/finders/ci/freeze_periods_finder_spec.rb b/spec/finders/ci/freeze_periods_finder_spec.rb
index 6c58028a221..0aa73e698ed 100644
--- a/spec/finders/ci/freeze_periods_finder_spec.rb
+++ b/spec/finders/ci/freeze_periods_finder_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe Ci::FreezePeriodsFinder, feature_category: :release_orchestration
project.add_developer(user)
end
- it_behaves_like 'returns nothing'
+ it_behaves_like 'returns freeze_periods ordered by created_at asc'
end
context 'when user is not a project member' do
diff --git a/spec/frontend/api/groups_api_spec.js b/spec/frontend/api/groups_api_spec.js
index e064ee9fec4..abd627dab10 100644
--- a/spec/frontend/api/groups_api_spec.js
+++ b/spec/frontend/api/groups_api_spec.js
@@ -3,7 +3,7 @@ import getGroupTransferLocationsResponse from 'test_fixtures/api/groups/transfer
import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils';
import { DEFAULT_PER_PAGE } from '~/api';
-import { updateGroup, getGroupTransferLocations } from '~/api/groups_api';
+import { updateGroup, getGroupTransferLocations, getGroupMembers } from '~/api/groups_api';
const mockApiVersion = 'v4';
const mockUrlRoot = '/gitlab';
@@ -68,4 +68,30 @@ describe('GroupsApi', () => {
});
});
});
+
+ describe('getGroupMembers', () => {
+ it('requests members of a group', async () => {
+ const expectedUrl = `${mockUrlRoot}/api/${mockApiVersion}/groups/${mockGroupId}/members`;
+
+ const response = [{ id: 0, username: 'root' }];
+
+ mock.onGet(expectedUrl).replyOnce(200, response);
+
+ await expect(getGroupMembers(mockGroupId)).resolves.toMatchObject({
+ data: response,
+ });
+ });
+
+ it('requests inherited members of a group when requested', async () => {
+ const expectedUrl = `${mockUrlRoot}/api/${mockApiVersion}/groups/${mockGroupId}/members/all`;
+
+ const response = [{ id: 0, username: 'root' }];
+
+ mock.onGet(expectedUrl).replyOnce(200, response);
+
+ await expect(getGroupMembers(mockGroupId, true)).resolves.toMatchObject({
+ data: response,
+ });
+ });
+ });
});
diff --git a/spec/frontend/api/projects_api_spec.js b/spec/frontend/api/projects_api_spec.js
index 0a6392bdc5b..a6ae8b14ea9 100644
--- a/spec/frontend/api/projects_api_spec.js
+++ b/spec/frontend/api/projects_api_spec.js
@@ -125,4 +125,30 @@ describe('~/api/projects_api.js', () => {
});
});
});
+
+ describe('getProjectMembers', () => {
+ it('requests members of a project', async () => {
+ const expectedUrl = `/api/v7/projects/1/members`;
+
+ const response = [{ id: 0, username: 'root' }];
+
+ mock.onGet(expectedUrl).replyOnce(200, response);
+
+ await expect(projectsApi.getProjectMembers(projectId)).resolves.toMatchObject({
+ data: response,
+ });
+ });
+
+ it('requests inherited members of a project when requested', async () => {
+ const expectedUrl = `/api/v7/projects/1/members/all`;
+
+ const response = [{ id: 0, username: 'root' }];
+
+ mock.onGet(expectedUrl).replyOnce(200, response);
+
+ await expect(projectsApi.getProjectMembers(projectId, true)).resolves.toMatchObject({
+ data: response,
+ });
+ });
+ });
});
diff --git a/spec/frontend/commit/commit_box_pipeline_mini_graph_spec.js b/spec/frontend/commit/commit_box_pipeline_mini_graph_spec.js
index c73f5cf3043..debd10de118 100644
--- a/spec/frontend/commit/commit_box_pipeline_mini_graph_spec.js
+++ b/spec/frontend/commit/commit_box_pipeline_mini_graph_spec.js
@@ -141,6 +141,16 @@ describe('Commit box pipeline mini graph', () => {
expect(upstreamPipeline).toEqual(null);
});
+ it('should render the latest downstream pipeline only', async () => {
+ createComponent(downstreamHandler);
+
+ await waitForPromises();
+
+ const downstreamPipelines = findPipelineMiniGraph().props('downstreamPipelines');
+
+ expect(downstreamPipelines).toHaveLength(1);
+ });
+
it('should pass the pipeline path prop for the counter badge', async () => {
createComponent(downstreamHandler);
diff --git a/spec/frontend/commit/mock_data.js b/spec/frontend/commit/mock_data.js
index 0f168ca6b17..80f62d5bfd8 100644
--- a/spec/frontend/commit/mock_data.js
+++ b/spec/frontend/commit/mock_data.js
@@ -21,6 +21,48 @@ const downstream = {
},
__typename: 'Pipeline',
},
+ {
+ id: 'gid://gitlab/Ci::Pipeline/611',
+ path: '/root/job-log-sections/-/pipelines/611',
+ project: {
+ id: 'gid://gitlab/Project/21',
+ name: 'job-log-sections',
+ __typename: 'Project',
+ },
+ detailedStatus: {
+ id: 'success-611-611',
+ group: 'success',
+ icon: 'status_success',
+ label: 'passed',
+ __typename: 'DetailedStatus',
+ },
+ sourceJob: {
+ id: 'gid://gitlab/Ci::Bridge/531',
+ retried: true,
+ },
+ __typename: 'Pipeline',
+ },
+ {
+ id: 'gid://gitlab/Ci::Pipeline/609',
+ path: '/root/job-log-sections/-/pipelines/609',
+ project: {
+ id: 'gid://gitlab/Project/21',
+ name: 'job-log-sections',
+ __typename: 'Project',
+ },
+ detailedStatus: {
+ id: 'success-609-609',
+ group: 'success',
+ icon: 'status_success',
+ label: 'passed',
+ __typename: 'DetailedStatus',
+ },
+ sourceJob: {
+ id: 'gid://gitlab/Ci::Bridge/530',
+ retried: true,
+ },
+ __typename: 'Pipeline',
+ },
],
__typename: 'PipelineConnection',
};
diff --git a/spec/frontend/issues/list/components/issue_card_time_info_spec.js b/spec/frontend/issues/list/components/issue_card_time_info_spec.js
index b0d3a63a8cf..ab4d023ee39 100644
--- a/spec/frontend/issues/list/components/issue_card_time_info_spec.js
+++ b/spec/frontend/issues/list/components/issue_card_time_info_spec.js
@@ -1,7 +1,7 @@
import { GlIcon, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { useFakeDate } from 'helpers/fake_date';
-import { IssuableStatus } from '~/issues/constants';
+import { STATUS_CLOSED, STATUS_OPEN } from '~/issues/constants';
import IssueCardTimeInfo from '~/issues/list/components/issue_card_time_info.vue';
describe('CE IssueCardTimeInfo component', () => {
@@ -25,7 +25,7 @@ describe('CE IssueCardTimeInfo component', () => {
const findDueDate = () => wrapper.find('[data-testid="issuable-due-date"]');
const mountComponent = ({
- state = IssuableStatus.Open,
+ state = STATUS_OPEN,
dueDate = issue.dueDate,
milestoneDueDate = issue.milestone.dueDate,
milestoneStartDate = issue.milestone.startDate,
@@ -102,7 +102,7 @@ describe('CE IssueCardTimeInfo component', () => {
it('does not render in red', () => {
wrapper = mountComponent({
dueDate: '2020-10-10',
- state: IssuableStatus.Closed,
+ state: STATUS_CLOSED,
});
expect(findDueDate().classes()).not.toContain('gl-text-red-500');
diff --git a/spec/frontend/issues/show/components/app_spec.js b/spec/frontend/issues/show/components/app_spec.js
index 7c1d643dc0f..acb04e0af56 100644
--- a/spec/frontend/issues/show/components/app_spec.js
+++ b/spec/frontend/issues/show/components/app_spec.js
@@ -6,7 +6,13 @@ import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
-import { IssuableStatus, IssuableStatusText, IssuableType } from '~/issues/constants';
+import {
+ IssuableStatusText,
+ IssuableType,
+ STATUS_CLOSED,
+ STATUS_OPEN,
+ STATUS_REOPENED,
+} from '~/issues/constants';
import IssuableApp from '~/issues/show/components/app.vue';
import DescriptionComponent from '~/issues/show/components/description.vue';
import EditedComponent from '~/issues/show/components/edited.vue';
@@ -473,11 +479,11 @@ describe('Issuable output', () => {
});
it.each`
- issuableType | issuableStatus | statusIcon
- ${IssuableType.Issue} | ${IssuableStatus.Open} | ${'issues'}
- ${IssuableType.Issue} | ${IssuableStatus.Closed} | ${'issue-closed'}
- ${IssuableType.Epic} | ${IssuableStatus.Open} | ${'epic'}
- ${IssuableType.Epic} | ${IssuableStatus.Closed} | ${'epic-closed'}
+ issuableType | issuableStatus | statusIcon
+ ${IssuableType.Issue} | ${STATUS_OPEN} | ${'issues'}
+ ${IssuableType.Issue} | ${STATUS_CLOSED} | ${'issue-closed'}
+ ${IssuableType.Epic} | ${STATUS_OPEN} | ${'epic'}
+ ${IssuableType.Epic} | ${STATUS_CLOSED} | ${'epic-closed'}
`(
'shows with state icon "$statusIcon" for $issuableType when status is $issuableStatus',
async ({ issuableType, issuableStatus, statusIcon }) => {
@@ -491,9 +497,9 @@ describe('Issuable output', () => {
it.each`
title | state
- ${'shows with Open when status is opened'} | ${IssuableStatus.Open}
- ${'shows with Closed when status is closed'} | ${IssuableStatus.Closed}
- ${'shows with Open when status is reopened'} | ${IssuableStatus.Reopened}
+ ${'shows with Open when status is opened'} | ${STATUS_OPEN}
+ ${'shows with Closed when status is closed'} | ${STATUS_CLOSED}
+ ${'shows with Open when status is reopened'} | ${STATUS_REOPENED}
`('$title', async ({ state }) => {
wrapper.setProps({ issuableStatus: state });
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index 8a0fdcb50d0..43507f78a97 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -4,7 +4,7 @@ import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
import { createAlert, VARIANT_SUCCESS } from '~/flash';
-import { IssuableStatus, IssueType } from '~/issues/constants';
+import { IssueType, STATUS_CLOSED, STATUS_OPEN } from '~/issues/constants';
import DeleteIssueModal from '~/issues/show/components/delete_issue_modal.vue';
import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue';
import HeaderActions from '~/issues/show/components/header_actions.vue';
@@ -81,7 +81,7 @@ describe('HeaderActions component', () => {
const mountComponent = ({
props = {},
- issueState = IssuableStatus.Open,
+ issueState = STATUS_OPEN,
blockedByIssues = [],
mutateResponse = {},
} = {}) => {
@@ -123,9 +123,9 @@ describe('HeaderActions component', () => {
`('when issue type is $issueType', ({ issueType }) => {
describe('close/reopen button', () => {
describe.each`
- description | issueState | buttonText | newIssueState
- ${`when the ${issueType} is open`} | ${IssuableStatus.Open} | ${`Close ${issueType}`} | ${ISSUE_STATE_EVENT_CLOSE}
- ${`when the ${issueType} is closed`} | ${IssuableStatus.Closed} | ${`Reopen ${issueType}`} | ${ISSUE_STATE_EVENT_REOPEN}
+ description | issueState | buttonText | newIssueState
+ ${`when the ${issueType} is open`} | ${STATUS_OPEN} | ${`Close ${issueType}`} | ${ISSUE_STATE_EVENT_CLOSE}
+ ${`when the ${issueType} is closed`} | ${STATUS_CLOSED} | ${`Reopen ${issueType}`} | ${ISSUE_STATE_EVENT_REOPEN}
`('$description', ({ issueState, buttonText, newIssueState }) => {
beforeEach(() => {
dispatchEventSpy = jest.spyOn(document, 'dispatchEvent');
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
index b2d7a61f548..e352f9708e4 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
@@ -149,7 +149,7 @@ describe('Timeline events form', () => {
it('should show the number of selected tags, when more than one is selected', async () => {
await selectTags(mockTags);
- expect(findTagsListbox().props('toggleText')).toBe('2 tags');
+ expect(findTagsListbox().props('toggleText')).toBe(`${mockTags.length} tags`);
});
it('should be cleared when clear is triggered', async () => {
diff --git a/spec/frontend/search/mock_data.js b/spec/frontend/search/mock_data.js
index 4ccfbe41836..fb9c0a93907 100644
--- a/spec/frontend/search/mock_data.js
+++ b/spec/frontend/search/mock_data.js
@@ -622,3 +622,34 @@ export const MOCK_RECEIVE_AGGREGATIONS_ERROR_MUTATION = [
type: types.RECEIVE_AGGREGATIONS_ERROR,
},
];
+
+export const TEST_RAW_BUCKETS = [
+ { key: 'Go', count: 350 },
+ { key: 'C', count: 298 },
+ { key: 'JavaScript', count: 128 },
+ { key: 'YAML', count: 58 },
+ { key: 'Text', count: 46 },
+ { key: 'Markdown', count: 37 },
+ { key: 'HTML', count: 34 },
+ { key: 'Shell', count: 34 },
+ { key: 'Makefile', count: 21 },
+ { key: 'JSON', count: 15 },
+];
+
+export const TEST_FILTER_DATA = {
+ header: 'Language',
+ scopes: { BLOBS: 'blobs' },
+ filterParam: 'language',
+ filters: {
+ GO: { label: 'Go', value: 'Go', count: 350 },
+ C: { label: 'C', value: 'C', count: 298 },
+ JAVASCRIPT: { label: 'JavaScript', value: 'JavaScript', count: 128 },
+ YAML: { label: 'YAML', value: 'YAML', count: 58 },
+ TEXT: { label: 'Text', value: 'Text', count: 46 },
+ MARKDOWN: { label: 'Markdown', value: 'Markdown', count: 37 },
+ HTML: { label: 'HTML', value: 'HTML', count: 34 },
+ SHELL: { label: 'Shell', value: 'Shell', count: 34 },
+ MAKEFILE: { label: 'Makefile', value: 'Makefile', count: 21 },
+ JSON: { label: 'JSON', value: 'JSON', count: 15 },
+ },
+};
diff --git a/spec/frontend/search/sidebar/components/app_spec.js b/spec/frontend/search/sidebar/components/app_spec.js
index 6aa40b7a2be..760c83a1dde 100644
--- a/spec/frontend/search/sidebar/components/app_spec.js
+++ b/spec/frontend/search/sidebar/components/app_spec.js
@@ -5,6 +5,7 @@ import { MOCK_QUERY } from 'jest/search/mock_data';
import GlobalSearchSidebar from '~/search/sidebar/components/app.vue';
import ResultsFilters from '~/search/sidebar/components/results_filters.vue';
import ScopeNavigation from '~/search/sidebar/components/scope_navigation.vue';
+import LanguageFilter from '~/search/sidebar/components/language_filter.vue';
Vue.use(Vuex);
@@ -35,53 +36,41 @@ describe('GlobalSearchSidebar', () => {
});
};
- afterEach(() => {
- wrapper.destroy();
- });
-
const findSidebarSection = () => wrapper.find('section');
const findFilters = () => wrapper.findComponent(ResultsFilters);
const findSidebarNavigation = () => wrapper.findComponent(ScopeNavigation);
+ const findLanguageAggregation = () => wrapper.findComponent(LanguageFilter);
describe('renders properly', () => {
- describe('scope=projects', () => {
+ describe('always', () => {
beforeEach(() => {
- createComponent({ urlQuery: { ...MOCK_QUERY, scope: 'projects' } });
+ createComponent({});
});
-
- it('shows section', () => {
+ it(`shows section`, () => {
expect(findSidebarSection().exists()).toBe(true);
});
-
- it("doesn't shows filters", () => {
- expect(findFilters().exists()).toBe(false);
- });
});
- describe('scope=merge_requests', () => {
+ describe.each`
+ scope | showFilters | ShowsLanguage
+ ${'issues'} | ${true} | ${false}
+ ${'merge_requests'} | ${true} | ${false}
+ ${'projects'} | ${false} | ${false}
+ ${'blobs'} | ${false} | ${true}
+ `('sidebar scope: $scope', ({ scope, showFilters, ShowsLanguage }) => {
beforeEach(() => {
- createComponent({ urlQuery: { ...MOCK_QUERY, scope: 'merge_requests' } });
+ createComponent(
+ { urlQuery: { scope } },
+ { searchBlobsLanguageAggregation: true, searchPageVerticalNav: true },
+ );
});
- it('shows section', () => {
- expect(findSidebarSection().exists()).toBe(true);
+ it(`${!showFilters ? "doesn't" : ''} shows filters`, () => {
+ expect(findFilters().exists()).toBe(showFilters);
});
- it('shows filters', () => {
- expect(findFilters().exists()).toBe(true);
- });
- });
-
- describe('scope=issues', () => {
- beforeEach(() => {
- createComponent({ urlQuery: MOCK_QUERY });
- });
- it('shows section', () => {
- expect(findSidebarSection().exists()).toBe(true);
- });
-
- it('shows filters', () => {
- expect(findFilters().exists()).toBe(true);
+ it(`${!ShowsLanguage ? "doesn't" : ''} shows language filters`, () => {
+ expect(findLanguageAggregation().exists()).toBe(ShowsLanguage);
});
});
@@ -94,4 +83,22 @@ describe('GlobalSearchSidebar', () => {
});
});
});
+
+ describe('when search_blobs_language_aggregation is enabled', () => {
+ beforeEach(() => {
+ createComponent({ urlQuery: { scope: 'blobs' } }, { searchBlobsLanguageAggregation: true });
+ });
+ it('shows the language filter', () => {
+ expect(findLanguageAggregation().exists()).toBe(true);
+ });
+ });
+
+ describe('when search_blobs_language_aggregation is disabled', () => {
+ beforeEach(() => {
+ createComponent({ urlQuery: { scope: 'blobs' } }, { searchBlobsLanguageAggregation: false });
+ });
+ it('hides the language filter', () => {
+ expect(findLanguageAggregation().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/search/sidebar/components/checkbox_filter_spec.js b/spec/frontend/search/sidebar/components/checkbox_filter_spec.js
new file mode 100644
index 00000000000..82017754b23
--- /dev/null
+++ b/spec/frontend/search/sidebar/components/checkbox_filter_spec.js
@@ -0,0 +1,85 @@
+import { GlFormCheckboxGroup, GlFormCheckbox } from '@gitlab/ui';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { MOCK_QUERY, MOCK_LANGUAGE_AGGREGATIONS_BUCKETS } from 'jest/search/mock_data';
+import CheckboxFilter from '~/search/sidebar/components/checkbox_filter.vue';
+
+import { languageFilterData } from '~/search/sidebar/constants/language_filter_data';
+import { convertFiltersData } from '~/search/sidebar/utils';
+
+Vue.use(Vuex);
+
+describe('CheckboxFilter', () => {
+ let wrapper;
+
+ const actionSpies = {
+ setQuery: jest.fn(),
+ };
+
+ const defaultProps = {
+ filterData: convertFiltersData(MOCK_LANGUAGE_AGGREGATIONS_BUCKETS),
+ };
+
+ const createComponent = () => {
+ const store = new Vuex.Store({
+ state: {
+ query: MOCK_QUERY,
+ },
+ actions: actionSpies,
+ });
+
+ wrapper = shallowMountExtended(CheckboxFilter, {
+ store,
+ propsData: {
+ ...defaultProps,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ const findFormCheckboxGroup = () => wrapper.findComponent(GlFormCheckboxGroup);
+ const findAllCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
+ const fintAllCheckboxLabels = () => wrapper.findAllByTestId('label');
+ const fintAllCheckboxLabelCounts = () => wrapper.findAllByTestId('labelCount');
+
+ describe('Renders correctly', () => {
+ it('renders form', () => {
+ expect(findFormCheckboxGroup().exists()).toBe(true);
+ });
+
+ it('renders checkbox-filter', () => {
+ expect(findAllCheckboxes().exists()).toBe(true);
+ });
+
+ it('renders all checkbox-filter checkboxes', () => {
+ expect(findAllCheckboxes()).toHaveLength(MOCK_LANGUAGE_AGGREGATIONS_BUCKETS.length);
+ });
+
+ it('renders correctly label for the element', () => {
+ expect(fintAllCheckboxLabels().at(0).text()).toBe(MOCK_LANGUAGE_AGGREGATIONS_BUCKETS[0].key);
+ });
+
+ it('renders correctly count for the element', () => {
+ expect(fintAllCheckboxLabelCounts().at(0).text()).toBe(
+ MOCK_LANGUAGE_AGGREGATIONS_BUCKETS[0].count.toString(),
+ );
+ });
+ });
+
+ describe('actions', () => {
+ it('triggers setQuery', () => {
+ const filter =
+ defaultProps.filterData.filters[Object.keys(defaultProps.filterData.filters)[0]].value;
+ findFormCheckboxGroup().vm.$emit('input', filter);
+
+ expect(actionSpies.setQuery).toHaveBeenCalledWith(expect.any(Object), {
+ key: languageFilterData.filterParam,
+ value: filter,
+ });
+ });
+ });
+});
diff --git a/spec/frontend/search/sidebar/components/language_filters_spec.js b/spec/frontend/search/sidebar/components/language_filters_spec.js
new file mode 100644
index 00000000000..e297d1c33b0
--- /dev/null
+++ b/spec/frontend/search/sidebar/components/language_filters_spec.js
@@ -0,0 +1,152 @@
+import { GlAlert, GlFormCheckbox, GlForm } from '@gitlab/ui';
+import Vue, { nextTick } from 'vue';
+import Vuex from 'vuex';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ MOCK_QUERY,
+ MOCK_AGGREGATIONS,
+ MOCK_LANGUAGE_AGGREGATIONS_BUCKETS,
+} from 'jest/search/mock_data';
+import LanguageFilter from '~/search/sidebar/components/language_filter.vue';
+import CheckboxFilter from '~/search/sidebar/components/checkbox_filter.vue';
+import { MAX_ITEM_LENGTH } from '~/search/sidebar/constants/language_filter_data';
+
+Vue.use(Vuex);
+
+describe('GlobalSearchSidebarLanguageFilter', () => {
+ let wrapper;
+
+ const actionSpies = {
+ fetchLanguageAggregation: jest.fn(),
+ applyQuery: jest.fn(),
+ };
+
+ const getterSpies = {
+ langugageAggregationBuckets: jest.fn(() => MOCK_LANGUAGE_AGGREGATIONS_BUCKETS),
+ };
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ query: MOCK_QUERY,
+ urlQuery: MOCK_QUERY,
+ aggregations: MOCK_AGGREGATIONS,
+ ...initialState,
+ },
+ actions: actionSpies,
+ getters: getterSpies,
+ });
+
+ wrapper = shallowMountExtended(LanguageFilter, {
+ store,
+ stubs: {
+ CheckboxFilter,
+ },
+ });
+ };
+
+ const findForm = () => wrapper.findComponent(GlForm);
+ const findCheckboxFilter = () => wrapper.findComponent(CheckboxFilter);
+ const findApplyButton = () => wrapper.findByTestId('apply-button');
+ const findShowMoreButton = () => wrapper.findByTestId('show-more-button');
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findAllCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
+ const findHasOverMax = () => wrapper.findByTestId('has-over-max-text');
+
+ describe('Renders correctly', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders form', () => {
+ expect(findForm().exists()).toBe(true);
+ });
+
+ it('renders checkbox-filter', () => {
+ expect(findCheckboxFilter().exists()).toBe(true);
+ });
+
+ it('renders all checkbox-filter checkboxes', () => {
+ // 11th checkbox is hidden
+ expect(findAllCheckboxes()).toHaveLength(10);
+ });
+
+ it('renders ApplyButton', () => {
+ expect(findApplyButton().exists()).toBe(true);
+ });
+
+ it('renders Show More button', () => {
+ expect(findShowMoreButton().exists()).toBe(true);
+ });
+
+ it("doesn't render Alert", () => {
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+
+ describe('ApplyButton', () => {
+ describe('when sidebarDirty is false', () => {
+ beforeEach(() => {
+ createComponent({ sidebarDirty: false });
+ });
+
+ it('disables the button', () => {
+ expect(findApplyButton().attributes('disabled')).toBe('true');
+ });
+ });
+
+ describe('when sidebarDirty is true', () => {
+ beforeEach(() => {
+ createComponent({ sidebarDirty: true });
+ });
+
+ it('enables the button', () => {
+ expect(findApplyButton().attributes('disabled')).toBe(undefined);
+ });
+ });
+ });
+
+ describe('Show All button works', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it(`renders ${MAX_ITEM_LENGTH} amount of items`, async () => {
+ findShowMoreButton().vm.$emit('click');
+ await nextTick();
+ expect(findAllCheckboxes()).toHaveLength(MAX_ITEM_LENGTH);
+ });
+
+ it(`renders more then ${MAX_ITEM_LENGTH} text`, async () => {
+ findShowMoreButton().vm.$emit('click');
+ await nextTick();
+ expect(findHasOverMax().exists()).toBe(true);
+ });
+
+ it(`doesn't render show more button after click`, async () => {
+ findShowMoreButton().vm.$emit('click');
+ await nextTick();
+ expect(findShowMoreButton().exists()).toBe(false);
+ });
+ });
+
+ describe('actions', () => {
+ beforeEach(() => {
+ createComponent({});
+ });
+
+ it('uses getter langugageAggregationBuckets', () => {
+ expect(getterSpies.langugageAggregationBuckets).toHaveBeenCalled();
+ });
+
+ it('uses action fetchLanguageAggregation', () => {
+ expect(actionSpies.fetchLanguageAggregation).toHaveBeenCalled();
+ });
+
+ it('clicking ApplyButton calls applyQuery', () => {
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+
+ expect(actionSpies.applyQuery).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/search/sidebar/utils_spec.js b/spec/frontend/search/sidebar/utils_spec.js
new file mode 100644
index 00000000000..652d32c836e
--- /dev/null
+++ b/spec/frontend/search/sidebar/utils_spec.js
@@ -0,0 +1,10 @@
+import { convertFiltersData } from '~/search/sidebar/utils';
+import { TEST_RAW_BUCKETS, TEST_FILTER_DATA } from '../mock_data';
+
+describe('Global Search sidebar utils', () => {
+ describe('convertFiltersData', () => {
+ it('converts raw buckets to array', () => {
+ expect(convertFiltersData(TEST_RAW_BUCKETS)).toStrictEqual(TEST_FILTER_DATA);
+ });
+ });
+});
diff --git a/spec/haml_lint/linter/documentation_links_spec.rb b/spec/haml_lint/linter/documentation_links_spec.rb
index 380df49cde3..d47127d9661 100644
--- a/spec/haml_lint/linter/documentation_links_spec.rb
+++ b/spec/haml_lint/linter/documentation_links_spec.rb
@@ -6,7 +6,7 @@ require 'haml_lint/spec'
require_relative '../../../haml_lint/linter/documentation_links'
-RSpec.describe HamlLint::Linter::DocumentationLinks do
+RSpec.describe HamlLint::Linter::DocumentationLinks, feature_category: :tooling do
include_context 'linter'
shared_examples 'link validation rules' do |link_pattern|
@@ -95,11 +95,8 @@ RSpec.describe HamlLint::Linter::DocumentationLinks do
end
end
- context 'help_page_path' do
- it_behaves_like 'link validation rules', 'help_page_path'
- end
-
- context 'help_page_url' do
- it_behaves_like 'link validation rules', 'help_page_url'
- end
+ it_behaves_like 'link validation rules', 'help_page_path'
+ it_behaves_like 'link validation rules', 'help_page_url'
+ it_behaves_like 'link validation rules', 'Rails.application.routes.url_helpers.help_page_url'
+ it_behaves_like 'link validation rules', 'Gitlab::Routing.url_helpers.help_page_url'
end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index f628651b4da..4e921fe1719 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -540,6 +540,23 @@ RSpec.describe ApplicationHelper do
end
end
+ describe '#profile_social_links' do
+ context 'when discord is set' do
+ let_it_be(:user) { build(:user) }
+ let(:discord) { discord_url(user) }
+
+ it 'returns an empty string if discord is not set' do
+ expect(discord).to eq('')
+ end
+
+ it 'returns discord url when discord id is set' do
+ user.discord = '1234567890123456789'
+
+ expect(discord).to eq('https://discord.com/users/1234567890123456789')
+ end
+ end
+ end
+
describe '#gitlab_ui_form_for' do
let_it_be(:user) { build(:user) }
diff --git a/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb b/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb
deleted file mode 100644
index a19a3760958..00000000000
--- a/spec/lib/gitlab/background_migration/sanitize_confidential_todos_spec.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::BackgroundMigration::SanitizeConfidentialTodos, :migration, feature_category: :team_planning do
- let!(:issue_type_id) { table(:work_item_types).find_by(base_type: 0).id }
-
- let(:todos) { table(:todos) }
- let(:notes) { table(:notes) }
- let(:namespaces) { table(:namespaces) }
- let(:projects) { table(:projects) }
- let(:project_features) { table(:project_features) }
- let(:users) { table(:users) }
- let(:issues) { table(:issues) }
- let(:members) { table(:members) }
- let(:project_authorizations) { table(:project_authorizations) }
-
- let(:user) { users.create!(first_name: 'Test', last_name: 'User', email: 'test@user.com', projects_limit: 1) }
- let(:project_namespace1) { namespaces.create!(path: 'pns1', name: 'pns1') }
- let(:project_namespace2) { namespaces.create!(path: 'pns2', name: 'pns2') }
-
- let(:project1) do
- projects.create!(namespace_id: project_namespace1.id,
- project_namespace_id: project_namespace1.id, visibility_level: 20)
- end
-
- let(:project2) do
- projects.create!(namespace_id: project_namespace2.id,
- project_namespace_id: project_namespace2.id)
- end
-
- let(:issue1) do
- issues.create!(
- project_id: project1.id, namespace_id: project_namespace1.id, issue_type: 1, title: 'issue1', author_id: user.id,
- work_item_type_id: issue_type_id
- )
- end
-
- let(:issue2) do
- issues.create!(
- project_id: project2.id, namespace_id: project_namespace2.id, issue_type: 1, title: 'issue2',
- work_item_type_id: issue_type_id
- )
- end
-
- let(:public_note) { notes.create!(note: 'text', project_id: project1.id) }
-
- let(:confidential_note) do
- notes.create!(note: 'text', project_id: project1.id, confidential: true,
- noteable_id: issue1.id, noteable_type: 'Issue')
- end
-
- let(:other_confidential_note) do
- notes.create!(note: 'text', project_id: project2.id, confidential: true,
- noteable_id: issue2.id, noteable_type: 'Issue')
- end
-
- let(:common_params) { { user_id: user.id, author_id: user.id, action: 1, state: 'pending', target_type: 'Note' } }
- let!(:ignored_todo1) { todos.create!(**common_params) }
- let!(:ignored_todo2) { todos.create!(**common_params, target_id: public_note.id, note_id: public_note.id) }
- let!(:valid_todo) { todos.create!(**common_params, target_id: confidential_note.id, note_id: confidential_note.id) }
- let!(:invalid_todo) do
- todos.create!(**common_params, target_id: other_confidential_note.id, note_id: other_confidential_note.id)
- end
-
- describe '#perform' do
- before do
- project_features.create!(project_id: project1.id, issues_access_level: 20, pages_access_level: 20)
- members.create!(state: 0, source_id: project1.id, source_type: 'Project',
- type: 'ProjectMember', user_id: user.id, access_level: 50, notification_level: 0,
- member_namespace_id: project_namespace1.id)
- project_authorizations.create!(project_id: project1.id, user_id: user.id, access_level: 50)
- end
-
- subject(:perform) do
- described_class.new(
- start_id: notes.minimum(:id),
- end_id: notes.maximum(:id),
- batch_table: :notes,
- batch_column: :id,
- sub_batch_size: 1,
- pause_ms: 0,
- connection: ApplicationRecord.connection
- ).perform
- end
-
- it 'deletes todos where user can not read its note and logs deletion', :aggregate_failures do
- expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |logger|
- expect(logger).to receive(:info).with(
- hash_including(
- message: "#{described_class.name} deleting invalid todo",
- attributes: hash_including(invalid_todo.attributes.slice(:id, :user_id, :target_id, :target_type))
- )
- ).once
- end
-
- expect { perform }.to change(todos, :count).by(-1)
-
- expect(todos.all).to match_array([ignored_todo1, ignored_todo2, valid_todo])
- end
- end
-end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 6cff39c1167..d6d0de63a3b 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1947,6 +1947,53 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
expect(reference.name).to be_a(String)
expect(reference.target).to be_a(String)
end
+
+ it 'filters by pattern' do
+ refs = repository.list_refs([Gitlab::Git::TAG_REF_PREFIX])
+
+ refs.each do |reference|
+ expect(reference.name).to include(Gitlab::Git::TAG_REF_PREFIX)
+ end
+ end
+
+ context 'with pointing_at_oids and peel_tags options' do
+ let(:commit_id) { mutable_repository.commit.id }
+ let!(:annotated_tag) { mutable_repository.add_tag('annotated-tag', user: user, target: commit_id, message: 'Tag message') }
+ let!(:lw_tag) { mutable_repository.add_tag('lw-tag', user: user, target: commit_id) }
+
+ it 'filters by target OIDs' do
+ refs = mutable_repository.list_refs([Gitlab::Git::TAG_REF_PREFIX], pointing_at_oids: [commit_id])
+
+ expect(refs.length).to eq(2)
+ expect(refs).to contain_exactly(
+ Gitaly::ListRefsResponse::Reference.new(
+ name: "#{Gitlab::Git::TAG_REF_PREFIX}#{lw_tag.name}",
+ target: commit_id
+ ),
+ Gitaly::ListRefsResponse::Reference.new(
+ name: "#{Gitlab::Git::TAG_REF_PREFIX}#{annotated_tag.name}",
+ target: annotated_tag.id
+ )
+ )
+ end
+
+ it 'returns peeled_target for annotated tags' do
+ refs = mutable_repository.list_refs([Gitlab::Git::TAG_REF_PREFIX], pointing_at_oids: [commit_id], peel_tags: true)
+
+ expect(refs.length).to eq(2)
+ expect(refs).to contain_exactly(
+ Gitaly::ListRefsResponse::Reference.new(
+ name: "#{Gitlab::Git::TAG_REF_PREFIX}#{lw_tag.name}",
+ target: commit_id
+ ),
+ Gitaly::ListRefsResponse::Reference.new(
+ name: "#{Gitlab::Git::TAG_REF_PREFIX}#{annotated_tag.name}",
+ target: annotated_tag.id,
+ peeled_target: commit_id
+ )
+ )
+ end
+ end
end
describe '#refs_by_oid' do
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index 14d5cef103b..09d8ea3cc0a 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::GitalyClient::RefService do
+RSpec.describe Gitlab::GitalyClient::RefService, feature_category: :gitaly do
let_it_be(:project) { create(:project, :repository, create_tag: 'test') }
let(:storage_name) { project.repository_storage }
@@ -390,10 +390,15 @@ RSpec.describe Gitlab::GitalyClient::RefService do
end
describe '#list_refs' do
+ let(:oid) { project.repository.commit.id }
+
it 'sends a list_refs message' do
expect_any_instance_of(Gitaly::RefService::Stub)
.to receive(:list_refs)
- .with(gitaly_request_with_params(patterns: ['refs/heads/']), kind_of(Hash))
+ .with(
+ gitaly_request_with_params(patterns: ['refs/heads/'], pointing_at_oids: [], peel_tags: false),
+ kind_of(Hash)
+ )
.and_call_original
client.list_refs
@@ -407,6 +412,24 @@ RSpec.describe Gitlab::GitalyClient::RefService do
client.list_refs([Gitlab::Git::TAG_REF_PREFIX])
end
+
+ it 'accepts a pointing_at_oids argument' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:list_refs)
+ .with(gitaly_request_with_params(pointing_at_oids: [oid]), kind_of(Hash))
+ .and_call_original
+
+ client.list_refs(pointing_at_oids: [oid])
+ end
+
+ it 'accepts a peel_tags argument' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:list_refs)
+ .with(gitaly_request_with_params(peel_tags: true), kind_of(Hash))
+ .and_call_original
+
+ client.list_refs(peel_tags: true)
+ end
end
describe '#find_refs_by_oid' do
diff --git a/spec/migrations/sanitize_confidential_note_todos_spec.rb b/spec/migrations/sanitize_confidential_note_todos_spec.rb
deleted file mode 100644
index 142378e07e1..00000000000
--- a/spec/migrations/sanitize_confidential_note_todos_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-require_migration!
-
-RSpec.describe SanitizeConfidentialNoteTodos, feature_category: :team_planning do
- let(:migration) { described_class::MIGRATION }
-
- describe '#up' do
- it 'schedules a batched background migration' do
- migrate!
-
- expect(migration).to have_scheduled_batched_migration(
- table_name: :notes,
- column_name: :id,
- interval: described_class::DELAY_INTERVAL,
- batch_size: described_class::BATCH_SIZE,
- max_batch_size: described_class::MAX_BATCH_SIZE,
- sub_batch_size: described_class::SUB_BATCH_SIZE
- )
- end
- end
-
- describe '#down' do
- it 'deletes all batched migration records' do
- migrate!
- schema_migrate_down!
-
- expect(migration).not_to have_scheduled_batched_migration
- end
- end
-end
diff --git a/spec/models/user_detail_spec.rb b/spec/models/user_detail_spec.rb
index 1893b6530a5..7d433896cf8 100644
--- a/spec/models/user_detail_spec.rb
+++ b/spec/models/user_detail_spec.rb
@@ -38,6 +38,27 @@ RSpec.describe UserDetail do
it { is_expected.to validate_length_of(:skype).is_at_most(500) }
end
+ describe '#discord' do
+ it { is_expected.to validate_length_of(:discord).is_at_most(500) }
+
+ context 'when discord is set' do
+ let_it_be(:user_detail) { create(:user_detail) }
+
+ it 'accepts a valid discord user id' do
+ user_detail.discord = '1234567890123456789'
+
+ expect(user_detail).to be_valid
+ end
+
+ it 'throws an error when other url format is wrong' do
+ user_detail.discord = '123456789'
+
+ expect(user_detail).not_to be_valid
+ expect(user_detail.errors.full_messages).to match_array([_('Discord must contain only a discord user ID.')])
+ end
+ end
+ end
+
describe '#location' do
it { is_expected.to validate_length_of(:location).is_at_most(500) }
end
@@ -72,11 +93,12 @@ RSpec.describe UserDetail do
let(:user_detail) do
create(:user_detail,
bio: 'bio',
+ discord: '1234567890123456789',
linkedin: 'linkedin',
- twitter: 'twitter',
- skype: 'skype',
location: 'location',
organization: 'organization',
+ skype: 'skype',
+ twitter: 'twitter',
website_url: 'https://example.com')
end
@@ -90,11 +112,12 @@ RSpec.describe UserDetail do
end
it_behaves_like 'prevents `nil` value', :bio
+ it_behaves_like 'prevents `nil` value', :discord
it_behaves_like 'prevents `nil` value', :linkedin
- it_behaves_like 'prevents `nil` value', :twitter
- it_behaves_like 'prevents `nil` value', :skype
it_behaves_like 'prevents `nil` value', :location
it_behaves_like 'prevents `nil` value', :organization
+ it_behaves_like 'prevents `nil` value', :skype
+ it_behaves_like 'prevents `nil` value', :twitter
it_behaves_like 'prevents `nil` value', :website_url
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 5570eb36c81..7b5b8acdb66 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -102,6 +102,9 @@ RSpec.describe User, feature_category: :user_profile do
it { is_expected.to delegate_method(:requires_credit_card_verification).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:requires_credit_card_verification=).to(:user_detail).with_arguments(:args).allow_nil }
+ it { is_expected.to delegate_method(:discord).to(:user_detail).allow_nil }
+ it { is_expected.to delegate_method(:discord=).to(:user_detail).with_arguments(:args).allow_nil }
+
it { is_expected.to delegate_method(:linkedin).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:linkedin=).to(:user_detail).with_arguments(:args).allow_nil }
diff --git a/spec/models/wiki_directory_spec.rb b/spec/models/wiki_directory_spec.rb
index 90ff42998ae..1b177934ace 100644
--- a/spec/models/wiki_directory_spec.rb
+++ b/spec/models/wiki_directory_spec.rb
@@ -100,7 +100,7 @@ RSpec.describe WikiDirectory do
describe '#to_partial_path' do
it 'returns the relative path to the partial to be used' do
- expect(directory.to_partial_path).to eq('../shared/wikis/wiki_directory')
+ expect(directory.to_partial_path).to eq('shared/wikis/wiki_directory')
end
end
end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index fcb041aebe5..21da06a222f 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -912,7 +912,7 @@ RSpec.describe WikiPage do
describe '#to_partial_path' do
it 'returns the relative path to the partial to be used' do
- expect(build_wiki_page(container).to_partial_path).to eq('../shared/wikis/wiki_page')
+ expect(build_wiki_page(container).to_partial_path).to eq('shared/wikis/wiki_page')
end
end
diff --git a/spec/rubocop/cop/migration/prevent_single_statement_with_disable_ddl_transaction_spec.rb b/spec/rubocop/cop/migration/prevent_single_statement_with_disable_ddl_transaction_spec.rb
index 3f5845f8f58..968de7d2160 100644
--- a/spec/rubocop/cop/migration/prevent_single_statement_with_disable_ddl_transaction_spec.rb
+++ b/spec/rubocop/cop/migration/prevent_single_statement_with_disable_ddl_transaction_spec.rb
@@ -3,7 +3,7 @@
require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/prevent_single_statement_with_disable_ddl_transaction'
-RSpec.describe RuboCop::Cop::Migration::PreventSingleStatementWithDisableDdlTransaction do
+RSpec.describe RuboCop::Cop::Migration::PreventSingleStatementWithDisableDdlTransaction, feature_category: :database do
context 'when in migration' do
before do
allow(cop).to receive(:in_migration?).and_return(true)
diff --git a/spec/views/shared/wikis/_sidebar.html.haml_spec.rb b/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
index 0e7b657a154..821112e12bc 100644
--- a/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
+++ b/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
@@ -52,8 +52,8 @@ RSpec.describe 'shared/wikis/_sidebar.html.haml' do
before do
assign(:sidebar_wiki_entries, create_list(:wiki_page, 3, wiki: wiki))
assign(:sidebar_limited, true)
- stub_template "../shared/wikis/_wiki_pages.html.erb" => "Entries: <%= @sidebar_wiki_entries.size %>"
- stub_template "../shared/wikis/_wiki_page.html.erb" => 'A WIKI PAGE'
+ stub_template "shared/wikis/_wiki_pages.html.erb" => "Entries: <%= @sidebar_wiki_entries.size %>"
+ stub_template "shared/wikis/_wiki_page.html.erb" => 'A WIKI PAGE'
end
it 'does not show an alert' do
@@ -66,7 +66,7 @@ RSpec.describe 'shared/wikis/_sidebar.html.haml' do
it 'renders the wiki content' do
render
- expect(rendered).to include('A WIKI PAGE' * 3)
+ expect(rendered).to include("A WIKI PAGE\n" * 3)
expect(rendered).to have_link('View All Pages')
end