Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
1f84ff323d
commit
bbd945a9ea
|
@ -62,7 +62,7 @@ _Consider adding links to check for Sentry errors, Production logs for 5xx, 302s
|
|||
- Ensure that the feature MRs have been deployed to non-production environments.
|
||||
- [ ] `/chatops run auto_deploy status <merge-commit-of-your-feature>`
|
||||
- [ ] Enable the feature globally on non-production environments.
|
||||
- [ ] `/chatops run feature set <feature-flag-name> true --dev --staging`
|
||||
- [ ] `/chatops run feature set <feature-flag-name> true --dev --staging --staging-ref`
|
||||
- [ ] Verify that the feature works as expected. Posting the QA result in this issue is preferable.
|
||||
The best environment to validate the feature in is [staging-canary](https://about.gitlab.com/handbook/engineering/infrastructure/environments/#staging-canary)
|
||||
as this is the first environment deployed to. Note you will need to make sure you are configured to use canary as outlined [here](https://about.gitlab.com/handbook/engineering/infrastructure/environments/canary-stage/)
|
||||
|
@ -120,7 +120,7 @@ To do so, follow these steps:
|
|||
the feature can be officially announced in a release blog post.
|
||||
- [ ] `/chatops run release check <merge-request-url> <milestone>`
|
||||
- [ ] Consider cleaning up the feature flag from all environments by running these chatops command in `#production` channel. Otherwise these settings may override the default enabled.
|
||||
- [ ] `/chatops run feature delete <feature-flag-name> --dev --staging --production`
|
||||
- [ ] `/chatops run feature delete <feature-flag-name> --dev --staging --staging-ref --production`
|
||||
- [ ] Close [the feature issue](ISSUE LINK) to indicate the feature will be released in the current milestone.
|
||||
- [ ] Set the next milestone to this rollout issue for scheduling [the flag removal](#release-the-feature).
|
||||
- [ ] (Optional) You can [create a separate issue](https://gitlab.com/gitlab-org/gitlab/-/issues/new?issuable_template=Feature%20Flag%20Cleanup) for scheduling the steps below to [Release the feature](#release-the-feature).
|
||||
|
@ -156,7 +156,7 @@ You can either [create a follow-up issue for Feature Flag Cleanup](https://gitla
|
|||
- [ ] `/chatops run release check <merge-request-url> <milestone>`
|
||||
- [ ] Close [the feature issue](ISSUE LINK) to indicate the feature will be released in the current milestone.
|
||||
- [ ] If not already done, clean up the feature flag from all environments by running these chatops command in `#production` channel:
|
||||
- [ ] `/chatops run feature delete <feature-flag-name> --dev --staging --production`
|
||||
- [ ] `/chatops run feature delete <feature-flag-name> --dev --staging --staging-ref --production`
|
||||
- [ ] Close this rollout issue.
|
||||
|
||||
## Rollback Steps
|
||||
|
|
|
@ -2825,7 +2825,6 @@ Layout/LineLength:
|
|||
- 'ee/spec/services/ee/boards/issues/list_service_spec.rb'
|
||||
- 'ee/spec/services/ee/boards/lists/max_limits_spec.rb'
|
||||
- 'ee/spec/services/ee/ci/pipeline_processing/atomic_processing_service_spec.rb'
|
||||
- 'ee/spec/services/ee/commits/create_service_spec.rb'
|
||||
- 'ee/spec/services/ee/git/wiki_push_service_spec.rb'
|
||||
- 'ee/spec/services/ee/groups/autocomplete_service_spec.rb'
|
||||
- 'ee/spec/services/ee/groups/deploy_tokens/create_service_spec.rb'
|
||||
|
|
|
@ -41,7 +41,7 @@ export default {
|
|||
'gl-mt-5': !commitsEmpty && contextCommitsEmpty,
|
||||
},
|
||||
]"
|
||||
:variant="commitsEmpty ? 'info' : 'default'"
|
||||
:variant="commitsEmpty ? 'confirm' : 'default'"
|
||||
@click="openModal"
|
||||
>
|
||||
{{ buttonText }}
|
||||
|
|
|
@ -206,6 +206,7 @@ export default {
|
|||
);
|
||||
},
|
||||
updateStartLine(line) {
|
||||
this.commentLineStart = line;
|
||||
this.lines.start = line;
|
||||
},
|
||||
},
|
||||
|
@ -216,7 +217,6 @@ export default {
|
|||
<div class="content discussion-form discussion-form-container discussion-notes">
|
||||
<div class="gl-mb-3 gl-text-gray-500 gl-pb-3">
|
||||
<multiline-comment-form
|
||||
v-model="commentLineStart"
|
||||
:line="line"
|
||||
:line-range="lines"
|
||||
:comment-line-options="commentLineOptions"
|
||||
|
|
|
@ -7,14 +7,16 @@ import mrPageModule from './modules';
|
|||
|
||||
Vue.use(Vuex);
|
||||
|
||||
export const createStore = () =>
|
||||
new Vuex.Store({
|
||||
modules: {
|
||||
export const createModules = () => ({
|
||||
page: mrPageModule(),
|
||||
notes: notesModule(),
|
||||
diffs: diffsModule(),
|
||||
batchComments: batchCommentsModule(),
|
||||
},
|
||||
});
|
||||
|
||||
export const createStore = () =>
|
||||
new Vuex.Store({
|
||||
modules: createModules(),
|
||||
});
|
||||
|
||||
export default createStore();
|
||||
|
|
|
@ -14,12 +14,12 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="color-item">
|
||||
<span
|
||||
class="dropdown-label-box gl-flex-shrink-0 gl-top-1 gl-mr-0"
|
||||
class="dropdown-label-box color-item-color"
|
||||
data-testid="color-item"
|
||||
:style="{ backgroundColor: color }"
|
||||
></span>
|
||||
<span class="hide-collapsed">{{ title }}</span>
|
||||
<span class="color-item-text">{{ title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script>
|
||||
import { isString } from 'lodash';
|
||||
import createFlash from '~/flash';
|
||||
import { s__ } from '~/locale';
|
||||
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
||||
|
@ -52,13 +53,23 @@ export default {
|
|||
required: false,
|
||||
default: s__('ColorWidget|Assign epic color'),
|
||||
},
|
||||
defaultColor: {
|
||||
type: Object,
|
||||
required: false,
|
||||
validator(value) {
|
||||
return isString(value?.color) && isString(value?.title);
|
||||
},
|
||||
default() {
|
||||
return {
|
||||
color: '',
|
||||
title: '',
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
issuableColor: {
|
||||
color: '',
|
||||
title: '',
|
||||
},
|
||||
issuableColor: this.defaultColor,
|
||||
colorUpdateInProgress: false,
|
||||
oldIid: null,
|
||||
sidebarExpandedOnClick: false,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { __, s__ } from '~/locale';
|
||||
import { s__ } from '~/locale';
|
||||
|
||||
export const COLOR_WIDGET_COLOR = s__('ColorWidget|Color');
|
||||
|
||||
|
@ -7,7 +7,7 @@ export const DROPDOWN_VARIANT = {
|
|||
Embedded: 'embedded',
|
||||
};
|
||||
|
||||
export const DEFAULT_COLOR = { title: __('SuggestedColors|Blue'), color: '#1068bf' };
|
||||
export const DEFAULT_COLOR = { title: s__('SuggestedColors|Blue'), color: '#1068bf' };
|
||||
|
||||
export const ISSUABLE_COLORS = [
|
||||
DEFAULT_COLOR,
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
<script>
|
||||
import { GlDropdown } from '@gitlab/ui';
|
||||
import ColorItem from './color_item.vue';
|
||||
import DropdownContentsColorView from './dropdown_contents_color_view.vue';
|
||||
import DropdownHeader from './dropdown_header.vue';
|
||||
import { isDropdownVariantSidebar } from './utils';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ColorItem,
|
||||
DropdownContentsColorView,
|
||||
DropdownHeader,
|
||||
GlDropdown,
|
||||
|
@ -42,12 +44,15 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
buttonText() {
|
||||
if (!this.localSelectedColor?.title) {
|
||||
if (!this.hasSelectedColor()) {
|
||||
return this.dropdownButtonText;
|
||||
}
|
||||
|
||||
return this.localSelectedColor.title;
|
||||
},
|
||||
hasSelectedColor() {
|
||||
return this.localSelectedColor?.title;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
localSelectedColor: {
|
||||
|
@ -91,7 +96,15 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-dropdown ref="dropdown" :text="buttonText" class="gl-w-full" @hide="handleDropdownHide">
|
||||
<gl-dropdown ref="dropdown" class="gl-w-full" @hide="handleDropdownHide">
|
||||
<template #button-text>
|
||||
<color-item
|
||||
v-if="hasSelectedColor"
|
||||
:color="localSelectedColor.color"
|
||||
:title="localSelectedColor.title"
|
||||
/>
|
||||
<span v-else>{{ buttonText }}</span>
|
||||
</template>
|
||||
<template #header>
|
||||
<dropdown-header
|
||||
ref="header"
|
||||
|
|
|
@ -36,8 +36,8 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<gl-dropdown-form>
|
||||
<div>
|
||||
<gl-dropdown-form class="js-colors-list">
|
||||
<div data-testid="dropdown-content">
|
||||
<gl-dropdown-item
|
||||
v-for="color in colors"
|
||||
:key="color.color"
|
||||
|
|
|
@ -20,6 +20,11 @@ export default {
|
|||
required: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
hasColor() {
|
||||
return this.selectedColor.color !== '';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -31,13 +36,18 @@ export default {
|
|||
class="sidebar-collapsed-icon"
|
||||
>
|
||||
<gl-icon name="appearance" />
|
||||
<color-item
|
||||
:color="selectedColor.color"
|
||||
:title="selectedColor.title"
|
||||
class="gl-font-base gl-line-height-24"
|
||||
/>
|
||||
<color-item :color="selectedColor.color" :title="selectedColor.title" />
|
||||
</div>
|
||||
|
||||
<color-item class="hide-collapsed" :color="selectedColor.color" :title="selectedColor.title" />
|
||||
<span v-if="!hasColor" class="no-value hide-collapsed">
|
||||
<slot></slot>
|
||||
</span>
|
||||
<template v-else>
|
||||
<color-item
|
||||
class="hide-collapsed"
|
||||
:color="selectedColor.color"
|
||||
:title="selectedColor.title"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@import './pages/branches';
|
||||
@import './pages/clusters';
|
||||
@import './pages/colors';
|
||||
@import './pages/commits';
|
||||
@import './pages/deploy_keys';
|
||||
@import './pages/detail_page';
|
||||
|
@ -8,6 +9,7 @@
|
|||
@import './pages/events';
|
||||
@import './pages/groups';
|
||||
@import './pages/help';
|
||||
@import './pages/hierarchy';
|
||||
@import './pages/issuable';
|
||||
@import './pages/issues';
|
||||
@import './pages/labels';
|
||||
|
@ -25,9 +27,8 @@
|
|||
@import './pages/registry';
|
||||
@import './pages/search';
|
||||
@import './pages/service_desk';
|
||||
@import './pages/settings';
|
||||
@import './pages/settings_ci_cd';
|
||||
@import './pages/settings';
|
||||
@import './pages/storage_quota';
|
||||
@import './pages/tree';
|
||||
@import './pages/users';
|
||||
@import './pages/hierarchy';
|
||||
|
|
|
@ -188,7 +188,11 @@ $dark-il: #de935f;
|
|||
.diff-line-num.new,
|
||||
.line-coverage.new,
|
||||
.line-codequality.new,
|
||||
.line_content.new {
|
||||
.line_content.new,
|
||||
.diff-line-num.new-nomappinginraw,
|
||||
.line-coverage.new-nomappinginraw,
|
||||
.line-codequality.new-nomappinginraw,
|
||||
.line_content.new-nomappinginraw {
|
||||
@include diff-background($dark-new-bg, $dark-new-idiff, $dark-border);
|
||||
|
||||
&::before,
|
||||
|
@ -200,7 +204,11 @@ $dark-il: #de935f;
|
|||
.diff-line-num.old,
|
||||
.line-coverage.old,
|
||||
.line-codequality.old,
|
||||
.line_content.old {
|
||||
.line_content.old,
|
||||
.diff-line-num.old-nomappinginraw,
|
||||
.line-coverage.old-nomappinginraw,
|
||||
.line-codequality.old-nomappinginraw,
|
||||
.line_content.old-nomappinginraw {
|
||||
@include diff-background($dark-old-bg, $dark-old-idiff, $dark-border);
|
||||
|
||||
&::before,
|
||||
|
|
|
@ -178,7 +178,11 @@ $monokai-gh: #75715e;
|
|||
.diff-line-num.new,
|
||||
.line-coverage.new,
|
||||
.line-codequality.new,
|
||||
.line_content.new {
|
||||
.line_content.new,
|
||||
.diff-line-num.new-nomappinginraw,
|
||||
.line-coverage.new-nomappinginraw,
|
||||
.line-codequality.new-nomappinginraw,
|
||||
.line_content.new-nomappinginraw {
|
||||
@include diff-background($monokai-new-bg, $monokai-new-idiff, $monokai-diff-border);
|
||||
|
||||
&::before,
|
||||
|
@ -190,7 +194,11 @@ $monokai-gh: #75715e;
|
|||
.diff-line-num.old,
|
||||
.line-coverage.old,
|
||||
.line-codequality.old,
|
||||
.line_content.old {
|
||||
.line_content.old,
|
||||
.diff-line-num.old-nomappinginraw,
|
||||
.line-coverage.old-nomappinginraw,
|
||||
.line-codequality.old-nomappinginraw,
|
||||
.line_content.old-nomappinginraw {
|
||||
@include diff-background($monokai-old-bg, $monokai-old-idiff, $monokai-diff-border);
|
||||
|
||||
&::before,
|
||||
|
|
|
@ -75,7 +75,9 @@
|
|||
.line-coverage,
|
||||
.line-codequality {
|
||||
&.old,
|
||||
&.new {
|
||||
&.new,
|
||||
&.new-nomappinginraw,
|
||||
&.old-nomappinginraw {
|
||||
background-color: $white-normal;
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +133,7 @@
|
|||
}
|
||||
|
||||
.line_content {
|
||||
&.old {
|
||||
&.old, &.old-nomappinginraw {
|
||||
background-color: $white-normal;
|
||||
|
||||
&::before {
|
||||
|
@ -144,7 +146,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.new {
|
||||
&.new, &.new-nomappinginraw {
|
||||
background-color: $white-normal;
|
||||
|
||||
&::before {
|
||||
|
|
|
@ -189,7 +189,11 @@ $solarized-dark-il: #2aa198;
|
|||
.diff-line-num.new,
|
||||
.line-coverage.new,
|
||||
.line-codequality.new,
|
||||
.line_content.new {
|
||||
.line_content.new,
|
||||
.diff-line-num.new-nomappinginraw,
|
||||
.line-coverage.new-nomappinginraw,
|
||||
.line-codequality.new-nomappinginraw,
|
||||
.line_content.new-nomappinginraw {
|
||||
@include diff-background($solarized-dark-new-bg, $solarized-dark-new-idiff, $solarized-dark-border);
|
||||
|
||||
&::before,
|
||||
|
@ -201,7 +205,11 @@ $solarized-dark-il: #2aa198;
|
|||
.diff-line-num.old,
|
||||
.line-coverage.old,
|
||||
.line-codequality.old,
|
||||
.line_content.old {
|
||||
.line_content.old,
|
||||
.diff-line-num.old-nomappinginraw,
|
||||
.line-coverage.old-nomappinginraw,
|
||||
.line-codequality.old-nomappinginraw,
|
||||
.line_content.old-nomappinginraw {
|
||||
@include diff-background($solarized-dark-old-bg, $solarized-dark-old-idiff, $solarized-dark-border);
|
||||
|
||||
&::before,
|
||||
|
|
|
@ -169,7 +169,11 @@ $solarized-light-il: #2aa198;
|
|||
.diff-line-num.new,
|
||||
.line-coverage.new,
|
||||
.line-codequality.new,
|
||||
.line_content.new {
|
||||
.line_content.new,
|
||||
.diff-line-num.new-nomappinginraw,
|
||||
.line-coverage.new-nomappinginraw,
|
||||
.line-codequality.new-nomappinginraw,
|
||||
.line_content.new-nomappinginraw {
|
||||
@include diff-background($solarized-light-new-bg,
|
||||
$solarized-light-new-idiff, $solarized-light-border);
|
||||
|
||||
|
@ -190,7 +194,11 @@ $solarized-light-il: #2aa198;
|
|||
.diff-line-num.old,
|
||||
.line-coverage.old,
|
||||
.line-codequality.old,
|
||||
.line_content.old {
|
||||
.line_content.old,
|
||||
.diff-line-num.old-nomappinginraw,
|
||||
.line-coverage.old-nomappinginraw,
|
||||
.line-codequality.old-nomappinginraw,
|
||||
.line_content.old-nomappinginraw {
|
||||
@include diff-background($solarized-light-old-bg, $solarized-light-old-idiff, $solarized-light-border);
|
||||
|
||||
&::before,
|
||||
|
|
|
@ -158,7 +158,8 @@ pre.code,
|
|||
}
|
||||
|
||||
.diff-line-num {
|
||||
&.old {
|
||||
&.old,
|
||||
&.old-nomappinginraw {
|
||||
background-color: $line-number-old;
|
||||
|
||||
a {
|
||||
|
@ -166,7 +167,8 @@ pre.code,
|
|||
}
|
||||
}
|
||||
|
||||
&.new {
|
||||
&.new,
|
||||
&.new-nomappinginraw {
|
||||
background-color: $line-number-new;
|
||||
|
||||
a {
|
||||
|
@ -204,7 +206,8 @@ pre.code,
|
|||
}
|
||||
|
||||
.line_content {
|
||||
&.old {
|
||||
&.old,
|
||||
&.old-nomappinginraw {
|
||||
background-color: $line-removed;
|
||||
|
||||
&::before {
|
||||
|
@ -216,7 +219,8 @@ pre.code,
|
|||
}
|
||||
}
|
||||
|
||||
&.new {
|
||||
&.new,
|
||||
&.new-nomappinginraw {
|
||||
background-color: $line-added;
|
||||
|
||||
&::before {
|
||||
|
@ -243,11 +247,13 @@ pre.code,
|
|||
|
||||
.line-coverage,
|
||||
.line-codequality {
|
||||
&.old {
|
||||
&.old,
|
||||
&.old-nomappinginraw {
|
||||
background-color: $line-removed;
|
||||
}
|
||||
|
||||
&.new {
|
||||
&.new,
|
||||
&.new-nomappinginraw {
|
||||
background-color: $line-added;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
.color-item {
|
||||
@include gl-align-items-center;
|
||||
@include gl-display-flex;
|
||||
}
|
||||
|
||||
.color-item-color {
|
||||
@include gl-flex-shrink-0;
|
||||
@include gl-mr-3;
|
||||
@include gl-top-0;
|
||||
}
|
||||
|
||||
.right-sidebar-collapsed {
|
||||
.color-item {
|
||||
@include gl-pt-3;
|
||||
}
|
||||
|
||||
.color-item-color {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.color-item-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
= gitlab_ui_form_for @application_setting, url: metrics_and_profiling_admin_application_settings_path(anchor: 'js-performance-bar-settings'), html: { class: 'fieldset-form' } do |f|
|
||||
= form_errors(@application_setting)
|
||||
= form_errors(@application_setting, pajamas_alert: true)
|
||||
|
||||
%fieldset
|
||||
.form-group
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
%b= s_('ProjectSettings|Squash commits when merging')
|
||||
%p.text-secondary
|
||||
= s_('ProjectSettings|Set the default behavior of this option in merge requests. Changes to this are also applied to existing merge requests.')
|
||||
= link_to "What is squashing?", help_page_path('user/project/merge_requests/squash_and_merge.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
= link_to s_('ProjectSettings|What is squashing?'), help_page_path('user/project/merge_requests/squash_and_merge.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
|
||||
= settings.gitlab_ui_radio_component :squash_option,
|
||||
:never,
|
||||
|
|
|
@ -1060,6 +1060,9 @@ License.current.expires_at
|
|||
|
||||
# Is this a trial license?
|
||||
License.current.trial?
|
||||
|
||||
# License ID for lookup on CustomersDot
|
||||
License.current.license_id
|
||||
```
|
||||
|
||||
### Check if a project feature is available on the instance
|
||||
|
|
|
@ -1147,6 +1147,9 @@ Payload example:
|
|||
"created_at": "2016-08-12 15:23:28 UTC",
|
||||
"started_at": null,
|
||||
"finished_at": null,
|
||||
"duration": null,
|
||||
"queued_duration": null,
|
||||
"failure_reason": null,
|
||||
"when": "manual",
|
||||
"manual": true,
|
||||
"allow_failure": false,
|
||||
|
@ -1175,7 +1178,10 @@ Payload example:
|
|||
"status": "success",
|
||||
"created_at": "2016-08-12 15:23:28 UTC",
|
||||
"started_at": "2016-08-12 15:26:12 UTC",
|
||||
"finished_at": null,
|
||||
"finished_at": "2016-08-12 15:26:29 UTC",
|
||||
"duration": 17.0,
|
||||
"queued_duration": 196.0,
|
||||
"failure_reason": null,
|
||||
"when": "on_success",
|
||||
"manual": false,
|
||||
"allow_failure": false,
|
||||
|
@ -1208,10 +1214,13 @@ Payload example:
|
|||
"id": 378,
|
||||
"stage": "test",
|
||||
"name": "test-build",
|
||||
"status": "success",
|
||||
"status": "failed",
|
||||
"created_at": "2016-08-12 15:23:28 UTC",
|
||||
"started_at": "2016-08-12 15:26:12 UTC",
|
||||
"finished_at": "2016-08-12 15:26:29 UTC",
|
||||
"duration": 17.0,
|
||||
"queued_duration": 196.0,
|
||||
"failure_reason": "script_failure",
|
||||
"when": "on_success",
|
||||
"manual": false,
|
||||
"allow_failure": false,
|
||||
|
@ -1247,6 +1256,9 @@ Payload example:
|
|||
"created_at": "2016-08-12 15:23:28 UTC",
|
||||
"started_at": "2016-08-12 15:24:56 UTC",
|
||||
"finished_at": "2016-08-12 15:25:26 UTC",
|
||||
"duration": 17.0,
|
||||
"queued_duration": 196.0,
|
||||
"failure_reason": null,
|
||||
"when": "on_success",
|
||||
"manual": false,
|
||||
"allow_failure": false,
|
||||
|
@ -1282,6 +1294,9 @@ Payload example:
|
|||
"created_at": "2016-08-12 15:23:28 UTC",
|
||||
"started_at": null,
|
||||
"finished_at": null,
|
||||
"duration": null,
|
||||
"queued_duration": null,
|
||||
"failure_reason": null,
|
||||
"when": "on_success",
|
||||
"manual": false,
|
||||
"allow_failure": false,
|
||||
|
|
|
@ -118,6 +118,7 @@ module Gitlab
|
|||
finished_at: build.finished_at,
|
||||
duration: build.duration,
|
||||
queued_duration: build.queued_duration,
|
||||
failure_reason: (build.failure_reason if build.failed?),
|
||||
when: build.when,
|
||||
manual: build.action?,
|
||||
allow_failure: build.allow_failure,
|
||||
|
|
|
@ -9035,6 +9035,9 @@ msgstr ""
|
|||
msgid "Collector hostname"
|
||||
msgstr ""
|
||||
|
||||
msgid "Color"
|
||||
msgstr ""
|
||||
|
||||
msgid "ColorWidget|An error occurred while updating color."
|
||||
msgstr ""
|
||||
|
||||
|
@ -30331,6 +30334,9 @@ msgstr ""
|
|||
msgid "ProjectSettings|What are merge trains?"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|What is squashing?"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -34766,6 +34772,9 @@ msgstr ""
|
|||
msgid "Select a branch to compare"
|
||||
msgstr ""
|
||||
|
||||
msgid "Select a color"
|
||||
msgstr ""
|
||||
|
||||
msgid "Select a compliance framework to apply to this project. %{linkStart}How are these added?%{linkEnd}"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
"graphql": "^15.7.2",
|
||||
"graphql-tag": "^2.11.0",
|
||||
"hast-util-to-string": "^2.0.0",
|
||||
"highlight.js": "^11.3.1",
|
||||
"highlight.js": "^11.5.1",
|
||||
"immer": "^7.0.7",
|
||||
"ipaddr.js": "^1.9.1",
|
||||
"jed": "^1.1.1",
|
||||
|
@ -136,7 +136,7 @@
|
|||
"jszip-utils": "^0.0.2",
|
||||
"katex": "^0.13.2",
|
||||
"lodash": "^4.17.20",
|
||||
"lowlight": "^2.5.0",
|
||||
"lowlight": "^2.6.1",
|
||||
"marked": "^0.3.12",
|
||||
"mathjax": "3",
|
||||
"mermaid": "^9.1.1",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import MockAdapter from 'axios-mock-adapter';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import initMRPage from '~/mr_notes';
|
||||
import diffFileMockData from '../diffs/mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../diffs/mock_data/diff_file';
|
||||
import { userDataMock, notesDataMock, noteableDataMock } from '../notes/mock_data';
|
||||
|
||||
export default function initVueMRPage() {
|
||||
|
@ -39,7 +39,7 @@ export default function initVueMRPage() {
|
|||
const mock = new MockAdapter(axios);
|
||||
mock.onGet(diffsAppEndpoint).reply(200, {
|
||||
branch_name: 'foo',
|
||||
diff_files: [diffFileMockData],
|
||||
diff_files: [getDiffFileMock()],
|
||||
});
|
||||
|
||||
initMRPage();
|
||||
|
|
|
@ -6,7 +6,7 @@ import { EVT_EXPAND_ALL_FILES } from '~/diffs/constants';
|
|||
import eventHub from '~/diffs/event_hub';
|
||||
import createStore from '~/diffs/store/modules';
|
||||
|
||||
import file from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
const propsData = {
|
||||
limited: true,
|
||||
|
@ -15,7 +15,7 @@ const propsData = {
|
|||
};
|
||||
|
||||
async function files(store, count) {
|
||||
const copies = Array(count).fill(file);
|
||||
const copies = Array(count).fill(getDiffFileMock());
|
||||
store.state.diffs.diffFiles.push(...copies);
|
||||
|
||||
await nextTick();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { diffViewerModes } from '~/ide/constants';
|
|||
import NoteForm from '~/notes/components/note_form.vue';
|
||||
import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_preview.vue';
|
||||
import NotDiffableViewer from '~/vue_shared/components/diff_viewer/viewers/not_diffable.vue';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
Vue.use(Vuex);
|
||||
|
||||
|
@ -28,7 +28,7 @@ describe('DiffContent', () => {
|
|||
const getCommentFormForDiffFileGetterMock = jest.fn();
|
||||
|
||||
const defaultProps = {
|
||||
diffFile: JSON.parse(JSON.stringify(diffFileMockData)),
|
||||
diffFile: getDiffFileMock(),
|
||||
};
|
||||
|
||||
const createComponent = ({ props, state, provide } = {}) => {
|
||||
|
@ -70,7 +70,7 @@ describe('DiffContent', () => {
|
|||
isInlineView: isInlineViewGetterMock,
|
||||
isParallelView: isParallelViewGetterMock,
|
||||
getCommentFormForDiffFile: getCommentFormForDiffFileGetterMock,
|
||||
diffLines: () => () => [...diffFileMockData.parallel_diff_lines],
|
||||
diffLines: () => () => [...getDiffFileMock().parallel_diff_lines],
|
||||
fileLineCodequality: () => () => [],
|
||||
},
|
||||
actions: {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { mount } from '@vue/test-utils';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import DiffExpansionCell from '~/diffs/components/diff_expansion_cell.vue';
|
||||
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
|
||||
import { getPreviousLineIndex } from '~/diffs/store/utils';
|
||||
import { createStore } from '~/mr_notes/stores';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
const EXPAND_UP_CLASS = '.js-unfold';
|
||||
const EXPAND_DOWN_CLASS = '.js-unfold-down';
|
||||
|
@ -26,7 +25,7 @@ function makeLoadMoreLinesPayload({
|
|||
isExpandDown = false,
|
||||
}) {
|
||||
return {
|
||||
endpoint: diffFileMockData.context_lines_path,
|
||||
endpoint: getDiffFileMock().context_lines_path,
|
||||
params: {
|
||||
since: sinceLine,
|
||||
to: toLine,
|
||||
|
@ -57,7 +56,7 @@ describe('DiffExpansionCell', () => {
|
|||
let store;
|
||||
|
||||
beforeEach(() => {
|
||||
mockFile = cloneDeep(diffFileMockData);
|
||||
mockFile = getDiffFileMock();
|
||||
mockLine = getLine(mockFile, INLINE_DIFF_VIEW_TYPE, 8);
|
||||
store = createStore();
|
||||
store.state.diffs.diffFiles = [mockFile];
|
||||
|
@ -117,9 +116,8 @@ describe('DiffExpansionCell', () => {
|
|||
});
|
||||
|
||||
describe('any row', () => {
|
||||
[
|
||||
{ diffViewType: INLINE_DIFF_VIEW_TYPE, lineIndex: 8, file: cloneDeep(diffFileMockData) },
|
||||
].forEach(({ diffViewType, file, lineIndex }) => {
|
||||
[{ diffViewType: INLINE_DIFF_VIEW_TYPE, lineIndex: 8, file: getDiffFileMock() }].forEach(
|
||||
({ diffViewType, file, lineIndex }) => {
|
||||
describe(`with diffViewType (${diffViewType})`, () => {
|
||||
beforeEach(() => {
|
||||
mockLine = getLine(mockFile, diffViewType, lineIndex);
|
||||
|
@ -179,9 +177,9 @@ describe('DiffExpansionCell', () => {
|
|||
});
|
||||
|
||||
it('on expand down clicked, dispatch loadMoreLines', () => {
|
||||
mockFile[lineSources[diffViewType]][lineIndex + 1] = cloneDeep(
|
||||
mockFile[lineSources[diffViewType]][lineIndex],
|
||||
);
|
||||
mockFile[lineSources[diffViewType]][lineIndex + 1] = getDiffFileMock()[
|
||||
lineSources[diffViewType]
|
||||
][lineIndex];
|
||||
const nextLine = getLine(mockFile, diffViewType, lineIndex + 1);
|
||||
|
||||
nextLine.meta_data.old_pos = 300;
|
||||
|
@ -194,7 +192,7 @@ describe('DiffExpansionCell', () => {
|
|||
findExpandDown(wrapper).trigger('click');
|
||||
|
||||
expect(store.dispatch).toHaveBeenCalledWith('diffs/loadMoreLines', {
|
||||
endpoint: diffFileMockData.context_lines_path,
|
||||
endpoint: mockFile.context_lines_path,
|
||||
params: {
|
||||
since: 1,
|
||||
to: 21, // the load amount, plus 1 line
|
||||
|
@ -213,6 +211,7 @@ describe('DiffExpansionCell', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,7 +20,7 @@ import axios from '~/lib/utils/axios_utils';
|
|||
import { scrollToElement } from '~/lib/utils/common_utils';
|
||||
import httpStatus from '~/lib/utils/http_status';
|
||||
import createNotesStore from '~/notes/stores/modules';
|
||||
import diffFileMockDataReadable from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
import diffFileMockDataUnreadable from '../mock_data/diff_file_unreadable';
|
||||
|
||||
jest.mock('~/lib/utils/common_utils');
|
||||
|
@ -106,7 +106,7 @@ const findLoader = (wrapper) => wrapper.find('[data-testid="loader-icon"]');
|
|||
const findToggleButton = (wrapper) => wrapper.find('[data-testid="expand-button"]');
|
||||
|
||||
const toggleFile = (wrapper) => findDiffHeader(wrapper).vm.$emit('toggleFile');
|
||||
const getReadableFile = () => JSON.parse(JSON.stringify(diffFileMockDataReadable));
|
||||
const getReadableFile = () => getDiffFileMock();
|
||||
const getUnreadableFile = () => JSON.parse(JSON.stringify(diffFileMockDataUnreadable));
|
||||
|
||||
const makeFileAutomaticallyCollapsed = (store, index = 0) =>
|
||||
|
|
|
@ -1,82 +1,166 @@
|
|||
import { shallowMount } from '@vue/test-utils';
|
||||
import { nextTick } from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import Autosave from '~/autosave';
|
||||
import DiffLineNoteForm from '~/diffs/components/diff_line_note_form.vue';
|
||||
import { createStore } from '~/mr_notes/stores';
|
||||
import { createModules } from '~/mr_notes/stores';
|
||||
import NoteForm from '~/notes/components/note_form.vue';
|
||||
import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue';
|
||||
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
|
||||
import { noteableDataMock } from 'jest/notes/mock_data';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => {
|
||||
return {
|
||||
confirmAction: jest.fn(),
|
||||
};
|
||||
});
|
||||
jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal');
|
||||
jest.mock('~/autosave');
|
||||
|
||||
describe('DiffLineNoteForm', () => {
|
||||
let wrapper;
|
||||
let diffFile;
|
||||
let diffLines;
|
||||
const getDiffFileMock = () => ({ ...diffFileMockData });
|
||||
let actions;
|
||||
let store;
|
||||
|
||||
const createComponent = (args = {}) => {
|
||||
diffFile = getDiffFileMock();
|
||||
diffLines = diffFile.highlighted_diff_lines;
|
||||
const store = createStore();
|
||||
const getSelectedLine = () => {
|
||||
const lineCode = diffLines[1].line_code;
|
||||
return diffFile.highlighted_diff_lines.find((l) => l.line_code === lineCode);
|
||||
};
|
||||
|
||||
const createStore = (state) => {
|
||||
const modules = createModules();
|
||||
modules.diffs.actions = {
|
||||
...modules.diffs.actions,
|
||||
saveDiffDiscussion: jest.fn(() => Promise.resolve()),
|
||||
};
|
||||
modules.diffs.getters = {
|
||||
...modules.diffs.getters,
|
||||
diffCompareDropdownTargetVersions: jest.fn(),
|
||||
diffCompareDropdownSourceVersions: jest.fn(),
|
||||
selectedSourceIndex: jest.fn(),
|
||||
};
|
||||
modules.notes.getters = {
|
||||
...modules.notes.getters,
|
||||
noteableType: jest.fn(),
|
||||
};
|
||||
actions = modules.diffs.actions;
|
||||
|
||||
store = new Vuex.Store({ modules });
|
||||
store.state.notes.userData.id = 1;
|
||||
store.state.notes.noteableData = noteableDataMock;
|
||||
|
||||
store.replaceState({ ...store.state, ...state });
|
||||
};
|
||||
|
||||
const createComponent = ({ props, state } = {}) => {
|
||||
wrapper?.destroy();
|
||||
diffFile = getDiffFileMock();
|
||||
diffLines = diffFile.highlighted_diff_lines;
|
||||
|
||||
createStore(state);
|
||||
store.state.diffs.diffFiles = [diffFile];
|
||||
|
||||
store.replaceState({ ...store.state, ...args.state });
|
||||
|
||||
return shallowMount(DiffLineNoteForm, {
|
||||
store,
|
||||
propsData: {
|
||||
...{
|
||||
const propsData = {
|
||||
diffFileHash: diffFile.file_hash,
|
||||
diffLines,
|
||||
line: diffLines[1],
|
||||
range: { start: diffLines[0], end: diffLines[1] },
|
||||
noteTargetLine: diffLines[1],
|
||||
},
|
||||
...(args.props || {}),
|
||||
},
|
||||
...props,
|
||||
};
|
||||
|
||||
wrapper = shallowMount(DiffLineNoteForm, {
|
||||
store,
|
||||
propsData,
|
||||
});
|
||||
};
|
||||
|
||||
const findNoteForm = () => wrapper.findComponent(NoteForm);
|
||||
const findCommentForm = () => wrapper.findComponent(MultilineCommentForm);
|
||||
|
||||
describe('methods', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = createComponent();
|
||||
Autosave.mockClear();
|
||||
createComponent();
|
||||
});
|
||||
|
||||
describe('handleCancelCommentForm', () => {
|
||||
it('shows note form', () => {
|
||||
expect(wrapper.find(NoteForm).exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('passes the provided range of lines to comment form', () => {
|
||||
expect(findCommentForm().props('lineRange')).toMatchObject({
|
||||
start: diffLines[0],
|
||||
end: diffLines[1],
|
||||
});
|
||||
});
|
||||
|
||||
it('respects empty range when passing a range of lines', () => {
|
||||
createComponent({ props: { range: null } });
|
||||
expect(findCommentForm().props('lineRange')).toMatchObject({
|
||||
start: diffLines[1],
|
||||
end: diffLines[1],
|
||||
});
|
||||
});
|
||||
|
||||
it('should init autosave', () => {
|
||||
expect(Autosave).toHaveBeenCalledWith({}, [
|
||||
'Note',
|
||||
'Issue',
|
||||
98,
|
||||
undefined,
|
||||
'DiffNote',
|
||||
undefined,
|
||||
'1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2',
|
||||
]);
|
||||
});
|
||||
|
||||
describe('when cancelling form', () => {
|
||||
afterEach(() => {
|
||||
confirmAction.mockReset();
|
||||
});
|
||||
|
||||
it('should ask for confirmation when shouldConfirm and isDirty passed as truthy', () => {
|
||||
confirmAction.mockResolvedValueOnce(false);
|
||||
|
||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||
|
||||
expect(confirmAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should only ask for confirmation once', () => {
|
||||
// Never resolve so we can test what happens when triggered while "confirmAction" is loading
|
||||
confirmAction.mockImplementation(() => new Promise(() => {}));
|
||||
let finalizePromise;
|
||||
confirmAction.mockImplementation(
|
||||
() =>
|
||||
new Promise((resolve) => {
|
||||
finalizePromise = resolve;
|
||||
}),
|
||||
);
|
||||
|
||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||
|
||||
expect(confirmAction).toHaveBeenCalledTimes(1);
|
||||
finalizePromise();
|
||||
});
|
||||
|
||||
describe('with confirmation', () => {
|
||||
beforeEach(() => {
|
||||
confirmAction.mockResolvedValueOnce(true);
|
||||
});
|
||||
|
||||
it('should ask form confirmation and hide form for a line', async () => {
|
||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||
await nextTick();
|
||||
expect(confirmAction).toHaveBeenCalled();
|
||||
await nextTick();
|
||||
|
||||
expect(getSelectedLine().hasForm).toBe(false);
|
||||
expect(Autosave.mock.instances[0].reset).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('without confirmation', () => {
|
||||
beforeEach(() => {
|
||||
confirmAction.mockResolvedValueOnce(false);
|
||||
});
|
||||
|
||||
it('should ask for confirmation when shouldConfirm and isDirty passed as truthy', () => {
|
||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||
|
||||
expect(confirmAction).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not ask for confirmation when one of the params false', () => {
|
||||
confirmAction.mockResolvedValueOnce(false);
|
||||
|
||||
findNoteForm().vm.$emit('cancelForm', true, false);
|
||||
|
||||
expect(confirmAction).not.toHaveBeenCalled();
|
||||
|
@ -85,116 +169,39 @@ describe('DiffLineNoteForm', () => {
|
|||
|
||||
expect(confirmAction).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call cancelCommentForm with lineCode', async () => {
|
||||
confirmAction.mockResolvedValueOnce(true);
|
||||
jest.spyOn(wrapper.vm, 'cancelCommentForm').mockImplementation(() => {});
|
||||
jest.spyOn(wrapper.vm, 'resetAutoSave').mockImplementation(() => {});
|
||||
|
||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(confirmAction).toHaveBeenCalled();
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(wrapper.vm.cancelCommentForm).toHaveBeenCalledWith({
|
||||
lineCode: diffLines[1].line_code,
|
||||
fileHash: wrapper.vm.diffFileHash,
|
||||
});
|
||||
expect(wrapper.vm.resetAutoSave).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveNoteForm', () => {
|
||||
it('should call saveNote action with proper params', async () => {
|
||||
const saveDiffDiscussionSpy = jest
|
||||
.spyOn(wrapper.vm, 'saveDiffDiscussion')
|
||||
.mockReturnValue(Promise.resolve());
|
||||
|
||||
describe('saving note', () => {
|
||||
it('should save original line', async () => {
|
||||
const lineRange = {
|
||||
start: {
|
||||
line_code: wrapper.vm.commentLineStart.line_code,
|
||||
type: wrapper.vm.commentLineStart.type,
|
||||
line_code: diffLines[1].line_code,
|
||||
type: diffLines[1].type,
|
||||
new_line: 2,
|
||||
old_line: null,
|
||||
},
|
||||
end: {
|
||||
line_code: wrapper.vm.line.line_code,
|
||||
type: wrapper.vm.line.type,
|
||||
line_code: diffLines[1].line_code,
|
||||
type: diffLines[1].type,
|
||||
new_line: 2,
|
||||
old_line: null,
|
||||
},
|
||||
};
|
||||
|
||||
const formData = {
|
||||
...wrapper.vm.formData,
|
||||
await findNoteForm().vm.$emit('handleFormUpdate', 'note body');
|
||||
expect(actions.saveDiffDiscussion.mock.calls[0][1].formData).toMatchObject({
|
||||
lineRange,
|
||||
};
|
||||
|
||||
await wrapper.vm.handleSaveNote('note body');
|
||||
expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({
|
||||
note: 'note body',
|
||||
formData,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('created', () => {
|
||||
it('should use the provided `range` of lines', () => {
|
||||
wrapper = createComponent();
|
||||
|
||||
expect(wrapper.vm.lines.start).toBe(diffLines[0]);
|
||||
expect(wrapper.vm.lines.end).toBe(diffLines[1]);
|
||||
});
|
||||
|
||||
it("should fill the internal `lines` data with the provided `line` if there's no provided `range", () => {
|
||||
wrapper = createComponent({ props: { range: null } });
|
||||
|
||||
expect(wrapper.vm.lines.start).toBe(diffLines[1]);
|
||||
expect(wrapper.vm.lines.end).toBe(diffLines[1]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mounted', () => {
|
||||
it('should init autosave', () => {
|
||||
const key = 'autosave/Note/Issue/98//DiffNote//1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2';
|
||||
wrapper = createComponent();
|
||||
|
||||
expect(wrapper.vm.autosave).toBeDefined();
|
||||
expect(wrapper.vm.autosave.key).toEqual(key);
|
||||
});
|
||||
|
||||
it('should set selectedCommentPosition', () => {
|
||||
wrapper = createComponent();
|
||||
let startLineCode = wrapper.vm.commentLineStart.line_code;
|
||||
let lineCode = wrapper.vm.line.line_code;
|
||||
|
||||
expect(startLineCode).toEqual(lineCode);
|
||||
wrapper.destroy();
|
||||
|
||||
const state = {
|
||||
notes: {
|
||||
selectedCommentPosition: {
|
||||
start: {
|
||||
line_code: 'test',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
wrapper = createComponent({ state });
|
||||
startLineCode = wrapper.vm.commentLineStart.line_code;
|
||||
lineCode = state.notes.selectedCommentPosition.start.line_code;
|
||||
expect(startLineCode).toEqual(lineCode);
|
||||
});
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
it('should have note form', () => {
|
||||
wrapper = createComponent();
|
||||
expect(wrapper.find(NoteForm).exists()).toBe(true);
|
||||
it('should save selected line from the store', async () => {
|
||||
const lineCode = 'test';
|
||||
store.state.notes.selectedCommentPosition = { start: { line_code: lineCode } };
|
||||
createComponent({ state: store.state });
|
||||
await findNoteForm().vm.$emit('handleFormUpdate', 'note body');
|
||||
expect(actions.saveDiffDiscussion.mock.calls[0][1].formData.lineRange.start.line_code).toBe(
|
||||
lineCode,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ import DiffRow from '~/diffs/components/diff_row.vue';
|
|||
import { mapParallel } from '~/diffs/components/diff_row_utils';
|
||||
import diffsModule from '~/diffs/store/modules';
|
||||
import { findInteropAttributes } from '../find_interop_attributes';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
const showCommentForm = jest.fn();
|
||||
const enterdragging = jest.fn();
|
||||
|
@ -210,6 +210,7 @@ describe('DiffRow', () => {
|
|||
});
|
||||
|
||||
describe('sets coverage title and class', () => {
|
||||
const diffFileMockData = getDiffFileMock();
|
||||
const thisLine = diffFileMockData.parallel_diff_lines[2];
|
||||
const rightLine = diffFileMockData.parallel_diff_lines[2].right;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils';
|
|||
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||
|
||||
import DiffStats from '~/diffs/components/diff_stats.vue';
|
||||
import mockDiffFile from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
const TEST_ADDED_LINES = 100;
|
||||
const TEST_REMOVED_LINES = 200;
|
||||
|
@ -48,6 +48,7 @@ describe('diff_stats', () => {
|
|||
const getBytesContainer = () => wrapper.find('.diff-stats > div:first-child');
|
||||
|
||||
beforeEach(() => {
|
||||
const mockDiffFile = getDiffFileMock();
|
||||
file = {
|
||||
...mockDiffFile,
|
||||
viewer: {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export default {
|
||||
export const getDiffFileMock = () => ({
|
||||
submodule: false,
|
||||
submodule_link: null,
|
||||
blob: {
|
||||
|
@ -305,4 +305,4 @@ export default {
|
|||
],
|
||||
discussions: [],
|
||||
renderingLines: false,
|
||||
};
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import Cookies from '~/lib/utils/cookies';
|
|||
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
|
||||
import { TEST_HOST } from 'helpers/test_constants';
|
||||
import testAction from 'helpers/vuex_action_helper';
|
||||
import mockDiffFile from 'jest/diffs/mock_data/diff_file';
|
||||
import { getDiffFileMock } from 'jest/diffs/mock_data/diff_file';
|
||||
import {
|
||||
DIFF_VIEW_COOKIE_NAME,
|
||||
INLINE_DIFF_VIEW_TYPE,
|
||||
|
@ -754,7 +754,7 @@ describe('DiffsStoreActions', () => {
|
|||
it('dispatches actions', () => {
|
||||
const commitId = 'something';
|
||||
const formData = {
|
||||
diffFile: { ...mockDiffFile },
|
||||
diffFile: getDiffFileMock(),
|
||||
noteableData: {},
|
||||
};
|
||||
const note = {};
|
||||
|
|
|
@ -3,7 +3,7 @@ import createState from '~/diffs/store/modules/diff_state';
|
|||
import * as types from '~/diffs/store/mutation_types';
|
||||
import mutations from '~/diffs/store/mutations';
|
||||
import * as utils from '~/diffs/store/utils';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
describe('DiffsStoreMutations', () => {
|
||||
describe('SET_BASE_CONFIG', () => {
|
||||
|
@ -71,6 +71,7 @@ describe('DiffsStoreMutations', () => {
|
|||
|
||||
describe('SET_DIFF_METADATA', () => {
|
||||
it('should overwrite state with the camelCased data that is passed in', () => {
|
||||
const diffFileMockData = getDiffFileMock();
|
||||
const state = {
|
||||
diffFiles: [],
|
||||
};
|
||||
|
@ -94,7 +95,7 @@ describe('DiffsStoreMutations', () => {
|
|||
it('should set diff data batch type properly', () => {
|
||||
const state = { diffFiles: [] };
|
||||
const diffMock = {
|
||||
diff_files: [diffFileMockData],
|
||||
diff_files: [getDiffFileMock()],
|
||||
};
|
||||
|
||||
mutations[types.SET_DIFF_DATA_BATCH](state, diffMock);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { clone } from 'lodash';
|
||||
import {
|
||||
LINE_POSITION_LEFT,
|
||||
LINE_POSITION_RIGHT,
|
||||
|
@ -14,10 +13,9 @@ import {
|
|||
import * as utils from '~/diffs/store/utils';
|
||||
import { MERGE_REQUEST_NOTEABLE_TYPE } from '~/notes/constants';
|
||||
import { noteableDataMock } from 'jest/notes/mock_data';
|
||||
import diffFileMockData from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
import { diffMetadata } from '../mock_data/diff_metadata';
|
||||
|
||||
const getDiffFileMock = () => JSON.parse(JSON.stringify(diffFileMockData));
|
||||
const getDiffMetadataMock = () => JSON.parse(JSON.stringify(diffMetadata));
|
||||
|
||||
describe('DiffsStoreUtils', () => {
|
||||
|
@ -47,7 +45,7 @@ describe('DiffsStoreUtils', () => {
|
|||
let diffFile;
|
||||
|
||||
beforeEach(() => {
|
||||
diffFile = { ...clone(diffFileMockData) };
|
||||
diffFile = getDiffFileMock();
|
||||
});
|
||||
|
||||
it('should return the correct previous line number', () => {
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
match,
|
||||
} from '~/diffs/utils/diff_file';
|
||||
import { diffViewerModes } from '~/ide/constants';
|
||||
import mockDiffFile from '../mock_data/diff_file';
|
||||
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||
|
||||
function getDiffFiles() {
|
||||
const loadFull = 'namespace/project/-/merge_requests/12345/diff_for_path?file_identifier=abc';
|
||||
|
@ -210,7 +210,7 @@ describe('diff_file utilities', () => {
|
|||
];
|
||||
const validFile = [
|
||||
'computes the correct stats from a file',
|
||||
mockDiffFile,
|
||||
getDiffFileMock(),
|
||||
{
|
||||
changed: 1024,
|
||||
percent: 100,
|
||||
|
@ -223,7 +223,7 @@ describe('diff_file utilities', () => {
|
|||
const negativeChange = [
|
||||
'computed the correct states from a file with a negative size change',
|
||||
{
|
||||
...mockDiffFile,
|
||||
...getDiffFileMock(),
|
||||
new_size: 0,
|
||||
old_size: 1024,
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils';
|
|||
import { nextTick } from 'vue';
|
||||
import discussionWithTwoUnresolvedNotes from 'test_fixtures/merge_requests/resolved_diff_discussion.json';
|
||||
import { trimText } from 'helpers/text_helper';
|
||||
import mockDiffFile from 'jest/diffs/mock_data/diff_file';
|
||||
import { getDiffFileMock } from 'jest/diffs/mock_data/diff_file';
|
||||
import DiscussionNotes from '~/notes/components/discussion_notes.vue';
|
||||
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
|
||||
import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.vue';
|
||||
|
@ -45,7 +45,7 @@ describe('noteable_discussion component', () => {
|
|||
|
||||
it('should render thread header', async () => {
|
||||
const discussion = { ...discussionMock };
|
||||
discussion.diff_file = mockDiffFile;
|
||||
discussion.diff_file = getDiffFileMock();
|
||||
discussion.diff_discussion = true;
|
||||
discussion.expanded = false;
|
||||
|
||||
|
@ -57,7 +57,7 @@ describe('noteable_discussion component', () => {
|
|||
|
||||
it('should hide actions when diff refs do not exists', async () => {
|
||||
const discussion = { ...discussionMock };
|
||||
discussion.diff_file = { ...mockDiffFile, diff_refs: null };
|
||||
discussion.diff_file = { ...getDiffFileMock(), diff_refs: null };
|
||||
discussion.diff_discussion = true;
|
||||
discussion.expanded = false;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ describe('DropdownValue', () => {
|
|||
|
||||
it.each`
|
||||
index | cssClass
|
||||
${0} | ${['gl-font-base', 'gl-line-height-24']}
|
||||
${0} | ${[]}
|
||||
${1} | ${['hide-collapsed']}
|
||||
`(
|
||||
'passes correct props to the ColorItem with CSS class `$cssClass`',
|
||||
|
|
|
@ -36,6 +36,7 @@ RSpec.describe Gitlab::DataBuilder::Pipeline do
|
|||
expect(build_data).to be_a(Hash)
|
||||
expect(build_data[:id]).to eq(build.id)
|
||||
expect(build_data[:status]).to eq(build.status)
|
||||
expect(build_data[:failure_reason]).to be_nil
|
||||
expect(build_data[:allow_failure]).to eq(build.allow_failure)
|
||||
expect(build_data[:environment]).to be_nil
|
||||
expect(runner_data).to eq(nil)
|
||||
|
@ -197,4 +198,14 @@ RSpec.describe Gitlab::DataBuilder::Pipeline do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.build failed' do
|
||||
let(:build) { create(:ci_build, :failed, pipeline: pipeline, failure_reason: :script_failure) }
|
||||
let(:data) { described_class.build(pipeline) }
|
||||
let(:build_data) { data[:builds].last }
|
||||
|
||||
it 'has failure_reason' do
|
||||
expect(build_data[:failure_reason]).to eq(build.failure_reason)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -6673,10 +6673,10 @@ he@^1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
highlight.js@^11.3.1, highlight.js@~11.4.0:
|
||||
version "11.4.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.4.0.tgz#34ceadd49e1596ee5aba3d99346cdfd4845ee05a"
|
||||
integrity sha512-nawlpCBCSASs7EdvZOYOYVkJpGmAOKMYZgZtUqSRqodZE0GRVcFKwo1RcpeOemqh9hyttTdd5wDBwHkuSyUfnA==
|
||||
highlight.js@^11.5.1, highlight.js@~11.5.0:
|
||||
version "11.5.1"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.5.1.tgz#027c24e4509e2f4dcd00b4a6dda542ce0a1f7aea"
|
||||
integrity sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==
|
||||
|
||||
highlight.js@~10.7.0:
|
||||
version "10.7.2"
|
||||
|
@ -8405,14 +8405,14 @@ lowlight@^1.20.0:
|
|||
fault "^1.0.0"
|
||||
highlight.js "~10.7.0"
|
||||
|
||||
lowlight@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-2.5.0.tgz#723a39fc0d9b911731a395b320519cbb0790ab14"
|
||||
integrity sha512-OXGUch9JZu4q5r4Ir6QlUp5pBXMxS7NHaclhRiUlxNRcOSK0gtXZcVrsGP4eM7bv0/KDHg/TXQagx/X35EULsA==
|
||||
lowlight@^2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-2.6.1.tgz#d3cbc7ae0530c848e512b8e6528609587520b44f"
|
||||
integrity sha512-t0ueDL6SIn9FKHipm78CNjWcJQv0xi6WCjYAICyO6GyPzoT7E58yom1mNwvI7AMwVe3pLwwFT0Bt2gml7uaUeQ==
|
||||
dependencies:
|
||||
"@types/hast" "^2.0.0"
|
||||
fault "^2.0.0"
|
||||
highlight.js "~11.4.0"
|
||||
highlight.js "~11.5.0"
|
||||
|
||||
lru-cache@^4.1.2, lru-cache@^4.1.5:
|
||||
version "4.1.5"
|
||||
|
|
Loading…
Reference in New Issue