summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml5
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_row.vue22
-rw-r--r--app/assets/javascripts/diffs/components/tree_list.vue6
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js2
-rw-r--r--app/assets/javascripts/ide/components/ide_file_row.vue23
-rw-r--r--app/assets/javascripts/ide/components/ide_tree_list.vue3
-rw-r--r--app/assets/javascripts/main.js10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue45
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/file_row.vue30
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss21
-rw-r--r--app/workers/concerns/security_scans_queue.rb13
-rw-r--r--changelogs/unreleased/10225-detroy-oauth-application-when-secondary-becomes-primary.yml5
-rw-r--r--changelogs/unreleased/202109.yml6
-rw-r--r--changelogs/unreleased/georgekoltsov-remove-name-path-from-group-ie-yml.yml5
-rw-r--r--changelogs/unreleased/i18n-groups-audit-events.yml5
-rw-r--r--changelogs/unreleased/rk4bir-master-patch-88996.yml5
-rw-r--r--db/post_migrate/20200213220159_migrate_store_security_reports_sidekiq_queue.rb15
-rw-r--r--db/post_migrate/20200213220211_migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue.rb17
-rw-r--r--db/schema.rb2
-rw-r--r--doc/administration/gitaly/praefect.md11
-rw-r--r--doc/development/fe_guide/icons.md16
-rw-r--r--doc/development/pipelines.md8
-rw-r--r--lib/gitlab/import_export/group_import_export.yml2
-rw-r--r--locale/gitlab.pot9
-rw-r--r--spec/frontend/diffs/components/diff_file_row_spec.js37
-rw-r--r--spec/frontend/helpers/dom_shims/element_scroll_into_view.js1
-rw-r--r--spec/frontend/helpers/dom_shims/index.js1
-rw-r--r--spec/frontend/ide/components/ide_file_row_spec.js110
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js52
-rw-r--r--spec/javascripts/vue_mr_widget/mock_data.js2
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js55
-rw-r--r--spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js14
-rw-r--r--spec/javascripts/vue_shared/components/file_row_spec.js59
-rw-r--r--spec/lib/gitlab/import_export/group_tree_restorer_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/group_tree_saver_spec.rb2
-rw-r--r--spec/migrations/migrate_store_security_reports_sidekiq_queue_spec.rb33
-rw-r--r--spec/migrations/migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue_spec.rb33
-rw-r--r--spec/models/user_spec.rb28
-rw-r--r--spec/requests/api/access_requests_spec.rb12
-rw-r--r--spec/requests/api/award_emoji_spec.rb15
-rw-r--r--spec/requests/api/boards_spec.rb32
-rw-r--r--spec/requests/api/branches_spec.rb2
-rw-r--r--spec/requests/api/broadcast_messages_spec.rb6
-rw-r--r--spec/requests/api/features_spec.rb4
-rw-r--r--spec/requests/api/graphql/current_user_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/gitlab_schema_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/add_spec.rb6
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb6
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb2
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/note_spec.rb2
-rw-r--r--spec/requests/api/graphql/tasks/task_completion_status_spec.rb4
-rw-r--r--spec/requests/api/group_boards_spec.rb28
-rw-r--r--spec/requests/api/issues/get_group_issues_spec.rb22
-rw-r--r--spec/requests/api/issues/get_project_issues_spec.rb22
-rw-r--r--spec/requests/api/issues/issues_spec.rb22
-rw-r--r--spec/requests/api/issues/post_projects_issues_spec.rb20
-rw-r--r--spec/requests/api/issues/put_projects_issues_spec.rb20
-rw-r--r--spec/requests/api/jobs_spec.rb4
-rw-r--r--spec/requests/api/markdown_spec.rb4
-rw-r--r--spec/requests/api/merge_requests_spec.rb6
-rw-r--r--spec/requests/api/pages/internal_access_spec.rb19
-rw-r--r--spec/requests/api/pages/private_access_spec.rb19
-rw-r--r--spec/requests/api/pages/public_access_spec.rb19
-rw-r--r--spec/requests/api/pipeline_schedules_spec.rb12
-rw-r--r--spec/requests/api/project_container_repositories_spec.rb11
-rw-r--r--spec/requests/api/project_export_spec.rb10
-rw-r--r--spec/requests/api/project_snippets_spec.rb6
-rw-r--r--spec/requests/api/resource_label_events_spec.rb6
-rw-r--r--spec/requests/api/runners_spec.rb2
-rw-r--r--spec/requests/api/search_spec.rb8
-rw-r--r--spec/requests/api/services_spec.rb6
-rw-r--r--spec/requests/api/settings_spec.rb2
-rw-r--r--spec/requests/api/snippets_spec.rb12
-rw-r--r--spec/requests/api/task_completion_status_spec.rb4
-rw-r--r--spec/requests/api/triggers_spec.rb4
79 files changed, 782 insertions, 332 deletions
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index 682ed12e199..c15c7c2ab5d 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -126,7 +126,6 @@ review-build-cng:
- .default-tags
- .default-retry
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
- dependencies: []
variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
@@ -142,6 +141,9 @@ review-deploy:
- .review-workflow-base
- .review:rules:mr-and-schedule
stage: review
+ needs:
+ - job: review-build-cng
+ artifacts: false
allow_failure: true
before_script:
- '[[ ! -d "ee/" ]] || export GITLAB_EDITION="ee"'
@@ -169,6 +171,7 @@ review-deploy:
extends: .review-workflow-base
environment:
action: stop
+ dependencies: []
variables:
# We're cloning the repo instead of downloading the script for now
# because some repos are private and CI_JOB_TOKEN cannot access files.
diff --git a/app/assets/javascripts/diffs/components/diff_file_row.vue b/app/assets/javascripts/diffs/components/diff_file_row.vue
index f41337762fd..5aaed0d40db 100644
--- a/app/assets/javascripts/diffs/components/diff_file_row.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_row.vue
@@ -4,14 +4,34 @@
* https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23720
*/
import FileRow from '~/vue_shared/components/file_row.vue';
+import FileRowStats from './file_row_stats.vue';
export default {
+ name: 'DiffFileRow',
components: {
FileRow,
+ FileRowStats,
+ },
+ props: {
+ file: {
+ type: Object,
+ required: true,
+ },
+ hideFileStats: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ showFileRowStats() {
+ return !this.hideFileStats && this.file.type === 'blob';
+ },
},
};
</script>
<template>
- <file-row v-bind="$attrs" v-on="$listeners" />
+ <file-row :file="file" :hide-file-stats="hideFileStats" v-bind="$attrs" v-on="$listeners">
+ <file-row-stats v-if="showFileRowStats" :file="file" />
+ </file-row>
</template>
diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue
index 18c3002825e..1eac3430a20 100644
--- a/app/assets/javascripts/diffs/components/tree_list.vue
+++ b/app/assets/javascripts/diffs/components/tree_list.vue
@@ -5,7 +5,6 @@ import { s__, sprintf } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import FileTree from '~/vue_shared/components/file_tree.vue';
import DiffFileRow from './diff_file_row.vue';
-import FileRowStats from './file_row_stats.vue';
export default {
directives: {
@@ -49,9 +48,6 @@ export default {
return acc;
}, []);
},
- fileRowExtraComponent() {
- return this.hideFileStats ? null : FileRowStats;
- },
},
methods: {
...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']),
@@ -98,8 +94,8 @@ export default {
:key="file.key"
:file="file"
:level="0"
+ :hide-file-stats="hideFileStats"
:hide-extra-on-tree="true"
- :extra-component="fileRowExtraComponent"
:show-changed-icon="true"
:file-row-component="$options.DiffFileRow"
@toggleTreeOpen="toggleTreeOpen"
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 6f486e1a539..fa2e3f94f87 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -719,7 +719,7 @@ GfmAutoComplete.Milestones = {
};
GfmAutoComplete.Loading = {
template:
- '<li style="pointer-events: none;"><i class="fa fa-spinner fa-spin"></i> Loading...</li>',
+ '<li style="pointer-events: none;"><span class="spinner align-text-bottom mr-1"></span>Loading...</li>',
};
export default GfmAutoComplete;
diff --git a/app/assets/javascripts/ide/components/ide_file_row.vue b/app/assets/javascripts/ide/components/ide_file_row.vue
index f41337762fd..b777d89f0bb 100644
--- a/app/assets/javascripts/ide/components/ide_file_row.vue
+++ b/app/assets/javascripts/ide/components/ide_file_row.vue
@@ -4,14 +4,35 @@
* https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23720
*/
import FileRow from '~/vue_shared/components/file_row.vue';
+import FileRowExtra from './file_row_extra.vue';
export default {
+ name: 'IdeFileRow',
components: {
FileRow,
+ FileRowExtra,
+ },
+ props: {
+ file: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ dropdownOpen: false,
+ };
+ },
+ methods: {
+ toggleDropdown(val) {
+ this.dropdownOpen = val;
+ },
},
};
</script>
<template>
- <file-row v-bind="$attrs" v-on="$listeners" />
+ <file-row :file="file" v-bind="$attrs" @mouseleave="toggleDropdown(false)" v-on="$listeners">
+ <file-row-extra :file="file" :dropdown-open="dropdownOpen" @toggle="toggleDropdown($event)" />
+ </file-row>
</template>
diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue
index 151f7f0c421..36e8951bea3 100644
--- a/app/assets/javascripts/ide/components/ide_tree_list.vue
+++ b/app/assets/javascripts/ide/components/ide_tree_list.vue
@@ -4,7 +4,6 @@ import { GlSkeletonLoading } from '@gitlab/ui';
import FileTree from '~/vue_shared/components/file_tree.vue';
import IdeFileRow from './ide_file_row.vue';
import NavDropdown from './nav_dropdown.vue';
-import FileRowExtra from './file_row_extra.vue';
export default {
components: {
@@ -36,7 +35,6 @@ export default {
methods: {
...mapActions(['updateViewer', 'toggleTreeOpen']),
},
- FileRowExtra,
IdeFileRow,
};
</script>
@@ -60,7 +58,6 @@ export default {
:key="file.key"
:file="file"
:level="0"
- :extra-component="$options.FileRowExtra"
:file-row-component="$options.IdeFileRow"
@toggleTreeOpen="toggleTreeOpen"
/>
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index 8fb973b1c1f..5b645b032ed 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -201,9 +201,15 @@ document.addEventListener('DOMContentLoaded', () => {
});
if (bootstrapBreakpoint === 'sm' || bootstrapBreakpoint === 'xs') {
- const $rightSidebar = $('aside.right-sidebar, .layout-page');
+ const $rightSidebar = $('aside.right-sidebar');
+ const $layoutPage = $('.layout-page');
- $rightSidebar.removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
+ if ($rightSidebar.length > 0) {
+ $rightSidebar.removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
+ $layoutPage.removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
+ } else {
+ $layoutPage.removeClass('right-sidebar-expanded right-sidebar-collapsed');
+ }
}
// prevent default action for disabled buttons
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
index 2aaba6e1c8a..7c71463c949 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_header.vue
@@ -77,7 +77,7 @@ export default {
};
</script>
<template>
- <div class="mr-source-target append-bottom-default">
+ <div class="d-flex mr-source-target append-bottom-default">
<mr-widget-icon name="git-merge" />
<div class="git-merge-container d-flex">
<div class="normal">
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue
new file mode 100644
index 00000000000..f08bfb3a90f
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue
@@ -0,0 +1,45 @@
+<script>
+import { GlLink, GlSprintf } from '@gitlab/ui';
+import MrWidgetIcon from './mr_widget_icon.vue';
+
+export default {
+ name: 'MRWidgetSuggestPipeline',
+ iconName: 'status_notfound',
+ components: {
+ GlLink,
+ GlSprintf,
+ MrWidgetIcon,
+ },
+ props: {
+ pipelinePath: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <div class="d-flex mr-pipeline-suggest append-bottom-default">
+ <mr-widget-icon :name="$options.iconName" />
+ <gl-sprintf
+ class="js-no-pipeline-message"
+ :message="
+ s__(`mrWidget|%{prefixToLinkStart}No pipeline%{prefixToLinkEnd}
+ %{addPipelineLinkStart}Add the .gitlab-ci.yml file%{addPipelineLinkEnd}
+ to create one.`)
+ "
+ >
+ <template #prefixToLink="{content}">
+ <strong>
+ {{ content }}
+ </strong>
+ </template>
+ <template #addPipelineLink="{content}">
+ <gl-link :href="pipelinePath" class="ml-2">
+ {{ content }}
+ </gl-link>
+ &nbsp;
+ </template>
+ </gl-sprintf>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index 9085383e230..27f13ace779 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -9,6 +9,7 @@ import SmartInterval from '~/smart_interval';
import createFlash from '../flash';
import Loading from './components/loading.vue';
import WidgetHeader from './components/mr_widget_header.vue';
+import WidgetSuggestPipeline from './components/mr_widget_suggest_pipeline.vue';
import WidgetMergeHelp from './components/mr_widget_merge_help.vue';
import MrWidgetPipelineContainer from './components/mr_widget_pipeline_container.vue';
import Deployment from './components/deployment/deployment.vue';
@@ -46,6 +47,7 @@ export default {
components: {
Loading,
'mr-widget-header': WidgetHeader,
+ 'mr-widget-suggest-pipeline': WidgetSuggestPipeline,
'mr-widget-merge-help': WidgetMergeHelp,
MrWidgetPipelineContainer,
Deployment,
@@ -99,6 +101,9 @@ export default {
shouldRenderPipelines() {
return this.mr.hasCI;
},
+ shouldSuggestPipelines() {
+ return gon.features?.suggestPipeline && !this.mr.hasCI && this.mr.mergeRequestAddCiConfigPath;
+ },
shouldRenderRelatedLinks() {
return Boolean(this.mr.relatedLinks) && !this.mr.isNothingToMergeState;
},
@@ -353,6 +358,11 @@ export default {
<template>
<div v-if="mr" class="mr-state-widget prepend-top-default">
<mr-widget-header :mr="mr" />
+ <mr-widget-suggest-pipeline
+ v-if="shouldSuggestPipelines"
+ class="mr-widget-workflow"
+ :pipeline-path="mr.mergeRequestAddCiConfigPath"
+ />
<mr-widget-pipeline-container
v-if="shouldRenderPipelines"
class="mr-widget-workflow"
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index c7949fa264e..73a0b3cb673 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -175,6 +175,8 @@ export default class MergeRequestStore {
this.securityApprovalsHelpPagePath = data.security_approvals_help_page_path;
this.eligibleApproversDocsPath = data.eligible_approvers_docs_path;
this.mergeImmediatelyDocsPath = data.merge_immediately_docs_path;
+ this.mergeRequestAddCiConfigPath = data.merge_request_add_ci_config_path;
+ this.humanAccess = data.human_access;
}
get isNothingToMergeState() {
diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue
index d962f644ff8..1ea6eb2628b 100644
--- a/app/assets/javascripts/vue_shared/components/file_row.vue
+++ b/app/assets/javascripts/vue_shared/components/file_row.vue
@@ -1,5 +1,4 @@
<script>
-import Icon from '~/vue_shared/components/icon.vue';
import FileHeader from '~/vue_shared/components/file_row_header.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import ChangedFileIcon from '~/vue_shared/components/changed_file_icon.vue';
@@ -9,7 +8,6 @@ export default {
components: {
FileHeader,
FileIcon,
- Icon,
ChangedFileIcon,
},
props: {
@@ -21,27 +19,12 @@ export default {
type: Number,
required: true,
},
- extraComponent: {
- type: Object,
- required: false,
- default: null,
- },
- hideExtraOnTree: {
- type: Boolean,
- required: false,
- default: false,
- },
showChangedIcon: {
type: Boolean,
required: false,
default: false,
},
},
- data() {
- return {
- dropdownOpen: false,
- };
- },
computed: {
isTree() {
return this.file.type === 'tree';
@@ -120,9 +103,6 @@ export default {
return this.$router.currentRoute.path === `/project${this.file.url}`;
},
- toggleDropdown(val) {
- this.dropdownOpen = val;
- },
},
};
</script>
@@ -136,7 +116,7 @@ export default {
class="file-row"
role="button"
@click="clickFile"
- @mouseleave="toggleDropdown(false)"
+ @mouseleave="$emit('mouseleave', $event)"
>
<div class="file-row-name-container">
<span ref="textOutput" :style="levelIndentation" class="file-row-name str-truncated">
@@ -152,13 +132,7 @@ export default {
<changed-file-icon v-else :file="file" :size="16" class="append-right-5" />
{{ file.name }}
</span>
- <component
- :is="extraComponent"
- v-if="extraComponent && !(hideExtraOnTree && file.type === 'tree')"
- :file="file"
- :dropdown-open="dropdownOpen"
- @toggle="toggleDropdown($event)"
- />
+ <slot></slot>
</div>
</div>
</template>
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 84daec4fb43..5ca75c28ac3 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -3,6 +3,8 @@
*
*/
+$mr-widget-min-height: 69px;
+
.space-children {
@include clearfix;
@@ -555,12 +557,11 @@
}
.mr-source-target {
- display: flex;
flex-wrap: wrap;
border-radius: $border-radius-default;
padding: $gl-padding;
border: 1px solid $border-color;
- min-height: 69px;
+ min-height: $mr-widget-min-height;
@include media-breakpoint-up(md) {
align-items: center;
@@ -599,6 +600,22 @@
}
}
+.mr-pipeline-suggest {
+ flex-wrap: wrap;
+ border-radius: $border-radius-default;
+ padding: $gl-padding;
+ border: 1px solid $border-color;
+ min-height: $mr-widget-min-height;
+
+ @include media-breakpoint-up(md) {
+ align-items: center;
+ }
+
+ .circle-icon-container {
+ color: $gl-text-color-quaternary;
+ }
+}
+
.card-new-merge-request {
.card-header {
padding: 5px 10px;
diff --git a/app/workers/concerns/security_scans_queue.rb b/app/workers/concerns/security_scans_queue.rb
new file mode 100644
index 00000000000..f731317bb37
--- /dev/null
+++ b/app/workers/concerns/security_scans_queue.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+##
+# Concern for setting Sidekiq settings for the various Secure product queues
+#
+module SecurityScansQueue
+ extend ActiveSupport::Concern
+
+ included do
+ queue_namespace :security_scans
+ feature_category :static_application_security_testing
+ end
+end
diff --git a/changelogs/unreleased/10225-detroy-oauth-application-when-secondary-becomes-primary.yml b/changelogs/unreleased/10225-detroy-oauth-application-when-secondary-becomes-primary.yml
new file mode 100644
index 00000000000..59600a31f46
--- /dev/null
+++ b/changelogs/unreleased/10225-detroy-oauth-application-when-secondary-becomes-primary.yml
@@ -0,0 +1,5 @@
+---
+title: Destroy the OAuth application when Geo secondary becomes a primary
+merge_request: 25154
+author: briankabiro
+type: other
diff --git a/changelogs/unreleased/202109.yml b/changelogs/unreleased/202109.yml
new file mode 100644
index 00000000000..29376d0f947
--- /dev/null
+++ b/changelogs/unreleased/202109.yml
@@ -0,0 +1,6 @@
+---
+title: update main javascript file to only apply right sidebar class when an aside
+ is present
+merge_request:
+author: Oregand
+type: fixed
diff --git a/changelogs/unreleased/georgekoltsov-remove-name-path-from-group-ie-yml.yml b/changelogs/unreleased/georgekoltsov-remove-name-path-from-group-ie-yml.yml
new file mode 100644
index 00000000000..f21a91a21b2
--- /dev/null
+++ b/changelogs/unreleased/georgekoltsov-remove-name-path-from-group-ie-yml.yml
@@ -0,0 +1,5 @@
+---
+title: Remove name & path from list of excluded attributes during Group Import
+merge_request: 25342
+author:
+type: fixed
diff --git a/changelogs/unreleased/i18n-groups-audit-events.yml b/changelogs/unreleased/i18n-groups-audit-events.yml
new file mode 100644
index 00000000000..9b8601fc4cf
--- /dev/null
+++ b/changelogs/unreleased/i18n-groups-audit-events.yml
@@ -0,0 +1,5 @@
+---
+title: Internationalize messages for group audit events
+merge_request: 25233
+author: Takuya Noguchi
+type: other
diff --git a/changelogs/unreleased/rk4bir-master-patch-88996.yml b/changelogs/unreleased/rk4bir-master-patch-88996.yml
new file mode 100644
index 00000000000..11e97ec4012
--- /dev/null
+++ b/changelogs/unreleased/rk4bir-master-patch-88996.yml
@@ -0,0 +1,5 @@
+---
+title: Migrate from class .fa-spinner to .spinner in app/assets/javascripts/gfm_auto_complete.js
+merge_request: 25039
+author: rk4bir
+type: changed
diff --git a/db/post_migrate/20200213220159_migrate_store_security_reports_sidekiq_queue.rb b/db/post_migrate/20200213220159_migrate_store_security_reports_sidekiq_queue.rb
new file mode 100644
index 00000000000..5bba4c95328
--- /dev/null
+++ b/db/post_migrate/20200213220159_migrate_store_security_reports_sidekiq_queue.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class MigrateStoreSecurityReportsSidekiqQueue < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ sidekiq_queue_migrate 'pipeline_default:store_security_reports', to: 'security_scans:store_security_reports'
+ end
+
+ def down
+ sidekiq_queue_migrate 'security_scans:store_security_reports', to: 'pipeline_default:store_security_reports'
+ end
+end
diff --git a/db/post_migrate/20200213220211_migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue.rb b/db/post_migrate/20200213220211_migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue.rb
new file mode 100644
index 00000000000..e3ed4c60f21
--- /dev/null
+++ b/db/post_migrate/20200213220211_migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class MigrateSyncSecurityReportsToReportApprovalRulesSidekiqQueue < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ sidekiq_queue_migrate 'pipeline_default:sync_security_reports_to_report_approval_rules',
+ to: 'security_scans:sync_security_reports_to_report_approval_rules'
+ end
+
+ def down
+ sidekiq_queue_migrate 'security_scans:sync_security_reports_to_report_approval_rules',
+ to: 'pipeline_default:sync_security_reports_to_report_approval_rules'
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 8836ace2312..0259c63d3e5 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2020_02_13_204737) do
+ActiveRecord::Schema.define(version: 2020_02_13_220211) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index 073e2010fd2..7f314bc5e31 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -261,7 +261,10 @@ gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
# Configure the gitlab-shell API callback URL. Without this, `git push` will
# fail. This can be your 'front door' GitLab URL or an internal load
# balancer.
-gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
+# Possible values could be: 'http://10.23.101.53', 'https://gitlab.example.com',
+# etc. Please replace GITLAB_SERVER_ADDRESS with proper value and change schema
+# to 'https' in case you use encrypted connection.
+gitlab_rails['internal_api_url'] = 'http://GITLAB_SERVER_ADDRESS'
# Replace PRAEFECT_INTERNAL_TOKEN below with a real secret.
gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN'
@@ -324,6 +327,12 @@ git_data_dirs({
# Replace GITLAB_SHELL_SECRET_TOKEN below with real secret
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN'
+
+# Possible values could be: 'http://10.23.101.53', 'https://gitlab.example.com',
+# etc. Please replace GITLAB_SERVER_ADDRESS with proper value and change schema
+# to 'https' in case you use encrypted connection. For more info please refer
+# to https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab
+external_url "http://<GITLAB_SERVER_ADDRESS>"
```
Replace `GITLAB_SHELL_SECRET_TOKEN` and `PRAEFECT_EXTERNAL_TOKEN`
diff --git a/doc/development/fe_guide/icons.md b/doc/development/fe_guide/icons.md
index d81a520c5f3..36537a22e67 100644
--- a/doc/development/fe_guide/icons.md
+++ b/doc/development/fe_guide/icons.md
@@ -42,25 +42,25 @@ sprite_icon(icon_name, size: nil, css_class: '')
### Usage in Vue
-We have a special Vue component for our sprite icons in `\vue_shared\components\icon.vue`.
+[GitLab UI][gitlab-ui], our components library, provides a component to display sprite icons.
Sample usage :
-```javascript
+```html
<script>
-import Icon from "~/vue_shared/components/icon.vue"
+import { GlIcon } from "@gitlab/ui";
export default {
components: {
- Icon,
+ GlIcon,
},
};
<script>
+
<template>
- <icon
+ <gl-icon
name="issues"
:size="24"
- class="icon-danger"
/>
</template>
```
@@ -95,7 +95,7 @@ To use an SVG illustrations in a template provide the path as a property and dis
Component:
-```js
+```html
<script>
export default {
props: {
@@ -106,6 +106,7 @@ export default {
},
};
<script>
+
<template>
<img :src="svgIllustrationPath" />
</template>
@@ -114,3 +115,4 @@ export default {
[npm]: https://www.npmjs.com/package/@gitlab/svgs
[gitlab-svgs]: https://gitlab.com/gitlab-org/gitlab-svgs
[svg-preview]: https://gitlab-org.gitlab.io/gitlab-svgs
+[gitlab-ui]: https://gitlab-org.gitlab.io/gitlab-ui/
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index 32b4c97cb62..29208c1bf76 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -253,7 +253,6 @@ graph RL;
E[review-build-cng];
F[build-qa-image];
G[review-deploy];
- G2["schedule:review-deploy<br/>(master only)"];
I["karma, jest, webpack-dev-server, static-analysis"];
I2["karma-foss, jest-foss<br/>(EE default refs only)"];
J["compile-assets pull-push-cache<br/>(master only)"];
@@ -297,19 +296,16 @@ subgraph "`post-test` stage"
subgraph "`review-prepare` stage"
E -.-> |needs| C;
- E2["schedule:review-build-cng<br/>(master schedule only)"] -.-> |needs| C;
end
subgraph "`review` stage"
- G --> |happens after| E
- G2 --> |happens after| E2
+ G -.-> |needs| E
end
subgraph "`qa` stage"
Q -.-> |needs| C;
Q -.-> |needs| F;
- QA1["review-qa-smoke, review-qa-all, review-performance, dast"] -.-> |needs and depends on| G;
- QA2["schedule:review-performance<br/>(master only)"] -.-> |needs and depends on| G2;
+ QA1["review-qa-smoke, review-qa-all, review-performance, dast"] -.-> |needs| G;
end
subgraph "`post-qa` stage"
diff --git a/lib/gitlab/import_export/group_import_export.yml b/lib/gitlab/import_export/group_import_export.yml
index 7203c1aa216..d4e0ff12373 100644
--- a/lib/gitlab/import_export/group_import_export.yml
+++ b/lib/gitlab/import_export/group_import_export.yml
@@ -28,8 +28,6 @@ included_attributes:
excluded_attributes:
group:
- :id
- - :name
- - :path
- :owner_id
- :parent_id
- :created_at
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index ecf73002112..187e7f2e7f7 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -7806,6 +7806,9 @@ msgstr ""
msgid "Events"
msgstr ""
+msgid "Events in %{group_name}"
+msgstr ""
+
msgid "Events in %{project_path}"
msgstr ""
@@ -9525,6 +9528,9 @@ msgstr ""
msgid "Group %{group_name} was successfully created."
msgstr ""
+msgid "Group Audit Events"
+msgstr ""
+
msgid "Group CI/CD settings"
msgstr ""
@@ -23123,6 +23129,9 @@ msgstr ""
msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage is %{emphasisStart} unchanged %{emphasisEnd} at %{memoryFrom}MB"
msgstr ""
+msgid "mrWidget|%{prefixToLinkStart}No pipeline%{prefixToLinkEnd} %{addPipelineLinkStart}Add the .gitlab-ci.yml file%{addPipelineLinkEnd} to create one."
+msgstr ""
+
msgid "mrWidget|Added to the merge train by"
msgstr ""
diff --git a/spec/frontend/diffs/components/diff_file_row_spec.js b/spec/frontend/diffs/components/diff_file_row_spec.js
index 3e95d1d55bd..bd5b3afdc05 100644
--- a/spec/frontend/diffs/components/diff_file_row_spec.js
+++ b/spec/frontend/diffs/components/diff_file_row_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import DiffFileRow from '~/diffs/components/diff_file_row.vue';
import FileRow from '~/vue_shared/components/file_row.vue';
+import FileRowStats from '~/diffs/components/file_row_stats.vue';
describe('Diff File Row component', () => {
let wrapper;
@@ -16,10 +17,42 @@ describe('Diff File Row component', () => {
});
it('renders file row component', () => {
- createComponent({
+ const sharedProps = {
level: 4,
file: {},
+ };
+
+ const diffFileRowProps = {
+ hideFileStats: false,
+ };
+
+ createComponent({
+ ...sharedProps,
+ ...diffFileRowProps,
+ });
+
+ expect(wrapper.find(FileRow).props()).toEqual(
+ expect.objectContaining({
+ ...sharedProps,
+ }),
+ );
+ });
+
+ describe('FileRowStats components', () => {
+ it.each`
+ type | hideFileStats | value | desc
+ ${'blob'} | ${false} | ${true} | ${'is shown if file type is blob'}
+ ${'tree'} | ${false} | ${false} | ${'is hidden if file is not blob'}
+ ${'blob'} | ${true} | ${false} | ${'is hidden if hideFileStats is true'}
+ `('$desc', ({ type, value, hideFileStats }) => {
+ createComponent({
+ level: 4,
+ file: {
+ type,
+ },
+ hideFileStats,
+ });
+ expect(wrapper.find(FileRowStats).exists()).toEqual(value);
});
- expect(wrapper.find(FileRow).exists()).toEqual(true);
});
});
diff --git a/spec/frontend/helpers/dom_shims/element_scroll_into_view.js b/spec/frontend/helpers/dom_shims/element_scroll_into_view.js
new file mode 100644
index 00000000000..a7262d04db0
--- /dev/null
+++ b/spec/frontend/helpers/dom_shims/element_scroll_into_view.js
@@ -0,0 +1 @@
+Element.prototype.scrollIntoView = jest.fn();
diff --git a/spec/frontend/helpers/dom_shims/index.js b/spec/frontend/helpers/dom_shims/index.js
index 95a28f8bfbd..63850b62ff7 100644
--- a/spec/frontend/helpers/dom_shims/index.js
+++ b/spec/frontend/helpers/dom_shims/index.js
@@ -1,3 +1,4 @@
+import './element_scroll_into_view';
import './get_client_rects';
import './inner_text';
import './window_scroll_to';
diff --git a/spec/frontend/ide/components/ide_file_row_spec.js b/spec/frontend/ide/components/ide_file_row_spec.js
index 7531bc3e144..c00ad7c8365 100644
--- a/spec/frontend/ide/components/ide_file_row_spec.js
+++ b/spec/frontend/ide/components/ide_file_row_spec.js
@@ -1,25 +1,117 @@
-import { shallowMount } from '@vue/test-utils';
+import { createLocalVue, mount } from '@vue/test-utils';
+import Vuex from 'vuex';
import IdeFileRow from '~/ide/components/ide_file_row.vue';
import FileRow from '~/vue_shared/components/file_row.vue';
+import FileRowExtra from '~/ide/components/file_row_extra.vue';
+import { createStore } from '~/ide/stores';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+const TEST_EXTRA_PROPS = {
+ testattribute: 'abc',
+};
+
+const defaultComponentProps = (type = 'tree') => ({
+ level: 4,
+ file: {
+ type,
+ name: 'js',
+ },
+});
describe('Ide File Row component', () => {
let wrapper;
- const createComponent = (props = {}) => {
- wrapper = shallowMount(IdeFileRow, {
- propsData: { ...props },
+ const createComponent = (props = {}, options = {}) => {
+ wrapper = mount(IdeFileRow, {
+ propsData: {
+ ...defaultComponentProps(),
+ ...props,
+ },
+ store: createStore(),
+ localVue,
+ ...options,
});
};
afterEach(() => {
wrapper.destroy();
+ wrapper = null;
});
- it('renders file row component', () => {
- createComponent({
- level: 4,
- file: {},
+ const findFileRowExtra = () => wrapper.find(FileRowExtra);
+ const findFileRow = () => wrapper.find(FileRow);
+ const hasDropdownOpen = () => findFileRowExtra().props('dropdownOpen');
+
+ it('fileRow component has listeners', () => {
+ const toggleTreeOpen = jest.fn();
+ createComponent(
+ {},
+ {
+ listeners: {
+ toggleTreeOpen,
+ },
+ },
+ );
+
+ findFileRow().vm.$emit('toggleTreeOpen');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(toggleTreeOpen).toHaveBeenCalled();
+ });
+ });
+
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent(TEST_EXTRA_PROPS);
+ });
+
+ it('renders file row component', () => {
+ const fileRow = findFileRow();
+
+ expect(fileRow.props()).toEqual(expect.objectContaining(defaultComponentProps()));
+ expect(fileRow.attributes()).toEqual(expect.objectContaining(TEST_EXTRA_PROPS));
+ });
+
+ it('renders file row extra', () => {
+ const extra = findFileRowExtra();
+
+ expect(extra.exists()).toBe(true);
+ expect(extra.props()).toEqual({
+ file: defaultComponentProps().file,
+ dropdownOpen: false,
+ });
+ });
+ });
+
+ describe('with open dropdown', () => {
+ beforeEach(() => {
+ createComponent();
+
+ findFileRowExtra().vm.$emit('toggle', true);
+
+ return wrapper.vm.$nextTick();
+ });
+
+ it('shows open dropdown', () => {
+ expect(hasDropdownOpen()).toBe(true);
+ });
+
+ it('hides dropdown when mouseleave', () => {
+ findFileRow().vm.$emit('mouseleave');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(hasDropdownOpen()).toEqual(false);
+ });
+ });
+
+ it('hides dropdown on toggle', () => {
+ findFileRowExtra().vm.$emit('toggle', false);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(hasDropdownOpen()).toEqual(false);
+ });
});
- expect(wrapper.find(FileRow).exists()).toEqual(true);
});
});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js
new file mode 100644
index 00000000000..77293a5b187
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js
@@ -0,0 +1,52 @@
+import { mount } from '@vue/test-utils';
+import { GlLink } from '@gitlab/ui';
+import suggestPipelineComponent from '~/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue';
+import MrWidgetIcon from '~/vue_merge_request_widget/components/mr_widget_icon.vue';
+
+describe('MRWidgetHeader', () => {
+ let wrapper;
+ const pipelinePath = '/foo/bar/add/pipeline/path';
+ const iconName = 'status_notfound';
+
+ beforeEach(() => {
+ wrapper = mount(suggestPipelineComponent, {
+ propsData: { pipelinePath },
+ });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('template', () => {
+ it('renders add pipeline file link', () => {
+ const link = wrapper.find(GlLink);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(link.exists()).toBe(true);
+ expect(link.attributes().href).toBe(pipelinePath);
+ });
+ });
+
+ it('renders the expected text', () => {
+ const messageText = /\s*No pipeline\s*Add the .gitlab-ci.yml file\s*to create one./;
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.text()).toMatch(messageText);
+ });
+ });
+
+ it('renders widget icon', () => {
+ const icon = wrapper.find(MrWidgetIcon);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(icon.exists()).toBe(true);
+ expect(icon.props()).toEqual(
+ expect.objectContaining({
+ name: iconName,
+ }),
+ );
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js
index 4db6b421200..2eaba46cdce 100644
--- a/spec/javascripts/vue_mr_widget/mock_data.js
+++ b/spec/javascripts/vue_mr_widget/mock_data.js
@@ -16,6 +16,7 @@ export default {
updated_at: '2017-04-07T15:39:25.852Z',
time_estimate: 0,
total_time_spent: 0,
+ human_access: 'Maintainer',
human_time_estimate: null,
human_total_time_spent: null,
in_progress_merge_commit_sha: null,
@@ -34,6 +35,7 @@ export default {
target_branch: 'master',
target_project_id: 19,
target_project_full_path: '/group2/project2',
+ merge_request_add_ci_config_path: '/group2/project2/new/pipeline',
metrics: {
merged_by: {
name: 'Administrator',
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index 296be43f793..35c1495be58 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -94,6 +94,61 @@ describe('mrWidgetOptions', () => {
});
});
+ describe('shouldSuggestPipelines', () => {
+ describe('given suggestPipeline feature flag is enabled', () => {
+ beforeEach(() => {
+ gon.features = { suggestPipeline: true };
+ vm = mountComponent(MrWidgetOptions, {
+ mrData: { ...mockData },
+ });
+ });
+
+ afterEach(() => {
+ gon.features = {};
+ });
+
+ it('should suggest pipelines when none exist', () => {
+ vm.mr.mergeRequestAddCiConfigPath = 'some/path';
+ vm.mr.hasCI = false;
+
+ expect(vm.shouldSuggestPipelines).toBeTruthy();
+ });
+
+ it('should not suggest pipelines when they exist', () => {
+ vm.mr.mergeRequestAddCiConfigPath = null;
+ vm.mr.hasCI = false;
+
+ expect(vm.shouldSuggestPipelines).toBeFalsy();
+ });
+
+ it('should not suggest pipelines hasCI is true', () => {
+ vm.mr.mergeRequestAddCiConfigPath = 'some/path';
+ vm.mr.hasCI = true;
+
+ expect(vm.shouldSuggestPipelines).toBeFalsy();
+ });
+ });
+
+ describe('given suggestPipeline feature flag is not enabled', () => {
+ beforeEach(() => {
+ gon.features = { suggestPipeline: false };
+ vm = mountComponent(MrWidgetOptions, {
+ mrData: { ...mockData },
+ });
+ });
+
+ afterEach(() => {
+ gon.features = {};
+ });
+
+ it('should not suggest pipelines', () => {
+ vm.mr.mergeRequestAddCiConfigPath = null;
+
+ expect(vm.shouldSuggestPipelines).toBeFalsy();
+ });
+ });
+ });
+
describe('shouldRenderRelatedLinks', () => {
it('should return false for the initial data', () => {
expect(vm.shouldRenderRelatedLinks).toBeFalsy();
diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
index e2cd0f084fd..272f6cad5fc 100644
--- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
+++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -83,4 +83,18 @@ describe('MergeRequestStore', () => {
});
});
});
+
+ describe('setPaths', () => {
+ it('should set the add ci config path', () => {
+ store.setData({ ...mockData });
+
+ expect(store.mergeRequestAddCiConfigPath).toEqual('/group2/project2/new/pipeline');
+ });
+
+ it('should set humanAccess=Maintainer when user has that role', () => {
+ store.setData({ ...mockData });
+
+ expect(store.humanAccess).toEqual('Maintainer');
+ });
+ });
});
diff --git a/spec/javascripts/vue_shared/components/file_row_spec.js b/spec/javascripts/vue_shared/components/file_row_spec.js
index 071a09f8b93..11fcb9b89c1 100644
--- a/spec/javascripts/vue_shared/components/file_row_spec.js
+++ b/spec/javascripts/vue_shared/components/file_row_spec.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import { file } from 'spec/ide/helpers';
import FileRow from '~/vue_shared/components/file_row.vue';
-import FileRowExtra from '~/ide/components/file_row_extra.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
describe('File row component', () => {
@@ -17,9 +16,6 @@ describe('File row component', () => {
vm.$destroy();
});
- const findNewDropdown = () => vm.$el.querySelector('.ide-new-btn .dropdown');
- const findNewDropdownButton = () => vm.$el.querySelector('.ide-new-btn .dropdown button');
-
it('renders name', () => {
createComponent({
file: file('t4'),
@@ -88,59 +84,4 @@ describe('File row component', () => {
expect(vm.$el.classList).toContain('js-file-row-header');
});
-
- describe('new dropdown', () => {
- beforeEach(() => {
- createComponent({
- file: file('t5'),
- level: 1,
- extraComponent: FileRowExtra,
- });
- });
-
- it('renders in extra component', () => {
- expect(findNewDropdown()).not.toBe(null);
- });
-
- it('is hidden at start', () => {
- expect(findNewDropdown()).not.toHaveClass('show');
- });
-
- it('is opened when button is clicked', done => {
- expect(vm.dropdownOpen).toBe(false);
- findNewDropdownButton().dispatchEvent(new Event('click'));
-
- vm.$nextTick()
- .then(() => {
- expect(vm.dropdownOpen).toBe(true);
- expect(findNewDropdown()).toHaveClass('show');
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('when opened', () => {
- beforeEach(() => {
- vm.dropdownOpen = true;
- });
-
- it('stays open when button triggers mouseout', () => {
- findNewDropdownButton().dispatchEvent(new Event('mouseout'));
-
- expect(vm.dropdownOpen).toBe(true);
- });
-
- it('stays open when button triggers mouseleave', () => {
- findNewDropdownButton().dispatchEvent(new Event('mouseleave'));
-
- expect(vm.dropdownOpen).toBe(true);
- });
-
- it('closes when row triggers mouseleave', () => {
- vm.$el.dispatchEvent(new Event('mouseleave'));
-
- expect(vm.dropdownOpen).toBe(false);
- });
- });
- });
});
diff --git a/spec/lib/gitlab/import_export/group_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/group_tree_restorer_spec.rb
index d6bda7507c6..b2c8398d358 100644
--- a/spec/lib/gitlab/import_export/group_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/group_tree_restorer_spec.rb
@@ -82,8 +82,6 @@ describe Gitlab::ImportExport::GroupTreeRestorer do
shared_examples 'excluded attributes' do
excluded_attributes = %w[
id
- name
- path
owner_id
parent_id
created_at
diff --git a/spec/lib/gitlab/import_export/group_tree_saver_spec.rb b/spec/lib/gitlab/import_export/group_tree_saver_spec.rb
index d5ab8ca1e8d..7f49c7af8fa 100644
--- a/spec/lib/gitlab/import_export/group_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/group_tree_saver_spec.rb
@@ -160,8 +160,6 @@ describe Gitlab::ImportExport::GroupTreeSaver do
shared_examples 'excluded attributes' do
excluded_attributes = %w[
id
- name
- path
owner_id
parent_id
created_at
diff --git a/spec/migrations/migrate_store_security_reports_sidekiq_queue_spec.rb b/spec/migrations/migrate_store_security_reports_sidekiq_queue_spec.rb
new file mode 100644
index 00000000000..ddffa036af1
--- /dev/null
+++ b/spec/migrations/migrate_store_security_reports_sidekiq_queue_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200213220159_migrate_store_security_reports_sidekiq_queue.rb')
+
+describe MigrateStoreSecurityReportsSidekiqQueue, :redis do
+ include Gitlab::Database::MigrationHelpers
+ include StubWorker
+
+ context 'when there are jobs in the queue' do
+ it 'migrates queue when migrating up' do
+ Sidekiq::Testing.disable! do
+ stub_worker(queue: 'pipeline_default:store_security_reports').perform_async(1, 5)
+
+ described_class.new.up
+
+ expect(sidekiq_queue_length('pipeline_default:store_security_reports')).to eq 0
+ expect(sidekiq_queue_length('security_scans:store_security_reports')).to eq 1
+ end
+ end
+
+ it 'migrates queue when migrating down' do
+ Sidekiq::Testing.disable! do
+ stub_worker(queue: 'security_scans:store_security_reports').perform_async(1, 5)
+
+ described_class.new.down
+
+ expect(sidekiq_queue_length('pipeline_default:store_security_reports')).to eq 1
+ expect(sidekiq_queue_length('security_scans:store_security_reports')).to eq 0
+ end
+ end
+ end
+end
diff --git a/spec/migrations/migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue_spec.rb b/spec/migrations/migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue_spec.rb
new file mode 100644
index 00000000000..6dfaff06ddb
--- /dev/null
+++ b/spec/migrations/migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20200213220211_migrate_sync_security_reports_to_report_approval_rules_sidekiq_queue.rb')
+
+describe MigrateSyncSecurityReportsToReportApprovalRulesSidekiqQueue, :redis do
+ include Gitlab::Database::MigrationHelpers
+ include StubWorker
+
+ context 'when there are jobs in the queue' do
+ it 'migrates queue when migrating up' do
+ Sidekiq::Testing.disable! do
+ stub_worker(queue: 'pipeline_default:sync_security_reports_to_report_approval_rules').perform_async(1, 5)
+
+ described_class.new.up
+
+ expect(sidekiq_queue_length('pipeline_default:sync_security_reports_to_report_approval_rules')).to eq 0
+ expect(sidekiq_queue_length('security_scans:sync_security_reports_to_report_approval_rules')).to eq 1
+ end
+ end
+
+ it 'migrates queue when migrating down' do
+ Sidekiq::Testing.disable! do
+ stub_worker(queue: 'security_scans:sync_security_reports_to_report_approval_rules').perform_async(1, 5)
+
+ described_class.new.down
+
+ expect(sidekiq_queue_length('pipeline_default:sync_security_reports_to_report_approval_rules')).to eq 1
+ expect(sidekiq_queue_length('security_scans:sync_security_reports_to_report_approval_rules')).to eq 0
+ end
+ end
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 36ddb624cba..cd84bf54e8f 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -303,6 +303,20 @@ describe User, :do_not_mock_admin_mode do
end
end
+ context 'bad regex' do
+ before do
+ allow_any_instance_of(ApplicationSetting).to receive(:domain_whitelist).and_return(['([a-zA-Z0-9]+)+\.com'])
+ end
+
+ it 'does not hang on evil input' do
+ user = build(:user, email: 'user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!.com')
+
+ expect do
+ Timeout.timeout(2.seconds) { user.valid? }
+ end.not_to raise_error
+ end
+ end
+
context 'when a signup domain is whitelisted and subdomains are allowed' do
before do
allow_any_instance_of(ApplicationSetting).to receive(:domain_whitelist).and_return(['example.com', '*.example.com'])
@@ -356,6 +370,20 @@ describe User, :do_not_mock_admin_mode do
allow_any_instance_of(ApplicationSetting).to receive(:domain_blacklist).and_return(['example.com'])
end
+ context 'bad regex' do
+ before do
+ allow_any_instance_of(ApplicationSetting).to receive(:domain_blacklist).and_return(['([a-zA-Z0-9]+)+\.com'])
+ end
+
+ it 'does not hang on evil input' do
+ user = build(:user, email: 'user@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!.com')
+
+ expect do
+ Timeout.timeout(2.seconds) { user.valid? }
+ end.not_to raise_error
+ end
+ end
+
context 'when a signup domain is blacklisted' do
it 'accepts info@test.com' do
user = build(:user, email: 'info@test.com')
diff --git a/spec/requests/api/access_requests_spec.rb b/spec/requests/api/access_requests_spec.rb
index 3bfca00776f..17f4cde5b8c 100644
--- a/spec/requests/api/access_requests_spec.rb
+++ b/spec/requests/api/access_requests_spec.rb
@@ -3,12 +3,12 @@
require 'spec_helper'
describe API::AccessRequests do
- set(:maintainer) { create(:user) }
- set(:developer) { create(:user) }
- set(:access_requester) { create(:user) }
- set(:stranger) { create(:user) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:access_requester) { create(:user) }
+ let_it_be(:stranger) { create(:user) }
- set(:project) do
+ let_it_be(:project) do
create(:project, :public, creator_id: maintainer.id, namespace: maintainer.namespace) do |project|
project.add_developer(developer)
project.add_maintainer(maintainer)
@@ -16,7 +16,7 @@ describe API::AccessRequests do
end
end
- set(:group) do
+ let_it_be(:group) do
create(:group, :public) do |group|
group.add_developer(developer)
group.add_owner(maintainer)
diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb
index 19a34314bb8..4a830f2b449 100644
--- a/spec/requests/api/award_emoji_spec.rb
+++ b/spec/requests/api/award_emoji_spec.rb
@@ -3,14 +3,13 @@
require 'spec_helper'
describe API::AwardEmoji do
- set(:user) { create(:user) }
- set(:project) { create(:project) }
- set(:issue) { create(:issue, project: project) }
- set(:award_emoji) { create(:award_emoji, awardable: issue, user: user) }
- let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let!(:downvote) { create(:award_emoji, :downvote, awardable: merge_request, user: user) }
-
- set(:note) { create(:note, project: project, noteable: issue) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:award_emoji) { create(:award_emoji, awardable: issue, user: user) }
+ let_it_be(:note) { create(:note, project: project, noteable: issue) }
+ let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+ let!(:downvote) { create(:award_emoji, :downvote, awardable: merge_request, user: user) }
before do
project.add_maintainer(user)
diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb
index 510ef9d7d0a..f53bfedb49a 100644
--- a/spec/requests/api/boards_spec.rb
+++ b/spec/requests/api/boards_spec.rb
@@ -3,35 +3,35 @@
require 'spec_helper'
describe API::Boards do
- set(:user) { create(:user) }
- set(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:admin) { create(:user, :admin) }
- set(:board_parent) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:admin) { create(:user, :admin) }
+ let_it_be(:board_parent, reload: true) { create(:project, :public, creator_id: user.id, namespace: user.namespace ) }
- set(:dev_label) do
+ let_it_be(:dev_label) do
create(:label, title: 'Development', color: '#FFAABB', project: board_parent)
end
- set(:test_label) do
+ let_it_be(:test_label) do
create(:label, title: 'Testing', color: '#FFAACC', project: board_parent)
end
- set(:ux_label) do
+ let_it_be(:ux_label) do
create(:label, title: 'UX', color: '#FF0000', project: board_parent)
end
- set(:dev_list) do
+ let_it_be(:dev_list) do
create(:list, label: dev_label, position: 1)
end
- set(:test_list) do
+ let_it_be(:test_list) do
create(:list, label: test_label, position: 2)
end
- set(:milestone) { create(:milestone, project: board_parent) }
- set(:board_label) { create(:label, project: board_parent) }
- set(:board) { create(:board, project: board_parent, lists: [dev_list, test_list]) }
+ let_it_be(:milestone) { create(:milestone, project: board_parent) }
+ let_it_be(:board_label) { create(:label, project: board_parent) }
+ let_it_be(:board) { create(:board, project: board_parent, lists: [dev_list, test_list]) }
it_behaves_like 'group and project boards', "/projects/:id/boards"
@@ -66,11 +66,11 @@ describe API::Boards do
end
describe "POST /groups/:id/boards/lists" do
- set(:group) { create(:group) }
- set(:board_parent) { create(:group, parent: group ) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:board_parent) { create(:group, parent: group ) }
let(:url) { "/groups/#{board_parent.id}/boards/#{board.id}/lists" }
- set(:board) { create(:board, group: board_parent) }
+ let_it_be(:board) { create(:board, group: board_parent) }
it 'creates a new board list for ancestor group labels' do
group.add_developer(user)
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index d4deb049ea7..046ec40f218 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe API::Branches do
- set(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
let(:project) { create(:project, :repository, creator: user, path: 'my.project') }
let(:guest) { create(:user).tap { |u| project.add_guest(u) } }
let(:branch_name) { 'feature' }
diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb
index 163479226e3..7d71b83e147 100644
--- a/spec/requests/api/broadcast_messages_spec.rb
+++ b/spec/requests/api/broadcast_messages_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe API::BroadcastMessages do
- set(:user) { create(:user) }
- set(:admin) { create(:admin) }
- set(:message) { create(:broadcast_message) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:message) { create(:broadcast_message) }
describe 'GET /broadcast_messages' do
it 'returns an Array of BroadcastMessages' do
diff --git a/spec/requests/api/features_spec.rb b/spec/requests/api/features_spec.rb
index dfd14f89dbf..d7b0bf881a6 100644
--- a/spec/requests/api/features_spec.rb
+++ b/spec/requests/api/features_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
describe API::Features do
- set(:user) { create(:user) }
- set(:admin) { create(:admin) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
before do
Flipper.unregister_groups
diff --git a/spec/requests/api/graphql/current_user_query_spec.rb b/spec/requests/api/graphql/current_user_query_spec.rb
index 9db638ea59e..2b38b8e98ab 100644
--- a/spec/requests/api/graphql/current_user_query_spec.rb
+++ b/spec/requests/api/graphql/current_user_query_spec.rb
@@ -16,7 +16,7 @@ describe 'getting project information' do
end
context 'when there is a current_user' do
- set(:current_user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
it_behaves_like 'a working graphql query'
diff --git a/spec/requests/api/graphql/gitlab_schema_spec.rb b/spec/requests/api/graphql/gitlab_schema_spec.rb
index e10f0732852..8d020cd3a4e 100644
--- a/spec/requests/api/graphql/gitlab_schema_spec.rb
+++ b/spec/requests/api/graphql/gitlab_schema_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe 'GitlabSchema configurations' do
include GraphqlHelpers
- set(:project) { create(:project) }
+ let_it_be(:project) { create(:project) }
shared_examples 'imposing query limits' do
describe 'timeouts' do
diff --git a/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
index b24981873c8..3fdeccc84f9 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe 'Adding an AwardEmoji' do
include GraphqlHelpers
- set(:current_user) { create(:user) }
- set(:project) { create(:project) }
- set(:awardable) { create(:note, project: project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:awardable) { create(:note, project: project) }
let(:emoji_name) { 'thumbsup' }
let(:mutation) do
variables = {
diff --git a/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
index 5e2c0e668a5..bc796b34db4 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe 'Toggling an AwardEmoji' do
include GraphqlHelpers
- set(:current_user) { create(:user) }
- set(:project) { create(:project) }
- set(:awardable) { create(:note, project: project) }
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:awardable) { create(:note, project: project) }
let(:emoji_name) { 'thumbsup' }
let(:mutation) do
variables = {
diff --git a/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb
index b04fcb9aece..4c535434faa 100644
--- a/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/diff_note_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe 'Adding a DiffNote' do
include GraphqlHelpers
- set(:current_user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
let(:noteable) { create(:merge_request, source_project: project, target_project: project) }
let(:project) { create(:project, :repository) }
let(:diff_refs) { noteable.diff_refs }
diff --git a/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb
index 3ba6c689024..0bba3e79434 100644
--- a/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/image_diff_note_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe 'Adding an image DiffNote' do
include GraphqlHelpers
- set(:current_user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
let(:noteable) { create(:merge_request, source_project: project, target_project: project) }
let(:project) { create(:project, :repository) }
let(:diff_refs) { noteable.diff_refs }
diff --git a/spec/requests/api/graphql/mutations/notes/create/note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
index 14aaa430ac9..9a78d44245e 100644
--- a/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe 'Adding a Note' do
include GraphqlHelpers
- set(:current_user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
let(:noteable) { create(:merge_request, source_project: project, target_project: project) }
let(:project) { create(:project) }
let(:discussion) { nil }
diff --git a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
index 566d0fe636a..188bfa8b924 100644
--- a/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
+++ b/spec/requests/api/graphql/tasks/task_completion_status_spec.rb
@@ -9,8 +9,8 @@ describe 'getting task completion status information' do
DESCRIPTION_1_DONE = '- [x] task 1\n- [ ] task 2'
DESCRIPTION_2_DONE = '- [x] task 1\n- [x] task 2'
- set(:user1) { create(:user) }
- set(:project) { create(:project, :repository, :public) }
+ let_it_be(:user1) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, :public) }
let(:fields) do
<<~QUERY
diff --git a/spec/requests/api/group_boards_spec.rb b/spec/requests/api/group_boards_spec.rb
index 232ec9aca32..d2d10f357fe 100644
--- a/spec/requests/api/group_boards_spec.rb
+++ b/spec/requests/api/group_boards_spec.rb
@@ -3,42 +3,42 @@
require 'spec_helper'
describe API::GroupBoards do
- set(:user) { create(:user) }
- set(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:admin) { create(:user, :admin) }
- set(:board_parent) { create(:group, :public) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:admin) { create(:user, :admin) }
+ let_it_be(:board_parent) { create(:group, :public) }
before do
board_parent.add_owner(user)
end
- set(:project) { create(:project, :public, namespace: board_parent ) }
+ let_it_be(:project) { create(:project, :public, namespace: board_parent ) }
- set(:dev_label) do
+ let_it_be(:dev_label) do
create(:group_label, title: 'Development', color: '#FFAABB', group: board_parent)
end
- set(:test_label) do
+ let_it_be(:test_label) do
create(:group_label, title: 'Testing', color: '#FFAACC', group: board_parent)
end
- set(:ux_label) do
+ let_it_be(:ux_label) do
create(:group_label, title: 'UX', color: '#FF0000', group: board_parent)
end
- set(:dev_list) do
+ let_it_be(:dev_list) do
create(:list, label: dev_label, position: 1)
end
- set(:test_list) do
+ let_it_be(:test_list) do
create(:list, label: test_label, position: 2)
end
- set(:milestone) { create(:milestone, group: board_parent) }
- set(:board_label) { create(:group_label, group: board_parent) }
+ let_it_be(:milestone) { create(:milestone, group: board_parent) }
+ let_it_be(:board_label) { create(:group_label, group: board_parent) }
- set(:board) { create(:board, group: board_parent, lists: [dev_list, test_list]) }
+ let_it_be(:board) { create(:board, group: board_parent, lists: [dev_list, test_list]) }
it_behaves_like 'group and project boards', "/groups/:id/boards", false
diff --git a/spec/requests/api/issues/get_group_issues_spec.rb b/spec/requests/api/issues/get_group_issues_spec.rb
index f2a1b335589..59e89a7f452 100644
--- a/spec/requests/api/issues/get_group_issues_spec.rb
+++ b/spec/requests/api/issues/get_group_issues_spec.rb
@@ -3,18 +3,16 @@
require 'spec_helper'
describe API::Issues do
- set(:user) { create(:user) }
- let(:user2) { create(:user) }
- let(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:author) { create(:author) }
- set(:assignee) { create(:assignee) }
- let(:admin) { create(:user, :admin) }
-
- let(:issue_title) { 'foo' }
- let(:issue_description) { 'closed' }
-
- let(:no_milestone_title) { 'None' }
+ let_it_be(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:author) { create(:author) }
+ let_it_be(:assignee) { create(:assignee) }
+ let(:admin) { create(:user, :admin) }
+ let(:issue_title) { 'foo' }
+ let(:issue_description) { 'closed' }
+ let(:no_milestone_title) { 'None' }
let(:any_milestone_title) { 'Any' }
before do
diff --git a/spec/requests/api/issues/get_project_issues_spec.rb b/spec/requests/api/issues/get_project_issues_spec.rb
index e031cc9b0c6..edd4ae85729 100644
--- a/spec/requests/api/issues/get_project_issues_spec.rb
+++ b/spec/requests/api/issues/get_project_issues_spec.rb
@@ -3,18 +3,18 @@
require 'spec_helper'
describe API::Issues do
- set(:user) { create(:user) }
- set(:project) { create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace) }
- set(:private_mrs_project) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace) }
+ let_it_be(:private_mrs_project) do
create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace, merge_requests_access_level: ProjectFeature::PRIVATE)
end
- let(:user2) { create(:user) }
- let(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:author) { create(:author) }
- set(:assignee) { create(:assignee) }
- let(:admin) { create(:user, :admin) }
+ let(:user2) { create(:user) }
+ let(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:author) { create(:author) }
+ let_it_be(:assignee) { create(:assignee) }
+ let(:admin) { create(:user, :admin) }
let(:issue_title) { 'foo' }
let(:issue_description) { 'closed' }
let!(:closed_issue) do
@@ -48,12 +48,12 @@ describe API::Issues do
title: issue_title,
description: issue_description
end
- set(:label) do
+ let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
- set(:empty_milestone) do
+ let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
diff --git a/spec/requests/api/issues/issues_spec.rb b/spec/requests/api/issues/issues_spec.rb
index 19422d4ca39..45754736a2c 100644
--- a/spec/requests/api/issues/issues_spec.rb
+++ b/spec/requests/api/issues/issues_spec.rb
@@ -3,18 +3,18 @@
require 'spec_helper'
describe API::Issues do
- set(:user) { create(:user) }
- set(:project) { create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace) }
- set(:private_mrs_project) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace) }
+ let_it_be(:private_mrs_project) do
create(:project, :public, :repository, creator_id: user.id, namespace: user.namespace, merge_requests_access_level: ProjectFeature::PRIVATE)
end
- let(:user2) { create(:user) }
- let(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:author) { create(:author) }
- set(:assignee) { create(:assignee) }
- let(:admin) { create(:user, :admin) }
+ let(:user2) { create(:user) }
+ let(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:author) { create(:author) }
+ let_it_be(:assignee) { create(:assignee) }
+ let(:admin) { create(:user, :admin) }
let(:issue_title) { 'foo' }
let(:issue_description) { 'closed' }
let!(:closed_issue) do
@@ -48,12 +48,12 @@ describe API::Issues do
title: issue_title,
description: issue_description
end
- set(:label) do
+ let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
- set(:empty_milestone) do
+ let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
diff --git a/spec/requests/api/issues/post_projects_issues_spec.rb b/spec/requests/api/issues/post_projects_issues_spec.rb
index 341d0e8ae6b..782eda875af 100644
--- a/spec/requests/api/issues/post_projects_issues_spec.rb
+++ b/spec/requests/api/issues/post_projects_issues_spec.rb
@@ -3,17 +3,17 @@
require 'spec_helper'
describe API::Issues do
- set(:user) { create(:user) }
- set(:project) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) do
create(:project, :public, creator_id: user.id, namespace: user.namespace)
end
- let(:user2) { create(:user) }
- let(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:author) { create(:author) }
- set(:assignee) { create(:assignee) }
- let(:admin) { create(:user, :admin) }
+ let(:user2) { create(:user) }
+ let(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:author) { create(:author) }
+ let_it_be(:assignee) { create(:assignee) }
+ let(:admin) { create(:user, :admin) }
let(:issue_title) { 'foo' }
let(:issue_description) { 'closed' }
let!(:closed_issue) do
@@ -47,12 +47,12 @@ describe API::Issues do
title: issue_title,
description: issue_description
end
- set(:label) do
+ let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
- set(:empty_milestone) do
+ let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
diff --git a/spec/requests/api/issues/put_projects_issues_spec.rb b/spec/requests/api/issues/put_projects_issues_spec.rb
index 8e78aca59b2..709520b6bdf 100644
--- a/spec/requests/api/issues/put_projects_issues_spec.rb
+++ b/spec/requests/api/issues/put_projects_issues_spec.rb
@@ -3,17 +3,17 @@
require 'spec_helper'
describe API::Issues do
- set(:user) { create(:user) }
- set(:project) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) do
create(:project, :public, creator_id: user.id, namespace: user.namespace)
end
- let(:user2) { create(:user) }
- let(:non_member) { create(:user) }
- set(:guest) { create(:user) }
- set(:author) { create(:author) }
- set(:assignee) { create(:assignee) }
- let(:admin) { create(:user, :admin) }
+ let(:user2) { create(:user) }
+ let(:non_member) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:author) { create(:author) }
+ let_it_be(:assignee) { create(:assignee) }
+ let(:admin) { create(:user, :admin) }
let(:issue_title) { 'foo' }
let(:issue_description) { 'closed' }
let!(:closed_issue) do
@@ -47,12 +47,12 @@ describe API::Issues do
title: issue_title,
description: issue_description
end
- set(:label) do
+ let_it_be(:label) do
create(:label, title: 'label', color: '#FFAABB', project: project)
end
let!(:label_link) { create(:label_link, label: label, target: issue) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
- set(:empty_milestone) do
+ let_it_be(:empty_milestone) do
create(:milestone, title: '2.0.0', project: project)
end
let!(:note) { create(:note_on_issue, author: user, project: project, noteable: issue) }
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 1e1099ebcb6..652be20f1e4 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -31,11 +31,11 @@ describe API::Jobs do
end
end
- set(:project) do
+ let_it_be(:project, reload: true) do
create(:project, :repository, public_builds: false)
end
- set(:pipeline) do
+ let_it_be(:pipeline, reload: true) do
create(:ci_empty_pipeline, project: project,
sha: project.commit.id,
ref: project.default_branch)
diff --git a/spec/requests/api/markdown_spec.rb b/spec/requests/api/markdown_spec.rb
index 99263f2fc1e..8a1e1b05c9a 100644
--- a/spec/requests/api/markdown_spec.rb
+++ b/spec/requests/api/markdown_spec.rb
@@ -52,8 +52,8 @@ describe API::Markdown do
end
context "when arguments are valid" do
- set(:project) { create(:project) }
- set(:issue) { create(:issue, project: project) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:issue) { create(:issue, project: project) }
let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
context "when not using gfm" do
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 58190beb38a..862afd11b86 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -6,9 +6,9 @@ describe API::MergeRequests do
include ProjectForksHelper
let(:base_time) { Time.now }
- set(:user) { create(:user) }
- set(:user2) { create(:user) }
- set(:admin) { create(:user, :admin) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+ let_it_be(:admin) { create(:user, :admin) }
let(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) }
let(:milestone) { create(:milestone, title: '1.0.0', project: project) }
let(:milestone1) { create(:milestone, title: '0.9', project: project) }
diff --git a/spec/requests/api/pages/internal_access_spec.rb b/spec/requests/api/pages/internal_access_spec.rb
index 821a210a414..91139b987df 100644
--- a/spec/requests/api/pages/internal_access_spec.rb
+++ b/spec/requests/api/pages/internal_access_spec.rb
@@ -6,16 +6,15 @@ describe "Internal Project Pages Access" do
using RSpec::Parameterized::TableSyntax
include AccessMatchers
- set(:group) { create(:group) }
- set(:project) { create(:project, :internal, pages_access_level: ProjectFeature::ENABLED, namespace: group) }
-
- set(:admin) { create(:admin) }
- set(:owner) { create(:user) }
- set(:master) { create(:user) }
- set(:developer) { create(:user) }
- set(:reporter) { create(:user) }
- set(:guest) { create(:user) }
- set(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project, reload: true) { create(:project, :internal, pages_access_level: ProjectFeature::ENABLED, namespace: group) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:master) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:user) { create(:user) }
before do
allow(Gitlab.config.pages).to receive(:access_control).and_return(true)
diff --git a/spec/requests/api/pages/private_access_spec.rb b/spec/requests/api/pages/private_access_spec.rb
index ec84762b05a..7c592ccfd43 100644
--- a/spec/requests/api/pages/private_access_spec.rb
+++ b/spec/requests/api/pages/private_access_spec.rb
@@ -6,16 +6,15 @@ describe "Private Project Pages Access" do
using RSpec::Parameterized::TableSyntax
include AccessMatchers
- set(:group) { create(:group) }
- set(:project) { create(:project, :private, pages_access_level: ProjectFeature::ENABLED, namespace: group) }
-
- set(:admin) { create(:admin) }
- set(:owner) { create(:user) }
- set(:master) { create(:user) }
- set(:developer) { create(:user) }
- set(:reporter) { create(:user) }
- set(:guest) { create(:user) }
- set(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project, reload: true) { create(:project, :private, pages_access_level: ProjectFeature::ENABLED, namespace: group) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:master) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:user) { create(:user) }
before do
allow(Gitlab.config.pages).to receive(:access_control).and_return(true)
diff --git a/spec/requests/api/pages/public_access_spec.rb b/spec/requests/api/pages/public_access_spec.rb
index 67b8cfb8fbc..f2fe64434c6 100644
--- a/spec/requests/api/pages/public_access_spec.rb
+++ b/spec/requests/api/pages/public_access_spec.rb
@@ -6,16 +6,15 @@ describe "Public Project Pages Access" do
using RSpec::Parameterized::TableSyntax
include AccessMatchers
- set(:group) { create(:group) }
- set(:project) { create(:project, :public, pages_access_level: ProjectFeature::ENABLED, namespace: group) }
-
- set(:admin) { create(:admin) }
- set(:owner) { create(:user) }
- set(:master) { create(:user) }
- set(:developer) { create(:user) }
- set(:reporter) { create(:user) }
- set(:guest) { create(:user) }
- set(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project, reload: true) { create(:project, :public, pages_access_level: ProjectFeature::ENABLED, namespace: group) }
+ let_it_be(:admin) { create(:admin) }
+ let_it_be(:owner) { create(:user) }
+ let_it_be(:master) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:user) { create(:user) }
before do
allow(Gitlab.config.pages).to receive(:access_control).and_return(true)
diff --git a/spec/requests/api/pipeline_schedules_spec.rb b/spec/requests/api/pipeline_schedules_spec.rb
index 42fc97729bd..fdb9508ed08 100644
--- a/spec/requests/api/pipeline_schedules_spec.rb
+++ b/spec/requests/api/pipeline_schedules_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe API::PipelineSchedules do
- set(:developer) { create(:user) }
- set(:user) { create(:user) }
- set(:project) { create(:project, :repository, public_builds: false) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, public_builds: false) }
before do
project.add_developer(developer)
@@ -375,7 +375,7 @@ describe API::PipelineSchedules do
describe 'POST /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables' do
let(:params) { attributes_for(:ci_pipeline_schedule_variable) }
- set(:pipeline_schedule) do
+ let_it_be(:pipeline_schedule) do
create(:ci_pipeline_schedule, project: project, owner: developer)
end
@@ -432,7 +432,7 @@ describe API::PipelineSchedules do
end
describe 'PUT /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do
- set(:pipeline_schedule) do
+ let_it_be(:pipeline_schedule) do
create(:ci_pipeline_schedule, project: project, owner: developer)
end
@@ -472,7 +472,7 @@ describe API::PipelineSchedules do
describe 'DELETE /projects/:id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do
let(:maintainer) { create(:user) }
- set(:pipeline_schedule) do
+ let_it_be(:pipeline_schedule) do
create(:ci_pipeline_schedule, project: project, owner: developer)
end
diff --git a/spec/requests/api/project_container_repositories_spec.rb b/spec/requests/api/project_container_repositories_spec.rb
index 7cec0867b32..98b3416a2bc 100644
--- a/spec/requests/api/project_container_repositories_spec.rb
+++ b/spec/requests/api/project_container_repositories_spec.rb
@@ -5,12 +5,11 @@ require 'spec_helper'
describe API::ProjectContainerRepositories do
include ExclusiveLeaseHelpers
- set(:project) { create(:project, :private) }
- set(:maintainer) { create(:user) }
- set(:developer) { create(:user) }
- set(:reporter) { create(:user) }
- set(:guest) { create(:user) }
-
+ let_it_be(:project) { create(:project, :private) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:reporter) { create(:user) }
+ let_it_be(:guest) { create(:user) }
let(:root_repository) { create(:container_repository, :root, project: project) }
let(:test_repository) { create(:container_repository, project: project) }
diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb
index 37f2cc85a50..98214a8c471 100644
--- a/spec/requests/api/project_export_spec.rb
+++ b/spec/requests/api/project_export_spec.rb
@@ -3,13 +3,13 @@
require 'spec_helper'
describe API::ProjectExport, :clean_gitlab_redis_cache do
- set(:project) { create(:project) }
- set(:project_none) { create(:project) }
- set(:project_started) { create(:project) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:project_none) { create(:project) }
+ let_it_be(:project_started) { create(:project) }
let(:project_finished) { create(:project, :with_export) }
let(:project_after_export) { create(:project, :with_export) }
- set(:user) { create(:user) }
- set(:admin) { create(:admin) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
let(:path) { "/projects/#{project.id}/export" }
let(:path_none) { "/projects/#{project_none.id}/export" }
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index ccbfe040fca..2c6a13efc12 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe API::ProjectSnippets do
- set(:project) { create(:project, :public) }
- set(:user) { create(:user) }
- set(:admin) { create(:admin) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:admin) { create(:admin) }
describe "GET /projects/:project_id/snippets/:id/user_agent_detail" do
let(:snippet) { create(:project_snippet, :public, project: project) }
diff --git a/spec/requests/api/resource_label_events_spec.rb b/spec/requests/api/resource_label_events_spec.rb
index 8bac378787c..7619399458a 100644
--- a/spec/requests/api/resource_label_events_spec.rb
+++ b/spec/requests/api/resource_label_events_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
describe API::ResourceLabelEvents do
- set(:user) { create(:user) }
- set(:project) { create(:project, :public, namespace: user.namespace) }
- set(:label) { create(:label, project: project) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project, reload: true) { create(:project, :public, namespace: user.namespace) }
+ let_it_be(:label) { create(:label, project: project) }
before do
project.add_developer(user)
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 7bad30d107d..c54487a68fe 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -557,7 +557,7 @@ describe API::Runners do
end
describe 'GET /runners/:id/jobs' do
- set(:job_1) { create(:ci_build) }
+ let_it_be(:job_1) { create(:ci_build) }
let!(:job_2) { create(:ci_build, :running, runner: shared_runner, project: project) }
let!(:job_3) { create(:ci_build, :failed, runner: shared_runner, project: project) }
let!(:job_4) { create(:ci_build, :running, runner: project_runner, project: project) }
diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb
index 24d7f1e313c..04794b2ba58 100644
--- a/spec/requests/api/search_spec.rb
+++ b/spec/requests/api/search_spec.rb
@@ -3,10 +3,10 @@
require 'spec_helper'
describe API::Search do
- set(:user) { create(:user) }
- set(:group) { create(:group) }
- set(:project) { create(:project, :wiki_repo, :public, name: 'awesome project', group: group) }
- set(:repo_project) { create(:project, :public, :repository, group: group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project, reload: true) { create(:project, :wiki_repo, :public, name: 'awesome project', group: group) }
+ let_it_be(:repo_project) { create(:project, :public, :repository, group: group) }
shared_examples 'response is correct' do |schema:, size: 1|
it { expect(response).to have_gitlab_http_status(200) }
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
index 628d5533366..323164f26f0 100644
--- a/spec/requests/api/services_spec.rb
+++ b/spec/requests/api/services_spec.rb
@@ -3,10 +3,10 @@
require "spec_helper"
describe API::Services do
- set(:user) { create(:user) }
- set(:user2) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
- set(:project) do
+ let_it_be(:project, reload: true) do
create(:project, creator_id: user.id, namespace: user.namespace)
end
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index af86ba86303..1a6bd4e6c0d 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
describe API::Settings, 'Settings' do
let(:user) { create(:user) }
- set(:admin) { create(:admin) }
+ let_it_be(:admin) { create(:admin) }
describe "GET /application/settings" do
it "returns application settings" do
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index 1749ec89bc1..21565265b99 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -89,8 +89,8 @@ describe API::Snippets do
end
describe 'GET /snippets/:id/raw' do
- set(:author) { create(:user) }
- set(:snippet) { create(:personal_snippet, :private, author: author) }
+ let_it_be(:author) { create(:user) }
+ let_it_be(:snippet) { create(:personal_snippet, :private, author: author) }
it 'requires authentication' do
get api("/snippets/#{snippet.id}", nil)
@@ -137,10 +137,10 @@ describe API::Snippets do
end
describe 'GET /snippets/:id' do
- set(:admin) { create(:user, :admin) }
- set(:author) { create(:user) }
- set(:private_snippet) { create(:personal_snippet, :private, author: author) }
- set(:internal_snippet) { create(:personal_snippet, :internal, author: author) }
+ let_it_be(:admin) { create(:user, :admin) }
+ let_it_be(:author) { create(:user) }
+ let_it_be(:private_snippet) { create(:personal_snippet, :private, author: author) }
+ let_it_be(:internal_snippet) { create(:personal_snippet, :internal, author: author) }
it 'requires authentication' do
get api("/snippets/#{private_snippet.id}", nil)
diff --git a/spec/requests/api/task_completion_status_spec.rb b/spec/requests/api/task_completion_status_spec.rb
index ee2531197b1..a2891e1d983 100644
--- a/spec/requests/api/task_completion_status_spec.rb
+++ b/spec/requests/api/task_completion_status_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
describe 'task completion status response' do
- set(:user) { create(:user) }
- set(:project) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) do
create(:project, :public, creator_id: user.id, namespace: user.namespace)
end
diff --git a/spec/requests/api/triggers_spec.rb b/spec/requests/api/triggers_spec.rb
index d54d112cd9f..35e41f5ae52 100644
--- a/spec/requests/api/triggers_spec.rb
+++ b/spec/requests/api/triggers_spec.rb
@@ -3,8 +3,8 @@
require 'spec_helper'
describe API::Triggers do
- set(:user) { create(:user) }
- set(:user2) { create(:user) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
let!(:trigger_token) { 'secure_token' }
let!(:trigger_token_2) { 'secure_token_2' }