Commit a8a3056b authored by Kushal Pandya's avatar Kushal Pandya

Merge branch '225345-re-add-swap-branches-feature' into 'master'

Re-add swap revisions feature (legacy)

See merge request gitlab-org/gitlab!57802
parents cbb1587b fad26a45
...@@ -37,10 +37,22 @@ export default { ...@@ -37,10 +37,22 @@ export default {
required: true, required: true,
}, },
}, },
data() {
return {
from: this.paramsFrom,
to: this.paramsTo,
};
},
methods: { methods: {
onSubmit() { onSubmit() {
this.$refs.form.submit(); this.$refs.form.submit();
}, },
onSwapRevision() {
[this.from, this.to] = [this.to, this.from]; // swaps 'from' and 'to'
},
onSelectRevision({ direction, revision }) {
this[direction] = revision; // direction is either 'from' or 'to'
},
}, },
}; };
</script> </script>
...@@ -57,18 +69,29 @@ export default { ...@@ -57,18 +69,29 @@ export default {
:refs-project-path="refsProjectPath" :refs-project-path="refsProjectPath"
revision-text="Source" revision-text="Source"
params-name="to" params-name="to"
:params-branch="paramsTo" :params-branch="to"
data-testid="sourceRevisionDropdown"
@selectRevision="onSelectRevision"
/> />
<div class="compare-ellipsis gl-display-inline" data-testid="ellipsis">...</div> <div class="compare-ellipsis gl-display-inline" data-testid="ellipsis">...</div>
<revision-dropdown <revision-dropdown
:refs-project-path="refsProjectPath" :refs-project-path="refsProjectPath"
revision-text="Target" revision-text="Target"
params-name="from" params-name="from"
:params-branch="paramsFrom" :params-branch="from"
data-testid="targetRevisionDropdown"
@selectRevision="onSelectRevision"
/> />
<gl-button category="primary" variant="success" class="gl-ml-3" @click="onSubmit"> <gl-button category="primary" variant="success" class="gl-ml-3" @click="onSubmit">
{{ s__('CompareRevisions|Compare') }} {{ s__('CompareRevisions|Compare') }}
</gl-button> </gl-button>
<gl-button
data-testid="swapRevisionsButton"
class="btn btn-default gl-button gl-ml-3"
@click="onSwapRevision"
>
{{ s__('CompareRevisions|Swap revisions') }}
</gl-button>
<gl-button <gl-button
v-if="projectMergeRequestPath" v-if="projectMergeRequestPath"
:href="projectMergeRequestPath" :href="projectMergeRequestPath"
......
...@@ -55,6 +55,11 @@ export default { ...@@ -55,6 +55,11 @@ export default {
return this.filteredTags.length; return this.filteredTags.length;
}, },
}, },
watch: {
paramsBranch(newBranch) {
this.setSelectedRevision(newBranch);
},
},
mounted() { mounted() {
this.fetchBranchesAndTags(); this.fetchBranchesAndTags();
}, },
...@@ -83,10 +88,14 @@ export default { ...@@ -83,10 +88,14 @@ export default {
return this.paramsBranch || s__('CompareRevisions|Select branch/tag'); return this.paramsBranch || s__('CompareRevisions|Select branch/tag');
}, },
onClick(revision) { onClick(revision) {
this.selectedRevision = revision; this.setSelectedRevision(revision);
}, },
onSearchEnter() { onSearchEnter() {
this.selectedRevision = this.searchTerm; this.setSelectedRevision(this.searchTerm);
},
setSelectedRevision(revision) {
this.selectedRevision = revision || s__('CompareRevisions|Select branch/tag');
this.$emit('selectRevision', { direction: this.paramsName, revision });
}, },
}, },
}; };
......
---
title: Re-add swap revisions feature (legacy)
merge_request: 57802
author:
type: added
...@@ -7892,6 +7892,9 @@ msgstr "" ...@@ -7892,6 +7892,9 @@ msgstr ""
msgid "CompareRevisions|Select target project" msgid "CompareRevisions|Select target project"
msgstr "" msgstr ""
msgid "CompareRevisions|Swap revisions"
msgstr ""
msgid "CompareRevisions|Tags" msgid "CompareRevisions|Tags"
msgstr "" msgstr ""
......
...@@ -8,7 +8,7 @@ jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' })); ...@@ -8,7 +8,7 @@ jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
const projectCompareIndexPath = 'some/path'; const projectCompareIndexPath = 'some/path';
const refsProjectPath = 'some/refs/path'; const refsProjectPath = 'some/refs/path';
const paramsFrom = 'master'; const paramsFrom = 'master';
const paramsTo = 'master'; const paramsTo = 'some-other-branch';
describe('CompareApp component', () => { describe('CompareApp component', () => {
let wrapper; let wrapper;
...@@ -36,6 +36,9 @@ describe('CompareApp component', () => { ...@@ -36,6 +36,9 @@ describe('CompareApp component', () => {
createComponent(); createComponent();
}); });
const findSourceDropdown = () => wrapper.find('[data-testid="sourceRevisionDropdown"]');
const findTargetDropdown = () => wrapper.find('[data-testid="targetRevisionDropdown"]');
it('renders component with prop', () => { it('renders component with prop', () => {
expect(wrapper.props()).toEqual( expect(wrapper.props()).toEqual(
expect.objectContaining({ expect.objectContaining({
...@@ -62,12 +65,31 @@ describe('CompareApp component', () => { ...@@ -62,12 +65,31 @@ describe('CompareApp component', () => {
expect(wrapper.find('[data-testid="ellipsis"]').exists()).toBe(true); expect(wrapper.find('[data-testid="ellipsis"]').exists()).toBe(true);
}); });
it('render Source and Target BranchDropdown components', () => { describe('Source and Target BranchDropdown components', () => {
const branchDropdowns = wrapper.findAll(RevisionDropdown); const findAllBranchDropdowns = () => wrapper.findAll(RevisionDropdown);
it('renders the components with the correct props', () => {
expect(findAllBranchDropdowns().length).toBe(2);
expect(findSourceDropdown().props('revisionText')).toBe('Source');
expect(findTargetDropdown().props('revisionText')).toBe('Target');
});
it('sets the revision when the "selectRevision" event is emitted', async () => {
findSourceDropdown().vm.$emit('selectRevision', {
direction: 'to',
revision: 'some-source-revision',
});
findTargetDropdown().vm.$emit('selectRevision', {
direction: 'from',
revision: 'some-target-revision',
});
await wrapper.vm.$nextTick();
expect(branchDropdowns.length).toBe(2); expect(findTargetDropdown().props('paramsBranch')).toBe('some-target-revision');
expect(branchDropdowns.at(0).props('revisionText')).toBe('Source'); expect(findSourceDropdown().props('paramsBranch')).toBe('some-source-revision');
expect(branchDropdowns.at(1).props('revisionText')).toBe('Target'); });
}); });
describe('compare button', () => { describe('compare button', () => {
...@@ -87,6 +109,27 @@ describe('CompareApp component', () => { ...@@ -87,6 +109,27 @@ describe('CompareApp component', () => {
}); });
}); });
describe('swap revisions button', () => {
const findSwapRevisionsButton = () => wrapper.find('[data-testid="swapRevisionsButton"]');
it('renders the swap revisions button', () => {
expect(findSwapRevisionsButton().exists()).toBe(true);
});
it('has the correct text', () => {
expect(findSwapRevisionsButton().text()).toBe('Swap revisions');
});
it('swaps revisions when clicked', async () => {
findSwapRevisionsButton().vm.$emit('click');
await wrapper.vm.$nextTick();
expect(findTargetDropdown().props('paramsBranch')).toBe(paramsTo);
expect(findSourceDropdown().props('paramsBranch')).toBe(paramsFrom);
});
});
describe('merge request buttons', () => { describe('merge request buttons', () => {
const findProjectMrButton = () => wrapper.find('[data-testid="projectMrButton"]'); const findProjectMrButton = () => wrapper.find('[data-testid="projectMrButton"]');
const findCreateMrButton = () => wrapper.find('[data-testid="createMrButton"]'); const findCreateMrButton = () => wrapper.find('[data-testid="createMrButton"]');
......
import { GlDropdown } from '@gitlab/ui'; import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter'; import AxiosMockAdapter from 'axios-mock-adapter';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -29,6 +29,7 @@ describe('RevisionDropdown component', () => { ...@@ -29,6 +29,7 @@ describe('RevisionDropdown component', () => {
beforeEach(() => { beforeEach(() => {
axiosMock = new AxiosMockAdapter(axios); axiosMock = new AxiosMockAdapter(axios);
createComponent();
}); });
afterEach(() => { afterEach(() => {
...@@ -39,7 +40,6 @@ describe('RevisionDropdown component', () => { ...@@ -39,7 +40,6 @@ describe('RevisionDropdown component', () => {
const findGlDropdown = () => wrapper.find(GlDropdown); const findGlDropdown = () => wrapper.find(GlDropdown);
it('sets hidden input', () => { it('sets hidden input', () => {
createComponent();
expect(wrapper.find('input[type="hidden"]').attributes('value')).toBe( expect(wrapper.find('input[type="hidden"]').attributes('value')).toBe(
defaultProps.paramsBranch, defaultProps.paramsBranch,
); );
...@@ -68,8 +68,6 @@ describe('RevisionDropdown component', () => { ...@@ -68,8 +68,6 @@ describe('RevisionDropdown component', () => {
Tags: undefined, Tags: undefined,
}); });
createComponent();
await axios.waitForAll(); await axios.waitForAll();
expect(wrapper.vm.branches).toEqual([]); expect(wrapper.vm.branches).toEqual([]);
...@@ -79,15 +77,12 @@ describe('RevisionDropdown component', () => { ...@@ -79,15 +77,12 @@ describe('RevisionDropdown component', () => {
it('shows flash message on error', async () => { it('shows flash message on error', async () => {
axiosMock.onGet('some/invalid/path').replyOnce(404); axiosMock.onGet('some/invalid/path').replyOnce(404);
createComponent();
await wrapper.vm.fetchBranchesAndTags(); await wrapper.vm.fetchBranchesAndTags();
expect(createFlash).toHaveBeenCalled(); expect(createFlash).toHaveBeenCalled();
}); });
describe('GlDropdown component', () => { describe('GlDropdown component', () => {
it('renders props', () => { it('renders props', () => {
createComponent();
expect(wrapper.props()).toEqual(expect.objectContaining(defaultProps)); expect(wrapper.props()).toEqual(expect.objectContaining(defaultProps));
}); });
...@@ -99,8 +94,22 @@ describe('RevisionDropdown component', () => { ...@@ -99,8 +94,22 @@ describe('RevisionDropdown component', () => {
}); });
it('display params branch text', () => { it('display params branch text', () => {
createComponent();
expect(findGlDropdown().props('text')).toBe(defaultProps.paramsBranch); expect(findGlDropdown().props('text')).toBe(defaultProps.paramsBranch);
}); });
it('emits a "selectRevision" event when a revision is selected', async () => {
const findGlDropdownItems = () => wrapper.findAll(GlDropdownItem);
const findFirstGlDropdownItem = () => findGlDropdownItems().at(0);
wrapper.setData({ branches: ['some-branch'] });
await wrapper.vm.$nextTick();
findFirstGlDropdownItem().vm.$emit('click');
expect(wrapper.emitted()).toEqual({
selectRevision: [[{ direction: 'from', revision: 'some-branch' }]],
});
});
}); });
}); });
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