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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-22 12:10:46 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-22 12:10:46 +0300
commit2e9f877e8b6dd58c8011745b1d9a28dd67c8179c (patch)
tree0e2d42aa2ef1c3ae386b54962815623466a3dd54
parentc86c0e01469fd7c9aa72283db23d539c02f44bdb (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop.yml12
-rw-r--r--.rubocop_manual_todo.yml17
-rw-r--r--app/assets/javascripts/boards/boards_util.js10
-rw-r--r--app/assets/javascripts/boards/components/board_column.vue8
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue28
-rw-r--r--app/assets/javascripts/boards/stores/actions.js8
-rw-r--r--app/assets/javascripts/boards/stores/getters.js12
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js35
-rw-r--r--app/assets/javascripts/boards/stores/state.js4
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/signup.scss5
-rw-r--r--app/assets/stylesheets/pages/login.scss11
-rw-r--r--app/assets/stylesheets/startup/startup-signin.scss5
-rw-r--r--app/controllers/projects/pipelines_controller.rb2
-rw-r--r--app/helpers/auth_helper.rb4
-rw-r--r--app/models/merge_request.rb15
-rw-r--r--app/models/snippet.rb6
-rw-r--r--app/models/snippet_repository.rb6
-rw-r--r--app/views/devise/sessions/_new_base.html.haml2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml2
-rw-r--r--changelogs/unreleased/273292-fy21q4-foundations-kr2-audit-and-update-buttons-on-sessionscontrol.yml6
-rw-r--r--changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml5
-rw-r--r--changelogs/unreleased/322096-fj-fix-regression-in-snippet-background-migration.yml5
-rw-r--r--changelogs/unreleased/kassio-bulkimports-import-group-label-timestamps.yml5
-rw-r--r--changelogs/unreleased/lm-fix-authorization-lint.yml5
-rw-r--r--config/feature_flags/development/pipelines_security_report_summary.yml2
-rw-r--r--config/feature_flags/ops/marginalia.yml8
-rw-r--r--config/initializers/0_marginalia.rb7
-rw-r--r--danger/changes_size/Dangerfile4
-rw-r--r--doc/development/contributing/style_guides.md3
-rw-r--r--doc/development/database_query_comments.md13
-rw-r--r--doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v13_10.pngbin0 -> 167108 bytes
-rw-r--r--doc/user/application_security/security_dashboard/index.md2
-rw-r--r--doc/user/group/import/index.md7
-rw-r--r--lib/api/lint.rb2
-rw-r--r--lib/bulk_imports/groups/graphql/get_labels_query.rb2
-rw-r--r--lib/gitlab/current_settings.rb4
-rw-r--r--lib/gitlab/marginalia.rb9
-rw-r--r--lib/gitlab/marginalia/active_record_instrumentation.rb12
-rw-r--r--locale/gitlab.pot5
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb6
-rw-r--r--spec/frontend/boards/board_list_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js8
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js4
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js6
-rw-r--r--spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js2
-rw-r--r--spec/frontend/boards/stores/actions_spec.js16
-rw-r--r--spec/frontend/boards/stores/getters_spec.js23
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js70
-rw-r--r--spec/frontend/fixtures/pipelines.rb32
-rw-r--r--spec/frontend/fixtures/test_report.rb29
-rw-r--r--spec/frontend/pipelines/mock_data.js322
-rw-r--r--spec/frontend/pipelines/pipelines_spec.js10
-rw-r--r--spec/frontend/pipelines/pipelines_table_row_spec.js7
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb35
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb20
-rw-r--r--spec/lib/marginalia_spec.rb83
-rw-r--r--spec/models/merge_request_spec.rb87
-rw-r--r--spec/models/snippet_spec.rb10
-rw-r--r--spec/presenters/snippet_presenter_spec.rb2
-rw-r--r--spec/requests/api/lint_spec.rb19
-rw-r--r--spec/spec_helper.rb3
63 files changed, 398 insertions, 708 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index a4a74aa4100..b9f52ebc055 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -18,6 +18,7 @@ inherit_from:
inherit_mode:
merge:
- Include
+ - Exclude
AllCops:
TargetRubyVersion: 2.7
@@ -597,3 +598,14 @@ FactoryBot/InlineAssociation:
Include:
- 'spec/factories/**/*.rb'
- 'ee/spec/factories/**/*.rb'
+
+# WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/321982
+Gitlab/NamespacedClass:
+ Exclude:
+ - 'config/**/*.rb'
+ - 'db/**/*.rb'
+ - 'ee/bin/**/*'
+ - 'ee/db/**/*.rb'
+ - 'ee/elastic/**/*.rb'
+ - 'scripts/**/*'
+ - 'spec/migrations/**/*.rb'
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 8b43895de57..6c1af1a5455 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -10,6 +10,7 @@
# - guidelines for use found in
# https://docs.gitlab.com/ee/development/contributing/style_guides.html#resolving-rubocop-exceptions.
+# WIP See https://gitlab.com/gitlab-org/gitlab/-/issues/267606
FactoryBot/InlineAssociation:
Exclude:
- 'ee/spec/factories/analytics/cycle_analytics/group_stages.rb'
@@ -28,6 +29,7 @@ FactoryBot/InlineAssociation:
- 'spec/factories/uploads.rb'
- 'spec/factories/wiki_pages.rb'
+# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
Rails/SaveBang:
Exclude:
- 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
@@ -1174,22 +1176,9 @@ RSpec/AnyInstanceOf:
- 'spec/workers/wait_for_cluster_creation_worker_spec.rb'
- 'ee/spec/workers/security/auto_fix_worker_spec.rb'
+# WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/321982
Gitlab/NamespacedClass:
Exclude:
- - 'config/**/*.rb'
- - 'db/**/*.rb'
- - 'ee/bin/**/*'
- - 'ee/db/**/*.rb'
- - 'ee/elastic/**/*.rb'
- - 'scripts/**/*'
- - 'spec/migrations/**/*.rb'
- # The list above represents the permanent exclusions for this rule
- # due to the fact these files are related to infrastructure code.
- # This list should eventually be moved to .rubocop.yml after all TODOs
- # are addressed.
- #
- # The list below represents the classes that require
- # a namespace as they make the domain related code.
- 'app/channels/issues_channel.rb'
- 'app/controllers/abuse_reports_controller.rb'
- 'app/controllers/acme_challenges_controller.rb'
diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js
index 13ad820477f..cf7e8cb94d1 100644
--- a/app/assets/javascripts/boards/boards_util.js
+++ b/app/assets/javascripts/boards/boards_util.js
@@ -36,11 +36,11 @@ export function formatIssue(issue) {
}
export function formatListIssues(listIssues) {
- const issues = {};
- let listIssuesCount;
+ const boardItems = {};
+ let listItemsCount;
const listData = listIssues.nodes.reduce((map, list) => {
- listIssuesCount = list.issues.count;
+ listItemsCount = list.issues.count;
let sortedIssues = list.issues.edges.map((issueNode) => ({
...issueNode.node,
}));
@@ -58,14 +58,14 @@ export function formatListIssues(listIssues) {
assignees: i.assignees?.nodes || [],
};
- issues[id] = listIssue;
+ boardItems[id] = listIssue;
return id;
}),
};
}, {});
- return { listData, issues, listIssuesCount };
+ return { listData, boardItems, listItemsCount };
}
export function formatListsPageInfo(lists) {
diff --git a/app/assets/javascripts/boards/components/board_column.vue b/app/assets/javascripts/boards/components/board_column.vue
index 7c32626a4ce..95a90d7ab11 100644
--- a/app/assets/javascripts/boards/components/board_column.vue
+++ b/app/assets/javascripts/boards/components/board_column.vue
@@ -32,12 +32,12 @@ export default {
},
computed: {
...mapState(['filterParams', 'highlightedLists']),
- ...mapGetters(['getIssuesByList']),
+ ...mapGetters(['getBoardItemsByList']),
highlighted() {
return this.highlightedLists.includes(this.list.id);
},
- listIssues() {
- return this.getIssuesByList(this.list.id);
+ listItems() {
+ return this.getBoardItemsByList(this.list.id);
},
isListDraggable() {
return isListDraggable(this.list);
@@ -87,7 +87,7 @@ export default {
<board-list
ref="board-list"
:disabled="disabled"
- :issues="listIssues"
+ :board-items="listItems"
:list="list"
:can-admin-list="canAdminList"
/>
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 0142b0f4e31..4bd5a530b8c 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -12,8 +12,8 @@ import BoardNewIssue from './board_new_issue.vue';
export default {
name: 'BoardList',
i18n: {
- loadingIssues: __('Loading issues'),
- loadingMoreissues: __('Loading more issues'),
+ loading: __('Loading'),
+ loadingMoreboardItems: __('Loading more'),
showingAllIssues: __('Showing all issues'),
},
components: {
@@ -30,7 +30,7 @@ export default {
type: Object,
required: true,
},
- issues: {
+ boardItems: {
type: Array,
required: true,
},
@@ -51,11 +51,11 @@ export default {
...mapState(['pageInfoByListId', 'listsFlags']),
paginatedIssueText() {
return sprintf(__('Showing %{pageSize} of %{total} issues'), {
- pageSize: this.issues.length,
+ pageSize: this.boardItems.length,
total: this.list.issuesCount,
});
},
- issuesSizeExceedsMax() {
+ boardItemsSizeExceedsMax() {
return this.list.maxIssueCount > 0 && this.list.issuesCount > this.list.maxIssueCount;
},
hasNextPage() {
@@ -72,7 +72,7 @@ export default {
return this.canAdminList ? this.$refs.list.$el : this.$refs.list;
},
showingAllIssues() {
- return this.issues.length === this.list.issuesCount;
+ return this.boardItems.length === this.list.issuesCount;
},
treeRootWrapper() {
return this.canAdminList ? Draggable : 'ul';
@@ -85,14 +85,14 @@ export default {
tag: 'ul',
'ghost-class': 'board-card-drag-active',
'data-list-id': this.list.id,
- value: this.issues,
+ value: this.boardItems,
};
return this.canAdminList ? options : {};
},
},
watch: {
- issues() {
+ boardItems() {
this.$nextTick(() => {
this.showCount = this.scrollHeight() > Math.ceil(this.listHeight());
});
@@ -201,7 +201,7 @@ export default {
<div
v-if="loading"
class="gl-mt-4 gl-text-center"
- :aria-label="$options.i18n.loadingIssues"
+ :aria-label="$options.i18n.loading"
data-testid="board_list_loading"
>
<gl-loading-icon />
@@ -214,25 +214,25 @@ export default {
v-bind="treeRootOptions"
:data-board="list.id"
:data-board-type="list.listType"
- :class="{ 'bg-danger-100': issuesSizeExceedsMax }"
+ :class="{ 'bg-danger-100': boardItemsSizeExceedsMax }"
class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2 js-board-list"
data-testid="tree-root-wrapper"
@start="handleDragOnStart"
@end="handleDragOnEnd"
>
<board-card
- v-for="(issue, index) in issues"
+ v-for="(item, index) in boardItems"
ref="issue"
- :key="issue.id"
+ :key="item.id"
:index="index"
:list="list"
- :issue="issue"
+ :issue="item"
:disabled="disabled"
/>
<li v-if="showCount" class="board-list-count gl-text-center" data-issue-id="-1">
<gl-loading-icon
v-if="loadingMore"
- :label="$options.i18n.loadingMoreissues"
+ :label="$options.i18n.loadingMoreboardItems"
data-testid="count-loading-icon"
/>
<span v-if="showingAllIssues">{{ $options.i18n.showingAllIssues }}</span>
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 9cb8d664e70..b8d84899782 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -289,9 +289,9 @@ export default {
})
.then(({ data }) => {
const { lists } = data[boardType]?.board;
- const listIssues = formatListIssues(lists);
+ const listItems = formatListIssues(lists);
const listPageInfo = formatListsPageInfo(lists);
- commit(types.RECEIVE_ITEMS_FOR_LIST_SUCCESS, { listIssues, listPageInfo, listId });
+ commit(types.RECEIVE_ITEMS_FOR_LIST_SUCCESS, { listItems, listPageInfo, listId });
})
.catch(() => commit(types.RECEIVE_ITEMS_FOR_LIST_FAILURE, listId));
},
@@ -304,8 +304,8 @@ export default {
{ state, commit },
{ issueId, issueIid, issuePath, fromListId, toListId, moveBeforeId, moveAfterId },
) => {
- const originalIssue = state.issues[issueId];
- const fromList = state.issuesByListId[fromListId];
+ const originalIssue = state.boardItems[issueId];
+ const fromList = state.boardItemsByListId[fromListId];
const originalIndex = fromList.indexOf(Number(issueId));
commit(types.MOVE_ISSUE, { originalIssue, fromListId, toListId, moveBeforeId, moveAfterId });
diff --git a/app/assets/javascripts/boards/stores/getters.js b/app/assets/javascripts/boards/stores/getters.js
index cab97088bc6..308dbd0f1b0 100644
--- a/app/assets/javascripts/boards/stores/getters.js
+++ b/app/assets/javascripts/boards/stores/getters.js
@@ -4,17 +4,17 @@ import { inactiveId } from '../constants';
export default {
isSidebarOpen: (state) => state.activeId !== inactiveId,
isSwimlanesOn: () => false,
- getIssueById: (state) => (id) => {
- return state.issues[id] || {};
+ getBoardItemById: (state) => (id) => {
+ return state.boardItems[id] || {};
},
- getIssuesByList: (state, getters) => (listId) => {
- const listIssueIds = state.issuesByListId[listId] || [];
- return listIssueIds.map((id) => getters.getIssueById(id));
+ getBoardItemsByList: (state, getters) => (listId) => {
+ const listItemsIds = state.boardItemsByListId[listId] || [];
+ return listItemsIds.map((id) => getters.getBoardItemById(id));
},
activeIssue: (state) => {
- return state.issues[state.activeId] || {};
+ return state.boardItems[state.activeId] || {};
},
groupPathForActiveIssue: (_, getters) => {
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 12e96e7c9eb..8246ed8eb09 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -11,13 +11,13 @@ const notImplemented = () => {
};
export const removeIssueFromList = ({ state, listId, issueId }) => {
- Vue.set(state.issuesByListId, listId, pull(state.issuesByListId[listId], issueId));
+ Vue.set(state.boardItemsByListId, listId, pull(state.boardItemsByListId[listId], issueId));
const list = state.boardLists[listId];
Vue.set(state.boardLists, listId, { ...list, issuesCount: list.issuesCount - 1 });
};
export const addIssueToList = ({ state, listId, issueId, moveBeforeId, moveAfterId, atIndex }) => {
- const listIssues = state.issuesByListId[listId];
+ const listIssues = state.boardItemsByListId[listId];
let newIndex = atIndex || 0;
if (moveBeforeId) {
newIndex = listIssues.indexOf(moveBeforeId) + 1;
@@ -25,7 +25,7 @@ export const addIssueToList = ({ state, listId, issueId, moveBeforeId, moveAfter
newIndex = listIssues.indexOf(moveAfterId);
}
listIssues.splice(newIndex, 0, issueId);
- Vue.set(state.issuesByListId, listId, listIssues);
+ Vue.set(state.boardItemsByListId, listId, listIssues);
const list = state.boardLists[listId];
Vue.set(state.boardLists, listId, { ...list, issuesCount: list.issuesCount + 1 });
};
@@ -108,14 +108,13 @@ export default {
Vue.set(state.listsFlags, listId, { [fetchNext ? 'isLoadingMore' : 'isLoading']: true });
},
- [mutationTypes.RECEIVE_ITEMS_FOR_LIST_SUCCESS]: (state, { listIssues, listPageInfo, listId }) => {
- const { listData, issues } = listIssues;
- Vue.set(state, 'issues', { ...state.issues, ...issues });
-
+ [mutationTypes.RECEIVE_ITEMS_FOR_LIST_SUCCESS]: (state, { listItems, listPageInfo, listId }) => {
+ const { listData, boardItems } = listItems;
+ Vue.set(state, 'boardItems', { ...state.boardItems, ...boardItems });
Vue.set(
- state.issuesByListId,
+ state.boardItemsByListId,
listId,
- union(state.issuesByListId[listId] || [], listData[listId]),
+ union(state.boardItemsByListId[listId] || [], listData[listId]),
);
Vue.set(state.pageInfoByListId, listId, listPageInfo[listId]);
Vue.set(state.listsFlags, listId, { isLoading: false, isLoadingMore: false });
@@ -129,18 +128,18 @@ export default {
},
[mutationTypes.RESET_ISSUES]: (state) => {
- Object.keys(state.issuesByListId).forEach((listId) => {
- Vue.set(state.issuesByListId, listId, []);
+ Object.keys(state.boardItemsByListId).forEach((listId) => {
+ Vue.set(state.boardItemsByListId, listId, []);
});
},
[mutationTypes.UPDATE_ISSUE_BY_ID]: (state, { issueId, prop, value }) => {
- if (!state.issues[issueId]) {
+ if (!state.boardItems[issueId]) {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
throw new Error('No issue found.');
}
- Vue.set(state.issues[issueId], prop, value);
+ Vue.set(state.boardItems[issueId], prop, value);
},
[mutationTypes.SET_ASSIGNEE_LOADING](state, isLoading) {
@@ -167,7 +166,7 @@ export default {
const toList = state.boardLists[toListId];
const issue = moveIssueListHelper(originalIssue, fromList, toList);
- Vue.set(state.issues, issue.id, issue);
+ Vue.set(state.boardItems, issue.id, issue);
removeIssueFromList({ state, listId: fromListId, issueId: issue.id });
addIssueToList({ state, listId: toListId, issueId: issue.id, moveBeforeId, moveAfterId });
@@ -175,7 +174,7 @@ export default {
[mutationTypes.MOVE_ISSUE_SUCCESS]: (state, { issue }) => {
const issueId = getIdFromGraphQLId(issue.id);
- Vue.set(state.issues, issueId, formatIssue({ ...issue, id: issueId }));
+ Vue.set(state.boardItems, issueId, formatIssue({ ...issue, id: issueId }));
},
[mutationTypes.MOVE_ISSUE_FAILURE]: (
@@ -183,7 +182,7 @@ export default {
{ originalIssue, fromListId, toListId, originalIndex },
) => {
state.error = s__('Boards|An error occurred while moving the issue. Please try again.');
- Vue.set(state.issues, originalIssue.id, originalIssue);
+ Vue.set(state.boardItems, originalIssue.id, originalIssue);
removeIssueFromList({ state, listId: toListId, issueId: originalIssue.id });
addIssueToList({
state,
@@ -216,7 +215,7 @@ export default {
issueId: issue.id,
atIndex: position,
});
- Vue.set(state.issues, issue.id, issue);
+ Vue.set(state.boardItems, issue.id, issue);
},
[mutationTypes.ADD_ISSUE_TO_LIST_FAILURE]: (state, { list, issueId }) => {
@@ -226,7 +225,7 @@ export default {
[mutationTypes.REMOVE_ISSUE_FROM_LIST]: (state, { list, issue }) => {
removeIssueFromList({ state, listId: list.id, issueId: issue.id });
- Vue.delete(state.issues, issue.id);
+ Vue.delete(state.boardItems, issue.id);
},
[mutationTypes.SET_CURRENT_PAGE]: () => {
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index 1b4b8dd5c10..85d92589d30 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -9,10 +9,10 @@ export default () => ({
sidebarType: '',
boardLists: {},
listsFlags: {},
- issuesByListId: {},
+ boardItemsByListId: {},
isSettingAssignees: false,
pageInfoByListId: {},
- issues: {},
+ boardItems: {},
filterParams: {},
boardConfig: {},
labels: [],
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 4bf9236407f..089f130843f 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -443,7 +443,7 @@ $gl-avatar-size: 40px;
$border-radius-default: 4px;
$border-radius-small: 2px;
$border-radius-large: 8px;
-$default-icon-size: 18px;
+$default-icon-size: 16px;
$layout-link-gray: #7e7c7c;
$btn-side-margin: 10px;
$btn-sm-side-margin: 7px;
diff --git a/app/assets/stylesheets/page_bundles/signup.scss b/app/assets/stylesheets/page_bundles/signup.scss
index a207c10b04f..d6c3a3ff5da 100644
--- a/app/assets/stylesheets/page_bundles/signup.scss
+++ b/app/assets/stylesheets/page_bundles/signup.scss
@@ -32,11 +32,6 @@
@include media-breakpoint-down(md) {
width: 100%;
}
-
- img {
- width: $default-icon-size;
- height: $default-icon-size;
- }
}
.decline-page {
diff --git a/app/assets/stylesheets/pages/login.scss b/app/assets/stylesheets/pages/login.scss
index 019d827798c..2d04354a99d 100644
--- a/app/assets/stylesheets/pages/login.scss
+++ b/app/assets/stylesheets/pages/login.scss
@@ -106,17 +106,6 @@
width: 100%;
}
}
-
- .omniauth-btn {
- width: 100%;
- padding: $gl-padding-8;
-
- img {
- width: $default-icon-size;
- height: $default-icon-size;
- margin-right: $gl-padding;
- }
- }
}
.new-session-tabs {
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index 4b88b94f3a6..6b78abdb5e0 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -2142,11 +2142,6 @@ table.code {
width: 100%;
padding: 8px;
}
-.login-page .omniauth-container .omniauth-btn img {
- width: 1.125rem;
- height: 1.125rem;
- margin-right: 16px;
-}
.login-page .new-session-tabs {
display: flex;
box-shadow: 0 0 0 1px #dbdbdb;
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 59b14bbb91d..47c0bb6979d 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -13,7 +13,7 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action do
- push_frontend_feature_flag(:pipelines_security_report_summary, project)
+ push_frontend_feature_flag(:pipelines_security_report_summary, project, default_enabled: :yaml)
push_frontend_feature_flag(:new_pipeline_form, project, default_enabled: true)
push_frontend_feature_flag(:graphql_pipeline_details, project, type: :development, default_enabled: :yaml)
push_frontend_feature_flag(:graphql_pipeline_details_users, current_user, type: :development, default_enabled: :yaml)
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index ad995a6ce68..305b9a1faf3 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -138,11 +138,11 @@ module AuthHelper
label = label_for_provider(provider)
if provider_has_custom_icon?(provider)
- image_tag(icon_for_provider(provider), alt: label, title: "Sign in with #{label}")
+ image_tag(icon_for_provider(provider), alt: label, title: "Sign in with #{label}", class: "gl-button-icon")
elsif provider_has_builtin_icon?(provider)
file_name = "#{provider.to_s.split('_').first}_#{size}.png"
- image_tag("auth_buttons/#{file_name}", alt: label, title: "Sign in with #{label}")
+ image_tag("auth_buttons/#{file_name}", alt: label, title: "Sign in with #{label}", class: "gl-button-icon")
else
label
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b287c1dad0d..8d558098d94 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -376,8 +376,7 @@ class MergeRequest < ApplicationRecord
alias_attribute :auto_merge_enabled, :merge_when_pipeline_succeeds
alias_method :issuing_parent, :target_project
- delegate :active?, :builds_with_coverage, to: :head_pipeline, prefix: true, allow_nil: true
- delegate :success?, :active?, to: :actual_head_pipeline, prefix: true, allow_nil: true
+ delegate :builds_with_coverage, to: :head_pipeline, prefix: true, allow_nil: true
RebaseLockTimeout = Class.new(StandardError)
@@ -437,6 +436,18 @@ class MergeRequest < ApplicationRecord
target_project.latest_pipeline(target_branch, sha)
end
+ def head_pipeline_active?
+ !!head_pipeline&.active?
+ end
+
+ def actual_head_pipeline_active?
+ !!actual_head_pipeline&.active?
+ end
+
+ def actual_head_pipeline_success?
+ !!actual_head_pipeline&.success?
+ end
+
# Pattern used to extract `!123` merge request references from text
#
# This pattern supports cross-project references.
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index ab8782ed87f..b68e166af48 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -216,8 +216,10 @@ class Snippet < ApplicationRecord
def blobs
return [] unless repository_exists?
- branch = default_branch
- list_files(branch).map { |file| Blob.lazy(repository, branch, file) }
+ files = list_files(default_branch)
+ items = files.map { |file| [default_branch, file] }
+
+ repository.blobs_at(items).compact
end
def hook_attrs
diff --git a/app/models/snippet_repository.rb b/app/models/snippet_repository.rb
index 0219ddc45d5..54dbc579d54 100644
--- a/app/models/snippet_repository.rb
+++ b/app/models/snippet_repository.rb
@@ -115,10 +115,8 @@ class SnippetRepository < ApplicationRecord
end
def invalid_path_error?(err)
- (err.is_a?(Gitlab::Git::Index::IndexError) &&
- err.message.downcase.start_with?('invalid path', 'path cannot include directory traversal')) ||
- (err.is_a?(Gitlab::Git::CommandError) &&
- err.message.include?('CreateFile: invalid path'))
+ err.is_a?(Gitlab::Git::Index::IndexError) &&
+ err.message.downcase.start_with?('invalid path', 'path cannot include directory traversal')
end
def invalid_signature_error?(err)
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
index 270652483b7..98af69d43b7 100644
--- a/app/views/devise/sessions/_new_base.html.haml
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -20,4 +20,4 @@
= recaptcha_tags
.submit-container.move-submit-down
- = f.submit _('Sign in'), class: 'gl-button btn btn-success', data: { qa_selector: 'sign_in_button' }
+ = f.submit _('Sign in'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'sign_in_button' }
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index 705fd9bbd0f..3ec859551ca 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -7,7 +7,7 @@
.d-flex.justify-content-between.flex-wrap
- providers.each do |provider|
- has_icon = provider_has_icon?(provider)
- = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default d-flex align-items-center omniauth-btn text-left oauth-login #{qa_class_for_provider(provider)}" do
+ = button_to omniauth_authorize_path(:user, provider), id: "oauth-login-#{provider}", class: "btn gl-button btn-default omniauth-btn oauth-login #{qa_class_for_provider(provider)}" do
- if has_icon
= provider_image_tag(provider)
%span
diff --git a/changelogs/unreleased/273292-fy21q4-foundations-kr2-audit-and-update-buttons-on-sessionscontrol.yml b/changelogs/unreleased/273292-fy21q4-foundations-kr2-audit-and-update-buttons-on-sessionscontrol.yml
new file mode 100644
index 00000000000..c6f180481bd
--- /dev/null
+++ b/changelogs/unreleased/273292-fy21q4-foundations-kr2-audit-and-update-buttons-on-sessionscontrol.yml
@@ -0,0 +1,6 @@
+---
+title: Update the Sign In button to use the new confirm button variant, migrate OAuth
+ buttons to use the default variant of GlButton.
+merge_request: 53254
+author:
+type: other
diff --git a/changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml b/changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml
new file mode 100644
index 00000000000..ffbe850246e
--- /dev/null
+++ b/changelogs/unreleased/321834-fj-remove-nil-values-from-snippet-blobs.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug when snippet blobs array contain a nil value
+merge_request: 54552
+author:
+type: fixed
diff --git a/changelogs/unreleased/322096-fj-fix-regression-in-snippet-background-migration.yml b/changelogs/unreleased/322096-fj-fix-regression-in-snippet-background-migration.yml
deleted file mode 100644
index 82ab6906348..00000000000
--- a/changelogs/unreleased/322096-fj-fix-regression-in-snippet-background-migration.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Fix snippet commit bug because of different Gitaly error
-merge_request: 54662
-author:
-type: fixed
diff --git a/changelogs/unreleased/kassio-bulkimports-import-group-label-timestamps.yml b/changelogs/unreleased/kassio-bulkimports-import-group-label-timestamps.yml
new file mode 100644
index 00000000000..6abf01ddfeb
--- /dev/null
+++ b/changelogs/unreleased/kassio-bulkimports-import-group-label-timestamps.yml
@@ -0,0 +1,5 @@
+---
+title: 'BulkImports: Import Label timestamps'
+merge_request: 54678
+author:
+type: changed
diff --git a/changelogs/unreleased/lm-fix-authorization-lint.yml b/changelogs/unreleased/lm-fix-authorization-lint.yml
new file mode 100644
index 00000000000..cca59b7b43e
--- /dev/null
+++ b/changelogs/unreleased/lm-fix-authorization-lint.yml
@@ -0,0 +1,5 @@
+---
+title: Updates authorization for linting endpoint
+merge_request: 54492
+author:
+type: changed
diff --git a/config/feature_flags/development/pipelines_security_report_summary.yml b/config/feature_flags/development/pipelines_security_report_summary.yml
index 7b67212269c..d01d08c9042 100644
--- a/config/feature_flags/development/pipelines_security_report_summary.yml
+++ b/config/feature_flags/development/pipelines_security_report_summary.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/235943
milestone: '13.0'
type: development
group: group::dynamic analysis
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/ops/marginalia.yml b/config/feature_flags/ops/marginalia.yml
deleted file mode 100644
index fb82f274eb2..00000000000
--- a/config/feature_flags/ops/marginalia.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: marginalia
-introduced_by_url:
-rollout_issue_url:
-milestone:
-type: ops
-group:
-default_enabled: false
diff --git a/config/initializers/0_marginalia.rb b/config/initializers/0_marginalia.rb
index 952dd75886d..05893f29de9 100644
--- a/config/initializers/0_marginalia.rb
+++ b/config/initializers/0_marginalia.rb
@@ -4,11 +4,6 @@ require 'marginalia'
::Marginalia::Comment.extend(::Gitlab::Marginalia::Comment)
-# Patch to modify 'Marginalia::ActiveRecordInstrumentation.annotate_sql' method with feature check.
-# Orignal Marginalia::ActiveRecordInstrumentation is included to ActiveRecord::ConnectionAdapters::PostgreSQLAdapter in the Marginalia Railtie.
-# Refer: https://github.com/basecamp/marginalia/blob/v1.8.0/lib/marginalia/railtie.rb#L67
-ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(Gitlab::Marginalia::ActiveRecordInstrumentation)
-
# By default, PostgreSQL only tracks the first 1024 bytes of a SQL
# query. Prepending the comment allows us to trace the source of the
# query without having to increase the `track_activity_query_size`
@@ -25,5 +20,3 @@ Marginalia::Comment.components << :line if Rails.env.development?
Gitlab::Marginalia.set_application_name
Gitlab::Marginalia.enable_sidekiq_instrumentation
-
-Gitlab::Marginalia.set_enabled_from_feature_flag
diff --git a/danger/changes_size/Dangerfile b/danger/changes_size/Dangerfile
index f37632ced33..52e6cb65d04 100644
--- a/danger/changes_size/Dangerfile
+++ b/danger/changes_size/Dangerfile
@@ -13,7 +13,7 @@
# end
if git.lines_of_code > 2_000
- warn "This merge request is definitely too big (more than #{git.lines_of_code} lines changed), please split it into multiple merge requests."
+ warn "This merge request is definitely too big (#{git.lines_of_code} lines changed), please split it into multiple merge requests."
elsif git.lines_of_code > 500
- warn "This merge request is quite big (more than #{git.lines_of_code} lines changed), please consider splitting it into multiple merge requests."
+ warn "This merge request is quite big (#{git.lines_of_code} lines changed), please consider splitting it into multiple merge requests."
end
diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md
index f54886469f2..db1d01383ad 100644
--- a/doc/development/contributing/style_guides.md
+++ b/doc/development/contributing/style_guides.md
@@ -161,6 +161,9 @@ To reveal existing RuboCop exceptions in the code that have been excluded via `.
This allows you to reveal existing RuboCop exceptions during your daily work cycle and fix them along the way.
+NOTE:
+Permanent `Exclude`s should be defined in `.rubocop.yml` instead of `.rubocop_manual_todo.yml`.
+
## Database migrations
See the dedicated [Database Migrations Style Guide](../migration_style_guide.md).
diff --git a/doc/development/database_query_comments.md b/doc/development/database_query_comments.md
index 409acbd8449..39b14074073 100644
--- a/doc/development/database_query_comments.md
+++ b/doc/development/database_query_comments.md
@@ -47,16 +47,3 @@ Examples of queries with comments as observed in `development.log`:
```sql
/*application:sidekiq,jid:e7d6668a39a991e323009833,job_class:ExpireJobCacheWorker,correlation_id:rYF4mey9CH3,line:/app/workers/expire_job_cache_worker.rb:14:in `perform'*/ SELECT "ci_pipelines".* FROM "ci_pipelines" WHERE "ci_pipelines"."id" = $1 LIMIT $2 [["id", 64], ["LIMIT", 1]]
```
-
-## Enable/Disable the feature
-
-Enabling or disabling the feature requires a **restart/SIGHUP** of the Web and
-Sidekiq workers, as the feature flag's state is memoized upon starting up.
-
-The `feature_flag` for this feature is **disabled** by default. You can enable
-or disable it with:
-
-```ruby
-Feature.enable(:marginalia)
-Feature.disable(:marginalia)
-```
diff --git a/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v13_10.png b/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v13_10.png
new file mode 100644
index 00000000000..8adb58b8143
--- /dev/null
+++ b/doc/user/application_security/security_dashboard/img/pipeline_security_dashboard_v13_10.png
Binary files differ
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index 64b386d7828..96d584737e2 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -52,7 +52,7 @@ To use the security dashboards and vulnerability reports:
At the pipeline level, the Security section displays the vulnerabilities present in the branch of
the project the pipeline ran against.
-![Pipeline Security Dashboard](img/pipeline_security_dashboard_v13_3.png)
+![Pipeline Security Dashboard](img/pipeline_security_dashboard_v13_10.png)
Visit the page for any pipeline that ran any of the [supported reports](#supported-reports). To view
the pipeline's security findings, select the **Security** tab when viewing the pipeline.
diff --git a/doc/user/group/import/index.md b/doc/user/group/import/index.md
index 762b08bacd6..7f02c7b169f 100644
--- a/doc/user/group/import/index.md
+++ b/doc/user/group/import/index.md
@@ -24,7 +24,12 @@ The following resources are migrated to the target instance:
- description
- attributes
- subgroups
-- Labels ([Introduced in 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/292429))
+- Group Labels ([Introduced in 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/292429))
+ - title
+ - description
+ - color
+ - created_at ([Introduced in 13.10](https://gitlab.com/gitlab-org/gitlab/-/issues/300007))
+ - updated_at ([Introduced in 13.10](https://gitlab.com/gitlab-org/gitlab/-/issues/300007))
- Members ([Introduced in 13.9](https://gitlab.com/gitlab-org/gitlab/-/issues/299415))
Group members are associated with the imported group if:
- The user already exists in the target GitLab instance and
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index 2d30754a36d..e0806674c6a 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -11,7 +11,7 @@ module API
optional :include_merged_yaml, type: Boolean, desc: 'Whether or not to include merged CI config yaml in the response'
end
post '/lint' do
- unauthorized! unless Gitlab::CurrentSettings.signup_enabled? && current_user
+ unauthorized! if Gitlab::CurrentSettings.signup_disabled? && current_user.nil?
result = Gitlab::Ci::YamlProcessor.new(params[:content], user: current_user).execute
diff --git a/lib/bulk_imports/groups/graphql/get_labels_query.rb b/lib/bulk_imports/groups/graphql/get_labels_query.rb
index fd450dce599..23efbc33581 100644
--- a/lib/bulk_imports/groups/graphql/get_labels_query.rb
+++ b/lib/bulk_imports/groups/graphql/get_labels_query.rb
@@ -19,6 +19,8 @@ module BulkImports
title
description
color
+ created_at: createdAt
+ updated_at: updatedAt
}
}
}
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 0bf41f9dc0d..55f381fcb64 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -3,6 +3,10 @@
module Gitlab
module CurrentSettings
class << self
+ def signup_disabled?
+ !signup_enabled?
+ end
+
def current_application_settings
Gitlab::SafeRequestStore.fetch(:current_application_settings) { ensure_application_settings! }
end
diff --git a/lib/gitlab/marginalia.rb b/lib/gitlab/marginalia.rb
index 325a8c5c325..c99cf113638 100644
--- a/lib/gitlab/marginalia.rb
+++ b/lib/gitlab/marginalia.rb
@@ -2,8 +2,6 @@
module Gitlab
module Marginalia
- cattr_accessor :enabled, default: false
-
def self.set_application_name
::Marginalia.application_name = Gitlab.process_name
end
@@ -13,12 +11,5 @@ module Gitlab
::Marginalia::SidekiqInstrumentation.enable!
end
end
-
- def self.set_enabled_from_feature_flag
- # During db:create and db:bootstrap skip feature query as DB is not available yet.
- return false unless Gitlab::Database.cached_table_exists?('features')
-
- self.enabled = Feature.enabled?(:marginalia, type: :ops)
- end
end
end
diff --git a/lib/gitlab/marginalia/active_record_instrumentation.rb b/lib/gitlab/marginalia/active_record_instrumentation.rb
deleted file mode 100644
index 452f472bf6a..00000000000
--- a/lib/gitlab/marginalia/active_record_instrumentation.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-# frozen_string_literal: true
-
-# Patch to annotate sql only when the feature is enabled.
-module Gitlab
- module Marginalia
- module ActiveRecordInstrumentation
- def annotate_sql(sql)
- Gitlab::Marginalia.enabled ? super(sql) : sql
- end
- end
- end
-end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d55571ab580..a231b2f2fbf 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4808,6 +4808,9 @@ msgstr ""
msgid "Boards|An error occurred while fetching issues. Please reload the page."
msgstr ""
+msgid "Boards|An error occurred while fetching the board epics. Please reload the page."
+msgstr ""
+
msgid "Boards|An error occurred while fetching the board issues. Please reload the page."
msgstr ""
@@ -17897,7 +17900,7 @@ msgstr ""
msgid "Loading issues"
msgstr ""
-msgid "Loading more issues"
+msgid "Loading more"
msgstr ""
msgid "Loading snippet"
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index f9221c5a4ef..793ffbbfad9 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -207,14 +207,14 @@ RSpec.describe Projects::SnippetsController do
subject
expect(assigns(:snippet)).to eq(project_snippet)
- expect(assigns(:blobs)).to eq(project_snippet.blobs)
+ expect(assigns(:blobs).map(&:name)).to eq(project_snippet.blobs.map(&:name))
expect(response).to have_gitlab_http_status(:ok)
end
it 'does not show the blobs expanded by default' do
subject
- expect(project_snippet.blobs.map(&:expanded?)).to be_all(false)
+ expect(assigns(:blobs).map(&:expanded?)).to be_all(false)
end
context 'when param expanded is set' do
@@ -223,7 +223,7 @@ RSpec.describe Projects::SnippetsController do
it 'shows all blobs expanded' do
subject
- expect(project_snippet.blobs.map(&:expanded?)).to be_all(true)
+ expect(assigns(:blobs).map(&:expanded?)).to be_all(true)
end
end
end
diff --git a/spec/frontend/boards/board_list_spec.js b/spec/frontend/boards/board_list_spec.js
index ef5cc4c3cd1..ca9aa673359 100644
--- a/spec/frontend/boards/board_list_spec.js
+++ b/spec/frontend/boards/board_list_spec.js
@@ -29,8 +29,8 @@ const createComponent = ({
state = {},
} = {}) => {
const store = createStore({
- issuesByListId: mockIssuesByListId,
- issues,
+ boardItemsByListId: mockIssuesByListId,
+ boardItems: issues,
pageInfoByListId: {
'gid://gitlab/List/1': { hasNextPage: true },
'gid://gitlab/List/2': {},
@@ -65,7 +65,7 @@ const createComponent = ({
propsData: {
disabled: false,
list,
- issues: [issue],
+ boardItems: [issue],
canAdminList: true,
...componentProps,
},
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
index 7838b5a0b2f..8fd178a0856 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_due_date_spec.js
@@ -24,7 +24,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
const createWrapper = ({ dueDate = null } = {}) => {
store = createStore();
- store.state.issues = { [TEST_ISSUE.id]: { ...TEST_ISSUE, dueDate } };
+ store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, dueDate } };
store.state.activeId = TEST_ISSUE.id;
wrapper = shallowMount(BoardSidebarDueDate, {
@@ -61,7 +61,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].dueDate = TEST_DUE_DATE;
+ store.state.boardItems[TEST_ISSUE.id].dueDate = TEST_DUE_DATE;
});
findDatePicker().vm.$emit('input', TEST_PARSED_DATE);
await wrapper.vm.$nextTick();
@@ -86,7 +86,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].dueDate = null;
+ store.state.boardItems[TEST_ISSUE.id].dueDate = null;
});
findDatePicker().vm.$emit('clear');
await wrapper.vm.$nextTick();
@@ -104,7 +104,7 @@ describe('~/boards/components/sidebar/board_sidebar_due_date.vue', () => {
createWrapper({ dueDate: TEST_DUE_DATE });
jest.spyOn(wrapper.vm, 'setActiveIssueDueDate').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].dueDate = null;
+ store.state.boardItems[TEST_ISSUE.id].dueDate = null;
});
findResetButton().vm.$emit('click');
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js
index bc7df1c76c6..723d0345f76 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_issue_title_spec.js
@@ -34,7 +34,7 @@ describe('~/boards/components/sidebar/board_sidebar_issue_title.vue', () => {
const createWrapper = (issue = TEST_ISSUE_A) => {
store = createStore();
- store.state.issues = { [issue.id]: { ...issue } };
+ store.state.boardItems = { [issue.id]: { ...issue } };
store.dispatch('setActiveId', { id: issue.id });
wrapper = shallowMount(BoardSidebarIssueTitle, {
@@ -74,7 +74,7 @@ describe('~/boards/components/sidebar/board_sidebar_issue_title.vue', () => {
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueTitle').mockImplementation(() => {
- store.state.issues[TEST_ISSUE_A.id].title = TEST_TITLE;
+ store.state.boardItems[TEST_ISSUE_A.id].title = TEST_TITLE;
});
findFormInput().vm.$emit('input', TEST_TITLE);
findForm().vm.$emit('submit', { preventDefault: () => {} });
@@ -147,7 +147,7 @@ describe('~/boards/components/sidebar/board_sidebar_issue_title.vue', () => {
createWrapper(TEST_ISSUE_B);
jest.spyOn(wrapper.vm, 'setActiveIssueTitle').mockImplementation(() => {
- store.state.issues[TEST_ISSUE_B.id].title = TEST_TITLE;
+ store.state.boardItems[TEST_ISSUE_B.id].title = TEST_TITLE;
});
findFormInput().vm.$emit('input', TEST_TITLE);
findCancelButton().vm.$emit('click');
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
index 12b873ba7d8..98ac211238c 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_labels_select_spec.js
@@ -25,7 +25,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
const createWrapper = ({ labels = [] } = {}) => {
store = createStore();
- store.state.issues = { [TEST_ISSUE.id]: { ...TEST_ISSUE, labels } };
+ store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, labels } };
store.state.activeId = TEST_ISSUE.id;
wrapper = shallowMount(BoardSidebarLabelsSelect, {
@@ -66,7 +66,7 @@ describe('~/boards/components/sidebar/board_sidebar_labels_select.vue', () => {
jest.spyOn(wrapper.vm, 'setActiveIssueLabels').mockImplementation(() => TEST_LABELS);
findLabelsSelect().vm.$emit('updateSelectedLabels', TEST_LABELS_PAYLOAD);
- store.state.issues[TEST_ISSUE.id].labels = TEST_LABELS;
+ store.state.boardItems[TEST_ISSUE.id].labels = TEST_LABELS;
await wrapper.vm.$nextTick();
});
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
index 8820ec7ae63..8706424a296 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_milestone_select_spec.js
@@ -22,7 +22,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
const createWrapper = ({ milestone = null, loading = false } = {}) => {
store = createStore();
- store.state.issues = { [TEST_ISSUE.id]: { ...TEST_ISSUE, milestone } };
+ store.state.boardItems = { [TEST_ISSUE.id]: { ...TEST_ISSUE, milestone } };
store.state.activeId = TEST_ISSUE.id;
wrapper = shallowMount(BoardSidebarMilestoneSelect, {
@@ -113,7 +113,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
createWrapper();
jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].milestone = TEST_MILESTONE;
+ store.state.boardItems[TEST_ISSUE.id].milestone = TEST_MILESTONE;
});
findDropdownItem().vm.$emit('click');
await wrapper.vm.$nextTick();
@@ -137,7 +137,7 @@ describe('~/boards/components/sidebar/board_sidebar_milestone_select.vue', () =>
createWrapper({ milestone: TEST_MILESTONE });
jest.spyOn(wrapper.vm, 'setActiveIssueMilestone').mockImplementation(() => {
- store.state.issues[TEST_ISSUE.id].milestone = null;
+ store.state.boardItems[TEST_ISSUE.id].milestone = null;
});
findUnsetMilestoneItem().vm.$emit('click');
await wrapper.vm.$nextTick();
diff --git a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
index 3e6b0be0267..d2d10563ae5 100644
--- a/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
+++ b/spec/frontend/boards/components/sidebar/board_sidebar_subscription_spec.js
@@ -22,7 +22,7 @@ describe('~/boards/components/sidebar/board_sidebar_subscription_spec.vue', () =
const createComponent = (activeIssue = { ...mockActiveIssue }) => {
store = createStore();
- store.state.issues = { [activeIssue.id]: activeIssue };
+ store.state.boardItems = { [activeIssue.id]: activeIssue };
store.state.activeId = activeIssue.id;
wrapper = mount(BoardSidebarSubscription, {
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index c59e5876346..80d98c5eb6b 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -573,7 +573,7 @@ describe('fetchItemsForList', () => {
},
{
type: types.RECEIVE_ITEMS_FOR_LIST_SUCCESS,
- payload: { listIssues: formattedIssues, listPageInfo, listId },
+ payload: { listItems: formattedIssues, listPageInfo, listId },
},
],
[],
@@ -624,8 +624,8 @@ describe('moveIssue', () => {
boardType: 'group',
disabled: false,
boardLists: mockLists,
- issuesByListId: listIssues,
- issues,
+ boardItemsByListId: listIssues,
+ boardItems: issues,
};
it('should commit MOVE_ISSUE mutation and MOVE_ISSUE_SUCCESS mutation when successful', (done) => {
@@ -905,7 +905,7 @@ describe('addListIssue', () => {
});
describe('setActiveIssueLabels', () => {
- const state = { issues: { [mockIssue.id]: mockIssue } };
+ const state = { boardItems: { [mockIssue.id]: mockIssue } };
const getters = { activeIssue: mockIssue };
const testLabelIds = labels.map((label) => label.id);
const input = {
@@ -950,7 +950,7 @@ describe('setActiveIssueLabels', () => {
});
describe('setActiveIssueDueDate', () => {
- const state = { issues: { [mockIssue.id]: mockIssue } };
+ const state = { boardItems: { [mockIssue.id]: mockIssue } };
const getters = { activeIssue: mockIssue };
const testDueDate = '2020-02-20';
const input = {
@@ -1001,7 +1001,7 @@ describe('setActiveIssueDueDate', () => {
});
describe('setActiveIssueSubscribed', () => {
- const state = { issues: { [mockActiveIssue.id]: mockActiveIssue } };
+ const state = { boardItems: { [mockActiveIssue.id]: mockActiveIssue } };
const getters = { activeIssue: mockActiveIssue };
const subscribedState = true;
const input = {
@@ -1052,7 +1052,7 @@ describe('setActiveIssueSubscribed', () => {
});
describe('setActiveIssueMilestone', () => {
- const state = { issues: { [mockIssue.id]: mockIssue } };
+ const state = { boardItems: { [mockIssue.id]: mockIssue } };
const getters = { activeIssue: mockIssue };
const testMilestone = {
...mockMilestone,
@@ -1106,7 +1106,7 @@ describe('setActiveIssueMilestone', () => {
});
describe('setActiveIssueTitle', () => {
- const state = { issues: { [mockIssue.id]: mockIssue } };
+ const state = { boardItems: { [mockIssue.id]: mockIssue } };
const getters = { activeIssue: mockIssue };
const testTitle = 'Test Title';
const input = {
diff --git a/spec/frontend/boards/stores/getters_spec.js b/spec/frontend/boards/stores/getters_spec.js
index d5a19bf613f..d030b34ef80 100644
--- a/spec/frontend/boards/stores/getters_spec.js
+++ b/spec/frontend/boards/stores/getters_spec.js
@@ -38,15 +38,15 @@ describe('Boards - Getters', () => {
});
});
- describe('getIssueById', () => {
- const state = { issues: { 1: 'issue' } };
+ describe('getBoardItemById', () => {
+ const state = { boardItems: { 1: 'issue' } };
it.each`
id | expected
${'1'} | ${'issue'}
${''} | ${{}}
`('returns $expected when $id is passed to state', ({ id, expected }) => {
- expect(getters.getIssueById(state)(id)).toEqual(expected);
+ expect(getters.getBoardItemById(state)(id)).toEqual(expected);
});
});
@@ -56,7 +56,7 @@ describe('Boards - Getters', () => {
${'1'} | ${'issue'}
${''} | ${{}}
`('returns $expected when $id is passed to state', ({ id, expected }) => {
- const state = { issues: { 1: 'issue' }, activeId: id };
+ const state = { boardItems: { 1: 'issue' }, activeId: id };
expect(getters.activeIssue(state)).toEqual(expected);
});
@@ -94,17 +94,18 @@ describe('Boards - Getters', () => {
});
});
- describe('getIssuesByList', () => {
+ describe('getBoardItemsByList', () => {
const boardsState = {
- issuesByListId: mockIssuesByListId,
- issues,
+ boardItemsByListId: mockIssuesByListId,
+ boardItems: issues,
};
it('returns issues for a given listId', () => {
- const getIssueById = (issueId) => [mockIssue, mockIssue2].find(({ id }) => id === issueId);
+ const getBoardItemById = (issueId) =>
+ [mockIssue, mockIssue2].find(({ id }) => id === issueId);
- expect(getters.getIssuesByList(boardsState, { getIssueById })('gid://gitlab/List/2')).toEqual(
- mockIssues,
- );
+ expect(
+ getters.getBoardItemsByList(boardsState, { getBoardItemById })('gid://gitlab/List/2'),
+ ).toEqual(mockIssues);
});
});
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index e4dd368889a..2d7b80a997a 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -222,24 +222,24 @@ describe('Board Store Mutations', () => {
});
describe('RESET_ISSUES', () => {
- it('should remove issues from issuesByListId state', () => {
- const issuesByListId = {
+ it('should remove issues from boardItemsByListId state', () => {
+ const boardItemsByListId = {
'gid://gitlab/List/1': [mockIssue.id],
};
state = {
...state,
- issuesByListId,
+ boardItemsByListId,
};
mutations[types.RESET_ISSUES](state);
- expect(state.issuesByListId).toEqual({ 'gid://gitlab/List/1': [] });
+ expect(state.boardItemsByListId).toEqual({ 'gid://gitlab/List/1': [] });
});
});
describe('RECEIVE_ITEMS_FOR_LIST_SUCCESS', () => {
- it('updates issuesByListId and issues on state', () => {
+ it('updates boardItemsByListId and issues on state', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id],
};
@@ -249,10 +249,10 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issuesByListId: {
+ boardItemsByListId: {
'gid://gitlab/List/1': [],
},
- issues: {},
+ boardItems: {},
boardLists: initialBoardListsState,
};
@@ -264,13 +264,13 @@ describe('Board Store Mutations', () => {
};
mutations.RECEIVE_ITEMS_FOR_LIST_SUCCESS(state, {
- listIssues: { listData: listIssues, issues },
+ listItems: { listData: listIssues, boardItems: issues },
listPageInfo,
listId: 'gid://gitlab/List/1',
});
- expect(state.issuesByListId).toEqual(listIssues);
- expect(state.issues).toEqual(issues);
+ expect(state.boardItemsByListId).toEqual(listIssues);
+ expect(state.boardItems).toEqual(issues);
});
});
@@ -306,7 +306,7 @@ describe('Board Store Mutations', () => {
state = {
...state,
error: undefined,
- issues: {
+ boardItems: {
...issue,
},
};
@@ -320,7 +320,7 @@ describe('Board Store Mutations', () => {
value,
});
- expect(state.issues[issueId]).toEqual({ ...issue[issueId], id: '2' });
+ expect(state.boardItems[issueId]).toEqual({ ...issue[issueId], id: '2' });
});
});
@@ -346,7 +346,7 @@ describe('Board Store Mutations', () => {
});
describe('MOVE_ISSUE', () => {
- it('updates issuesByListId, moving issue between lists', () => {
+ it('updates boardItemsByListId, moving issue between lists', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
'gid://gitlab/List/2': [],
@@ -359,9 +359,9 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issuesByListId: listIssues,
+ boardItemsByListId: listIssues,
boardLists: initialBoardListsState,
- issues,
+ boardItems: issues,
};
mutations.MOVE_ISSUE(state, {
@@ -375,7 +375,7 @@ describe('Board Store Mutations', () => {
'gid://gitlab/List/2': [mockIssue2.id],
};
- expect(state.issuesByListId).toEqual(updatedListIssues);
+ expect(state.boardItemsByListId).toEqual(updatedListIssues);
});
});
@@ -387,19 +387,19 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issues,
+ boardItems: issues,
};
mutations.MOVE_ISSUE_SUCCESS(state, {
issue: rawIssue,
});
- expect(state.issues).toEqual({ 436: { ...mockIssue, id: 436 } });
+ expect(state.boardItems).toEqual({ 436: { ...mockIssue, id: 436 } });
});
});
describe('MOVE_ISSUE_FAILURE', () => {
- it('updates issuesByListId, reverting moving issue between lists, and sets error message', () => {
+ 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],
@@ -407,7 +407,7 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issuesByListId: listIssues,
+ boardItemsByListId: listIssues,
boardLists: initialBoardListsState,
};
@@ -423,7 +423,7 @@ describe('Board Store Mutations', () => {
'gid://gitlab/List/2': [],
};
- expect(state.issuesByListId).toEqual(updatedListIssues);
+ expect(state.boardItemsByListId).toEqual(updatedListIssues);
expect(state.error).toEqual('An error occurred while moving the issue. Please try again.');
});
});
@@ -449,7 +449,7 @@ describe('Board Store Mutations', () => {
});
describe('ADD_ISSUE_TO_LIST', () => {
- it('adds issue to issues state and issue id in list in issuesByListId', () => {
+ it('adds issue to issues state and issue id in list in boardItemsByListId', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id],
};
@@ -459,8 +459,8 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issuesByListId: listIssues,
- issues,
+ boardItemsByListId: listIssues,
+ boardItems: issues,
boardLists: initialBoardListsState,
};
@@ -468,14 +468,14 @@ describe('Board Store Mutations', () => {
mutations.ADD_ISSUE_TO_LIST(state, { list: mockLists[0], issue: mockIssue2 });
- expect(state.issuesByListId['gid://gitlab/List/1']).toContain(mockIssue2.id);
- expect(state.issues[mockIssue2.id]).toEqual(mockIssue2);
+ expect(state.boardItemsByListId['gid://gitlab/List/1']).toContain(mockIssue2.id);
+ expect(state.boardItems[mockIssue2.id]).toEqual(mockIssue2);
expect(state.boardLists['gid://gitlab/List/1'].issuesCount).toBe(2);
});
});
describe('ADD_ISSUE_TO_LIST_FAILURE', () => {
- it('removes issue id from list in issuesByListId and sets error message', () => {
+ it('removes issue id from list in boardItemsByListId and sets error message', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
};
@@ -486,20 +486,20 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issuesByListId: listIssues,
- issues,
+ boardItemsByListId: listIssues,
+ boardItems: issues,
boardLists: initialBoardListsState,
};
mutations.ADD_ISSUE_TO_LIST_FAILURE(state, { list: mockLists[0], issueId: mockIssue2.id });
- expect(state.issuesByListId['gid://gitlab/List/1']).not.toContain(mockIssue2.id);
+ expect(state.boardItemsByListId['gid://gitlab/List/1']).not.toContain(mockIssue2.id);
expect(state.error).toBe('An error occurred while creating the issue. Please try again.');
});
});
describe('REMOVE_ISSUE_FROM_LIST', () => {
- it('removes issue id from list in issuesByListId and deletes issue from state', () => {
+ it('removes issue id from list in boardItemsByListId and deletes issue from state', () => {
const listIssues = {
'gid://gitlab/List/1': [mockIssue.id, mockIssue2.id],
};
@@ -510,15 +510,15 @@ describe('Board Store Mutations', () => {
state = {
...state,
- issuesByListId: listIssues,
- issues,
+ boardItemsByListId: listIssues,
+ boardItems: issues,
boardLists: initialBoardListsState,
};
mutations.ADD_ISSUE_TO_LIST_FAILURE(state, { list: mockLists[0], issueId: mockIssue2.id });
- expect(state.issuesByListId['gid://gitlab/List/1']).not.toContain(mockIssue2.id);
- expect(state.issues).not.toContain(mockIssue2);
+ expect(state.boardItemsByListId['gid://gitlab/List/1']).not.toContain(mockIssue2.id);
+ expect(state.boardItems).not.toContain(mockIssue2);
});
});
diff --git a/spec/frontend/fixtures/pipelines.rb b/spec/frontend/fixtures/pipelines.rb
index b4b7f0e332f..2a538352abe 100644
--- a/spec/frontend/fixtures/pipelines.rb
+++ b/spec/frontend/fixtures/pipelines.rb
@@ -5,16 +5,22 @@ require 'spec_helper'
RSpec.describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controller do
include JavaScriptFixturesHelpers
- let(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
- let(:project) { create(:project, :repository, namespace: namespace, path: 'pipelines-project') }
- let(:commit) { create(:commit, project: project) }
- let(:commit_without_author) { RepoHelpers.another_sample_commit }
- let!(:user) { create(:user, developer_projects: [project], email: commit.author_email) }
- let!(:pipeline) { create(:ci_pipeline, project: project, sha: commit.id, user: user) }
+ let_it_be(:namespace) { create(:namespace, name: 'frontend-fixtures' )}
+ let_it_be(:project) { create(:project, :repository, namespace: namespace, path: 'pipelines-project') }
+
+ let_it_be(:commit_without_author) { RepoHelpers.another_sample_commit }
let!(:pipeline_without_author) { create(:ci_pipeline, project: project, sha: commit_without_author.id) }
- let!(:pipeline_without_commit) { create(:ci_pipeline, status: :success, project: project, sha: '0000') }
+ let!(:build_pipeline_without_author) { create(:ci_build, pipeline: pipeline_without_author, stage: 'test') }
- render_views
+ let_it_be(:pipeline_without_commit) { create(:ci_pipeline, status: :success, project: project, sha: '0000') }
+ let!(:build_pipeline_without_commit) { create(:ci_build, pipeline: pipeline_without_commit, stage: 'test') }
+
+ let(:commit) { create(:commit, project: project) }
+ let(:user) { create(:user, developer_projects: [project], email: commit.author_email) }
+ let!(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project, sha: commit.id, user: user) }
+ let!(:build_success) { create(:ci_build, pipeline: pipeline, stage: 'build') }
+ let!(:build_test) { create(:ci_build, pipeline: pipeline, stage: 'test') }
+ let!(:build_deploy_failed) { create(:ci_build, status: :failed, pipeline: pipeline, stage: 'deploy') }
before(:all) do
clean_frontend_fixtures('pipelines/')
@@ -32,4 +38,14 @@ RSpec.describe Projects::PipelinesController, '(JavaScript fixtures)', type: :co
expect(response).to be_successful
end
+
+ it "pipelines/test_report.json" do
+ get :test_report, params: {
+ namespace_id: namespace,
+ project_id: project,
+ id: pipeline.id
+ }, format: :json
+
+ expect(response).to be_successful
+ end
end
diff --git a/spec/frontend/fixtures/test_report.rb b/spec/frontend/fixtures/test_report.rb
deleted file mode 100644
index 3d09078ba68..00000000000
--- a/spec/frontend/fixtures/test_report.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require "spec_helper"
-
-RSpec.describe Projects::PipelinesController, "(JavaScript fixtures)", type: :controller do
- include JavaScriptFixturesHelpers
-
- let(:namespace) { create(:namespace, name: "frontend-fixtures") }
- let(:project) { create(:project, :repository, namespace: namespace, path: "pipelines-project") }
- let(:commit) { create(:commit, project: project) }
- let(:user) { create(:user, developer_projects: [project], email: commit.author_email) }
- let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project, user: user) }
-
- render_views
-
- before do
- sign_in(user)
- end
-
- it "pipelines/test_report.json" do
- get :test_report, params: {
- namespace_id: project.namespace,
- project_id: project,
- id: pipeline.id
- }, format: :json
-
- expect(response).to be_successful
- end
-end
diff --git a/spec/frontend/pipelines/mock_data.js b/spec/frontend/pipelines/mock_data.js
index 2afdbb05107..337838c41b3 100644
--- a/spec/frontend/pipelines/mock_data.js
+++ b/spec/frontend/pipelines/mock_data.js
@@ -2,328 +2,6 @@ const PIPELINE_RUNNING = 'RUNNING';
const PIPELINE_CANCELED = 'CANCELED';
const PIPELINE_FAILED = 'FAILED';
-export const pipelineWithStages = {
- id: 20333396,
- user: {
- id: 128633,
- name: 'Rémy Coutable',
- username: 'rymai',
- state: 'active',
- avatar_url:
- 'https://secure.gravatar.com/avatar/263da227929cc0035cb0eba512bcf81a?s=80\u0026d=identicon',
- web_url: 'https://gitlab.com/rymai',
- path: '/rymai',
- },
- active: true,
- coverage: '58.24',
- source: 'push',
- created_at: '2018-04-11T14:04:53.881Z',
- updated_at: '2018-04-11T14:05:00.792Z',
- path: '/gitlab-org/gitlab/pipelines/20333396',
- flags: {
- latest: true,
- stuck: false,
- auto_devops: false,
- yaml_errors: false,
- retryable: false,
- cancelable: true,
- failure_reason: false,
- },
- details: {
- status: {
- icon: 'status_running',
- text: 'running',
- label: 'running',
- group: 'running',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_running-2eb56be2871937954b2ba6d6f4ee9fdf7e5e1c146ac45f7be98119ccaca1aca9.ico',
- },
- duration: null,
- finished_at: null,
- stages: [
- {
- name: 'build',
- title: 'build: skipped',
- status: {
- icon: 'status_skipped',
- text: 'skipped',
- label: 'skipped',
- group: 'skipped',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396#build',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_skipped-a2eee568a5bffdb494050c7b62dde241de9189280836288ac8923d369f16222d.ico',
- },
- path: '/gitlab-org/gitlab/pipelines/20333396#build',
- dropdown_path: '/gitlab-org/gitlab/pipelines/20333396/stage.json?stage=build',
- },
- {
- name: 'prepare',
- title: 'prepare: passed',
- status: {
- icon: 'status_success',
- text: 'passed',
- label: 'passed',
- group: 'success',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396#prepare',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_success-26f59841becbef8c6fe414e9e74471d8bfd6a91b5855c19fe7f5923a40a7da47.ico',
- },
- path: '/gitlab-org/gitlab/pipelines/20333396#prepare',
- dropdown_path: '/gitlab-org/gitlab/pipelines/20333396/stage.json?stage=prepare',
- },
- {
- name: 'test',
- title: 'test: running',
- status: {
- icon: 'status_running',
- text: 'running',
- label: 'running',
- group: 'running',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396#test',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_running-2eb56be2871937954b2ba6d6f4ee9fdf7e5e1c146ac45f7be98119ccaca1aca9.ico',
- },
- path: '/gitlab-org/gitlab/pipelines/20333396#test',
- dropdown_path: '/gitlab-org/gitlab/pipelines/20333396/stage.json?stage=test',
- },
- {
- name: 'post-test',
- title: 'post-test: created',
- status: {
- icon: 'status_created',
- text: 'created',
- label: 'created',
- group: 'created',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396#post-test',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_created-e997aa0b7db73165df8a9d6803932b18d7b7cc37d604d2d96e378fea2dba9c5f.ico',
- },
- path: '/gitlab-org/gitlab/pipelines/20333396#post-test',
- dropdown_path: '/gitlab-org/gitlab/pipelines/20333396/stage.json?stage=post-test',
- },
- {
- name: 'pages',
- title: 'pages: created',
- status: {
- icon: 'status_created',
- text: 'created',
- label: 'created',
- group: 'created',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396#pages',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_created-e997aa0b7db73165df8a9d6803932b18d7b7cc37d604d2d96e378fea2dba9c5f.ico',
- },
- path: '/gitlab-org/gitlab/pipelines/20333396#pages',
- dropdown_path: '/gitlab-org/gitlab/pipelines/20333396/stage.json?stage=pages',
- },
- {
- name: 'post-cleanup',
- title: 'post-cleanup: created',
- status: {
- icon: 'status_created',
- text: 'created',
- label: 'created',
- group: 'created',
- has_details: true,
- details_path: '/gitlab-org/gitlab/pipelines/20333396#post-cleanup',
- favicon:
- 'https://assets.gitlab-static.net/assets/ci_favicons/favicon_status_created-e997aa0b7db73165df8a9d6803932b18d7b7cc37d604d2d96e378fea2dba9c5f.ico',
- },
- path: '/gitlab-org/gitlab/pipelines/20333396#post-cleanup',
- dropdown_path: '/gitlab-org/gitlab/pipelines/20333396/stage.json?stage=post-cleanup',
- },
- ],
- artifacts: [
- {
- name: 'gitlab:assets:compile',
- expired: false,
- expire_at: '2018-05-12T14:22:54.730Z',
- path: '/gitlab-org/gitlab/-/jobs/62411438/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411438/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411438/artifacts/browse',
- },
- {
- name: 'rspec-mysql 12 28',
- expired: false,
- expire_at: '2018-05-12T14:22:45.136Z',
- path: '/gitlab-org/gitlab/-/jobs/62411397/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411397/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411397/artifacts/browse',
- },
- {
- name: 'rspec-mysql 6 28',
- expired: false,
- expire_at: '2018-05-12T14:22:41.523Z',
- path: '/gitlab-org/gitlab/-/jobs/62411391/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411391/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411391/artifacts/browse',
- },
- {
- name: 'rspec-pg geo 0 1',
- expired: false,
- expire_at: '2018-05-12T14:22:13.287Z',
- path: '/gitlab-org/gitlab/-/jobs/62411353/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411353/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411353/artifacts/browse',
- },
- {
- name: 'rspec-mysql 0 28',
- expired: false,
- expire_at: '2018-05-12T14:22:06.834Z',
- path: '/gitlab-org/gitlab/-/jobs/62411385/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411385/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411385/artifacts/browse',
- },
- {
- name: 'spinach-mysql 0 2',
- expired: false,
- expire_at: '2018-05-12T14:21:51.409Z',
- path: '/gitlab-org/gitlab/-/jobs/62411423/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411423/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411423/artifacts/browse',
- },
- {
- name: 'karma',
- expired: false,
- expire_at: '2018-05-12T14:21:20.934Z',
- path: '/gitlab-org/gitlab/-/jobs/62411440/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411440/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411440/artifacts/browse',
- },
- {
- name: 'spinach-pg 0 2',
- expired: false,
- expire_at: '2018-05-12T14:20:01.028Z',
- path: '/gitlab-org/gitlab/-/jobs/62411419/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411419/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411419/artifacts/browse',
- },
- {
- name: 'spinach-pg 1 2',
- expired: false,
- expire_at: '2018-05-12T14:19:04.336Z',
- path: '/gitlab-org/gitlab/-/jobs/62411421/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411421/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411421/artifacts/browse',
- },
- {
- name: 'sast',
- expired: null,
- expire_at: null,
- path: '/gitlab-org/gitlab/-/jobs/62411442/artifacts/download',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411442/artifacts/browse',
- },
- {
- name: 'code_quality',
- expired: false,
- expire_at: '2018-04-18T14:16:24.484Z',
- path: '/gitlab-org/gitlab/-/jobs/62411441/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411441/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411441/artifacts/browse',
- },
- {
- name: 'cache gems',
- expired: null,
- expire_at: null,
- path: '/gitlab-org/gitlab/-/jobs/62411447/artifacts/download',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411447/artifacts/browse',
- },
- {
- name: 'dependency_scanning',
- expired: null,
- expire_at: null,
- path: '/gitlab-org/gitlab/-/jobs/62411443/artifacts/download',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411443/artifacts/browse',
- },
- {
- name: 'compile-assets',
- expired: false,
- expire_at: '2018-04-18T14:12:07.638Z',
- path: '/gitlab-org/gitlab/-/jobs/62411334/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411334/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411334/artifacts/browse',
- },
- {
- name: 'setup-test-env',
- expired: false,
- expire_at: '2018-04-18T14:10:27.024Z',
- path: '/gitlab-org/gitlab/-/jobs/62411336/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411336/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411336/artifacts/browse',
- },
- {
- name: 'retrieve-tests-metadata',
- expired: false,
- expire_at: '2018-05-12T14:06:35.926Z',
- path: '/gitlab-org/gitlab/-/jobs/62411333/artifacts/download',
- keep_path: '/gitlab-org/gitlab/-/jobs/62411333/artifacts/keep',
- browse_path: '/gitlab-org/gitlab/-/jobs/62411333/artifacts/browse',
- },
- ],
- manual_actions: [
- {
- name: 'package-and-qa',
- path: '/gitlab-org/gitlab/-/jobs/62411330/play',
- playable: true,
- },
- {
- name: 'review-docs-deploy',
- path: '/gitlab-org/gitlab/-/jobs/62411332/play',
- playable: true,
- },
- ],
- },
- ref: {
- name: 'master',
- path: '/gitlab-org/gitlab/commits/master',
- tag: false,
- branch: true,
- },
- commit: {
- id: 'e6a2885c503825792cb8a84a8731295e361bd059',
- short_id: 'e6a2885c',
- title: "Merge branch 'ce-to-ee-2018-04-11' into 'master'",
- created_at: '2018-04-11T14:04:39.000Z',
- parent_ids: [
- '5d9b5118f6055f72cff1a82b88133609912f2c1d',
- '6fdc6ee76a8062fe41b1a33f7c503334a6ebdc02',
- ],
- message:
- "Merge branch 'ce-to-ee-2018-04-11' into 'master'\n\nCE upstream - 2018-04-11 12:26 UTC\n\nSee merge request gitlab-org/gitlab-ee!5326",
- author_name: 'Rémy Coutable',
- author_email: 'remy@rymai.me',
- authored_date: '2018-04-11T14:04:39.000Z',
- committer_name: 'Rémy Coutable',
- committer_email: 'remy@rymai.me',
- committed_date: '2018-04-11T14:04:39.000Z',
- author: {
- id: 128633,
- name: 'Rémy Coutable',
- username: 'rymai',
- state: 'active',
- avatar_url:
- 'https://secure.gravatar.com/avatar/263da227929cc0035cb0eba512bcf81a?s=80\u0026d=identicon',
- web_url: 'https://gitlab.com/rymai',
- path: '/rymai',
- },
- author_gravatar_url:
- 'https://secure.gravatar.com/avatar/263da227929cc0035cb0eba512bcf81a?s=80\u0026d=identicon',
- commit_url:
- 'https://gitlab.com/gitlab-org/gitlab/commit/e6a2885c503825792cb8a84a8731295e361bd059',
- commit_path: '/gitlab-org/gitlab/commit/e6a2885c503825792cb8a84a8731295e361bd059',
- },
- cancel_path: '/gitlab-org/gitlab/pipelines/20333396/cancel',
- triggered_by: null,
- triggered: [],
-};
-
const threeWeeksAgo = new Date();
threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js
index 78c0bcab03a..ccf3f0b6667 100644
--- a/spec/frontend/pipelines/pipelines_spec.js
+++ b/spec/frontend/pipelines/pipelines_spec.js
@@ -18,7 +18,7 @@ import Store from '~/pipelines/stores/pipelines_store';
import NavigationTabs from '~/vue_shared/components/navigation_tabs.vue';
import TablePagination from '~/vue_shared/components/pagination/table_pagination.vue';
-import { pipelineWithStages, stageReply, users, mockSearch, branches } from './mock_data';
+import { stageReply, users, mockSearch, branches } from './mock_data';
jest.mock('~/flash');
@@ -27,6 +27,9 @@ const mockProjectId = '21';
const mockPipelinesEndpoint = `/${mockProjectPath}/pipelines.json`;
const mockPipelinesResponse = getJSONFixture('pipelines/pipelines.json');
const mockPipelinesIds = mockPipelinesResponse.pipelines.map(({ id }) => id);
+const mockPipelineWithStages = mockPipelinesResponse.pipelines.find(
+ (p) => p.details.stages && p.details.stages.length,
+);
describe('Pipelines', () => {
let wrapper;
@@ -611,14 +614,15 @@ describe('Pipelines', () => {
mock.onGet(mockPipelinesEndpoint, { scope: 'all', page: '1' }).reply(
200,
{
- pipelines: [pipelineWithStages],
+ pipelines: [mockPipelineWithStages],
count: { all: '1' },
},
{
'POLL-INTERVAL': 100,
},
);
- mock.onGet(pipelineWithStages.details.stages[0].dropdown_path).reply(200, stageReply);
+
+ mock.onGet(mockPipelineWithStages.details.stages[0].dropdown_path).reply(200, stageReply);
createComponent();
diff --git a/spec/frontend/pipelines/pipelines_table_row_spec.js b/spec/frontend/pipelines/pipelines_table_row_spec.js
index 60318511be2..8edf891b443 100644
--- a/spec/frontend/pipelines/pipelines_table_row_spec.js
+++ b/spec/frontend/pipelines/pipelines_table_row_spec.js
@@ -155,7 +155,7 @@ describe('Pipelines Table Row', () => {
it('should render an icon for each stage', () => {
expect(
wrapper.findAll(
- '.table-section:nth-child(4) [data-testid="mini-pipeline-graph-dropdown-toggle"]',
+ '.table-section:nth-child(5) [data-testid="mini-pipeline-graph-dropdown-toggle"]',
).length,
).toEqual(pipeline.details.stages.length);
});
@@ -182,9 +182,10 @@ describe('Pipelines Table Row', () => {
expect(wrapper.find('.js-pipelines-retry-button').attributes('title')).toMatch('Retry');
expect(wrapper.find('.js-pipelines-cancel-button').exists()).toBe(true);
expect(wrapper.find('.js-pipelines-cancel-button').attributes('title')).toMatch('Cancel');
- const dropdownMenu = wrapper.find('.dropdown-menu');
- expect(dropdownMenu.text()).toContain(scheduledJobAction.name);
+ const actionsMenu = wrapper.find('[data-testid="pipelines-manual-actions-dropdown"]');
+
+ expect(actionsMenu.text()).toContain(scheduledJobAction.name);
});
it('emits `retryPipeline` event when retry button is clicked and toggles loading', () => {
diff --git a/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
index f923a4a4721..3327a30f1d5 100644
--- a/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:cursor) { 'cursor' }
+ let(:timestamp) { Time.new(2020, 01, 01).utc }
let(:entity) do
create(
:bulk_import_entity,
@@ -20,21 +21,23 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
subject { described_class.new(context) }
- def extractor_data(title:, has_next_page:, cursor: nil)
- data = [
- {
- 'title' => title,
- 'description' => 'desc',
- 'color' => '#428BCA'
- }
- ]
+ def label_data(title)
+ {
+ 'title' => title,
+ 'description' => 'desc',
+ 'color' => '#428BCA',
+ 'created_at' => timestamp.to_s,
+ 'updated_at' => timestamp.to_s
+ }
+ end
+ def extractor_data(title:, has_next_page:, cursor: nil)
page_info = {
'end_cursor' => cursor,
'has_next_page' => has_next_page
}
- BulkImports::Pipeline::ExtractedData.new(data: data, page_info: page_info)
+ BulkImports::Pipeline::ExtractedData.new(data: [label_data(title)], page_info: page_info)
end
describe '#run' do
@@ -55,6 +58,8 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
expect(label.title).to eq('label2')
expect(label.description).to eq('desc')
expect(label.color).to eq('#428BCA')
+ expect(label.created_at).to eq(timestamp)
+ expect(label.updated_at).to eq(timestamp)
end
end
@@ -92,19 +97,15 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
describe '#load' do
it 'creates the label' do
- data = {
- 'title' => 'label',
- 'description' => 'description',
- 'color' => '#FFFFFF'
- }
+ data = label_data('label')
expect { subject.load(context, data) }.to change(Label, :count).by(1)
label = group.labels.first
- expect(label.title).to eq(data['title'])
- expect(label.description).to eq(data['description'])
- expect(label.color).to eq(data['color'])
+ data.each do |key, value|
+ expect(label[key]).to eq(value)
+ end
end
end
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index 01aceec12c5..f5cb1987c5c 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -24,6 +24,26 @@ RSpec.describe Gitlab::CurrentSettings do
end
end
+ describe '.signup_disabled?' do
+ subject { described_class.signup_disabled? }
+
+ context 'when signup is enabled' do
+ before do
+ create(:application_setting, signup_enabled: true)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when signup is disabled' do
+ before do
+ create(:application_setting, signup_enabled: false)
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
describe '#current_application_settings', :use_clean_rails_memory_store_caching do
it 'allows keys to be called directly' do
db_settings = create(:application_setting,
diff --git a/spec/lib/marginalia_spec.rb b/spec/lib/marginalia_spec.rb
index fa0cd214c7e..2ee27fbe20c 100644
--- a/spec/lib/marginalia_spec.rb
+++ b/spec/lib/marginalia_spec.rb
@@ -37,26 +37,9 @@ RSpec.describe 'Marginalia spec' do
}
end
- context 'when the feature is enabled' do
- before do
- stub_feature(true)
- end
-
- it 'generates a query that includes the component and value' do
- component_map.each do |component, value|
- expect(recorded.log.last).to include("#{component}:#{value}")
- end
- end
- end
-
- context 'when the feature is disabled' do
- before do
- stub_feature(false)
- end
-
- it 'excludes annotations in generated queries' do
- expect(recorded.log.last).not_to include("/*")
- expect(recorded.log.last).not_to include("*/")
+ it 'generates a query that includes the component and value' do
+ component_map.each do |component, value|
+ expect(recorded.log.last).to include("#{component}:#{value}")
end
end
end
@@ -90,59 +73,37 @@ RSpec.describe 'Marginalia spec' do
}
end
- context 'when the feature is enabled' do
- before do
- stub_feature(true)
+ it 'generates a query that includes the component and value' do
+ component_map.each do |component, value|
+ expect(recorded.log.last).to include("#{component}:#{value}")
end
+ end
- it 'generates a query that includes the component and value' do
- component_map.each do |component, value|
- expect(recorded.log.last).to include("#{component}:#{value}")
- end
- end
-
- describe 'for ActionMailer delivery jobs' do
- let(:delivery_job) { MarginaliaTestMailer.first_user.deliver_later }
-
- let(:recorded) do
- ActiveRecord::QueryRecorder.new do
- delivery_job.perform_now
- end
- end
-
- let(:component_map) do
- {
- "application" => "sidekiq",
- "jid" => delivery_job.job_id,
- "job_class" => delivery_job.arguments.first
- }
- end
+ describe 'for ActionMailer delivery jobs' do
+ let(:delivery_job) { MarginaliaTestMailer.first_user.deliver_later }
- it 'generates a query that includes the component and value' do
- component_map.each do |component, value|
- expect(recorded.log.last).to include("#{component}:#{value}")
- end
+ let(:recorded) do
+ ActiveRecord::QueryRecorder.new do
+ delivery_job.perform_now
end
end
- end
- context 'when the feature is disabled' do
- before do
- stub_feature(false)
+ let(:component_map) do
+ {
+ "application" => "sidekiq",
+ "jid" => delivery_job.job_id,
+ "job_class" => delivery_job.arguments.first
+ }
end
- it 'excludes annotations in generated queries' do
- expect(recorded.log.last).not_to include("/*")
- expect(recorded.log.last).not_to include("*/")
+ it 'generates a query that includes the component and value' do
+ component_map.each do |component, value|
+ expect(recorded.log.last).to include("#{component}:#{value}")
+ end
end
end
end
- def stub_feature(value)
- stub_feature_flags(marginalia: value)
- Gitlab::Marginalia.set_enabled_from_feature_flag
- end
-
def make_request(correlation_id)
request_env = Rack::MockRequest.env_for('/')
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index cbb20de75b0..06b6ba2088f 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -3082,32 +3082,83 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
describe "#head_pipeline_active? " do
- it do
- is_expected
- .to delegate_method(:active?)
- .to(:head_pipeline)
- .with_prefix
- .with_arguments(allow_nil: true)
+ context 'when project lacks a head_pipeline relation' do
+ before do
+ subject.head_pipeline = nil
+ end
+
+ it 'returns false' do
+ expect(subject.head_pipeline_active?).to be false
+ end
+ end
+
+ context 'when project has a head_pipeline relation' do
+ let(:pipeline) { create(:ci_empty_pipeline) }
+
+ before do
+ allow(subject).to receive(:head_pipeline) { pipeline }
+ end
+
+ it 'accesses the value from the head_pipeline' do
+ expect(subject.head_pipeline)
+ .to receive(:active?)
+
+ subject.head_pipeline_active?
+ end
end
end
describe "#actual_head_pipeline_success? " do
- it do
- is_expected
- .to delegate_method(:success?)
- .to(:actual_head_pipeline)
- .with_prefix
- .with_arguments(allow_nil: true)
+ context 'when project lacks an actual_head_pipeline relation' do
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { nil }
+ end
+
+ it 'returns false' do
+ expect(subject.actual_head_pipeline_success?).to be false
+ end
+ end
+
+ context 'when project has a actual_head_pipeline relation' do
+ let(:pipeline) { create(:ci_empty_pipeline) }
+
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { pipeline }
+ end
+
+ it 'accesses the value from the actual_head_pipeline' do
+ expect(subject.actual_head_pipeline)
+ .to receive(:success?)
+
+ subject.actual_head_pipeline_success?
+ end
end
end
describe "#actual_head_pipeline_active? " do
- it do
- is_expected
- .to delegate_method(:active?)
- .to(:actual_head_pipeline)
- .with_prefix
- .with_arguments(allow_nil: true)
+ context 'when project lacks an actual_head_pipeline relation' do
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { nil }
+ end
+
+ it 'returns false' do
+ expect(subject.actual_head_pipeline_active?).to be false
+ end
+ end
+
+ context 'when project has a actual_head_pipeline relation' do
+ let(:pipeline) { create(:ci_empty_pipeline) }
+
+ before do
+ allow(subject).to receive(:actual_head_pipeline) { pipeline }
+ end
+
+ it 'accesses the value from the actual_head_pipeline' do
+ expect(subject.actual_head_pipeline)
+ .to receive(:active?)
+
+ subject.actual_head_pipeline_active?
+ end
end
end
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 623767d19e0..c194a98fdd8 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -496,6 +496,16 @@ RSpec.describe Snippet do
it 'returns array of blobs' do
expect(snippet.blobs).to all(be_a(Blob))
end
+
+ context 'when file does not exist' do
+ it 'removes nil values from the blobs array' do
+ allow(snippet).to receive(:list_files).and_return(%w(LICENSE non_existent_snippet_file))
+
+ blobs = snippet.blobs
+ expect(blobs.count).to eq 1
+ expect(blobs.first.name).to eq 'LICENSE'
+ end
+ end
end
end
diff --git a/spec/presenters/snippet_presenter_spec.rb b/spec/presenters/snippet_presenter_spec.rb
index a1d987ed78f..b0387206bd9 100644
--- a/spec/presenters/snippet_presenter_spec.rb
+++ b/spec/presenters/snippet_presenter_spec.rb
@@ -159,7 +159,7 @@ RSpec.describe SnippetPresenter do
let(:snippet) { create(:snippet, :repository, author: user) }
it 'returns repository first blob' do
- expect(subject).to eq snippet.blobs.first
+ expect(subject.name).to eq snippet.blobs.first.name
end
end
end
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index 2316e702c3e..b5bf697e9e3 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -5,7 +5,9 @@ require 'spec_helper'
RSpec.describe API::Lint do
describe 'POST /ci/lint' do
context 'when signup settings are disabled' do
- Gitlab::CurrentSettings.signup_enabled = false
+ before do
+ Gitlab::CurrentSettings.signup_enabled = false
+ end
context 'when unauthenticated' do
it 'returns authentication error' do
@@ -16,22 +18,25 @@ RSpec.describe API::Lint do
end
context 'when authenticated' do
- it 'returns unauthorized error' do
- post api('/ci/lint'), params: { content: 'content' }
+ let_it_be(:api_user) { create(:user) }
+ it 'returns authorized' do
+ post api('/ci/lint', api_user), params: { content: 'content' }
- expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'when signup settings are enabled' do
- Gitlab::CurrentSettings.signup_enabled = true
+ before do
+ Gitlab::CurrentSettings.signup_enabled = true
+ end
context 'when unauthenticated' do
- it 'returns authentication error' do
+ it 'returns authorized success' do
post api('/ci/lint'), params: { content: 'content' }
- expect(response).to have_gitlab_http_status(:unauthorized)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 64c1479a412..2c745a0a70c 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -249,9 +249,6 @@ RSpec.configure do |config|
unstub_all_feature_flags
end
- # Enable Marginalia feature for all specs in the test suite.
- Gitlab::Marginalia.enabled = true
-
# Stub these calls due to being expensive operations
# It can be reenabled for specific tests via:
#