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
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/boards/boards_util.js33
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue2
-rw-r--r--app/assets/javascripts/boards/stores/actions.js144
-rw-r--r--app/assets/javascripts/boards/stores/mutation_types.js4
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js33
-rw-r--r--app/assets/javascripts/diffs/components/app.vue14
-rw-r--r--app/assets/javascripts/diffs/components/diff_file.vue11
-rw-r--r--app/assets/javascripts/diffs/store/actions.js47
-rw-r--r--app/assets/javascripts/diffs/store/getters.js10
-rw-r--r--app/assets/javascripts/diffs/store/modules/diff_state.js1
-rw-r--r--app/assets/javascripts/diffs/store/modules/index.js6
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js6
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue2
-rw-r--r--app/controllers/admin/users_controller.rb6
-rw-r--r--app/controllers/projects/logs_controller.rb2
-rw-r--r--app/finders/environments_finder.rb7
-rw-r--r--app/graphql/resolvers/environments_resolver.rb2
-rw-r--r--app/serializers/admin/user_entity.rb2
-rw-r--r--app/services/issues/create_service.rb6
-rw-r--r--app/services/prometheus/create_default_alerts_service.rb2
-rw-r--r--app/views/admin/projects/index.html.haml10
-rw-r--r--app/views/projects/jobs/_table.html.haml2
-rw-r--r--app/views/registrations/welcome/show.html.haml6
-rw-r--r--app/workers/new_issue_worker.rb8
-rw-r--r--changelogs/unreleased/21140-remove-issue-perform-after-creation-tasks-async-feature-flag.yml5
-rw-r--r--changelogs/unreleased/Externalize-strings-in-projects-index-html-haml.yml5
-rw-r--r--changelogs/unreleased/nicolasdular-welcome-page-text-change.yml5
-rw-r--r--changelogs/unreleased/reduce-pipline-tooltip-delay-to-zero.yml5
-rw-r--r--changelogs/unreleased/ui-text-job-pipeline-runtime.yml5
-rw-r--r--config/feature_flags/development/issue_perform_after_creation_tasks_async.yml8
-rw-r--r--doc/user/admin_area/img/export_permissions_v13_11.pngbin0 -> 11567 bytes
-rw-r--r--doc/user/admin_area/index.md2
-rw-r--r--lib/api/environments.rb2
-rw-r--r--lib/gitlab/alert_management/payload/base.rb2
-rw-r--r--locale/gitlab.pot15
-rw-r--r--spec/finders/environments_finder_spec.rb14
-rw-r--r--spec/frontend/boards/mock_data.js36
-rw-r--r--spec/frontend/boards/stores/actions_spec.js406
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js68
-rw-r--r--spec/frontend/diffs/components/app_spec.js12
-rw-r--r--spec/frontend/diffs/store/actions_spec.js48
-rw-r--r--spec/frontend/diffs/store/getters_spec.js20
-rw-r--r--spec/frontend/diffs/store/mutations_spec.js13
-rw-r--r--spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js9
-rw-r--r--spec/serializers/admin/user_entity_spec.rb2
-rw-r--r--spec/serializers/admin/user_serializer_spec.rb2
-rw-r--r--spec/services/issues/create_service_spec.rb24
-rw-r--r--spec/workers/new_issue_worker_spec.rb26
-rw-r--r--[-rwxr-xr-x]vendor/gitignore/C++.gitignore0
-rw-r--r--[-rwxr-xr-x]vendor/gitignore/Java.gitignore0
51 files changed, 619 insertions, 482 deletions
diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js
index 2cd25f58770..a8b870f9b8e 100644
--- a/app/assets/javascripts/boards/boards_util.js
+++ b/app/assets/javascripts/boards/boards_util.js
@@ -1,4 +1,4 @@
-import { sortBy } from 'lodash';
+import { sortBy, cloneDeep } from 'lodash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { ListType, NOT_FILTER } from './constants';
@@ -113,6 +113,37 @@ export function formatIssueInput(issueInput, boardConfig) {
};
}
+export function shouldCloneCard(fromListType, toListType) {
+ const involvesClosed = fromListType === ListType.closed || toListType === ListType.closed;
+ const involvesBacklog = fromListType === ListType.backlog || toListType === ListType.backlog;
+
+ if (involvesClosed || involvesBacklog) {
+ return false;
+ }
+
+ if (fromListType !== toListType) {
+ return true;
+ }
+
+ return false;
+}
+
+export function getMoveData(state, params) {
+ const { boardItems, boardItemsByListId, boardLists } = state;
+ const { itemId, fromListId, toListId } = params;
+ const fromListType = boardLists[fromListId].listType;
+ const toListType = boardLists[toListId].listType;
+
+ return {
+ reordering: fromListId === toListId,
+ shouldClone: shouldCloneCard(fromListType, toListType),
+ itemNotInToList: !boardItemsByListId[toListId].includes(itemId),
+ originalIssue: cloneDeep(boardItems[itemId]),
+ originalIndex: boardItemsByListId[fromListId].indexOf(itemId),
+ ...params,
+ };
+}
+
export function moveItemListHelper(item, fromList, toList) {
const updatedItem = item;
if (
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index ae8434be312..94e29f3ad86 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -190,7 +190,7 @@ export default {
}
this.moveItem({
- itemId,
+ itemId: Number(itemId),
itemIid,
itemPath,
fromListId: from.dataset.listId,
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index edae4c75de3..db4ecd8c614 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -2,6 +2,7 @@ import * as Sentry from '@sentry/browser';
import { pick } from 'lodash';
import createBoardListMutation from 'ee_else_ce/boards/graphql/board_list_create.mutation.graphql';
import boardListsQuery from 'ee_else_ce/boards/graphql/board_lists.query.graphql';
+import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import {
BoardType,
ListType,
@@ -23,13 +24,14 @@ import {
formatIssueInput,
updateListPosition,
transformNotFilters,
+ moveItemListHelper,
+ getMoveData,
} from '../boards_util';
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
import destroyBoardListMutation from '../graphql/board_list_destroy.mutation.graphql';
import updateBoardListMutation from '../graphql/board_list_update.mutation.graphql';
import groupProjectsQuery from '../graphql/group_projects.query.graphql';
import issueCreateMutation from '../graphql/issue_create.mutation.graphql';
-import issueMoveListMutation from '../graphql/issue_move_list.mutation.graphql';
import issueSetDueDateMutation from '../graphql/issue_set_due_date.mutation.graphql';
import issueSetLabelsMutation from '../graphql/issue_set_labels.mutation.graphql';
import issueSetMilestoneMutation from '../graphql/issue_set_milestone.mutation.graphql';
@@ -333,42 +335,134 @@ export default {
dispatch('moveIssue', payload);
},
- moveIssue: (
- { state, commit },
- { itemId, itemIid, itemPath, fromListId, toListId, moveBeforeId, moveAfterId },
+ moveIssue: ({ dispatch, state }, params) => {
+ const moveData = getMoveData(state, params);
+
+ dispatch('moveIssueCard', moveData);
+ dispatch('updateMovedIssue', moveData);
+ dispatch('updateIssueOrder', { moveData });
+ },
+
+ moveIssueCard: ({ commit }, moveData) => {
+ const {
+ reordering,
+ shouldClone,
+ itemNotInToList,
+ originalIndex,
+ itemId,
+ fromListId,
+ toListId,
+ moveBeforeId,
+ moveAfterId,
+ } = moveData;
+
+ commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
+
+ if (reordering) {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, {
+ itemId,
+ listId: toListId,
+ moveBeforeId,
+ moveAfterId,
+ });
+
+ return;
+ }
+
+ if (itemNotInToList) {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, {
+ itemId,
+ listId: toListId,
+ moveBeforeId,
+ moveAfterId,
+ });
+ }
+
+ if (shouldClone) {
+ commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
+ }
+ },
+
+ updateMovedIssue: (
+ { commit, state: { boardItems, boardLists } },
+ { itemId, fromListId, toListId },
) => {
- const originalIssue = state.boardItems[itemId];
- const fromList = state.boardItemsByListId[fromListId];
- const originalIndex = fromList.indexOf(Number(itemId));
- commit(types.MOVE_ISSUE, { originalIssue, fromListId, toListId, moveBeforeId, moveAfterId });
+ const updatedIssue = moveItemListHelper(
+ boardItems[itemId],
+ boardLists[fromListId],
+ boardLists[toListId],
+ );
- const { boardId } = state;
- const [fullProjectPath] = itemPath.split(/[#]/);
+ commit(types.UPDATE_BOARD_ITEM, updatedIssue);
+ },
- gqlClient
- .mutate({
+ undoMoveIssueCard: ({ commit }, moveData) => {
+ const {
+ reordering,
+ shouldClone,
+ itemNotInToList,
+ itemId,
+ fromListId,
+ toListId,
+ originalIssue,
+ originalIndex,
+ } = moveData;
+
+ commit(types.UPDATE_BOARD_ITEM, originalIssue);
+
+ if (reordering) {
+ commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
+ commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
+ return;
+ }
+
+ if (shouldClone) {
+ commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: fromListId });
+ }
+ if (itemNotInToList) {
+ commit(types.REMOVE_BOARD_ITEM_FROM_LIST, { itemId, listId: toListId });
+ }
+
+ commit(types.ADD_BOARD_ITEM_TO_LIST, { itemId, listId: fromListId, atIndex: originalIndex });
+ },
+
+ updateIssueOrder: async ({ commit, dispatch, state }, { moveData, mutationVariables = {} }) => {
+ try {
+ const { itemId, fromListId, toListId, moveBeforeId, moveAfterId } = moveData;
+ const {
+ boardId,
+ boardItems: {
+ [itemId]: { iid, referencePath },
+ },
+ } = state;
+
+ const { data } = await gqlClient.mutate({
mutation: issueMoveListMutation,
variables: {
- projectPath: fullProjectPath,
+ iid,
+ projectPath: referencePath.split(/[#]/)[0],
boardId: fullBoardId(boardId),
- iid: itemIid,
fromListId: getIdFromGraphQLId(fromListId),
toListId: getIdFromGraphQLId(toListId),
moveBeforeId,
moveAfterId,
+ // 'mutationVariables' allows EE code to pass in extra parameters.
+ ...mutationVariables,
},
- })
- .then(({ data }) => {
- if (data?.issueMoveList?.errors.length) {
- throw new Error();
- } else {
- const issue = data.issueMoveList?.issue;
- commit(types.MOVE_ISSUE_SUCCESS, { issue });
- }
- })
- .catch(() =>
- commit(types.MOVE_ISSUE_FAILURE, { originalIssue, fromListId, toListId, originalIndex }),
+ });
+
+ if (data?.issueMoveList?.errors.length || !data.issueMoveList) {
+ throw new Error('issueMoveList empty');
+ }
+
+ commit(types.MUTATE_ISSUE_SUCCESS, { issue: data.issueMoveList.issue });
+ } catch {
+ commit(
+ types.SET_ERROR,
+ s__('Boards|An error occurred while moving the issue. Please try again.'),
);
+ dispatch('undoMoveIssueCard', moveData);
+ }
},
setAssignees: ({ commit, getters }, assigneeUsernames) => {
diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js
index 7ff1f8296ca..22b9905ee62 100644
--- a/app/assets/javascripts/boards/stores/mutation_types.js
+++ b/app/assets/javascripts/boards/stores/mutation_types.js
@@ -23,12 +23,10 @@ export const RECEIVE_ITEMS_FOR_LIST_SUCCESS = 'RECEIVE_ITEMS_FOR_LIST_SUCCESS';
export const REQUEST_ADD_ISSUE = 'REQUEST_ADD_ISSUE';
export const RECEIVE_ADD_ISSUE_SUCCESS = 'RECEIVE_ADD_ISSUE_SUCCESS';
export const RECEIVE_ADD_ISSUE_ERROR = 'RECEIVE_ADD_ISSUE_ERROR';
-export const MOVE_ISSUE = 'MOVE_ISSUE';
-export const MOVE_ISSUE_SUCCESS = 'MOVE_ISSUE_SUCCESS';
-export const MOVE_ISSUE_FAILURE = 'MOVE_ISSUE_FAILURE';
export const UPDATE_BOARD_ITEM = 'UPDATE_BOARD_ITEM';
export const REMOVE_BOARD_ITEM = 'REMOVE_BOARD_ITEM';
export const REQUEST_UPDATE_ISSUE = 'REQUEST_UPDATE_ISSUE';
+export const MUTATE_ISSUE_SUCCESS = 'MUTATE_ISSUE_SUCCESS';
export const RECEIVE_UPDATE_ISSUE_SUCCESS = 'RECEIVE_UPDATE_ISSUE_SUCCESS';
export const RECEIVE_UPDATE_ISSUE_ERROR = 'RECEIVE_UPDATE_ISSUE_ERROR';
export const ADD_BOARD_ITEM_TO_LIST = 'ADD_BOARD_ITEM_TO_LIST';
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 495b3b31df5..561c21b78c1 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -2,7 +2,7 @@ import { pull, union } from 'lodash';
import Vue from 'vue';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { s__ } from '~/locale';
-import { formatIssue, moveItemListHelper } from '../boards_util';
+import { formatIssue } from '../boards_util';
import { issuableTypes } from '../constants';
import * as mutationTypes from './mutation_types';
@@ -183,40 +183,11 @@ export default {
notImplemented();
},
- [mutationTypes.MOVE_ISSUE]: (
- state,
- { originalIssue, fromListId, toListId, moveBeforeId, moveAfterId },
- ) => {
- const fromList = state.boardLists[fromListId];
- const toList = state.boardLists[toListId];
-
- const issue = moveItemListHelper(originalIssue, fromList, toList);
- Vue.set(state.boardItems, issue.id, issue);
-
- removeItemFromList({ state, listId: fromListId, itemId: issue.id });
- addItemToList({ state, listId: toListId, itemId: issue.id, moveBeforeId, moveAfterId });
- },
-
- [mutationTypes.MOVE_ISSUE_SUCCESS]: (state, { issue }) => {
+ [mutationTypes.MUTATE_ISSUE_SUCCESS]: (state, { issue }) => {
const issueId = getIdFromGraphQLId(issue.id);
Vue.set(state.boardItems, issueId, formatIssue({ ...issue, id: issueId }));
},
- [mutationTypes.MOVE_ISSUE_FAILURE]: (
- state,
- { originalIssue, fromListId, toListId, originalIndex },
- ) => {
- state.error = s__('Boards|An error occurred while moving the issue. Please try again.');
- Vue.set(state.boardItems, originalIssue.id, originalIssue);
- removeItemFromList({ state, listId: toListId, itemId: originalIssue.id });
- addItemToList({
- state,
- listId: fromListId,
- itemId: originalIssue.id,
- atIndex: originalIndex,
- });
- },
-
[mutationTypes.REQUEST_UPDATE_ISSUE]: () => {
notImplemented();
},
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue
index 02fb5df07e8..8f41b848b0b 100644
--- a/app/assets/javascripts/diffs/components/app.vue
+++ b/app/assets/javascripts/diffs/components/app.vue
@@ -184,12 +184,7 @@ export default {
'viewDiffsFileByFile',
'mrReviews',
]),
- ...mapGetters('diffs', [
- 'whichCollapsedTypes',
- 'isParallelView',
- 'currentDiffIndex',
- 'fileCodequalityDiff',
- ]),
+ ...mapGetters('diffs', ['whichCollapsedTypes', 'isParallelView', 'currentDiffIndex']),
...mapGetters(['isNotesFetched', 'getNoteableData']),
diffs() {
if (!this.viewDiffsFileByFile) {
@@ -287,7 +282,6 @@ export default {
endpointMetadata: this.endpointMetadata,
endpointBatch: this.endpointBatch,
endpointCoverage: this.endpointCoverage,
- endpointCodequality: this.endpointCodequality,
endpointUpdateUser: this.endpointUpdateUser,
projectPath: this.projectPath,
dismissEndpoint: this.dismissEndpoint,
@@ -297,6 +291,10 @@ export default {
mrReviews: this.rehydratedMrReviews,
});
+ if (this.endpointCodequality) {
+ this.setCodequalityEndpoint(this.endpointCodequality);
+ }
+
if (this.shouldShow) {
this.fetchData();
}
@@ -341,6 +339,7 @@ export default {
...mapActions('diffs', [
'moveToNeighboringCommit',
'setBaseConfig',
+ 'setCodequalityEndpoint',
'fetchDiffFilesMeta',
'fetchDiffFilesBatch',
'fetchCoverageFiles',
@@ -532,7 +531,6 @@ export default {
:help-page-path="helpPagePath"
:can-current-user-fork="canCurrentUserFork"
:view-diffs-file-by-file="viewDiffsFileByFile"
- :codequality-diff="fileCodequalityDiff(file.file_path)"
/>
<div
v-if="showFileByFileNavigation"
diff --git a/app/assets/javascripts/diffs/components/diff_file.vue b/app/assets/javascripts/diffs/components/diff_file.vue
index 93855db52b6..bdbc13a38c4 100644
--- a/app/assets/javascripts/diffs/components/diff_file.vue
+++ b/app/assets/javascripts/diffs/components/diff_file.vue
@@ -67,11 +67,6 @@ export default {
type: Boolean,
required: true,
},
- codequalityDiff: {
- type: Array,
- required: false,
- default: () => [],
- },
},
data() {
return {
@@ -85,7 +80,7 @@ export default {
genericError: GENERIC_ERROR,
},
computed: {
- ...mapState('diffs', ['currentDiffFileId']),
+ ...mapState('diffs', ['currentDiffFileId', 'codequalityDiff']),
...mapGetters(['isNotesFetched']),
...mapGetters('diffs', ['getDiffFileDiscussions']),
viewBlobHref() {
@@ -154,7 +149,9 @@ export default {
return loggedIn && featureOn;
},
hasCodequalityChanges() {
- return this.codequalityDiff.length > 0;
+ return (
+ this.codequalityDiff?.files && this.codequalityDiff?.files[this.file.file_path]?.length > 0
+ );
},
},
watch: {
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 81416984dbf..1c66ad1a18c 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -1,5 +1,4 @@
import Cookies from 'js-cookie';
-import Visibility from 'visibilityjs';
import Vue from 'vue';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import { diffViewerModes } from '~/ide/constants';
@@ -53,15 +52,12 @@ import {
prepareLineForRenamedFile,
} from './utils';
-let eTagPoll;
-
export const setBaseConfig = ({ commit }, options) => {
const {
endpoint,
endpointMetadata,
endpointBatch,
endpointCoverage,
- endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
@@ -75,7 +71,6 @@ export const setBaseConfig = ({ commit }, options) => {
endpointMetadata,
endpointBatch,
endpointCoverage,
- endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
@@ -238,48 +233,6 @@ export const fetchCoverageFiles = ({ commit, state }) => {
coveragePoll.makeRequest();
};
-export const clearEtagPoll = () => {
- eTagPoll = null;
-};
-
-export const stopCodequalityPolling = () => {
- if (eTagPoll) eTagPoll.stop();
-};
-
-export const restartCodequalityPolling = () => {
- if (eTagPoll) eTagPoll.restart();
-};
-
-export const fetchCodequality = ({ commit, state, dispatch }) => {
- eTagPoll = new Poll({
- resource: {
- getCodequalityDiffReports: (endpoint) => axios.get(endpoint),
- },
- data: state.endpointCodequality,
- method: 'getCodequalityDiffReports',
- successCallback: ({ status, data }) => {
- if (status === httpStatusCodes.OK) {
- commit(types.SET_CODEQUALITY_DATA, data);
-
- eTagPoll.stop();
- }
- },
- errorCallback: () => createFlash(__('Something went wrong on our end. Please try again!')),
- });
-
- if (!Visibility.hidden()) {
- eTagPoll.makeRequest();
- }
-
- Visibility.change(() => {
- if (!Visibility.hidden()) {
- dispatch('restartCodequalityPolling');
- } else {
- dispatch('stopCodequalityPolling');
- }
- });
-};
-
export const setHighlightedRow = ({ commit }, lineCode) => {
const fileHash = lineCode.split('_')[0];
commit(types.SET_HIGHLIGHTED_ROW, lineCode);
diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js
index b06faa2284b..dec3f87b03e 100644
--- a/app/assets/javascripts/diffs/store/getters.js
+++ b/app/assets/javascripts/diffs/store/getters.js
@@ -136,16 +136,6 @@ export const fileLineCoverage = (state) => (file, line) => {
};
/**
- * Returns the codequality diff data for a given file
- * @param {string} filePath
- * @returns {Array}
- */
-export const fileCodequalityDiff = (state) => (filePath) => {
- if (!state.codequalityDiff.files || !state.codequalityDiff.files[filePath]) return [];
- return state.codequalityDiff.files[filePath];
-};
-
-/**
* Returns index of a currently selected diff in diffFiles
* @returns {number}
*/
diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js
index a99ef00d61e..1674d3d3b5a 100644
--- a/app/assets/javascripts/diffs/store/modules/diff_state.js
+++ b/app/assets/javascripts/diffs/store/modules/diff_state.js
@@ -30,7 +30,6 @@ export default () => ({
startVersion: null, // Null unless a target diff is selected for comparison that is not the "base" diff
diffFiles: [],
coverageFiles: {},
- codequalityDiff: {},
mergeRequestDiffs: [],
mergeRequestDiff: null,
diffViewType: getViewTypeFromQueryString() || viewTypeFromCookie || defaultViewType,
diff --git a/app/assets/javascripts/diffs/store/modules/index.js b/app/assets/javascripts/diffs/store/modules/index.js
index 6860e24db6b..03d11e60745 100644
--- a/app/assets/javascripts/diffs/store/modules/index.js
+++ b/app/assets/javascripts/diffs/store/modules/index.js
@@ -1,7 +1,7 @@
-import * as actions from '../actions';
+import * as actions from 'ee_else_ce/diffs/store/actions';
+import createState from 'ee_else_ce/diffs/store/modules/diff_state';
+import mutations from 'ee_else_ce/diffs/store/mutations';
import * as getters from '../getters';
-import mutations from '../mutations';
-import createState from './diff_state';
export default () => ({
namespaced: true,
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index b0f396f905a..4641731c4b6 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -11,7 +11,6 @@ export const SET_MR_FILE_REVIEWS = 'SET_MR_FILE_REVIEWS';
export const SET_DIFF_VIEW_TYPE = 'SET_DIFF_VIEW_TYPE';
export const SET_COVERAGE_DATA = 'SET_COVERAGE_DATA';
-export const SET_CODEQUALITY_DATA = 'SET_CODEQUALITY_DATA';
export const SET_MERGE_REQUEST_DIFFS = 'SET_MERGE_REQUEST_DIFFS';
export const TOGGLE_LINE_HAS_FORM = 'TOGGLE_LINE_HAS_FORM';
export const ADD_CONTEXT_LINES = 'ADD_CONTEXT_LINES';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index eacf76234fc..9ff9a02d444 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -33,7 +33,6 @@ export default {
endpointMetadata,
endpointBatch,
endpointCoverage,
- endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
@@ -47,7 +46,6 @@ export default {
endpointMetadata,
endpointBatch,
endpointCoverage,
- endpointCodequality,
endpointUpdateUser,
projectPath,
dismissEndpoint,
@@ -91,10 +89,6 @@ export default {
Object.assign(state, { coverageFiles });
},
- [types.SET_CODEQUALITY_DATA](state, codequalityDiffData) {
- Object.assign(state, { codequalityDiff: codequalityDiffData });
- },
-
[types.RENDER_FILE](state, file) {
renderFile(file);
},
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue
index d15c3e0bb6d..bf992b84387 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_stage.vue
@@ -103,7 +103,7 @@ export default {
<template>
<gl-dropdown
ref="dropdown"
- v-gl-tooltip.hover
+ v-gl-tooltip.hover.ds0
data-testid="mini-pipeline-graph-dropdown"
:title="stage.title"
variant="link"
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index d0761083c8b..8a090c8ef10 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -13,7 +13,7 @@ class Admin::UsersController < Admin::ApplicationController
def index
@users = User.filter_items(params[:filter]).order_name_asc
@users = @users.search_with_secondary_emails(params[:search_query]) if params[:search_query].present?
- @users = @users.includes(:authorized_projects) # rubocop: disable CodeReuse/ActiveRecord
+ @users = users_with_included_associations(@users)
@users = @users.sort_by_attribute(@sort = params[:sort])
@users = @users.page(params[:page])
@@ -228,6 +228,10 @@ class Admin::UsersController < Admin::ApplicationController
protected
+ def users_with_included_associations(users)
+ users.includes(:authorized_projects) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
def admin_making_changes_for_another_user?
user != current_user
end
diff --git a/app/controllers/projects/logs_controller.rb b/app/controllers/projects/logs_controller.rb
index b9aa9bfc947..f9b8091a419 100644
--- a/app/controllers/projects/logs_controller.rb
+++ b/app/controllers/projects/logs_controller.rb
@@ -58,7 +58,7 @@ module Projects
def environment
strong_memoize(:environment) do
if cluster_params.key?(:environment_name)
- EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).find.first
+ EnvironmentsFinder.new(project, current_user, name: cluster_params[:environment_name]).execute.first
else
project.default_environment
end
diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb
index 62de2c6ecc8..3ce5e258cf2 100644
--- a/app/finders/environments_finder.rb
+++ b/app/finders/environments_finder.rb
@@ -9,12 +9,7 @@ class EnvironmentsFinder
@project, @current_user, @params = project, current_user, params
end
- # This method will eventually take the place of `#execute` as an
- # efficient way to get relevant environment entries.
- # Currently, `#execute` method has a serious technical debt and
- # we will likely rework on it in the future.
- # See more https://gitlab.com/gitlab-org/gitlab-foss/issues/63381
- def find
+ def execute
environments = project.environments
environments = by_name(environments)
environments = by_search(environments)
diff --git a/app/graphql/resolvers/environments_resolver.rb b/app/graphql/resolvers/environments_resolver.rb
index ed3395d05aa..df04e70e250 100644
--- a/app/graphql/resolvers/environments_resolver.rb
+++ b/app/graphql/resolvers/environments_resolver.rb
@@ -21,7 +21,7 @@ module Resolvers
def resolve(**args)
return unless project.present?
- EnvironmentsFinder.new(project, context[:current_user], args).find
+ EnvironmentsFinder.new(project, context[:current_user], args).execute
rescue EnvironmentsFinder::InvalidStatesError => exception
raise Gitlab::Graphql::Errors::ArgumentError, exception.message
end
diff --git a/app/serializers/admin/user_entity.rb b/app/serializers/admin/user_entity.rb
index 8908d610046..a5cf40a50b9 100644
--- a/app/serializers/admin/user_entity.rb
+++ b/app/serializers/admin/user_entity.rb
@@ -30,3 +30,5 @@ module Admin
end
end
end
+
+Admin::UserEntity.prepend_if_ee('EE::Admin::UserEntity')
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index cee24098049..68660b35bee 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -38,12 +38,6 @@ module Issues
user_agent_detail_service.create
resolve_discussions_with_issue(issue)
- if Feature.disabled?(:issue_perform_after_creation_tasks_async, issue.project, default_enabled: :yaml)
- Issues::AfterCreateService
- .new(issue.project, current_user)
- .execute(issue)
- end
-
super
end
diff --git a/app/services/prometheus/create_default_alerts_service.rb b/app/services/prometheus/create_default_alerts_service.rb
index 53baf6a650e..4ae2743cc28 100644
--- a/app/services/prometheus/create_default_alerts_service.rb
+++ b/app/services/prometheus/create_default_alerts_service.rb
@@ -84,7 +84,7 @@ module Prometheus
def environment
strong_memoize(:environment) do
- EnvironmentsFinder.new(project, nil, name: 'production').find.first ||
+ EnvironmentsFinder.new(project, nil, name: 'production').execute.first ||
project.environments.first
end
end
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 50f3c94bcb3..79d77790b02 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -18,20 +18,20 @@
.search-holder
= render 'shared/projects/search_form', autofocus: true, admin_view: true
.dropdown
- - toggle_text = 'Namespace'
+ - toggle_text = _('Namespace')
- if params[:namespace_id].present?
= hidden_field_tag :namespace_id, params[:namespace_id]
- namespace = Namespace.find(params[:namespace_id])
- toggle_text = "#{namespace.kind}: #{namespace.full_path}"
= dropdown_toggle(toggle_text, { toggle: 'dropdown', is_filter: 'true' }, { toggle_class: 'js-namespace-select large' })
.dropdown-menu.dropdown-select.dropdown-menu-right
- = dropdown_title('Namespaces')
- = dropdown_filter("Search for Namespace")
+ = dropdown_title(_('Namespaces'))
+ = dropdown_filter(_("Search for Namespace"))
= dropdown_content
= dropdown_loading
= render 'shared/projects/dropdown'
= link_to new_project_path, class: 'gl-button btn btn-confirm' do
- New Project
- = button_tag "Search", class: "gl-button btn btn-confirm btn-search hide"
+ = _('New Project')
+ = button_tag _("Search"), class: "gl-button btn btn-confirm btn-search hide"
= render 'projects'
diff --git a/app/views/projects/jobs/_table.html.haml b/app/views/projects/jobs/_table.html.haml
index fc4b3260ab3..819837a9eff 100644
--- a/app/views/projects/jobs/_table.html.haml
+++ b/app/views/projects/jobs/_table.html.haml
@@ -28,7 +28,7 @@
%th Runner
%th Stage
%th Name
- %th Timing
+ %th Duration
%th Coverage
%th
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index 390a070de02..94f16369e96 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -1,12 +1,16 @@
- page_title _('Your profile')
- add_page_specific_style 'page_bundles/signup'
+- gitlab_experience_text = _('To personalize your GitLab experience, we\'d like to know a bit more about you')
.row.gl-flex-grow-1
.d-flex.gl-flex-direction-column.gl-align-items-center.gl-w-full.gl-p-5
.edit-profile.login-page.d-flex.flex-column.gl-align-items-center.pt-lg-3
= render_if_exists "registrations/welcome/progress_bar"
%h2.gl-text-center= html_escape(_('Welcome to GitLab,%{br_tag}%{name}!')) % { name: html_escape(current_user.first_name), br_tag: '<br/>'.html_safe }
- %p.gl-text-center= html_escape(_('To personalize your GitLab experience, we\'d like to know a bit more about you. We won\'t share this information with anyone.')) % { br_tag: '<br/>'.html_safe }
+ - if Gitlab.com?
+ %p.gl-text-center= html_escape(_('%{gitlab_experience_text}. We won\'t share this information with anyone.')) % { gitlab_experience_text: gitlab_experience_text }
+ - else
+ %p.gl-text-center= html_escape(_('%{gitlab_experience_text}. Don\'t worry, this information isn\'t shared outside of your self-managed GitLab instance.')) % { gitlab_experience_text: gitlab_experience_text }
= form_for(current_user, url: users_sign_up_welcome_path, html: { class: 'card gl-w-full! gl-p-5', 'aria-live' => 'assertive' }) do |f|
.devise-errors
= render 'devise/shared/error_messages', resource: current_user
diff --git a/app/workers/new_issue_worker.rb b/app/workers/new_issue_worker.rb
index 03a8af30c6f..c08f4b4cd75 100644
--- a/app/workers/new_issue_worker.rb
+++ b/app/workers/new_issue_worker.rb
@@ -17,11 +17,9 @@ class NewIssueWorker # rubocop:disable Scalability/IdempotentWorker
issuable.create_cross_references!(user)
- if Feature.enabled?(:issue_perform_after_creation_tasks_async, issuable.project, default_enabled: :yaml)
- Issues::AfterCreateService
- .new(issuable.project, user)
- .execute(issuable)
- end
+ Issues::AfterCreateService
+ .new(issuable.project, user)
+ .execute(issuable)
end
def issuable_class
diff --git a/changelogs/unreleased/21140-remove-issue-perform-after-creation-tasks-async-feature-flag.yml b/changelogs/unreleased/21140-remove-issue-perform-after-creation-tasks-async-feature-flag.yml
new file mode 100644
index 00000000000..04c9d1b8d0d
--- /dev/null
+++ b/changelogs/unreleased/21140-remove-issue-perform-after-creation-tasks-async-feature-flag.yml
@@ -0,0 +1,5 @@
+---
+title: Remove issue_perform_after_creation_tasks_async feature flag
+merge_request: 59042
+author:
+type: other
diff --git a/changelogs/unreleased/Externalize-strings-in-projects-index-html-haml.yml b/changelogs/unreleased/Externalize-strings-in-projects-index-html-haml.yml
new file mode 100644
index 00000000000..5ed6e7fb88e
--- /dev/null
+++ b/changelogs/unreleased/Externalize-strings-in-projects-index-html-haml.yml
@@ -0,0 +1,5 @@
+---
+title: Externalize strings in projects/index.html.haml
+merge_request: 58160
+author: nuwe1
+type: other
diff --git a/changelogs/unreleased/nicolasdular-welcome-page-text-change.yml b/changelogs/unreleased/nicolasdular-welcome-page-text-change.yml
new file mode 100644
index 00000000000..ed3fbd335cc
--- /dev/null
+++ b/changelogs/unreleased/nicolasdular-welcome-page-text-change.yml
@@ -0,0 +1,5 @@
+---
+title: Clarify on welcome page that we do not share any data
+merge_request: 59183
+author:
+type: changed
diff --git a/changelogs/unreleased/reduce-pipline-tooltip-delay-to-zero.yml b/changelogs/unreleased/reduce-pipline-tooltip-delay-to-zero.yml
new file mode 100644
index 00000000000..aedff0a7080
--- /dev/null
+++ b/changelogs/unreleased/reduce-pipline-tooltip-delay-to-zero.yml
@@ -0,0 +1,5 @@
+---
+title: Reduce pipeline tooltip delay to 0
+merge_request: 59155
+author:
+type: changed
diff --git a/changelogs/unreleased/ui-text-job-pipeline-runtime.yml b/changelogs/unreleased/ui-text-job-pipeline-runtime.yml
new file mode 100644
index 00000000000..eeb9bfc502a
--- /dev/null
+++ b/changelogs/unreleased/ui-text-job-pipeline-runtime.yml
@@ -0,0 +1,5 @@
+---
+title: Update UI text from timing to Run time
+merge_request: 58838
+author:
+type: other
diff --git a/config/feature_flags/development/issue_perform_after_creation_tasks_async.yml b/config/feature_flags/development/issue_perform_after_creation_tasks_async.yml
deleted file mode 100644
index 0efef586022..00000000000
--- a/config/feature_flags/development/issue_perform_after_creation_tasks_async.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: issue_perform_after_creation_tasks_async
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58588
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/21140
-milestone: '13.11'
-type: development
-group: group::geo
-default_enabled: true
diff --git a/doc/user/admin_area/img/export_permissions_v13_11.png b/doc/user/admin_area/img/export_permissions_v13_11.png
new file mode 100644
index 00000000000..d9bbe8c3daf
--- /dev/null
+++ b/doc/user/admin_area/img/export_permissions_v13_11.png
Binary files differ
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index 6877148bd6d..08fcd4674dc 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -173,6 +173,8 @@ The following data is included in the export:
- Path
- Access level ([Project](../permissions.md#project-members-permissions) and [Group](../permissions.md#group-members-permissions))
+![user permission export button](img/export_permissions_v13_11.png)
+
#### Users statistics
The **Users statistics** page provides an overview of user accounts by role. These statistics are
diff --git a/lib/api/environments.rb b/lib/api/environments.rb
index 3e1e430c2f9..b606b2e814d 100644
--- a/lib/api/environments.rb
+++ b/lib/api/environments.rb
@@ -26,7 +26,7 @@ module API
get ':id/environments' do
authorize! :read_environment, user_project
- environments = ::EnvironmentsFinder.new(user_project, current_user, params).find
+ environments = ::EnvironmentsFinder.new(user_project, current_user, params).execute
present paginate(environments), with: Entities::Environment, current_user: current_user
end
diff --git a/lib/gitlab/alert_management/payload/base.rb b/lib/gitlab/alert_management/payload/base.rb
index c8b8d6c259d..786c5bf675b 100644
--- a/lib/gitlab/alert_management/payload/base.rb
+++ b/lib/gitlab/alert_management/payload/base.rb
@@ -132,7 +132,7 @@ module Gitlab
EnvironmentsFinder
.new(project, nil, { name: environment_name })
- .find
+ .execute
.first
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index cbcd2b4ed36..0efc8809179 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -539,6 +539,12 @@ msgstr ""
msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
msgstr ""
+msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
+msgstr ""
+
+msgid "%{gitlab_experience_text}. We won't share this information with anyone."
+msgstr ""
+
msgid "%{global_id} is not a valid ID for %{expected_type}."
msgstr ""
@@ -8048,7 +8054,7 @@ msgstr ""
msgid "ComplianceFrameworks|Invalid format: it should follow the format [PATH].y(a)ml@[GROUP]/[PROJECT]"
msgstr ""
-msgid "ComplianceFrameworks|Once you have created a compliance framework it will appear here."
+msgid "ComplianceFrameworks|Once a compliance framework is added it will appear here."
msgstr ""
msgid "ComplianceFrameworks|Regulated"
@@ -29056,6 +29062,9 @@ msgstr ""
msgid "Something went wrong on our end"
msgstr ""
+msgid "Something went wrong on our end while loading the code quality diff."
+msgstr ""
+
msgid "Something went wrong on our end."
msgstr ""
@@ -31027,7 +31036,7 @@ msgstr ""
msgid "The merge request can now be merged."
msgstr ""
-msgid "The merge request has been updated, and the number of code quality violations in this file has changed."
+msgid "The merge request has made changes to this file that affect the number of code quality violations in it."
msgstr ""
msgid "The metric must be one of %{metrics}."
@@ -32576,7 +32585,7 @@ msgstr ""
msgid "To pass variables to the triggered pipeline, add %{code_start}variables[VARIABLE]=VALUE%{code_end} to the API request."
msgstr ""
-msgid "To personalize your GitLab experience, we'd like to know a bit more about you. We won't share this information with anyone."
+msgid "To personalize your GitLab experience, we'd like to know a bit more about you"
msgstr ""
msgid "To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed."
diff --git a/spec/finders/environments_finder_spec.rb b/spec/finders/environments_finder_spec.rb
index 888a1ef9567..c2022331ad9 100644
--- a/spec/finders/environments_finder_spec.rb
+++ b/spec/finders/environments_finder_spec.rb
@@ -11,37 +11,37 @@ RSpec.describe EnvironmentsFinder do
project.add_maintainer(user)
end
- describe '#find' do
+ describe '#execute' do
context 'with states parameter' do
let(:stopped_environment) { create(:environment, :stopped, project: project) }
it 'returns environments with the requested state' do
- result = described_class.new(project, user, states: 'available').find
+ result = described_class.new(project, user, states: 'available').execute
expect(result).to contain_exactly(environment)
end
it 'returns environments with any of the requested states' do
- result = described_class.new(project, user, states: %w(available stopped)).find
+ result = described_class.new(project, user, states: %w(available stopped)).execute
expect(result).to contain_exactly(environment, stopped_environment)
end
it 'raises exception when requested state is invalid' do
- expect { described_class.new(project, user, states: %w(invalid stopped)).find }.to(
+ expect { described_class.new(project, user, states: %w(invalid stopped)).execute }.to(
raise_error(described_class::InvalidStatesError, 'Requested states are invalid')
)
end
context 'works with symbols' do
it 'returns environments with the requested state' do
- result = described_class.new(project, user, states: :available).find
+ result = described_class.new(project, user, states: :available).execute
expect(result).to contain_exactly(environment)
end
it 'returns environments with any of the requested states' do
- result = described_class.new(project, user, states: [:available, :stopped]).find
+ result = described_class.new(project, user, states: [:available, :stopped]).execute
expect(result).to contain_exactly(environment, stopped_environment)
end
@@ -53,7 +53,7 @@ RSpec.describe EnvironmentsFinder do
let(:environment3) { create(:environment, :available, name: 'test3', project: project) }
it 'searches environments by name and state' do
- result = described_class.new(project, user, search: 'test', states: :available).find
+ result = described_class.new(project, user, search: 'test', states: :available).execute
expect(result).to contain_exactly(environment3)
end
diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js
index a8a6423b47c..1c5b7cf8248 100644
--- a/spec/frontend/boards/mock_data.js
+++ b/spec/frontend/boards/mock_data.js
@@ -3,6 +3,7 @@
import { keyBy } from 'lodash';
import Vue from 'vue';
import '~/boards/models/list';
+import { ListType } from '~/boards/constants';
import boardsStore from '~/boards/stores/boards_store';
export const boardObj = {
@@ -488,3 +489,38 @@ export const mockBlockedIssue2 = {
blockedByCount: 4,
webUrl: 'http://gdk.test:3000/gitlab-org/my-project-1/-/issues/0',
};
+
+export const mockMoveIssueParams = {
+ itemId: 1,
+ fromListId: 'gid://gitlab/List/1',
+ toListId: 'gid://gitlab/List/2',
+ moveBeforeId: undefined,
+ moveAfterId: undefined,
+};
+
+export const mockMoveState = {
+ boardLists: {
+ 'gid://gitlab/List/1': {
+ listType: ListType.backlog,
+ },
+ 'gid://gitlab/List/2': {
+ listType: ListType.closed,
+ },
+ },
+ boardItems: {
+ [mockMoveIssueParams.itemId]: { foo: 'bar' },
+ },
+ boardItemsByListId: {
+ [mockMoveIssueParams.fromListId]: [mockMoveIssueParams.itemId],
+ [mockMoveIssueParams.toListId]: [],
+ },
+};
+
+export const mockMoveData = {
+ reordering: false,
+ shouldClone: false,
+ itemNotInToList: true,
+ originalIndex: 0,
+ originalIssue: { foo: 'bar' },
+ ...mockMoveIssueParams,
+};
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 9b034c49075..bb747779cac 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -1,4 +1,5 @@
import * as Sentry from '@sentry/browser';
+import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
import testAction from 'helpers/vuex_action_helper';
import {
fullBoardId,
@@ -6,14 +7,15 @@ import {
formatBoardLists,
formatIssueInput,
formatIssue,
+ getMoveData,
} from '~/boards/boards_util';
-import { inactiveId, ISSUABLE } from '~/boards/constants';
+import { inactiveId, ISSUABLE, ListType } from '~/boards/constants';
import destroyBoardListMutation from '~/boards/graphql/board_list_destroy.mutation.graphql';
import issueCreateMutation from '~/boards/graphql/issue_create.mutation.graphql';
-import issueMoveListMutation from '~/boards/graphql/issue_move_list.mutation.graphql';
import actions, { gqlClient } from '~/boards/stores/actions';
import * as types from '~/boards/stores/mutation_types';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+
import {
mockLists,
mockListsById,
@@ -25,6 +27,9 @@ import {
labels,
mockActiveIssue,
mockGroupProjects,
+ mockMoveIssueParams,
+ mockMoveState,
+ mockMoveData,
} from '../mock_data';
jest.mock('~/flash');
@@ -653,64 +658,302 @@ describe('moveItem', () => {
});
describe('moveIssue', () => {
- const listIssues = {
- 'gid://gitlab/List/1': [436, 437],
- 'gid://gitlab/List/2': [],
- };
+ it('should dispatch a correct set of actions', () => {
+ testAction({
+ action: actions.moveIssue,
+ payload: mockMoveIssueParams,
+ state: mockMoveState,
+ expectedActions: [
+ { type: 'moveIssueCard', payload: mockMoveData },
+ { type: 'updateMovedIssue', payload: mockMoveData },
+ { type: 'updateIssueOrder', payload: { moveData: mockMoveData } },
+ ],
+ });
+ });
+});
- const issues = {
- 436: mockIssue,
- 437: mockIssue2,
- };
+describe('moveIssueCard and undoMoveIssueCard', () => {
+ describe('card should move without clonning', () => {
+ let state;
+ let params;
+ let moveMutations;
+ let undoMutations;
+
+ describe('when re-ordering card', () => {
+ beforeEach(
+ ({
+ itemId = 123,
+ fromListId = 'gid://gitlab/List/1',
+ toListId = 'gid://gitlab/List/1',
+ originalIssue = { foo: 'bar' },
+ originalIndex = 0,
+ moveBeforeId = undefined,
+ moveAfterId = undefined,
+ } = {}) => {
+ state = {
+ boardLists: {
+ [toListId]: { listType: ListType.backlog },
+ [fromListId]: { listType: ListType.backlog },
+ },
+ boardItems: { [itemId]: originalIssue },
+ boardItemsByListId: { [fromListId]: [123] },
+ };
+ params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId };
+ moveMutations = [
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: toListId, moveBeforeId, moveAfterId },
+ },
+ ];
+ undoMutations = [
+ { type: types.UPDATE_BOARD_ITEM, payload: originalIssue },
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: fromListId, atIndex: originalIndex },
+ },
+ ];
+ },
+ );
- const state = {
- fullPath: 'gitlab-org',
- boardId: '1',
- boardType: 'group',
- disabled: false,
- boardLists: mockLists,
- boardItemsByListId: listIssues,
- boardItems: issues,
- };
+ it('moveIssueCard commits a correct set of actions', () => {
+ testAction({
+ action: actions.moveIssueCard,
+ state,
+ payload: getMoveData(state, params),
+ expectedMutations: moveMutations,
+ });
+ });
- it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_SUCCESS mutation when successful', (done) => {
- jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
- data: {
- issueMoveList: {
- issue: rawIssue,
- errors: [],
- },
- },
+ it('undoMoveIssueCard commits a correct set of actions', () => {
+ testAction({
+ action: actions.undoMoveIssueCard,
+ state,
+ payload: getMoveData(state, params),
+ expectedMutations: undoMutations,
+ });
+ });
});
- testAction(
- actions.moveIssue,
- {
- itemId: '436',
- itemIid: mockIssue.iid,
- itemPath: mockIssue.referencePath,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- },
- state,
+ describe.each([
[
+ 'issue moves out of backlog',
{
- type: types.MOVE_ISSUE,
- payload: {
- originalIssue: mockIssue,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- },
+ fromListType: ListType.backlog,
+ toListType: ListType.label,
},
+ ],
+ [
+ 'issue card moves to closed',
{
- type: types.MOVE_ISSUE_SUCCESS,
- payload: { issue: rawIssue },
+ fromListType: ListType.label,
+ toListType: ListType.closed,
},
],
- [],
- done,
- );
+ [
+ 'issue card moves to non-closed, non-backlog list of the same type',
+ {
+ fromListType: ListType.label,
+ toListType: ListType.label,
+ },
+ ],
+ ])('when %s', (_, { toListType, fromListType }) => {
+ beforeEach(
+ ({
+ itemId = 123,
+ fromListId = 'gid://gitlab/List/1',
+ toListId = 'gid://gitlab/List/2',
+ originalIssue = { foo: 'bar' },
+ originalIndex = 0,
+ moveBeforeId = undefined,
+ moveAfterId = undefined,
+ } = {}) => {
+ state = {
+ boardLists: {
+ [fromListId]: { listType: fromListType },
+ [toListId]: { listType: toListType },
+ },
+ boardItems: { [itemId]: originalIssue },
+ boardItemsByListId: { [fromListId]: [123], [toListId]: [] },
+ };
+ params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId };
+ moveMutations = [
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: toListId, moveBeforeId, moveAfterId },
+ },
+ ];
+ undoMutations = [
+ { type: types.UPDATE_BOARD_ITEM, payload: originalIssue },
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: toListId } },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: fromListId, atIndex: originalIndex },
+ },
+ ];
+ },
+ );
+
+ it('moveIssueCard commits a correct set of actions', () => {
+ testAction({
+ action: actions.moveIssueCard,
+ state,
+ payload: getMoveData(state, params),
+ expectedMutations: moveMutations,
+ });
+ });
+
+ it('undoMoveIssueCard commits a correct set of actions', () => {
+ testAction({
+ action: actions.undoMoveIssueCard,
+ state,
+ payload: getMoveData(state, params),
+ expectedMutations: undoMutations,
+ });
+ });
+ });
+ });
+
+ describe('card should clone on move', () => {
+ let state;
+ let params;
+ let moveMutations;
+ let undoMutations;
+
+ describe.each([
+ [
+ 'issue card moves to non-closed, non-backlog list of a different type',
+ {
+ fromListType: ListType.label,
+ toListType: ListType.assignee,
+ },
+ ],
+ ])('when %s', (_, { toListType, fromListType }) => {
+ beforeEach(
+ ({
+ itemId = 123,
+ fromListId = 'gid://gitlab/List/1',
+ toListId = 'gid://gitlab/List/2',
+ originalIssue = { foo: 'bar' },
+ originalIndex = 0,
+ moveBeforeId = undefined,
+ moveAfterId = undefined,
+ } = {}) => {
+ state = {
+ boardLists: {
+ [fromListId]: { listType: fromListType },
+ [toListId]: { listType: toListType },
+ },
+ boardItems: { [itemId]: originalIssue },
+ boardItemsByListId: { [fromListId]: [123], [toListId]: [] },
+ };
+ params = { itemId, fromListId, toListId, moveBeforeId, moveAfterId };
+ moveMutations = [
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: toListId, moveBeforeId, moveAfterId },
+ },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: fromListId, atIndex: originalIndex },
+ },
+ ];
+ undoMutations = [
+ { type: types.UPDATE_BOARD_ITEM, payload: originalIssue },
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: fromListId } },
+ { type: types.REMOVE_BOARD_ITEM_FROM_LIST, payload: { itemId, listId: toListId } },
+ {
+ type: types.ADD_BOARD_ITEM_TO_LIST,
+ payload: { itemId, listId: fromListId, atIndex: originalIndex },
+ },
+ ];
+ },
+ );
+
+ it('moveIssueCard commits a correct set of actions', () => {
+ testAction({
+ action: actions.moveIssueCard,
+ state,
+ payload: getMoveData(state, params),
+ expectedMutations: moveMutations,
+ });
+ });
+
+ it('undoMoveIssueCard commits a correct set of actions', () => {
+ testAction({
+ action: actions.undoMoveIssueCard,
+ state,
+ payload: getMoveData(state, params),
+ expectedMutations: undoMutations,
+ });
+ });
+ });
});
+});
+
+describe('updateMovedIssueCard', () => {
+ const label1 = {
+ id: 'label1',
+ };
+
+ it.each([
+ [
+ 'issue without a label is moved to a label list',
+ {
+ state: {
+ boardLists: {
+ from: {},
+ to: {
+ listType: ListType.label,
+ label: label1,
+ },
+ },
+ boardItems: {
+ 1: {
+ labels: [],
+ },
+ },
+ },
+ moveData: {
+ itemId: 1,
+ fromListId: 'from',
+ toListId: 'to',
+ },
+ updatedIssue: { labels: [label1] },
+ },
+ ],
+ ])(
+ 'should commit UPDATE_BOARD_ITEM with a correctly updated issue data when %s',
+ (_, { state, moveData, updatedIssue }) => {
+ testAction({
+ action: actions.updateMovedIssue,
+ payload: moveData,
+ state,
+ expectedMutations: [{ type: types.UPDATE_BOARD_ITEM, payload: updatedIssue }],
+ });
+ },
+ );
+});
+
+describe('updateIssueOrder', () => {
+ const issues = {
+ 436: mockIssue,
+ 437: mockIssue2,
+ };
+
+ const state = {
+ boardItems: issues,
+ boardId: 'gid://gitlab/Board/1',
+ };
+
+ const moveData = {
+ itemId: 436,
+ fromListId: 'gid://gitlab/List/1',
+ toListId: 'gid://gitlab/List/2',
+ };
it('calls mutate with the correct variables', () => {
const mutationVariables = {
@@ -734,61 +977,56 @@ describe('moveIssue', () => {
},
});
- actions.moveIssue(
- { state, commit: () => {} },
- {
- itemId: mockIssue.id,
- itemIid: mockIssue.iid,
- itemPath: mockIssue.referencePath,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- },
- );
+ actions.updateIssueOrder({ state, commit: () => {}, dispatch: () => {} }, { moveData });
expect(gqlClient.mutate).toHaveBeenCalledWith(mutationVariables);
});
- it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_FAILURE mutation when unsuccessful', (done) => {
+ it('should commit MUTATE_ISSUE_SUCCESS mutation when successful', () => {
jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
data: {
issueMoveList: {
- issue: {},
- errors: [{ foo: 'bar' }],
+ issue: rawIssue,
+ errors: [],
},
},
});
testAction(
- actions.moveIssue,
- {
- itemId: '436',
- itemIid: mockIssue.iid,
- itemPath: mockIssue.referencePath,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- },
+ actions.updateIssueOrder,
+ { moveData },
state,
[
{
- type: types.MOVE_ISSUE,
- payload: {
- originalIssue: mockIssue,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- },
+ type: types.MUTATE_ISSUE_SUCCESS,
+ payload: { issue: rawIssue },
+ },
+ ],
+ [],
+ );
+ });
+
+ it('should commit SET_ERROR and dispatch undoMoveIssueCard', () => {
+ jest.spyOn(gqlClient, 'mutate').mockResolvedValue({
+ data: {
+ issueMoveList: {
+ issue: {},
+ errors: [{ foo: 'bar' }],
},
+ },
+ });
+
+ testAction(
+ actions.updateIssueOrder,
+ { moveData },
+ state,
+ [
{
- type: types.MOVE_ISSUE_FAILURE,
- payload: {
- originalIssue: mockIssue,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- originalIndex: 0,
- },
+ type: types.SET_ERROR,
+ payload: 'An error occurred while moving the issue. Please try again.',
},
],
- [],
- done,
+ [{ type: 'undoMoveIssueCard', payload: moveData }],
);
});
});
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index ded69fc0e0f..af6d439e294 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -394,41 +394,7 @@ describe('Board Store Mutations', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_ERROR);
});
- describe('MOVE_ISSUE', () => {
- it('updates boardItemsByListId, moving issue between lists', () => {
- const listIssues = {
- 'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
- 'gid://gitlab/List/2': [],
- };
-
- const issues = {
- 1: mockIssue,
- 2: mockIssue2,
- };
-
- state = {
- ...state,
- boardItemsByListId: listIssues,
- boardLists: initialBoardListsState,
- boardItems: issues,
- };
-
- mutations.MOVE_ISSUE(state, {
- originalIssue: mockIssue2,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- });
-
- const updatedListIssues = {
- 'gid://gitlab/List/1': [mockIssue.id],
- 'gid://gitlab/List/2': [mockIssue2.id],
- };
-
- expect(state.boardItemsByListId).toEqual(updatedListIssues);
- });
- });
-
- describe('MOVE_ISSUE_SUCCESS', () => {
+ describe('MUTATE_ISSUE_SUCCESS', () => {
it('updates issue in issues state', () => {
const issues = {
436: { id: rawIssue.id },
@@ -439,7 +405,7 @@ describe('Board Store Mutations', () => {
boardItems: issues,
};
- mutations.MOVE_ISSUE_SUCCESS(state, {
+ mutations.MUTATE_ISSUE_SUCCESS(state, {
issue: rawIssue,
});
@@ -447,36 +413,6 @@ describe('Board Store Mutations', () => {
});
});
- describe('MOVE_ISSUE_FAILURE', () => {
- it('updates boardItemsByListId, reverting moving issue between lists, and sets error message', () => {
- const listIssues = {
- 'gid://gitlab/List/1': [mockIssue.id],
- 'gid://gitlab/List/2': [mockIssue2.id],
- };
-
- state = {
- ...state,
- boardItemsByListId: listIssues,
- boardLists: initialBoardListsState,
- };
-
- mutations.MOVE_ISSUE_FAILURE(state, {
- originalIssue: mockIssue2,
- fromListId: 'gid://gitlab/List/1',
- toListId: 'gid://gitlab/List/2',
- originalIndex: 1,
- });
-
- const updatedListIssues = {
- 'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
- 'gid://gitlab/List/2': [],
- };
-
- expect(state.boardItemsByListId).toEqual(updatedListIssues);
- expect(state.error).toEqual('An error occurred while moving the issue. Please try again.');
- });
- });
-
describe('UPDATE_BOARD_ITEM', () => {
it('updates the given issue in state.boardItems', () => {
const updatedIssue = { id: 'some_gid', foo: 'bar' };
diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js
index 90faf98c871..a339b7f8804 100644
--- a/spec/frontend/diffs/components/app_spec.js
+++ b/spec/frontend/diffs/components/app_spec.js
@@ -56,7 +56,7 @@ describe('diffs/components/app', () => {
endpointMetadata: `${TEST_HOST}/diff/endpointMetadata`,
endpointBatch: `${TEST_HOST}/diff/endpointBatch`,
endpointCoverage: `${TEST_HOST}/diff/endpointCoverage`,
- endpointCodequality: `${TEST_HOST}/diff/endpointCodequality`,
+ endpointCodequality: '',
projectPath: 'namespace/project',
currentUser: {},
changesEmptyStateIllustration: '',
@@ -143,19 +143,11 @@ describe('diffs/components/app', () => {
});
describe('codequality diff', () => {
- it('fetches code quality data when endpoint is provided', () => {
+ it('does not fetch code quality data on FOSS', async () => {
createComponent();
jest.spyOn(wrapper.vm, 'fetchCodequality');
wrapper.vm.fetchData(false);
- expect(wrapper.vm.fetchCodequality).toHaveBeenCalled();
- });
-
- it('does not fetch code quality data when endpoint is blank', async () => {
- createComponent({ endpointCodequality: '' });
- jest.spyOn(wrapper.vm, 'fetchCodequality');
- wrapper.vm.fetchData(false);
-
expect(wrapper.vm.fetchCodequality).not.toHaveBeenCalled();
});
});
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 1861de85ca9..f46a42fae7a 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -17,9 +17,6 @@ import {
fetchDiffFilesBatch,
fetchDiffFilesMeta,
fetchCoverageFiles,
- clearEtagPoll,
- stopCodequalityPolling,
- fetchCodequality,
assignDiscussionsToDiff,
removeDiscussionsFromDiff,
startRenderDiffsQueue,
@@ -101,7 +98,6 @@ describe('DiffsStoreActions', () => {
const endpointMetadata = '/diffs/set/endpoint/metadata';
const endpointBatch = '/diffs/set/endpoint/batch';
const endpointCoverage = '/diffs/set/coverage_reports';
- const endpointCodequality = '/diffs/set/codequality_diff';
const projectPath = '/root/project';
const dismissEndpoint = '/-/user_callouts';
const showSuggestPopover = false;
@@ -113,7 +109,6 @@ describe('DiffsStoreActions', () => {
endpointBatch,
endpointMetadata,
endpointCoverage,
- endpointCodequality,
projectPath,
dismissEndpoint,
showSuggestPopover,
@@ -123,7 +118,6 @@ describe('DiffsStoreActions', () => {
endpointBatch: '',
endpointMetadata: '',
endpointCoverage: '',
- endpointCodequality: '',
projectPath: '',
dismissEndpoint: '',
showSuggestPopover: true,
@@ -136,7 +130,6 @@ describe('DiffsStoreActions', () => {
endpointMetadata,
endpointBatch,
endpointCoverage,
- endpointCodequality,
projectPath,
dismissEndpoint,
showSuggestPopover,
@@ -306,47 +299,6 @@ describe('DiffsStoreActions', () => {
});
});
- describe('fetchCodequality', () => {
- let mock;
- const endpointCodequality = '/fetch';
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- stopCodequalityPolling();
- clearEtagPoll();
- });
-
- it('should commit SET_CODEQUALITY_DATA with received response', (done) => {
- const data = {
- files: { 'app.js': [{ line: 1, description: 'Unexpected alert.', severity: 'minor' }] },
- };
-
- mock.onGet(endpointCodequality).reply(200, { data });
-
- testAction(
- fetchCodequality,
- {},
- { endpointCodequality },
- [{ type: types.SET_CODEQUALITY_DATA, payload: { data } }],
- [],
- done,
- );
- });
-
- it('should show flash on API error', (done) => {
- mock.onGet(endpointCodequality).reply(400);
-
- testAction(fetchCodequality, {}, { endpointCodequality }, [], [], () => {
- expect(createFlash).toHaveBeenCalledTimes(1);
- expect(createFlash).toHaveBeenCalledWith(expect.stringMatching('Something went wrong'));
- done();
- });
- });
- });
-
describe('setHighlightedRow', () => {
it('should mark currently selected diff and set lineHash and fileHash of highlightedRow', () => {
testAction(setHighlightedRow, 'ABC_123', {}, [
diff --git a/spec/frontend/diffs/store/getters_spec.js b/spec/frontend/diffs/store/getters_spec.js
index aac4909b151..2e3a66d5b01 100644
--- a/spec/frontend/diffs/store/getters_spec.js
+++ b/spec/frontend/diffs/store/getters_spec.js
@@ -376,26 +376,6 @@ describe('Diffs Module Getters', () => {
});
});
- describe('fileCodequalityDiff', () => {
- beforeEach(() => {
- Object.assign(localState.codequalityDiff, {
- files: { 'app.js': [{ line: 1, description: 'Unexpected alert.', severity: 'minor' }] },
- });
- });
-
- it('returns empty array when no codequality data is available', () => {
- Object.assign(localState.codequalityDiff, {});
-
- expect(getters.fileCodequalityDiff(localState)('test.js')).toEqual([]);
- });
-
- it('returns array when codequality data is available for given file', () => {
- expect(getters.fileCodequalityDiff(localState)('app.js')).toEqual([
- { line: 1, description: 'Unexpected alert.', severity: 'minor' },
- ]);
- });
- });
-
describe('suggestionCommitMessage', () => {
let rootState;
diff --git a/spec/frontend/diffs/store/mutations_spec.js b/spec/frontend/diffs/store/mutations_spec.js
index eb31724ee45..b549ca42634 100644
--- a/spec/frontend/diffs/store/mutations_spec.js
+++ b/spec/frontend/diffs/store/mutations_spec.js
@@ -115,19 +115,6 @@ describe('DiffsStoreMutations', () => {
});
});
- describe('SET_CODEQUALITY_DATA', () => {
- it('should set codequality data', () => {
- const state = { codequalityDiff: {} };
- const codequality = {
- files: { 'app.js': [{ line: 1, description: 'Unexpected alert.', severity: 'minor' }] },
- };
-
- mutations[types.SET_CODEQUALITY_DATA](state, codequality);
-
- expect(state.codequalityDiff).toEqual(codequality);
- });
- });
-
describe('SET_DIFF_VIEW_TYPE', () => {
it('should set diff view type properly', () => {
const state = {};
diff --git a/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js b/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js
index 60026f69b84..93bc8faa51b 100644
--- a/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_list/pipeline_stage_spec.js
@@ -11,10 +11,15 @@ const dropdownPath = 'path.json';
describe('Pipelines stage component', () => {
let wrapper;
let mock;
+ let glTooltipDirectiveMock;
const createComponent = (props = {}) => {
+ glTooltipDirectiveMock = jest.fn();
wrapper = mount(PipelineStage, {
attachTo: document.body,
+ directives: {
+ GlTooltip: glTooltipDirectiveMock,
+ },
propsData: {
stage: {
status: {
@@ -62,6 +67,10 @@ describe('Pipelines stage component', () => {
createComponent();
});
+ it('sets up the tooltip to not have a show delay animation', () => {
+ expect(glTooltipDirectiveMock.mock.calls[0][1].modifiers.ds0).toBe(true);
+ });
+
it('should render a dropdown with the status icon', () => {
expect(findDropdown().exists()).toBe(true);
expect(findDropdownToggle().exists()).toBe(true);
diff --git a/spec/serializers/admin/user_entity_spec.rb b/spec/serializers/admin/user_entity_spec.rb
index 42efe0eec54..5ab5210d3e1 100644
--- a/spec/serializers/admin/user_entity_spec.rb
+++ b/spec/serializers/admin/user_entity_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Admin::UserEntity do
subject { entity.as_json&.keys }
it 'exposes correct attributes' do
- is_expected.to contain_exactly(
+ is_expected.to include(
:id,
:name,
:created_at,
diff --git a/spec/serializers/admin/user_serializer_spec.rb b/spec/serializers/admin/user_serializer_spec.rb
index 53a9457409c..ed78ea67bd1 100644
--- a/spec/serializers/admin/user_serializer_spec.rb
+++ b/spec/serializers/admin/user_serializer_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Admin::UserSerializer do
context 'when there is a single object provided' do
it 'contains important elements for the admin user table' do
- is_expected.to contain_exactly(
+ is_expected.to include(
:id,
:name,
:created_at,
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 2ae1edcc804..83c6373c335 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -120,30 +120,6 @@ RSpec.describe Issues::CreateService do
described_class.new(project, user, opts).execute
end
- context 'with issue_perform_after_creation_tasks_async feature disabled' do
- before do
- stub_feature_flags(issue_perform_after_creation_tasks_async: false)
- end
-
- it 'calls Issues::AfterCreateService' do
- expect_next(::Issues::AfterCreateService, project, user).to receive(:execute)
-
- described_class.new(project, user, opts).execute
- end
- end
-
- context 'with issue_perform_after_creation_tasks_async feature enabled' do
- before do
- stub_feature_flags(issue_perform_after_creation_tasks_async: true)
- end
-
- it 'does not call Issues::AfterCreateService' do
- expect(::Issues::AfterCreateService).not_to receive(:new)
-
- described_class.new(project, user, opts).execute
- end
- end
-
context 'when label belongs to project group' do
let(:group) { create(:group) }
let(:group_labels) { create_pair(:group_label, group: group) }
diff --git a/spec/workers/new_issue_worker_spec.rb b/spec/workers/new_issue_worker_spec.rb
index 364dd98ee44..35b83c3bee8 100644
--- a/spec/workers/new_issue_worker_spec.rb
+++ b/spec/workers/new_issue_worker_spec.rb
@@ -83,29 +83,11 @@ RSpec.describe NewIssueWorker do
worker.perform(issue.id, user.id)
end
- context 'with issue_perform_after_creation_tasks_async feature disabled' do
- before do
- stub_feature_flags(issue_perform_after_creation_tasks_async: false)
- end
+ it 'calls Issues::AfterCreateService' do
+ expect_next(::Issues::AfterCreateService)
+ .to receive(:execute)
- it 'does not call Issues::AfterCreateService' do
- expect(::Issues::AfterCreateService).not_to receive(:execute)
-
- worker.perform(issue.id, user.id)
- end
- end
-
- context 'with issue_perform_after_creation_tasks_async feature enabled' do
- before do
- stub_feature_flags(issue_perform_after_creation_tasks_async: true)
- end
-
- it 'calls Issues::AfterCreateService' do
- expect_next(::Issues::AfterCreateService)
- .to receive(:execute)
-
- worker.perform(issue.id, user.id)
- end
+ worker.perform(issue.id, user.id)
end
end
end
diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore
index 259148fa18f..259148fa18f 100755..100644
--- a/vendor/gitignore/C++.gitignore
+++ b/vendor/gitignore/C++.gitignore
diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore
index a1c2a238a96..a1c2a238a96 100755..100644
--- a/vendor/gitignore/Java.gitignore
+++ b/vendor/gitignore/Java.gitignore