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.
|
- Ensure that the feature MRs have been deployed to non-production environments.
|
||||||
- [ ] `/chatops run auto_deploy status <merge-commit-of-your-feature>`
|
- [ ] `/chatops run auto_deploy status <merge-commit-of-your-feature>`
|
||||||
- [ ] Enable the feature globally on non-production environments.
|
- [ ] 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.
|
- [ ] 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)
|
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/)
|
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.
|
the feature can be officially announced in a release blog post.
|
||||||
- [ ] `/chatops run release check <merge-request-url> <milestone>`
|
- [ ] `/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.
|
- [ ] 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.
|
- [ ] 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).
|
- [ ] 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).
|
- [ ] (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>`
|
- [ ] `/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.
|
- [ ] 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:
|
- [ ] 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.
|
- [ ] Close this rollout issue.
|
||||||
|
|
||||||
## Rollback Steps
|
## Rollback Steps
|
||||||
|
|
|
@ -2825,7 +2825,6 @@ Layout/LineLength:
|
||||||
- 'ee/spec/services/ee/boards/issues/list_service_spec.rb'
|
- 'ee/spec/services/ee/boards/issues/list_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/boards/lists/max_limits_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/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/git/wiki_push_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/groups/autocomplete_service_spec.rb'
|
- 'ee/spec/services/ee/groups/autocomplete_service_spec.rb'
|
||||||
- 'ee/spec/services/ee/groups/deploy_tokens/create_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,
|
'gl-mt-5': !commitsEmpty && contextCommitsEmpty,
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
:variant="commitsEmpty ? 'info' : 'default'"
|
:variant="commitsEmpty ? 'confirm' : 'default'"
|
||||||
@click="openModal"
|
@click="openModal"
|
||||||
>
|
>
|
||||||
{{ buttonText }}
|
{{ buttonText }}
|
||||||
|
|
|
@ -206,6 +206,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
updateStartLine(line) {
|
updateStartLine(line) {
|
||||||
|
this.commentLineStart = line;
|
||||||
this.lines.start = line;
|
this.lines.start = line;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -216,7 +217,6 @@ export default {
|
||||||
<div class="content discussion-form discussion-form-container discussion-notes">
|
<div class="content discussion-form discussion-form-container discussion-notes">
|
||||||
<div class="gl-mb-3 gl-text-gray-500 gl-pb-3">
|
<div class="gl-mb-3 gl-text-gray-500 gl-pb-3">
|
||||||
<multiline-comment-form
|
<multiline-comment-form
|
||||||
v-model="commentLineStart"
|
|
||||||
:line="line"
|
:line="line"
|
||||||
:line-range="lines"
|
:line-range="lines"
|
||||||
:comment-line-options="commentLineOptions"
|
:comment-line-options="commentLineOptions"
|
||||||
|
|
|
@ -7,14 +7,16 @@ import mrPageModule from './modules';
|
||||||
|
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
export const createModules = () => ({
|
||||||
|
page: mrPageModule(),
|
||||||
|
notes: notesModule(),
|
||||||
|
diffs: diffsModule(),
|
||||||
|
batchComments: batchCommentsModule(),
|
||||||
|
});
|
||||||
|
|
||||||
export const createStore = () =>
|
export const createStore = () =>
|
||||||
new Vuex.Store({
|
new Vuex.Store({
|
||||||
modules: {
|
modules: createModules(),
|
||||||
page: mrPageModule(),
|
|
||||||
notes: notesModule(),
|
|
||||||
diffs: diffsModule(),
|
|
||||||
batchComments: batchCommentsModule(),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default createStore();
|
export default createStore();
|
||||||
|
|
|
@ -14,12 +14,12 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="color-item">
|
||||||
<span
|
<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"
|
data-testid="color-item"
|
||||||
:style="{ backgroundColor: color }"
|
:style="{ backgroundColor: color }"
|
||||||
></span>
|
></span>
|
||||||
<span class="hide-collapsed">{{ title }}</span>
|
<span class="color-item-text">{{ title }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { isString } from 'lodash';
|
||||||
import createFlash from '~/flash';
|
import createFlash from '~/flash';
|
||||||
import { s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
|
||||||
|
@ -52,13 +53,23 @@ export default {
|
||||||
required: false,
|
required: false,
|
||||||
default: s__('ColorWidget|Assign epic color'),
|
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() {
|
data() {
|
||||||
return {
|
return {
|
||||||
issuableColor: {
|
issuableColor: this.defaultColor,
|
||||||
color: '',
|
|
||||||
title: '',
|
|
||||||
},
|
|
||||||
colorUpdateInProgress: false,
|
colorUpdateInProgress: false,
|
||||||
oldIid: null,
|
oldIid: null,
|
||||||
sidebarExpandedOnClick: false,
|
sidebarExpandedOnClick: false,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { __, s__ } from '~/locale';
|
import { s__ } from '~/locale';
|
||||||
|
|
||||||
export const COLOR_WIDGET_COLOR = s__('ColorWidget|Color');
|
export const COLOR_WIDGET_COLOR = s__('ColorWidget|Color');
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ export const DROPDOWN_VARIANT = {
|
||||||
Embedded: 'embedded',
|
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 = [
|
export const ISSUABLE_COLORS = [
|
||||||
DEFAULT_COLOR,
|
DEFAULT_COLOR,
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlDropdown } from '@gitlab/ui';
|
import { GlDropdown } from '@gitlab/ui';
|
||||||
|
import ColorItem from './color_item.vue';
|
||||||
import DropdownContentsColorView from './dropdown_contents_color_view.vue';
|
import DropdownContentsColorView from './dropdown_contents_color_view.vue';
|
||||||
import DropdownHeader from './dropdown_header.vue';
|
import DropdownHeader from './dropdown_header.vue';
|
||||||
import { isDropdownVariantSidebar } from './utils';
|
import { isDropdownVariantSidebar } from './utils';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
ColorItem,
|
||||||
DropdownContentsColorView,
|
DropdownContentsColorView,
|
||||||
DropdownHeader,
|
DropdownHeader,
|
||||||
GlDropdown,
|
GlDropdown,
|
||||||
|
@ -42,12 +44,15 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
buttonText() {
|
buttonText() {
|
||||||
if (!this.localSelectedColor?.title) {
|
if (!this.hasSelectedColor()) {
|
||||||
return this.dropdownButtonText;
|
return this.dropdownButtonText;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.localSelectedColor.title;
|
return this.localSelectedColor.title;
|
||||||
},
|
},
|
||||||
|
hasSelectedColor() {
|
||||||
|
return this.localSelectedColor?.title;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
localSelectedColor: {
|
localSelectedColor: {
|
||||||
|
@ -91,7 +96,15 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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>
|
<template #header>
|
||||||
<dropdown-header
|
<dropdown-header
|
||||||
ref="header"
|
ref="header"
|
||||||
|
|
|
@ -36,8 +36,8 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<gl-dropdown-form>
|
<gl-dropdown-form class="js-colors-list">
|
||||||
<div>
|
<div data-testid="dropdown-content">
|
||||||
<gl-dropdown-item
|
<gl-dropdown-item
|
||||||
v-for="color in colors"
|
v-for="color in colors"
|
||||||
:key="color.color"
|
:key="color.color"
|
||||||
|
|
|
@ -20,6 +20,11 @@ export default {
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
hasColor() {
|
||||||
|
return this.selectedColor.color !== '';
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -31,13 +36,18 @@ export default {
|
||||||
class="sidebar-collapsed-icon"
|
class="sidebar-collapsed-icon"
|
||||||
>
|
>
|
||||||
<gl-icon name="appearance" />
|
<gl-icon name="appearance" />
|
||||||
<color-item
|
<color-item :color="selectedColor.color" :title="selectedColor.title" />
|
||||||
:color="selectedColor.color"
|
|
||||||
:title="selectedColor.title"
|
|
||||||
class="gl-font-base gl-line-height-24"
|
|
||||||
/>
|
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
@import './pages/branches';
|
@import './pages/branches';
|
||||||
@import './pages/clusters';
|
@import './pages/clusters';
|
||||||
|
@import './pages/colors';
|
||||||
@import './pages/commits';
|
@import './pages/commits';
|
||||||
@import './pages/deploy_keys';
|
@import './pages/deploy_keys';
|
||||||
@import './pages/detail_page';
|
@import './pages/detail_page';
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
@import './pages/events';
|
@import './pages/events';
|
||||||
@import './pages/groups';
|
@import './pages/groups';
|
||||||
@import './pages/help';
|
@import './pages/help';
|
||||||
|
@import './pages/hierarchy';
|
||||||
@import './pages/issuable';
|
@import './pages/issuable';
|
||||||
@import './pages/issues';
|
@import './pages/issues';
|
||||||
@import './pages/labels';
|
@import './pages/labels';
|
||||||
|
@ -25,9 +27,8 @@
|
||||||
@import './pages/registry';
|
@import './pages/registry';
|
||||||
@import './pages/search';
|
@import './pages/search';
|
||||||
@import './pages/service_desk';
|
@import './pages/service_desk';
|
||||||
@import './pages/settings';
|
|
||||||
@import './pages/settings_ci_cd';
|
@import './pages/settings_ci_cd';
|
||||||
|
@import './pages/settings';
|
||||||
@import './pages/storage_quota';
|
@import './pages/storage_quota';
|
||||||
@import './pages/tree';
|
@import './pages/tree';
|
||||||
@import './pages/users';
|
@import './pages/users';
|
||||||
@import './pages/hierarchy';
|
|
||||||
|
|
|
@ -188,7 +188,11 @@ $dark-il: #de935f;
|
||||||
.diff-line-num.new,
|
.diff-line-num.new,
|
||||||
.line-coverage.new,
|
.line-coverage.new,
|
||||||
.line-codequality.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);
|
@include diff-background($dark-new-bg, $dark-new-idiff, $dark-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
@ -200,7 +204,11 @@ $dark-il: #de935f;
|
||||||
.diff-line-num.old,
|
.diff-line-num.old,
|
||||||
.line-coverage.old,
|
.line-coverage.old,
|
||||||
.line-codequality.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);
|
@include diff-background($dark-old-bg, $dark-old-idiff, $dark-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
|
|
@ -178,7 +178,11 @@ $monokai-gh: #75715e;
|
||||||
.diff-line-num.new,
|
.diff-line-num.new,
|
||||||
.line-coverage.new,
|
.line-coverage.new,
|
||||||
.line-codequality.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);
|
@include diff-background($monokai-new-bg, $monokai-new-idiff, $monokai-diff-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
@ -190,7 +194,11 @@ $monokai-gh: #75715e;
|
||||||
.diff-line-num.old,
|
.diff-line-num.old,
|
||||||
.line-coverage.old,
|
.line-coverage.old,
|
||||||
.line-codequality.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);
|
@include diff-background($monokai-old-bg, $monokai-old-idiff, $monokai-diff-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
|
|
@ -75,7 +75,9 @@
|
||||||
.line-coverage,
|
.line-coverage,
|
||||||
.line-codequality {
|
.line-codequality {
|
||||||
&.old,
|
&.old,
|
||||||
&.new {
|
&.new,
|
||||||
|
&.new-nomappinginraw,
|
||||||
|
&.old-nomappinginraw {
|
||||||
background-color: $white-normal;
|
background-color: $white-normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +133,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.line_content {
|
.line_content {
|
||||||
&.old {
|
&.old, &.old-nomappinginraw {
|
||||||
background-color: $white-normal;
|
background-color: $white-normal;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -144,7 +146,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.new {
|
&.new, &.new-nomappinginraw {
|
||||||
background-color: $white-normal;
|
background-color: $white-normal;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
|
|
@ -117,7 +117,7 @@ $solarized-dark-il: #2aa198;
|
||||||
@include hljs-override('bullet', $solarized-dark-n);
|
@include hljs-override('bullet', $solarized-dark-n);
|
||||||
@include hljs-override('subst', $solarized-dark-p);
|
@include hljs-override('subst', $solarized-dark-p);
|
||||||
@include hljs-override('symbol', $solarized-dark-ni);
|
@include hljs-override('symbol', $solarized-dark-ni);
|
||||||
|
|
||||||
// Line numbers
|
// Line numbers
|
||||||
.file-line-num {
|
.file-line-num {
|
||||||
@include line-number-link($solarized-dark-line-color);
|
@include line-number-link($solarized-dark-line-color);
|
||||||
|
@ -189,7 +189,11 @@ $solarized-dark-il: #2aa198;
|
||||||
.diff-line-num.new,
|
.diff-line-num.new,
|
||||||
.line-coverage.new,
|
.line-coverage.new,
|
||||||
.line-codequality.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);
|
@include diff-background($solarized-dark-new-bg, $solarized-dark-new-idiff, $solarized-dark-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
@ -201,7 +205,11 @@ $solarized-dark-il: #2aa198;
|
||||||
.diff-line-num.old,
|
.diff-line-num.old,
|
||||||
.line-coverage.old,
|
.line-coverage.old,
|
||||||
.line-codequality.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);
|
@include diff-background($solarized-dark-old-bg, $solarized-dark-old-idiff, $solarized-dark-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
|
|
@ -169,7 +169,11 @@ $solarized-light-il: #2aa198;
|
||||||
.diff-line-num.new,
|
.diff-line-num.new,
|
||||||
.line-coverage.new,
|
.line-coverage.new,
|
||||||
.line-codequality.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,
|
@include diff-background($solarized-light-new-bg,
|
||||||
$solarized-light-new-idiff, $solarized-light-border);
|
$solarized-light-new-idiff, $solarized-light-border);
|
||||||
|
|
||||||
|
@ -190,7 +194,11 @@ $solarized-light-il: #2aa198;
|
||||||
.diff-line-num.old,
|
.diff-line-num.old,
|
||||||
.line-coverage.old,
|
.line-coverage.old,
|
||||||
.line-codequality.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);
|
@include diff-background($solarized-light-old-bg, $solarized-light-old-idiff, $solarized-light-border);
|
||||||
|
|
||||||
&::before,
|
&::before,
|
||||||
|
|
|
@ -158,7 +158,8 @@ pre.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
.diff-line-num {
|
.diff-line-num {
|
||||||
&.old {
|
&.old,
|
||||||
|
&.old-nomappinginraw {
|
||||||
background-color: $line-number-old;
|
background-color: $line-number-old;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -166,7 +167,8 @@ pre.code,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.new {
|
&.new,
|
||||||
|
&.new-nomappinginraw {
|
||||||
background-color: $line-number-new;
|
background-color: $line-number-new;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -204,7 +206,8 @@ pre.code,
|
||||||
}
|
}
|
||||||
|
|
||||||
.line_content {
|
.line_content {
|
||||||
&.old {
|
&.old,
|
||||||
|
&.old-nomappinginraw {
|
||||||
background-color: $line-removed;
|
background-color: $line-removed;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -216,7 +219,8 @@ pre.code,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.new {
|
&.new,
|
||||||
|
&.new-nomappinginraw {
|
||||||
background-color: $line-added;
|
background-color: $line-added;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -243,11 +247,13 @@ pre.code,
|
||||||
|
|
||||||
.line-coverage,
|
.line-coverage,
|
||||||
.line-codequality {
|
.line-codequality {
|
||||||
&.old {
|
&.old,
|
||||||
|
&.old-nomappinginraw {
|
||||||
background-color: $line-removed;
|
background-color: $line-removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.new {
|
&.new,
|
||||||
|
&.new-nomappinginraw {
|
||||||
background-color: $line-added;
|
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|
|
= 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
|
%fieldset
|
||||||
.form-group
|
.form-group
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
%b= s_('ProjectSettings|Squash commits when merging')
|
%b= s_('ProjectSettings|Squash commits when merging')
|
||||||
%p.text-secondary
|
%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.')
|
= 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,
|
= settings.gitlab_ui_radio_component :squash_option,
|
||||||
:never,
|
:never,
|
||||||
|
|
|
@ -1060,6 +1060,9 @@ License.current.expires_at
|
||||||
|
|
||||||
# Is this a trial license?
|
# Is this a trial license?
|
||||||
License.current.trial?
|
License.current.trial?
|
||||||
|
|
||||||
|
# License ID for lookup on CustomersDot
|
||||||
|
License.current.license_id
|
||||||
```
|
```
|
||||||
|
|
||||||
### Check if a project feature is available on the instance
|
### 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",
|
"created_at": "2016-08-12 15:23:28 UTC",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"finished_at": null,
|
"finished_at": null,
|
||||||
|
"duration": null,
|
||||||
|
"queued_duration": null,
|
||||||
|
"failure_reason": null,
|
||||||
"when": "manual",
|
"when": "manual",
|
||||||
"manual": true,
|
"manual": true,
|
||||||
"allow_failure": false,
|
"allow_failure": false,
|
||||||
|
@ -1175,7 +1178,10 @@ Payload example:
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"created_at": "2016-08-12 15:23:28 UTC",
|
"created_at": "2016-08-12 15:23:28 UTC",
|
||||||
"started_at": "2016-08-12 15:26:12 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",
|
"when": "on_success",
|
||||||
"manual": false,
|
"manual": false,
|
||||||
"allow_failure": false,
|
"allow_failure": false,
|
||||||
|
@ -1208,10 +1214,13 @@ Payload example:
|
||||||
"id": 378,
|
"id": 378,
|
||||||
"stage": "test",
|
"stage": "test",
|
||||||
"name": "test-build",
|
"name": "test-build",
|
||||||
"status": "success",
|
"status": "failed",
|
||||||
"created_at": "2016-08-12 15:23:28 UTC",
|
"created_at": "2016-08-12 15:23:28 UTC",
|
||||||
"started_at": "2016-08-12 15:26:12 UTC",
|
"started_at": "2016-08-12 15:26:12 UTC",
|
||||||
"finished_at": "2016-08-12 15:26:29 UTC",
|
"finished_at": "2016-08-12 15:26:29 UTC",
|
||||||
|
"duration": 17.0,
|
||||||
|
"queued_duration": 196.0,
|
||||||
|
"failure_reason": "script_failure",
|
||||||
"when": "on_success",
|
"when": "on_success",
|
||||||
"manual": false,
|
"manual": false,
|
||||||
"allow_failure": false,
|
"allow_failure": false,
|
||||||
|
@ -1247,6 +1256,9 @@ Payload example:
|
||||||
"created_at": "2016-08-12 15:23:28 UTC",
|
"created_at": "2016-08-12 15:23:28 UTC",
|
||||||
"started_at": "2016-08-12 15:24:56 UTC",
|
"started_at": "2016-08-12 15:24:56 UTC",
|
||||||
"finished_at": "2016-08-12 15:25:26 UTC",
|
"finished_at": "2016-08-12 15:25:26 UTC",
|
||||||
|
"duration": 17.0,
|
||||||
|
"queued_duration": 196.0,
|
||||||
|
"failure_reason": null,
|
||||||
"when": "on_success",
|
"when": "on_success",
|
||||||
"manual": false,
|
"manual": false,
|
||||||
"allow_failure": false,
|
"allow_failure": false,
|
||||||
|
@ -1282,6 +1294,9 @@ Payload example:
|
||||||
"created_at": "2016-08-12 15:23:28 UTC",
|
"created_at": "2016-08-12 15:23:28 UTC",
|
||||||
"started_at": null,
|
"started_at": null,
|
||||||
"finished_at": null,
|
"finished_at": null,
|
||||||
|
"duration": null,
|
||||||
|
"queued_duration": null,
|
||||||
|
"failure_reason": null,
|
||||||
"when": "on_success",
|
"when": "on_success",
|
||||||
"manual": false,
|
"manual": false,
|
||||||
"allow_failure": false,
|
"allow_failure": false,
|
||||||
|
|
|
@ -118,6 +118,7 @@ module Gitlab
|
||||||
finished_at: build.finished_at,
|
finished_at: build.finished_at,
|
||||||
duration: build.duration,
|
duration: build.duration,
|
||||||
queued_duration: build.queued_duration,
|
queued_duration: build.queued_duration,
|
||||||
|
failure_reason: (build.failure_reason if build.failed?),
|
||||||
when: build.when,
|
when: build.when,
|
||||||
manual: build.action?,
|
manual: build.action?,
|
||||||
allow_failure: build.allow_failure,
|
allow_failure: build.allow_failure,
|
||||||
|
|
|
@ -9035,6 +9035,9 @@ msgstr ""
|
||||||
msgid "Collector hostname"
|
msgid "Collector hostname"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Color"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "ColorWidget|An error occurred while updating color."
|
msgid "ColorWidget|An error occurred while updating color."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -30331,6 +30334,9 @@ msgstr ""
|
||||||
msgid "ProjectSettings|What are merge trains?"
|
msgid "ProjectSettings|What are merge trains?"
|
||||||
msgstr ""
|
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}"
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -34766,6 +34772,9 @@ msgstr ""
|
||||||
msgid "Select a branch to compare"
|
msgid "Select a branch to compare"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Select a color"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Select a compliance framework to apply to this project. %{linkStart}How are these added?%{linkEnd}"
|
msgid "Select a compliance framework to apply to this project. %{linkStart}How are these added?%{linkEnd}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
"graphql": "^15.7.2",
|
"graphql": "^15.7.2",
|
||||||
"graphql-tag": "^2.11.0",
|
"graphql-tag": "^2.11.0",
|
||||||
"hast-util-to-string": "^2.0.0",
|
"hast-util-to-string": "^2.0.0",
|
||||||
"highlight.js": "^11.3.1",
|
"highlight.js": "^11.5.1",
|
||||||
"immer": "^7.0.7",
|
"immer": "^7.0.7",
|
||||||
"ipaddr.js": "^1.9.1",
|
"ipaddr.js": "^1.9.1",
|
||||||
"jed": "^1.1.1",
|
"jed": "^1.1.1",
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
"jszip-utils": "^0.0.2",
|
"jszip-utils": "^0.0.2",
|
||||||
"katex": "^0.13.2",
|
"katex": "^0.13.2",
|
||||||
"lodash": "^4.17.20",
|
"lodash": "^4.17.20",
|
||||||
"lowlight": "^2.5.0",
|
"lowlight": "^2.6.1",
|
||||||
"marked": "^0.3.12",
|
"marked": "^0.3.12",
|
||||||
"mathjax": "3",
|
"mathjax": "3",
|
||||||
"mermaid": "^9.1.1",
|
"mermaid": "^9.1.1",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import MockAdapter from 'axios-mock-adapter';
|
import MockAdapter from 'axios-mock-adapter';
|
||||||
import axios from '~/lib/utils/axios_utils';
|
import axios from '~/lib/utils/axios_utils';
|
||||||
import initMRPage from '~/mr_notes';
|
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';
|
import { userDataMock, notesDataMock, noteableDataMock } from '../notes/mock_data';
|
||||||
|
|
||||||
export default function initVueMRPage() {
|
export default function initVueMRPage() {
|
||||||
|
@ -39,7 +39,7 @@ export default function initVueMRPage() {
|
||||||
const mock = new MockAdapter(axios);
|
const mock = new MockAdapter(axios);
|
||||||
mock.onGet(diffsAppEndpoint).reply(200, {
|
mock.onGet(diffsAppEndpoint).reply(200, {
|
||||||
branch_name: 'foo',
|
branch_name: 'foo',
|
||||||
diff_files: [diffFileMockData],
|
diff_files: [getDiffFileMock()],
|
||||||
});
|
});
|
||||||
|
|
||||||
initMRPage();
|
initMRPage();
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { EVT_EXPAND_ALL_FILES } from '~/diffs/constants';
|
||||||
import eventHub from '~/diffs/event_hub';
|
import eventHub from '~/diffs/event_hub';
|
||||||
import createStore from '~/diffs/store/modules';
|
import createStore from '~/diffs/store/modules';
|
||||||
|
|
||||||
import file from '../mock_data/diff_file';
|
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||||
|
|
||||||
const propsData = {
|
const propsData = {
|
||||||
limited: true,
|
limited: true,
|
||||||
|
@ -15,7 +15,7 @@ const propsData = {
|
||||||
};
|
};
|
||||||
|
|
||||||
async function files(store, count) {
|
async function files(store, count) {
|
||||||
const copies = Array(count).fill(file);
|
const copies = Array(count).fill(getDiffFileMock());
|
||||||
store.state.diffs.diffFiles.push(...copies);
|
store.state.diffs.diffFiles.push(...copies);
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { diffViewerModes } from '~/ide/constants';
|
||||||
import NoteForm from '~/notes/components/note_form.vue';
|
import NoteForm from '~/notes/components/note_form.vue';
|
||||||
import NoPreviewViewer from '~/vue_shared/components/diff_viewer/viewers/no_preview.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 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);
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ describe('DiffContent', () => {
|
||||||
const getCommentFormForDiffFileGetterMock = jest.fn();
|
const getCommentFormForDiffFileGetterMock = jest.fn();
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
diffFile: JSON.parse(JSON.stringify(diffFileMockData)),
|
diffFile: getDiffFileMock(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const createComponent = ({ props, state, provide } = {}) => {
|
const createComponent = ({ props, state, provide } = {}) => {
|
||||||
|
@ -70,7 +70,7 @@ describe('DiffContent', () => {
|
||||||
isInlineView: isInlineViewGetterMock,
|
isInlineView: isInlineViewGetterMock,
|
||||||
isParallelView: isParallelViewGetterMock,
|
isParallelView: isParallelViewGetterMock,
|
||||||
getCommentFormForDiffFile: getCommentFormForDiffFileGetterMock,
|
getCommentFormForDiffFile: getCommentFormForDiffFileGetterMock,
|
||||||
diffLines: () => () => [...diffFileMockData.parallel_diff_lines],
|
diffLines: () => () => [...getDiffFileMock().parallel_diff_lines],
|
||||||
fileLineCodequality: () => () => [],
|
fileLineCodequality: () => () => [],
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { mount } from '@vue/test-utils';
|
import { mount } from '@vue/test-utils';
|
||||||
import { cloneDeep } from 'lodash';
|
|
||||||
import DiffExpansionCell from '~/diffs/components/diff_expansion_cell.vue';
|
import DiffExpansionCell from '~/diffs/components/diff_expansion_cell.vue';
|
||||||
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
|
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
|
||||||
import { getPreviousLineIndex } from '~/diffs/store/utils';
|
import { getPreviousLineIndex } from '~/diffs/store/utils';
|
||||||
import { createStore } from '~/mr_notes/stores';
|
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_UP_CLASS = '.js-unfold';
|
||||||
const EXPAND_DOWN_CLASS = '.js-unfold-down';
|
const EXPAND_DOWN_CLASS = '.js-unfold-down';
|
||||||
|
@ -26,7 +25,7 @@ function makeLoadMoreLinesPayload({
|
||||||
isExpandDown = false,
|
isExpandDown = false,
|
||||||
}) {
|
}) {
|
||||||
return {
|
return {
|
||||||
endpoint: diffFileMockData.context_lines_path,
|
endpoint: getDiffFileMock().context_lines_path,
|
||||||
params: {
|
params: {
|
||||||
since: sinceLine,
|
since: sinceLine,
|
||||||
to: toLine,
|
to: toLine,
|
||||||
|
@ -57,7 +56,7 @@ describe('DiffExpansionCell', () => {
|
||||||
let store;
|
let store;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockFile = cloneDeep(diffFileMockData);
|
mockFile = getDiffFileMock();
|
||||||
mockLine = getLine(mockFile, INLINE_DIFF_VIEW_TYPE, 8);
|
mockLine = getLine(mockFile, INLINE_DIFF_VIEW_TYPE, 8);
|
||||||
store = createStore();
|
store = createStore();
|
||||||
store.state.diffs.diffFiles = [mockFile];
|
store.state.diffs.diffFiles = [mockFile];
|
||||||
|
@ -117,102 +116,102 @@ describe('DiffExpansionCell', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('any row', () => {
|
describe('any row', () => {
|
||||||
[
|
[{ diffViewType: INLINE_DIFF_VIEW_TYPE, lineIndex: 8, file: getDiffFileMock() }].forEach(
|
||||||
{ diffViewType: INLINE_DIFF_VIEW_TYPE, lineIndex: 8, file: cloneDeep(diffFileMockData) },
|
({ diffViewType, file, lineIndex }) => {
|
||||||
].forEach(({ diffViewType, file, lineIndex }) => {
|
describe(`with diffViewType (${diffViewType})`, () => {
|
||||||
describe(`with diffViewType (${diffViewType})`, () => {
|
beforeEach(() => {
|
||||||
beforeEach(() => {
|
mockLine = getLine(mockFile, diffViewType, lineIndex);
|
||||||
mockLine = getLine(mockFile, diffViewType, lineIndex);
|
store.state.diffs.diffFiles = [{ ...mockFile, ...file }];
|
||||||
store.state.diffs.diffFiles = [{ ...mockFile, ...file }];
|
store.state.diffs.diffViewType = diffViewType;
|
||||||
store.state.diffs.diffViewType = diffViewType;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not initially dispatch anything', () => {
|
|
||||||
expect(store.dispatch).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('on expand all clicked, dispatch loadMoreLines', () => {
|
|
||||||
const oldLineNumber = mockLine.meta_data.old_pos;
|
|
||||||
const newLineNumber = mockLine.meta_data.new_pos;
|
|
||||||
const previousIndex = getPreviousLineIndex(mockFile, {
|
|
||||||
oldLineNumber,
|
|
||||||
newLineNumber,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const wrapper = createComponent({ file, lineCountBetween: 10 });
|
it('does not initially dispatch anything', () => {
|
||||||
|
expect(store.dispatch).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
findExpandAll(wrapper).trigger('click');
|
it('on expand all clicked, dispatch loadMoreLines', () => {
|
||||||
|
const oldLineNumber = mockLine.meta_data.old_pos;
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(
|
const newLineNumber = mockLine.meta_data.new_pos;
|
||||||
'diffs/loadMoreLines',
|
const previousIndex = getPreviousLineIndex(mockFile, {
|
||||||
makeLoadMoreLinesPayload({
|
|
||||||
fileHash: mockFile.file_hash,
|
|
||||||
toLine: newLineNumber - 1,
|
|
||||||
sinceLine: previousIndex,
|
|
||||||
oldLineNumber,
|
oldLineNumber,
|
||||||
}),
|
newLineNumber,
|
||||||
);
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('on expand up clicked, dispatch loadMoreLines', () => {
|
const wrapper = createComponent({ file, lineCountBetween: 10 });
|
||||||
mockLine.meta_data.old_pos = 200;
|
|
||||||
mockLine.meta_data.new_pos = 200;
|
|
||||||
|
|
||||||
const oldLineNumber = mockLine.meta_data.old_pos;
|
findExpandAll(wrapper).trigger('click');
|
||||||
const newLineNumber = mockLine.meta_data.new_pos;
|
|
||||||
|
|
||||||
const wrapper = createComponent({ file });
|
expect(store.dispatch).toHaveBeenCalledWith(
|
||||||
|
'diffs/loadMoreLines',
|
||||||
|
makeLoadMoreLinesPayload({
|
||||||
|
fileHash: mockFile.file_hash,
|
||||||
|
toLine: newLineNumber - 1,
|
||||||
|
sinceLine: previousIndex,
|
||||||
|
oldLineNumber,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
findExpandUp(wrapper).trigger('click');
|
it('on expand up clicked, dispatch loadMoreLines', () => {
|
||||||
|
mockLine.meta_data.old_pos = 200;
|
||||||
|
mockLine.meta_data.new_pos = 200;
|
||||||
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith(
|
const oldLineNumber = mockLine.meta_data.old_pos;
|
||||||
'diffs/loadMoreLines',
|
const newLineNumber = mockLine.meta_data.new_pos;
|
||||||
makeLoadMoreLinesPayload({
|
|
||||||
|
const wrapper = createComponent({ file });
|
||||||
|
|
||||||
|
findExpandUp(wrapper).trigger('click');
|
||||||
|
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith(
|
||||||
|
'diffs/loadMoreLines',
|
||||||
|
makeLoadMoreLinesPayload({
|
||||||
|
fileHash: mockFile.file_hash,
|
||||||
|
toLine: newLineNumber - 1,
|
||||||
|
sinceLine: 179,
|
||||||
|
oldLineNumber,
|
||||||
|
diffViewType,
|
||||||
|
unfold: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('on expand down clicked, dispatch loadMoreLines', () => {
|
||||||
|
mockFile[lineSources[diffViewType]][lineIndex + 1] = getDiffFileMock()[
|
||||||
|
lineSources[diffViewType]
|
||||||
|
][lineIndex];
|
||||||
|
const nextLine = getLine(mockFile, diffViewType, lineIndex + 1);
|
||||||
|
|
||||||
|
nextLine.meta_data.old_pos = 300;
|
||||||
|
nextLine.meta_data.new_pos = 300;
|
||||||
|
mockLine.meta_data.old_pos = 200;
|
||||||
|
mockLine.meta_data.new_pos = 200;
|
||||||
|
|
||||||
|
const wrapper = createComponent({ file });
|
||||||
|
|
||||||
|
findExpandDown(wrapper).trigger('click');
|
||||||
|
|
||||||
|
expect(store.dispatch).toHaveBeenCalledWith('diffs/loadMoreLines', {
|
||||||
|
endpoint: mockFile.context_lines_path,
|
||||||
|
params: {
|
||||||
|
since: 1,
|
||||||
|
to: 21, // the load amount, plus 1 line
|
||||||
|
offset: 0,
|
||||||
|
unfold: true,
|
||||||
|
bottom: true,
|
||||||
|
},
|
||||||
|
lineNumbers: {
|
||||||
|
// when expanding down, these are based on the previous line, 0, in this case
|
||||||
|
oldLineNumber: 0,
|
||||||
|
newLineNumber: 0,
|
||||||
|
},
|
||||||
|
nextLineNumbers: { old_line: 200, new_line: 200 },
|
||||||
fileHash: mockFile.file_hash,
|
fileHash: mockFile.file_hash,
|
||||||
toLine: newLineNumber - 1,
|
isExpandDown: true,
|
||||||
sinceLine: 179,
|
});
|
||||||
oldLineNumber,
|
|
||||||
diffViewType,
|
|
||||||
unfold: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('on expand down clicked, dispatch loadMoreLines', () => {
|
|
||||||
mockFile[lineSources[diffViewType]][lineIndex + 1] = cloneDeep(
|
|
||||||
mockFile[lineSources[diffViewType]][lineIndex],
|
|
||||||
);
|
|
||||||
const nextLine = getLine(mockFile, diffViewType, lineIndex + 1);
|
|
||||||
|
|
||||||
nextLine.meta_data.old_pos = 300;
|
|
||||||
nextLine.meta_data.new_pos = 300;
|
|
||||||
mockLine.meta_data.old_pos = 200;
|
|
||||||
mockLine.meta_data.new_pos = 200;
|
|
||||||
|
|
||||||
const wrapper = createComponent({ file });
|
|
||||||
|
|
||||||
findExpandDown(wrapper).trigger('click');
|
|
||||||
|
|
||||||
expect(store.dispatch).toHaveBeenCalledWith('diffs/loadMoreLines', {
|
|
||||||
endpoint: diffFileMockData.context_lines_path,
|
|
||||||
params: {
|
|
||||||
since: 1,
|
|
||||||
to: 21, // the load amount, plus 1 line
|
|
||||||
offset: 0,
|
|
||||||
unfold: true,
|
|
||||||
bottom: true,
|
|
||||||
},
|
|
||||||
lineNumbers: {
|
|
||||||
// when expanding down, these are based on the previous line, 0, in this case
|
|
||||||
oldLineNumber: 0,
|
|
||||||
newLineNumber: 0,
|
|
||||||
},
|
|
||||||
nextLineNumbers: { old_line: 200, new_line: 200 },
|
|
||||||
fileHash: mockFile.file_hash,
|
|
||||||
isExpandDown: true,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -20,7 +20,7 @@ import axios from '~/lib/utils/axios_utils';
|
||||||
import { scrollToElement } from '~/lib/utils/common_utils';
|
import { scrollToElement } from '~/lib/utils/common_utils';
|
||||||
import httpStatus from '~/lib/utils/http_status';
|
import httpStatus from '~/lib/utils/http_status';
|
||||||
import createNotesStore from '~/notes/stores/modules';
|
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';
|
import diffFileMockDataUnreadable from '../mock_data/diff_file_unreadable';
|
||||||
|
|
||||||
jest.mock('~/lib/utils/common_utils');
|
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 findToggleButton = (wrapper) => wrapper.find('[data-testid="expand-button"]');
|
||||||
|
|
||||||
const toggleFile = (wrapper) => findDiffHeader(wrapper).vm.$emit('toggleFile');
|
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 getUnreadableFile = () => JSON.parse(JSON.stringify(diffFileMockDataUnreadable));
|
||||||
|
|
||||||
const makeFileAutomaticallyCollapsed = (store, index = 0) =>
|
const makeFileAutomaticallyCollapsed = (store, index = 0) =>
|
||||||
|
|
|
@ -1,82 +1,166 @@
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
import Autosave from '~/autosave';
|
||||||
import DiffLineNoteForm from '~/diffs/components/diff_line_note_form.vue';
|
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 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 { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
|
||||||
import { noteableDataMock } from 'jest/notes/mock_data';
|
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', () => {
|
jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal');
|
||||||
return {
|
jest.mock('~/autosave');
|
||||||
confirmAction: jest.fn(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('DiffLineNoteForm', () => {
|
describe('DiffLineNoteForm', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
let diffFile;
|
let diffFile;
|
||||||
let diffLines;
|
let diffLines;
|
||||||
const getDiffFileMock = () => ({ ...diffFileMockData });
|
let actions;
|
||||||
|
let store;
|
||||||
|
|
||||||
const createComponent = (args = {}) => {
|
const getSelectedLine = () => {
|
||||||
diffFile = getDiffFileMock();
|
const lineCode = diffLines[1].line_code;
|
||||||
diffLines = diffFile.highlighted_diff_lines;
|
return diffFile.highlighted_diff_lines.find((l) => l.line_code === lineCode);
|
||||||
const store = createStore();
|
};
|
||||||
|
|
||||||
|
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.userData.id = 1;
|
||||||
store.state.notes.noteableData = noteableDataMock;
|
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.state.diffs.diffFiles = [diffFile];
|
||||||
|
|
||||||
store.replaceState({ ...store.state, ...args.state });
|
const propsData = {
|
||||||
|
diffFileHash: diffFile.file_hash,
|
||||||
|
diffLines,
|
||||||
|
line: diffLines[1],
|
||||||
|
range: { start: diffLines[0], end: diffLines[1] },
|
||||||
|
noteTargetLine: diffLines[1],
|
||||||
|
...props,
|
||||||
|
};
|
||||||
|
|
||||||
return shallowMount(DiffLineNoteForm, {
|
wrapper = shallowMount(DiffLineNoteForm, {
|
||||||
store,
|
store,
|
||||||
propsData: {
|
propsData,
|
||||||
...{
|
|
||||||
diffFileHash: diffFile.file_hash,
|
|
||||||
diffLines,
|
|
||||||
line: diffLines[1],
|
|
||||||
range: { start: diffLines[0], end: diffLines[1] },
|
|
||||||
noteTargetLine: diffLines[1],
|
|
||||||
},
|
|
||||||
...(args.props || {}),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const findNoteForm = () => wrapper.findComponent(NoteForm);
|
const findNoteForm = () => wrapper.findComponent(NoteForm);
|
||||||
|
const findCommentForm = () => wrapper.findComponent(MultilineCommentForm);
|
||||||
|
|
||||||
describe('methods', () => {
|
beforeEach(() => {
|
||||||
beforeEach(() => {
|
Autosave.mockClear();
|
||||||
wrapper = createComponent();
|
createComponent();
|
||||||
|
});
|
||||||
|
|
||||||
|
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();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('handleCancelCommentForm', () => {
|
it('should only ask for confirmation once', () => {
|
||||||
afterEach(() => {
|
let finalizePromise;
|
||||||
confirmAction.mockReset();
|
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', () => {
|
it('should ask for confirmation when shouldConfirm and isDirty passed as truthy', () => {
|
||||||
confirmAction.mockResolvedValueOnce(false);
|
|
||||||
|
|
||||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
findNoteForm().vm.$emit('cancelForm', true, true);
|
||||||
|
|
||||||
expect(confirmAction).toHaveBeenCalled();
|
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(() => {}));
|
|
||||||
|
|
||||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
|
||||||
findNoteForm().vm.$emit('cancelForm', true, true);
|
|
||||||
|
|
||||||
expect(confirmAction).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not ask for confirmation when one of the params false', () => {
|
it('should not ask for confirmation when one of the params false', () => {
|
||||||
confirmAction.mockResolvedValueOnce(false);
|
|
||||||
|
|
||||||
findNoteForm().vm.$emit('cancelForm', true, false);
|
findNoteForm().vm.$emit('cancelForm', true, false);
|
||||||
|
|
||||||
expect(confirmAction).not.toHaveBeenCalled();
|
expect(confirmAction).not.toHaveBeenCalled();
|
||||||
|
@ -85,116 +169,39 @@ describe('DiffLineNoteForm', () => {
|
||||||
|
|
||||||
expect(confirmAction).not.toHaveBeenCalled();
|
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());
|
|
||||||
|
|
||||||
const lineRange = {
|
|
||||||
start: {
|
|
||||||
line_code: wrapper.vm.commentLineStart.line_code,
|
|
||||||
type: wrapper.vm.commentLineStart.type,
|
|
||||||
new_line: 2,
|
|
||||||
old_line: null,
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
line_code: wrapper.vm.line.line_code,
|
|
||||||
type: wrapper.vm.line.type,
|
|
||||||
new_line: 2,
|
|
||||||
old_line: null,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const formData = {
|
|
||||||
...wrapper.vm.formData,
|
|
||||||
lineRange,
|
|
||||||
};
|
|
||||||
|
|
||||||
await wrapper.vm.handleSaveNote('note body');
|
|
||||||
expect(saveDiffDiscussionSpy).toHaveBeenCalledWith({
|
|
||||||
note: 'note body',
|
|
||||||
formData,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('created', () => {
|
describe('saving note', () => {
|
||||||
it('should use the provided `range` of lines', () => {
|
it('should save original line', async () => {
|
||||||
wrapper = createComponent();
|
const lineRange = {
|
||||||
|
start: {
|
||||||
expect(wrapper.vm.lines.start).toBe(diffLines[0]);
|
line_code: diffLines[1].line_code,
|
||||||
expect(wrapper.vm.lines.end).toBe(diffLines[1]);
|
type: diffLines[1].type,
|
||||||
});
|
new_line: 2,
|
||||||
|
old_line: null,
|
||||||
it("should fill the internal `lines` data with the provided `line` if there's no provided `range", () => {
|
},
|
||||||
wrapper = createComponent({ props: { range: null } });
|
end: {
|
||||||
|
line_code: diffLines[1].line_code,
|
||||||
expect(wrapper.vm.lines.start).toBe(diffLines[1]);
|
type: diffLines[1].type,
|
||||||
expect(wrapper.vm.lines.end).toBe(diffLines[1]);
|
new_line: 2,
|
||||||
});
|
old_line: null,
|
||||||
});
|
|
||||||
|
|
||||||
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 });
|
await findNoteForm().vm.$emit('handleFormUpdate', 'note body');
|
||||||
startLineCode = wrapper.vm.commentLineStart.line_code;
|
expect(actions.saveDiffDiscussion.mock.calls[0][1].formData).toMatchObject({
|
||||||
lineCode = state.notes.selectedCommentPosition.start.line_code;
|
lineRange,
|
||||||
expect(startLineCode).toEqual(lineCode);
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('template', () => {
|
it('should save selected line from the store', async () => {
|
||||||
it('should have note form', () => {
|
const lineCode = 'test';
|
||||||
wrapper = createComponent();
|
store.state.notes.selectedCommentPosition = { start: { line_code: lineCode } };
|
||||||
expect(wrapper.find(NoteForm).exists()).toBe(true);
|
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 { mapParallel } from '~/diffs/components/diff_row_utils';
|
||||||
import diffsModule from '~/diffs/store/modules';
|
import diffsModule from '~/diffs/store/modules';
|
||||||
import { findInteropAttributes } from '../find_interop_attributes';
|
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 showCommentForm = jest.fn();
|
||||||
const enterdragging = jest.fn();
|
const enterdragging = jest.fn();
|
||||||
|
@ -210,6 +210,7 @@ describe('DiffRow', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('sets coverage title and class', () => {
|
describe('sets coverage title and class', () => {
|
||||||
|
const diffFileMockData = getDiffFileMock();
|
||||||
const thisLine = diffFileMockData.parallel_diff_lines[2];
|
const thisLine = diffFileMockData.parallel_diff_lines[2];
|
||||||
const rightLine = diffFileMockData.parallel_diff_lines[2].right;
|
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 { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||||
|
|
||||||
import DiffStats from '~/diffs/components/diff_stats.vue';
|
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_ADDED_LINES = 100;
|
||||||
const TEST_REMOVED_LINES = 200;
|
const TEST_REMOVED_LINES = 200;
|
||||||
|
@ -48,6 +48,7 @@ describe('diff_stats', () => {
|
||||||
const getBytesContainer = () => wrapper.find('.diff-stats > div:first-child');
|
const getBytesContainer = () => wrapper.find('.diff-stats > div:first-child');
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
const mockDiffFile = getDiffFileMock();
|
||||||
file = {
|
file = {
|
||||||
...mockDiffFile,
|
...mockDiffFile,
|
||||||
viewer: {
|
viewer: {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export default {
|
export const getDiffFileMock = () => ({
|
||||||
submodule: false,
|
submodule: false,
|
||||||
submodule_link: null,
|
submodule_link: null,
|
||||||
blob: {
|
blob: {
|
||||||
|
@ -305,4 +305,4 @@ export default {
|
||||||
],
|
],
|
||||||
discussions: [],
|
discussions: [],
|
||||||
renderingLines: false,
|
renderingLines: false,
|
||||||
};
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Cookies from '~/lib/utils/cookies';
|
||||||
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
|
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
|
||||||
import { TEST_HOST } from 'helpers/test_constants';
|
import { TEST_HOST } from 'helpers/test_constants';
|
||||||
import testAction from 'helpers/vuex_action_helper';
|
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 {
|
import {
|
||||||
DIFF_VIEW_COOKIE_NAME,
|
DIFF_VIEW_COOKIE_NAME,
|
||||||
INLINE_DIFF_VIEW_TYPE,
|
INLINE_DIFF_VIEW_TYPE,
|
||||||
|
@ -754,7 +754,7 @@ describe('DiffsStoreActions', () => {
|
||||||
it('dispatches actions', () => {
|
it('dispatches actions', () => {
|
||||||
const commitId = 'something';
|
const commitId = 'something';
|
||||||
const formData = {
|
const formData = {
|
||||||
diffFile: { ...mockDiffFile },
|
diffFile: getDiffFileMock(),
|
||||||
noteableData: {},
|
noteableData: {},
|
||||||
};
|
};
|
||||||
const note = {};
|
const note = {};
|
||||||
|
|
|
@ -3,7 +3,7 @@ import createState from '~/diffs/store/modules/diff_state';
|
||||||
import * as types from '~/diffs/store/mutation_types';
|
import * as types from '~/diffs/store/mutation_types';
|
||||||
import mutations from '~/diffs/store/mutations';
|
import mutations from '~/diffs/store/mutations';
|
||||||
import * as utils from '~/diffs/store/utils';
|
import * as utils from '~/diffs/store/utils';
|
||||||
import diffFileMockData from '../mock_data/diff_file';
|
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||||
|
|
||||||
describe('DiffsStoreMutations', () => {
|
describe('DiffsStoreMutations', () => {
|
||||||
describe('SET_BASE_CONFIG', () => {
|
describe('SET_BASE_CONFIG', () => {
|
||||||
|
@ -71,6 +71,7 @@ describe('DiffsStoreMutations', () => {
|
||||||
|
|
||||||
describe('SET_DIFF_METADATA', () => {
|
describe('SET_DIFF_METADATA', () => {
|
||||||
it('should overwrite state with the camelCased data that is passed in', () => {
|
it('should overwrite state with the camelCased data that is passed in', () => {
|
||||||
|
const diffFileMockData = getDiffFileMock();
|
||||||
const state = {
|
const state = {
|
||||||
diffFiles: [],
|
diffFiles: [],
|
||||||
};
|
};
|
||||||
|
@ -94,7 +95,7 @@ describe('DiffsStoreMutations', () => {
|
||||||
it('should set diff data batch type properly', () => {
|
it('should set diff data batch type properly', () => {
|
||||||
const state = { diffFiles: [] };
|
const state = { diffFiles: [] };
|
||||||
const diffMock = {
|
const diffMock = {
|
||||||
diff_files: [diffFileMockData],
|
diff_files: [getDiffFileMock()],
|
||||||
};
|
};
|
||||||
|
|
||||||
mutations[types.SET_DIFF_DATA_BATCH](state, diffMock);
|
mutations[types.SET_DIFF_DATA_BATCH](state, diffMock);
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { clone } from 'lodash';
|
|
||||||
import {
|
import {
|
||||||
LINE_POSITION_LEFT,
|
LINE_POSITION_LEFT,
|
||||||
LINE_POSITION_RIGHT,
|
LINE_POSITION_RIGHT,
|
||||||
|
@ -14,10 +13,9 @@ import {
|
||||||
import * as utils from '~/diffs/store/utils';
|
import * as utils from '~/diffs/store/utils';
|
||||||
import { MERGE_REQUEST_NOTEABLE_TYPE } from '~/notes/constants';
|
import { MERGE_REQUEST_NOTEABLE_TYPE } from '~/notes/constants';
|
||||||
import { noteableDataMock } from 'jest/notes/mock_data';
|
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';
|
import { diffMetadata } from '../mock_data/diff_metadata';
|
||||||
|
|
||||||
const getDiffFileMock = () => JSON.parse(JSON.stringify(diffFileMockData));
|
|
||||||
const getDiffMetadataMock = () => JSON.parse(JSON.stringify(diffMetadata));
|
const getDiffMetadataMock = () => JSON.parse(JSON.stringify(diffMetadata));
|
||||||
|
|
||||||
describe('DiffsStoreUtils', () => {
|
describe('DiffsStoreUtils', () => {
|
||||||
|
@ -47,7 +45,7 @@ describe('DiffsStoreUtils', () => {
|
||||||
let diffFile;
|
let diffFile;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
diffFile = { ...clone(diffFileMockData) };
|
diffFile = getDiffFileMock();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the correct previous line number', () => {
|
it('should return the correct previous line number', () => {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
match,
|
match,
|
||||||
} from '~/diffs/utils/diff_file';
|
} from '~/diffs/utils/diff_file';
|
||||||
import { diffViewerModes } from '~/ide/constants';
|
import { diffViewerModes } from '~/ide/constants';
|
||||||
import mockDiffFile from '../mock_data/diff_file';
|
import { getDiffFileMock } from '../mock_data/diff_file';
|
||||||
|
|
||||||
function getDiffFiles() {
|
function getDiffFiles() {
|
||||||
const loadFull = 'namespace/project/-/merge_requests/12345/diff_for_path?file_identifier=abc';
|
const loadFull = 'namespace/project/-/merge_requests/12345/diff_for_path?file_identifier=abc';
|
||||||
|
@ -210,7 +210,7 @@ describe('diff_file utilities', () => {
|
||||||
];
|
];
|
||||||
const validFile = [
|
const validFile = [
|
||||||
'computes the correct stats from a file',
|
'computes the correct stats from a file',
|
||||||
mockDiffFile,
|
getDiffFileMock(),
|
||||||
{
|
{
|
||||||
changed: 1024,
|
changed: 1024,
|
||||||
percent: 100,
|
percent: 100,
|
||||||
|
@ -223,7 +223,7 @@ describe('diff_file utilities', () => {
|
||||||
const negativeChange = [
|
const negativeChange = [
|
||||||
'computed the correct states from a file with a negative size change',
|
'computed the correct states from a file with a negative size change',
|
||||||
{
|
{
|
||||||
...mockDiffFile,
|
...getDiffFileMock(),
|
||||||
new_size: 0,
|
new_size: 0,
|
||||||
old_size: 1024,
|
old_size: 1024,
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
import discussionWithTwoUnresolvedNotes from 'test_fixtures/merge_requests/resolved_diff_discussion.json';
|
import discussionWithTwoUnresolvedNotes from 'test_fixtures/merge_requests/resolved_diff_discussion.json';
|
||||||
import { trimText } from 'helpers/text_helper';
|
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 DiscussionNotes from '~/notes/components/discussion_notes.vue';
|
||||||
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
|
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
|
||||||
import ResolveWithIssueButton from '~/notes/components/discussion_resolve_with_issue_button.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 () => {
|
it('should render thread header', async () => {
|
||||||
const discussion = { ...discussionMock };
|
const discussion = { ...discussionMock };
|
||||||
discussion.diff_file = mockDiffFile;
|
discussion.diff_file = getDiffFileMock();
|
||||||
discussion.diff_discussion = true;
|
discussion.diff_discussion = true;
|
||||||
discussion.expanded = false;
|
discussion.expanded = false;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ describe('noteable_discussion component', () => {
|
||||||
|
|
||||||
it('should hide actions when diff refs do not exists', async () => {
|
it('should hide actions when diff refs do not exists', async () => {
|
||||||
const discussion = { ...discussionMock };
|
const discussion = { ...discussionMock };
|
||||||
discussion.diff_file = { ...mockDiffFile, diff_refs: null };
|
discussion.diff_file = { ...getDiffFileMock(), diff_refs: null };
|
||||||
discussion.diff_discussion = true;
|
discussion.diff_discussion = true;
|
||||||
discussion.expanded = false;
|
discussion.expanded = false;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ describe('DropdownValue', () => {
|
||||||
|
|
||||||
it.each`
|
it.each`
|
||||||
index | cssClass
|
index | cssClass
|
||||||
${0} | ${['gl-font-base', 'gl-line-height-24']}
|
${0} | ${[]}
|
||||||
${1} | ${['hide-collapsed']}
|
${1} | ${['hide-collapsed']}
|
||||||
`(
|
`(
|
||||||
'passes correct props to the ColorItem with CSS class `$cssClass`',
|
'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).to be_a(Hash)
|
||||||
expect(build_data[:id]).to eq(build.id)
|
expect(build_data[:id]).to eq(build.id)
|
||||||
expect(build_data[:status]).to eq(build.status)
|
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[:allow_failure]).to eq(build.allow_failure)
|
||||||
expect(build_data[:environment]).to be_nil
|
expect(build_data[:environment]).to be_nil
|
||||||
expect(runner_data).to eq(nil)
|
expect(runner_data).to eq(nil)
|
||||||
|
@ -197,4 +198,14 @@ RSpec.describe Gitlab::DataBuilder::Pipeline do
|
||||||
end
|
end
|
||||||
end
|
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
|
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"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||||
|
|
||||||
highlight.js@^11.3.1, highlight.js@~11.4.0:
|
highlight.js@^11.5.1, highlight.js@~11.5.0:
|
||||||
version "11.4.0"
|
version "11.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.4.0.tgz#34ceadd49e1596ee5aba3d99346cdfd4845ee05a"
|
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.5.1.tgz#027c24e4509e2f4dcd00b4a6dda542ce0a1f7aea"
|
||||||
integrity sha512-nawlpCBCSASs7EdvZOYOYVkJpGmAOKMYZgZtUqSRqodZE0GRVcFKwo1RcpeOemqh9hyttTdd5wDBwHkuSyUfnA==
|
integrity sha512-LKzHqnxr4CrD2YsNoIf/o5nJ09j4yi/GcH5BnYz9UnVpZdS4ucMgvP61TDty5xJcFGRjnH4DpujkS9bHT3hq0Q==
|
||||||
|
|
||||||
highlight.js@~10.7.0:
|
highlight.js@~10.7.0:
|
||||||
version "10.7.2"
|
version "10.7.2"
|
||||||
|
@ -8405,14 +8405,14 @@ lowlight@^1.20.0:
|
||||||
fault "^1.0.0"
|
fault "^1.0.0"
|
||||||
highlight.js "~10.7.0"
|
highlight.js "~10.7.0"
|
||||||
|
|
||||||
lowlight@^2.5.0:
|
lowlight@^2.6.1:
|
||||||
version "2.5.0"
|
version "2.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-2.5.0.tgz#723a39fc0d9b911731a395b320519cbb0790ab14"
|
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-2.6.1.tgz#d3cbc7ae0530c848e512b8e6528609587520b44f"
|
||||||
integrity sha512-OXGUch9JZu4q5r4Ir6QlUp5pBXMxS7NHaclhRiUlxNRcOSK0gtXZcVrsGP4eM7bv0/KDHg/TXQagx/X35EULsA==
|
integrity sha512-t0ueDL6SIn9FKHipm78CNjWcJQv0xi6WCjYAICyO6GyPzoT7E58yom1mNwvI7AMwVe3pLwwFT0Bt2gml7uaUeQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/hast" "^2.0.0"
|
"@types/hast" "^2.0.0"
|
||||||
fault "^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:
|
lru-cache@^4.1.2, lru-cache@^4.1.5:
|
||||||
version "4.1.5"
|
version "4.1.5"
|
||||||
|
|
Loading…
Reference in New Issue