Commit f4f3f286 authored by Phil Hughes's avatar Phil Hughes

Merge branch '47149-override-squash-commits-message-clean' into 'master'

Resolve "Override squash commit message"

Closes #47149

See merge request gitlab-org/gitlab-ce!24724
parents 232ae06a 407fd2ed
<script>
export default {
props: {
value: {
type: String,
required: true,
},
label: {
type: String,
required: true,
},
inputId: {
type: String,
required: true,
},
},
};
</script>
<template>
<li>
<div class="commit-message-editor">
<div class="d-flex flex-wrap align-items-center justify-content-between">
<label class="col-form-label" :for="inputId">
<strong>{{ label }}</strong>
</label>
<slot name="header"></slot>
</div>
<textarea
:id="inputId"
:value="value"
class="form-control js-gfm-input append-bottom-default commit-message-edit"
required="required"
rows="7"
@input="$emit('input', $event.target.value)"
></textarea>
<slot name="checkbox"></slot>
</div>
</li>
</template>
<script>
import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
export default {
components: {
GlDropdown,
GlDropdownItem,
},
props: {
commits: {
type: Array,
required: true,
default: () => [],
},
},
};
</script>
<template>
<div>
<gl-dropdown
right
no-caret
text="Use an existing commit message"
variant="link"
class="mr-commit-dropdown"
>
<gl-dropdown-item
v-for="commit in commits"
:key="commit.short_id"
class="text-nowrap text-truncate"
@click="$emit('input', commit.message)"
>
<span class="monospace mr-2">{{ commit.short_id }}</span> {{ commit.title }}
</gl-dropdown-item>
</gl-dropdown>
</div>
</template>
<script>
import { GlButton } from '@gitlab/ui';
import _ from 'underscore';
import { __, n__, sprintf, s__ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
export default {
components: {
Icon,
GlButton,
},
props: {
isSquashEnabled: {
type: Boolean,
required: true,
},
commitsCount: {
type: Number,
required: false,
default: 0,
},
targetBranch: {
type: String,
required: true,
},
},
data() {
return {
expanded: false,
};
},
computed: {
collapseIcon() {
return this.expanded ? 'chevron-down' : 'chevron-right';
},
commitsCountMessage() {
return n__(__('%d commit'), __('%d commits'), this.isSquashEnabled ? 1 : this.commitsCount);
},
modifyLinkMessage() {
return this.isSquashEnabled ? __('Modify commit messages') : __('Modify merge commit');
},
ariaLabel() {
return this.expanded ? __('Collapse') : __('Expand');
},
message() {
return sprintf(
s__(
'mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}.',
),
{
commitCount: `<strong class="commits-count-message">${this.commitsCountMessage}</strong>`,
mergeCommitCount: `<strong>${s__('mrWidgetCommitsAdded|1 merge commit')}</strong>`,
targetBranch: `<span class="label-branch">${_.escape(this.targetBranch)}</span>`,
},
false,
);
},
},
methods: {
toggle() {
this.expanded = !this.expanded;
},
},
};
</script>
<template>
<div>
<div
class="js-mr-widget-commits-count mr-widget-extension clickable d-flex align-items-center px-3 py-2"
@click="toggle()"
>
<gl-button
:aria-label="ariaLabel"
variant="blank"
class="commit-edit-toggle mr-2"
@click.stop="toggle()"
>
<icon :name="collapseIcon" :size="16" />
</gl-button>
<span v-if="expanded">{{ __('Collapse') }}</span>
<span v-else>
<span v-html="message"></span>
<gl-button variant="link" class="modify-message-button">
{{ modifyLinkMessage }}
</gl-button>
</span>
</div>
<div v-show="expanded"><slot></slot></div>
</div>
</template>
...@@ -315,7 +315,7 @@ export default { ...@@ -315,7 +315,7 @@ export default {
:endpoint="mr.testResultsPath" :endpoint="mr.testResultsPath"
/> />
<div class="mr-widget-section"> <div class="mr-widget-section p-0">
<component :is="componentName" :mr="mr" :service="service" /> <component :is="componentName" :mr="mr" :service="service" />
<section v-if="shouldRenderCollaborationStatus" class="mr-info-list mr-links"> <section v-if="shouldRenderCollaborationStatus" class="mr-info-list mr-links">
......
...@@ -42,6 +42,8 @@ export default class MergeRequestStore { ...@@ -42,6 +42,8 @@ export default class MergeRequestStore {
this.mergePipeline = data.merge_pipeline || {}; this.mergePipeline = data.merge_pipeline || {};
this.deployments = this.deployments || data.deployments || []; this.deployments = this.deployments || data.deployments || [];
this.postMergeDeployments = this.postMergeDeployments || []; this.postMergeDeployments = this.postMergeDeployments || [];
this.commits = data.commits_without_merge_commits || [];
this.squashCommitMessage = data.default_squash_commit_message;
this.initRebase(data); this.initRebase(data);
if (data.issues_links) { if (data.issues_links) {
......
...@@ -391,6 +391,11 @@ img.emoji { ...@@ -391,6 +391,11 @@ img.emoji {
.flex-no-shrink { flex-shrink: 0; } .flex-no-shrink { flex-shrink: 0; }
.ws-initial { white-space: initial; } .ws-initial { white-space: initial; }
.overflow-auto { overflow: auto; } .overflow-auto { overflow: auto; }
.d-flex-center {
display: flex;
align-items: center;
justify-content: center;
}
/** COMMON SIZING CLASSES **/ /** COMMON SIZING CLASSES **/
.w-0 { width: 0; } .w-0 { width: 0; }
...@@ -402,6 +407,10 @@ img.emoji { ...@@ -402,6 +407,10 @@ img.emoji {
.min-height-0 { min-height: 0; } .min-height-0 { min-height: 0; }
.w-3 { width: #{3 * $grid-size}; }
.h-3 { width: #{3 * $grid-size}; }
/** COMMON SPACING CLASSES **/ /** COMMON SPACING CLASSES **/
.gl-pl-0 { padding-left: 0; } .gl-pl-0 { padding-left: 0; }
.gl-pl-1 { padding-left: #{0.5 * $grid-size}; } .gl-pl-1 { padding-left: #{0.5 * $grid-size}; }
......
...@@ -243,6 +243,7 @@ $gl-padding-8: 8px; ...@@ -243,6 +243,7 @@ $gl-padding-8: 8px;
$gl-padding: 16px; $gl-padding: 16px;
$gl-padding-24: 24px; $gl-padding-24: 24px;
$gl-padding-32: 32px; $gl-padding-32: 32px;
$gl-padding-50: 50px;
$gl-col-padding: 15px; $gl-col-padding: 15px;
$gl-input-padding: 10px; $gl-input-padding: 10px;
$gl-vert-padding: 6px; $gl-vert-padding: 6px;
......
...@@ -38,9 +38,7 @@ ...@@ -38,9 +38,7 @@
} }
.mr-widget-section { .mr-widget-section {
.media { border-radius: $border-radius-default $border-radius-default 0 0;
align-items: center;
}
.code-text { .code-text {
flex: 1; flex: 1;
...@@ -56,6 +54,11 @@ ...@@ -56,6 +54,11 @@
.mr-widget-extension { .mr-widget-extension {
border-top: 1px solid $border-color; border-top: 1px solid $border-color;
background-color: $gray-light; background-color: $gray-light;
&.clickable:hover {
background-color: $gl-gray-200;
cursor: pointer;
}
} }
.mr-widget-workflow { .mr-widget-workflow {
...@@ -78,6 +81,7 @@ ...@@ -78,6 +81,7 @@
border-top: 0; border-top: 0;
} }
.mr-widget-body,
.mr-widget-section, .mr-widget-section,
.mr-widget-content, .mr-widget-content,
.mr-widget-footer { .mr-widget-footer {
...@@ -87,11 +91,38 @@ ...@@ -87,11 +91,38 @@
.mr-state-widget { .mr-state-widget {
color: $gl-text-color; color: $gl-text-color;
.commit-message-edit {
border-radius: $border-radius-default;
}
.mr-widget-section, .mr-widget-section,
.mr-widget-footer { .mr-widget-footer {
border-top: solid 1px $border-color; border-top: solid 1px $border-color;
} }
.mr-fast-forward-message {
padding-left: $gl-padding-50;
padding-bottom: $gl-padding;
}
.commits-list {
> li {
padding: $gl-padding;
@include media-breakpoint-up(md) {
padding-left: $gl-padding-50;
}
}
}
.mr-commit-dropdown {
.dropdown-menu {
@include media-breakpoint-up(md) {
width: 150%;
}
}
}
.mr-widget-footer { .mr-widget-footer {
padding: 0; padding: 0;
} }
...@@ -405,7 +436,7 @@ ...@@ -405,7 +436,7 @@
} }
.mr-widget-help { .mr-widget-help {
padding: 10px 16px 10px 48px; padding: 10px 16px 10px $gl-padding-50;
font-style: italic; font-style: italic;
} }
...@@ -423,10 +454,6 @@ ...@@ -423,10 +454,6 @@
} }
} }
.mr-widget-body-controls {
flex-wrap: wrap;
}
.mr_source_commit, .mr_source_commit,
.mr_target_commit { .mr_target_commit {
margin-bottom: 0; margin-bottom: 0;
......
---
title: Default squash commit message is now selected from the longest commit when
squashing merge requests
merge_request: 24518
author:
type: changed
...@@ -23,11 +23,14 @@ The squashed commit's commit message will be either: ...@@ -23,11 +23,14 @@ The squashed commit's commit message will be either:
- Taken from the first multi-line commit message in the merge. - Taken from the first multi-line commit message in the merge.
- The merge request's title if no multi-line commit message is found. - The merge request's title if no multi-line commit message is found.
Note that the squashed commit is still followed by a merge commit, It can be customized before merging a merge request.
as the merge method for this example repository uses a merge commit.
Squashing also works with the fast-forward merge strategy, see ![A squash commit message editor](img/squash_mr_message.png)
[squashing and fast-forward merge](#squash-and-fast-forward-merge) for more
details. NOTE: **Note:**
The squashed commit in this example is followed by a merge commit, as the merge method for this example repository uses a merge commit.
Squashing also works with the fast-forward merge strategy, see [squashing and fast-forward merge](#squash-and-fast-forward-merge) for more details.
## Use cases ## Use cases
...@@ -60,7 +63,7 @@ This can then be overridden at the time of accepting the merge request: ...@@ -60,7 +63,7 @@ This can then be overridden at the time of accepting the merge request:
The squashed commit has the following metadata: The squashed commit has the following metadata:
- Message: the message of the squash commit. - Message: the message of the squash commit, or a customized message.
- Author: the author of the merge request. - Author: the author of the merge request.
- Committer: the user who initiated the squash. - Committer: the user who initiated the squash.
......
...@@ -32,6 +32,9 @@ msgid_plural "%d commits behind" ...@@ -32,6 +32,9 @@ msgid_plural "%d commits behind"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "%d commits"
msgstr ""
msgid "%d exporter" msgid "%d exporter"
msgid_plural "%d exporters" msgid_plural "%d exporters"
msgstr[0] "" msgstr[0] ""
...@@ -2531,6 +2534,9 @@ msgstr "" ...@@ -2531,6 +2534,9 @@ msgstr ""
msgid "Delete list" msgid "Delete list"
msgstr "" msgstr ""
msgid "Delete source branch"
msgstr ""
msgid "Delete this attachment" msgid "Delete this attachment"
msgstr "" msgstr ""
...@@ -3256,6 +3262,9 @@ msgstr "" ...@@ -3256,6 +3262,9 @@ msgstr ""
msgid "Failure" msgid "Failure"
msgstr "" msgstr ""
msgid "Fast-forward merge without a merge commit"
msgstr ""
msgid "Faster as it re-uses the project workspace (falling back to clone if it doesn't exist)" msgid "Faster as it re-uses the project workspace (falling back to clone if it doesn't exist)"
msgstr "" msgstr ""
...@@ -3905,6 +3914,9 @@ msgstr "" ...@@ -3905,6 +3914,9 @@ msgstr ""
msgid "Include a Terms of Service agreement and Privacy Policy that all users must accept." msgid "Include a Terms of Service agreement and Privacy Policy that all users must accept."
msgstr "" msgstr ""
msgid "Include merge request description"
msgstr ""
msgid "Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>." msgid "Include the username in the URL if required: <code>https://username@gitlab.company.com/group/project.git</code>."
msgstr "" msgstr ""
...@@ -4437,9 +4449,18 @@ msgstr "" ...@@ -4437,9 +4449,18 @@ msgstr ""
msgid "Merge Requests" msgid "Merge Requests"
msgstr "" msgstr ""
msgid "Merge commit message"
msgstr ""
msgid "Merge events" msgid "Merge events"
msgstr "" msgstr ""
msgid "Merge immediately"
msgstr ""
msgid "Merge in progress"
msgstr ""
msgid "Merge request" msgid "Merge request"
msgstr "" msgstr ""
...@@ -4449,6 +4470,9 @@ msgstr "" ...@@ -4449,6 +4470,9 @@ msgstr ""
msgid "Merge requests are a place to propose changes you've made to a project and discuss those changes with others" msgid "Merge requests are a place to propose changes you've made to a project and discuss those changes with others"
msgstr "" msgstr ""
msgid "Merge when pipeline succeeds"
msgstr ""
msgid "MergeRequests|Add a reply" msgid "MergeRequests|Add a reply"
msgstr "" msgstr ""
...@@ -4605,6 +4629,12 @@ msgstr "" ...@@ -4605,6 +4629,12 @@ msgstr ""
msgid "Modal|Close" msgid "Modal|Close"
msgstr "" msgstr ""
msgid "Modify commit messages"
msgstr ""
msgid "Modify merge commit"
msgstr ""
msgid "Monitor your errors by integrating with Sentry" msgid "Monitor your errors by integrating with Sentry"
msgstr "" msgstr ""
...@@ -6622,6 +6652,9 @@ msgstr "" ...@@ -6622,6 +6652,9 @@ msgstr ""
msgid "Something went wrong while closing the %{issuable}. Please try again later" msgid "Something went wrong while closing the %{issuable}. Please try again later"
msgstr "" msgstr ""
msgid "Something went wrong while deleting the source branch. Please try again."
msgstr ""
msgid "Something went wrong while fetching comments. Please try again." msgid "Something went wrong while fetching comments. Please try again."
msgstr "" msgstr ""
...@@ -6634,6 +6667,9 @@ msgstr "" ...@@ -6634,6 +6667,9 @@ msgstr ""
msgid "Something went wrong while fetching the registry list." msgid "Something went wrong while fetching the registry list."
msgstr "" msgstr ""
msgid "Something went wrong while merging this merge request. Please try again."
msgstr ""
msgid "Something went wrong while reopening the %{issuable}. Please try again later" msgid "Something went wrong while reopening the %{issuable}. Please try again later"
msgstr "" msgstr ""
...@@ -6778,6 +6814,9 @@ msgstr "" ...@@ -6778,6 +6814,9 @@ msgstr ""
msgid "Specify the following URL during the Runner setup:" msgid "Specify the following URL during the Runner setup:"
msgstr "" msgstr ""
msgid "Squash commit message"
msgstr ""
msgid "Squash commits" msgid "Squash commits"
msgstr "" msgstr ""
...@@ -8294,6 +8333,9 @@ msgstr "" ...@@ -8294,6 +8333,9 @@ msgstr ""
msgid "You can only edit files when you are on a branch" msgid "You can only edit files when you are on a branch"
msgstr "" msgstr ""
msgid "You can only merge once the items above are resolved"
msgstr ""
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}" msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "" msgstr ""
...@@ -8588,6 +8630,12 @@ msgstr[1] "" ...@@ -8588,6 +8630,12 @@ msgstr[1] ""
msgid "missing" msgid "missing"
msgstr "" msgstr ""
msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}."
msgstr ""
msgid "mrWidgetCommitsAdded|1 merge commit"
msgstr ""
msgid "mrWidget| Please restore it or use a different %{missingBranchName} branch" msgid "mrWidget| Please restore it or use a different %{missingBranchName} branch"
msgstr "" msgstr ""
......
...@@ -80,8 +80,8 @@ describe 'User accepts a merge request', :js do ...@@ -80,8 +80,8 @@ describe 'User accepts a merge request', :js do
end end
it 'accepts a merge request' do it 'accepts a merge request' do
click_button('Modify commit message') find('.js-mr-widget-commits-count').click
fill_in('Commit message', with: 'wow such merge') fill_in('merge-message-edit', with: 'wow such merge')
click_button('Merge') click_button('Merge')
......
...@@ -13,7 +13,7 @@ describe 'Merge request < User customizes merge commit message', :js do ...@@ -13,7 +13,7 @@ describe 'Merge request < User customizes merge commit message', :js do
description: "Description\n\nclosing #{issue_1.to_reference}, #{issue_2.to_reference}" description: "Description\n\nclosing #{issue_1.to_reference}, #{issue_2.to_reference}"
) )
end end
let(:textbox) { page.find(:css, '.js-commit-message', visible: false) } let(:textbox) { page.find(:css, '#merge-message-edit', visible: false) }
let(:default_message) do let(:default_message) do
[ [
"Merge branch 'feature' into 'master'", "Merge branch 'feature' into 'master'",
...@@ -38,16 +38,16 @@ describe 'Merge request < User customizes merge commit message', :js do ...@@ -38,16 +38,16 @@ describe 'Merge request < User customizes merge commit message', :js do
end end
it 'toggles commit message between message with description and without description' do it 'toggles commit message between message with description and without description' do
expect(page).not_to have_selector('.js-commit-message') expect(page).not_to have_selector('#merge-message-edit')
click_button "Modify commit message" first('.js-mr-widget-commits-count').click
expect(textbox).to be_visible expect(textbox).to be_visible
expect(textbox.value).to eq(default_message) expect(textbox.value).to eq(default_message)
click_link "Include description in commit message" check('Include merge request description')
expect(textbox.value).to eq(message_with_description) expect(textbox.value).to eq(message_with_description)
click_link "Don't include description in commit message" uncheck('Include merge request description')
expect(textbox.value).to eq(default_message) expect(textbox.value).to eq(default_message)
end end
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
const localVue = createLocalVue();
const testCommitMessage = 'Test commit message';
const testLabel = 'Test label';
const testInputId = 'test-input-id';
describe('Commits edit component', () => {
let wrapper;
const createComponent = (slots = {}) => {
wrapper = shallowMount(localVue.extend(CommitEdit), {
localVue,
sync: false,
propsData: {
value: testCommitMessage,
label: testLabel,
inputId: testInputId,
},
slots: {
...slots,
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
const findTextarea = () => wrapper.find('.form-control');
it('has a correct label', () => {
const labelElement = wrapper.find('.col-form-label');
expect(labelElement.text()).toBe(testLabel);
});
describe('textarea', () => {
it('has a correct ID', () => {
expect(findTextarea().attributes('id')).toBe(testInputId);
});
it('has a correct value', () => {
expect(findTextarea().element.value).toBe(testCommitMessage);
});
it('emits an input event and receives changed value', () => {
const changedCommitMessage = 'Changed commit message';
findTextarea().element.value = changedCommitMessage;
findTextarea().trigger('input');
expect(wrapper.emitted().input[0]).toEqual([changedCommitMessage]);
expect(findTextarea().element.value).toBe(changedCommitMessage);
});
});
describe('when slots are present', () => {
beforeEach(() => {
createComponent({
header: `<div class="test-header">${testCommitMessage}</div>`,
checkbox: `<label slot="checkbox" class="test-checkbox">${testLabel}</label >`,
});
});
it('renders header slot correctly', () => {
const headerSlotElement = wrapper.find('.test-header');
expect(headerSlotElement.exists()).toBe(true);
expect(headerSlotElement.text()).toBe(testCommitMessage);
});
it('renders checkbox slot correctly', () => {
const checkboxSlotElement = wrapper.find('.test-checkbox');
expect(checkboxSlotElement.exists()).toBe(true);
expect(checkboxSlotElement.text()).toBe(testLabel);
});
});
});
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { GlDropdownItem } from '@gitlab/ui';
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
const localVue = createLocalVue();
const commits = [
{
title: 'Commit 1',
short_id: '78d5b7',
message: 'Update test.txt',
},
{
title: 'Commit 2',
short_id: '34cbe28b',
message: 'Fixed test',
},
{
title: 'Commit 3',
short_id: 'fa42932a',
message: 'Added changelog',
},
];
describe('Commits message dropdown component', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMount(localVue.extend(CommitMessageDropdown), {
localVue,
sync: false,
propsData: {
commits,
},
});
};
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
});
const findDropdownElements = () => wrapper.findAll(GlDropdownItem);
const findFirstDropdownElement = () => findDropdownElements().at(0);
it('should have 3 elements in dropdown list', () => {
expect(findDropdownElements().length).toBe(3);
});
it('should have correct message for the first dropdown list element', () => {
expect(findFirstDropdownElement().text()).toBe('78d5b7 Commit 1');
});
it('should emit a commit title on selecting commit', () => {
findFirstDropdownElement().vm.$emit('click');
expect(wrapper.emitted().input[0]).toEqual(['Update test.txt']);
});
});
import { createLocalVue, shallowMount } from '@vue/test-utils';
import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
import Icon from '~/vue_shared/components/icon.vue';
const localVue = createLocalVue();
describe('Commits header component', () => {
let wrapper;
const createComponent = props => {
wrapper = shallowMount(localVue.extend(CommitsHeader), {
localVue,
sync: false,
propsData: {
isSquashEnabled: false,
targetBranch: 'master',
commitsCount: 5,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
});
const findHeaderWrapper = () => wrapper.find('.js-mr-widget-commits-count');
const findCommitToggle = () => wrapper.find('.commit-edit-toggle');
const findIcon = () => wrapper.find(Icon);
const findCommitsCountMessage = () => wrapper.find('.commits-count-message');
const findTargetBranchMessage = () => wrapper.find('.label-branch');
const findModifyButton = () => wrapper.find('.modify-message-button');
describe('when collapsed', () => {
it('toggle has aria-label equal to Expand', () => {
createComponent();
expect(findCommitToggle().attributes('aria-label')).toBe('Expand');
});
it('has a chevron-right icon', () => {
createComponent();
wrapper.setData({ expanded: false });
expect(findIcon().props('name')).toBe('chevron-right');
});
describe('when squash is disabled', () => {
beforeEach(() => {
createComponent();
});
it('has commits count message showing correct amount of commits', () => {
expect(findCommitsCountMessage().text()).toBe('5 commits');
});
it('has button with modify merge commit message', () => {
expect(findModifyButton().text()).toBe('Modify merge commit');
});
});
describe('when squash is enabled', () => {
beforeEach(() => {
createComponent({ isSquashEnabled: true });
});
it('has commits count message showing one commit when squash is enabled', () => {
expect(findCommitsCountMessage().text()).toBe('1 commit');
});
it('has button with modify commit messages text', () => {
expect(findModifyButton().text()).toBe('Modify commit messages');
});
});
it('has correct target branch displayed', () => {
createComponent();
expect(findTargetBranchMessage().text()).toBe('master');
});
});
describe('when expanded', () => {
beforeEach(() => {
createComponent();
wrapper.setData({ expanded: true });
});
it('toggle has aria-label equal to collapse', done => {
wrapper.vm.$nextTick(() => {
expect(findCommitToggle().attributes('aria-label')).toBe('Collapse');
done();
});
});
it('has a chevron-down icon', done => {
wrapper.vm.$nextTick(() => {
expect(findIcon().props('name')).toBe('chevron-down');
done();
});
});
it('has a collapse text', done => {
wrapper.vm.$nextTick(() => {
expect(findHeaderWrapper().text()).toBe('Collapse');
done();
});
});
});
});
import Vue from 'vue'; import Vue from 'vue';
import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue'; import ReadyToMerge from '~/vue_merge_request_widget/components/states/ready_to_merge.vue';
import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue'; import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue';
import CommitsHeader from '~/vue_merge_request_widget/components/states/commits_header.vue';
import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit.vue';
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
import eventHub from '~/vue_merge_request_widget/event_hub'; import eventHub from '~/vue_merge_request_widget/event_hub';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
const commitMessage = 'This is the commit message'; const commitMessage = 'This is the commit message';
const squashCommitMessage = 'This is the squash commit message';
const commitMessageWithDescription = 'This is the commit message description'; const commitMessageWithDescription = 'This is the commit message description';
const createTestMr = customConfig => { const createTestMr = customConfig => {
const mr = { const mr = {
...@@ -19,9 +23,11 @@ const createTestMr = customConfig => { ...@@ -19,9 +23,11 @@ const createTestMr = customConfig => {
sha: '12345678', sha: '12345678',
squash: false, squash: false,
commitMessage, commitMessage,
squashCommitMessage,
commitMessageWithDescription, commitMessageWithDescription,
shouldRemoveSourceBranch: true, shouldRemoveSourceBranch: true,
canRemoveSourceBranch: false, canRemoveSourceBranch: false,
targetBranch: 'master',
}; };
Object.assign(mr, customConfig.mr); Object.assign(mr, customConfig.mr);
...@@ -98,21 +104,6 @@ describe('ReadyToMerge', () => { ...@@ -98,21 +104,6 @@ describe('ReadyToMerge', () => {
}); });
}); });
describe('commitMessageLinkTitle', () => {
const withDesc = 'Include description in commit message';
const withoutDesc = "Don't include description in commit message";
it('should return message with description', () => {
expect(vm.commitMessageLinkTitle).toEqual(withDesc);
});
it('should return message without description', () => {
vm.useCommitMessageWithDescription = true;
expect(vm.commitMessageLinkTitle).toEqual(withoutDesc);
});
});
describe('status', () => { describe('status', () => {
it('defaults to success', () => { it('defaults to success', () => {
vm.mr.pipeline = true; vm.mr.pipeline = true;
...@@ -279,55 +270,43 @@ describe('ReadyToMerge', () => { ...@@ -279,55 +270,43 @@ describe('ReadyToMerge', () => {
vm.mr.isMergeAllowed = false; vm.mr.isMergeAllowed = false;
vm.mr.isPipelineActive = false; vm.mr.isPipelineActive = false;
expect(vm.shouldShowMergeControls()).toBeFalsy(); expect(vm.shouldShowMergeControls).toBeFalsy();
}); });
it('should return true when the build succeeded or build not required to succeed', () => { it('should return true when the build succeeded or build not required to succeed', () => {
vm.mr.isMergeAllowed = true; vm.mr.isMergeAllowed = true;
vm.mr.isPipelineActive = false; vm.mr.isPipelineActive = false;
expect(vm.shouldShowMergeControls()).toBeTruthy(); expect(vm.shouldShowMergeControls).toBeTruthy();
}); });
it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => { it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
vm.mr.isMergeAllowed = false; vm.mr.isMergeAllowed = false;
vm.mr.isPipelineActive = true; vm.mr.isPipelineActive = true;
expect(vm.shouldShowMergeControls()).toBeTruthy(); expect(vm.shouldShowMergeControls).toBeTruthy();
}); });
it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => { it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
vm.mr.isMergeAllowed = true; vm.mr.isMergeAllowed = true;
vm.mr.isPipelineActive = true; vm.mr.isPipelineActive = true;
expect(vm.shouldShowMergeControls()).toBeTruthy(); expect(vm.shouldShowMergeControls).toBeTruthy();
}); });
}); });
describe('updateCommitMessage', () => { describe('updateMergeCommitMessage', () => {
it('should revert flag and change commitMessage', () => { it('should revert flag and change commitMessage', () => {
expect(vm.useCommitMessageWithDescription).toBeFalsy();
expect(vm.commitMessage).toEqual(commitMessage); expect(vm.commitMessage).toEqual(commitMessage);
vm.updateCommitMessage(); vm.updateMergeCommitMessage(true);
expect(vm.useCommitMessageWithDescription).toBeTruthy();
expect(vm.commitMessage).toEqual(commitMessageWithDescription); expect(vm.commitMessage).toEqual(commitMessageWithDescription);
vm.updateCommitMessage(); vm.updateMergeCommitMessage(false);
expect(vm.useCommitMessageWithDescription).toBeFalsy();
expect(vm.commitMessage).toEqual(commitMessage); expect(vm.commitMessage).toEqual(commitMessage);
}); });
}); });
describe('toggleCommitMessageEditor', () => {
it('should toggle showCommitMessageEditor flag', () => {
expect(vm.showCommitMessageEditor).toBeFalsy();
vm.toggleCommitMessageEditor();
expect(vm.showCommitMessageEditor).toBeTruthy();
});
});
describe('handleMergeButtonClick', () => { describe('handleMergeButtonClick', () => {
const returnPromise = status => const returnPromise = status =>
new Promise(resolve => { new Promise(resolve => {
...@@ -623,7 +602,7 @@ describe('ReadyToMerge', () => { ...@@ -623,7 +602,7 @@ describe('ReadyToMerge', () => {
}); });
}); });
describe('Squash checkbox component', () => { describe('render children components', () => {
let wrapper; let wrapper;
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -642,7 +621,11 @@ describe('ReadyToMerge', () => { ...@@ -642,7 +621,11 @@ describe('ReadyToMerge', () => {
}); });
const findCheckboxElement = () => wrapper.find(SquashBeforeMerge); const findCheckboxElement = () => wrapper.find(SquashBeforeMerge);
const findCommitsHeaderElement = () => wrapper.find(CommitsHeader);
const findCommitEditElements = () => wrapper.findAll(CommitEdit);
const findCommitDropdownElement = () => wrapper.find(CommitMessageDropdown);
describe('squash checkbox', () => {
it('should be rendered when squash before merge is enabled and there is more than 1 commit', () => { it('should be rendered when squash before merge is enabled and there is more than 1 commit', () => {
createLocalComponent({ createLocalComponent({
mr: { commitsCount: 2, enableSquashBeforeMerge: true }, mr: { commitsCount: 2, enableSquashBeforeMerge: true },
...@@ -664,6 +647,78 @@ describe('ReadyToMerge', () => { ...@@ -664,6 +647,78 @@ describe('ReadyToMerge', () => {
}); });
}); });
describe('commits count collapsible header', () => {
it('should be rendered if fast-forward is disabled', () => {
createLocalComponent();
expect(findCommitsHeaderElement().exists()).toBeTruthy();
});
it('should not be rendered if fast-forward is enabled', () => {
createLocalComponent({ mr: { ffOnlyEnabled: true } });
expect(findCommitsHeaderElement().exists()).toBeFalsy();
});
});
describe('commits edit components', () => {
it('should have one edit component when squash is disabled', () => {
createLocalComponent();
expect(findCommitEditElements().length).toBe(1);
});
const findFirstCommitEditLabel = () =>
findCommitEditElements()
.at(0)
.props('label');
it('should have two edit components when squash is enabled', () => {
createLocalComponent({
mr: {
commitsCount: 2,
squash: true,
enableSquashBeforeMerge: true,
},
});
expect(findCommitEditElements().length).toBe(2);
});
it('should have correct edit merge commit label', () => {
createLocalComponent();
expect(findFirstCommitEditLabel()).toBe('Merge commit message');
});
it('should have correct edit squash commit label', () => {
createLocalComponent({
mr: {
commitsCount: 2,
squash: true,
enableSquashBeforeMerge: true,
},
});
expect(findFirstCommitEditLabel()).toBe('Squash commit message');
});
});
describe('commits dropdown', () => {
it('should not be rendered if squash is disabled', () => {
createLocalComponent();
expect(findCommitDropdownElement().exists()).toBeFalsy();
});
it('should be rendered if squash is enabled', () => {
createLocalComponent({ mr: { squash: true } });
expect(findCommitDropdownElement().exists()).toBeTruthy();
});
});
});
describe('Merge controls', () => { describe('Merge controls', () => {
describe('when allowed to merge', () => { describe('when allowed to merge', () => {
beforeEach(() => { beforeEach(() => {
...@@ -696,10 +751,6 @@ describe('ReadyToMerge', () => { ...@@ -696,10 +751,6 @@ describe('ReadyToMerge', () => {
expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).toBeNull(); expect(vm.$el.querySelector('.js-remove-source-branch-checkbox')).toBeNull();
}); });
it('does not show modify commit message button', () => {
expect(vm.$el.querySelector('.js-modify-commit-message-button')).toBeNull();
});
it('shows message to resolve all items before being allowed to merge', () => { it('shows message to resolve all items before being allowed to merge', () => {
expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeDefined(); expect(vm.$el.querySelector('.js-resolve-mr-widget-items-message')).toBeDefined();
}); });
...@@ -712,7 +763,7 @@ describe('ReadyToMerge', () => { ...@@ -712,7 +763,7 @@ describe('ReadyToMerge', () => {
mr: { ffOnlyEnabled: false }, mr: { ffOnlyEnabled: false },
}); });
expect(customVm.$el.querySelector('.js-fast-forward-message')).toBeNull(); expect(customVm.$el.querySelector('.mr-fast-forward-message')).toBeNull();
expect(customVm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined(); expect(customVm.$el.querySelector('.js-modify-commit-message-button')).toBeDefined();
}); });
...@@ -721,7 +772,7 @@ describe('ReadyToMerge', () => { ...@@ -721,7 +772,7 @@ describe('ReadyToMerge', () => {
mr: { ffOnlyEnabled: true }, mr: { ffOnlyEnabled: true },
}); });
expect(customVm.$el.querySelector('.js-fast-forward-message')).toBeDefined(); expect(customVm.$el.querySelector('.mr-fast-forward-message')).toBeDefined();
expect(customVm.$el.querySelector('.js-modify-commit-message-button')).toBeNull(); expect(customVm.$el.querySelector('.js-modify-commit-message-button')).toBeNull();
}); });
}); });
......
...@@ -215,12 +215,14 @@ export default { ...@@ -215,12 +215,14 @@ export default {
project_archived: false, project_archived: false,
default_merge_commit_message_with_description: default_merge_commit_message_with_description:
"Merge branch 'daaaa' into 'master'\n\nUpdate README.md\n\nSee merge request !22", "Merge branch 'daaaa' into 'master'\n\nUpdate README.md\n\nSee merge request !22",
default_squash_commit_message: 'Test squash commit message',
diverged_commits_count: 0, diverged_commits_count: 0,
only_allow_merge_if_pipeline_succeeds: false, only_allow_merge_if_pipeline_succeeds: false,
commit_change_content_path: '/root/acets-app/merge_requests/22/commit_change_content', commit_change_content_path: '/root/acets-app/merge_requests/22/commit_change_content',
merge_commit_path: merge_commit_path:
'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775', 'http://localhost:3000/root/acets-app/commit/53027d060246c8f47e4a9310fb332aa52f221775',
troubleshooting_docs_path: 'help', troubleshooting_docs_path: 'help',
squash: true,
}; };
export const mockStore = { export const mockStore = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment