Commit 371e1ed3 authored by Denys Mishunov's avatar Denys Mishunov Committed by Paul Slaughter

Always pre-select "Start a new merge request"

One exception: there is an existing MR for the current branch and the
branch is non-default and non-protected.

Extended mock_data for ide/stores to have different types of branches:
default, protected and regular

Cleaned new MR checkbox view
parent 16edda3e
...@@ -41,10 +41,16 @@ export default { ...@@ -41,10 +41,16 @@ export default {
methods: { methods: {
...mapCommitActions(['updateCommitAction']), ...mapCommitActions(['updateCommitAction']),
updateSelectedCommitAction() { updateSelectedCommitAction() {
if (this.currentBranch && !this.currentBranch.can_push) { if (!this.currentBranch) {
this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH); return;
} else if (this.containsStagedChanges) { }
const { can_push: canPush = false, default: isDefault = false } = this.currentBranch;
if (canPush && !isDefault) {
this.updateCommitAction(consts.COMMIT_TO_CURRENT_BRANCH); this.updateCommitAction(consts.COMMIT_TO_CURRENT_BRANCH);
} else {
this.updateCommitAction(consts.COMMIT_TO_NEW_BRANCH);
} }
}, },
}, },
......
<script> <script>
import { mapGetters, createNamespacedHelpers } from 'vuex'; import { createNamespacedHelpers } from 'vuex';
const { const {
mapState: mapCommitState, mapState: mapCommitState,
mapGetters: mapCommitGetters,
mapActions: mapCommitActions, mapActions: mapCommitActions,
mapGetters: mapCommitGetters,
} = createNamespacedHelpers('commit'); } = createNamespacedHelpers('commit');
export default { export default {
computed: { computed: {
...mapCommitState(['shouldCreateMR']), ...mapCommitState(['shouldCreateMR']),
...mapCommitGetters(['isCommittingToCurrentBranch', 'isCommittingToDefaultBranch']), ...mapCommitGetters(['shouldHideNewMrOption']),
...mapGetters(['hasMergeRequest', 'isOnDefaultBranch']),
currentBranchHasMr() {
return this.hasMergeRequest && this.isCommittingToCurrentBranch;
},
showNewMrOption() {
return (
this.isCommittingToDefaultBranch || !this.currentBranchHasMr || this.isCommittingToNewBranch
);
},
},
mounted() {
this.setShouldCreateMR();
}, },
methods: { methods: {
...mapCommitActions(['toggleShouldCreateMR', 'setShouldCreateMR']), ...mapCommitActions(['toggleShouldCreateMR']),
}, },
}; };
</script> </script>
<template> <template>
<div v-if="showNewMrOption"> <fieldset v-if="!shouldHideNewMrOption">
<hr class="my-2" /> <hr class="my-2" />
<label class="mb-0"> <label class="mb-0 js-ide-commit-new-mr">
<input :checked="shouldCreateMR" type="checkbox" @change="toggleShouldCreateMR" /> <input
:checked="shouldCreateMR"
type="checkbox"
data-qa-selector="start_new_mr_checkbox"
@change="toggleShouldCreateMR"
/>
<span class="prepend-left-10"> <span class="prepend-left-10">
{{ __('Start a new merge request') }} {{ __('Start a new merge request') }}
</span> </span>
</label> </label>
</div> </fieldset>
</template> </template>
...@@ -104,5 +104,8 @@ export const packageJson = state => state.entries[packageJsonPath]; ...@@ -104,5 +104,8 @@ export const packageJson = state => state.entries[packageJsonPath];
export const isOnDefaultBranch = (_state, getters) => export const isOnDefaultBranch = (_state, getters) =>
getters.currentProject && getters.currentProject.default_branch === getters.branchName; getters.currentProject && getters.currentProject.default_branch === getters.branchName;
export const canPushToBranch = (_state, getters) =>
getters.currentBranch && getters.currentBranch.can_push;
// prevent babel-plugin-rewire from generating an invalid default during karma tests // prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {}; export default () => {};
...@@ -18,34 +18,15 @@ export const discardDraft = ({ commit }) => { ...@@ -18,34 +18,15 @@ export const discardDraft = ({ commit }) => {
commit(types.UPDATE_COMMIT_MESSAGE, ''); commit(types.UPDATE_COMMIT_MESSAGE, '');
}; };
export const updateCommitAction = ({ commit, dispatch }, commitAction) => { export const updateCommitAction = ({ commit, getters }, commitAction) => {
commit(types.UPDATE_COMMIT_ACTION, { commit(types.UPDATE_COMMIT_ACTION, {
commitAction, commitAction,
}); });
dispatch('setShouldCreateMR'); commit(types.TOGGLE_SHOULD_CREATE_MR, !getters.shouldHideNewMrOption);
}; };
export const toggleShouldCreateMR = ({ commit }) => { export const toggleShouldCreateMR = ({ commit }) => {
commit(types.TOGGLE_SHOULD_CREATE_MR); commit(types.TOGGLE_SHOULD_CREATE_MR);
commit(types.INTERACT_WITH_NEW_MR);
};
export const setShouldCreateMR = ({
commit,
getters,
rootGetters,
state: { interactedWithNewMR },
}) => {
const committingToExistingMR =
getters.isCommittingToCurrentBranch &&
rootGetters.hasMergeRequest &&
!rootGetters.isOnDefaultBranch;
if ((getters.isCommittingToDefaultBranch && !interactedWithNewMR) || committingToExistingMR) {
commit(types.TOGGLE_SHOULD_CREATE_MR, false);
} else if (!interactedWithNewMR) {
commit(types.TOGGLE_SHOULD_CREATE_MR, true);
}
}; };
export const updateBranchName = ({ commit }, branchName) => { export const updateBranchName = ({ commit }, branchName) => {
......
...@@ -20,7 +20,7 @@ export const placeholderBranchName = (state, _, rootState) => ...@@ -20,7 +20,7 @@ export const placeholderBranchName = (state, _, rootState) =>
)}`; )}`;
export const branchName = (state, getters, rootState) => { export const branchName = (state, getters, rootState) => {
if (state.commitAction === consts.COMMIT_TO_NEW_BRANCH) { if (getters.isCreatingNewBranch) {
if (state.newBranchName === '') { if (state.newBranchName === '') {
return getters.placeholderBranchName; return getters.placeholderBranchName;
} }
...@@ -48,11 +48,11 @@ export const preBuiltCommitMessage = (state, _, rootState) => { ...@@ -48,11 +48,11 @@ export const preBuiltCommitMessage = (state, _, rootState) => {
export const isCreatingNewBranch = state => state.commitAction === consts.COMMIT_TO_NEW_BRANCH; export const isCreatingNewBranch = state => state.commitAction === consts.COMMIT_TO_NEW_BRANCH;
export const isCommittingToCurrentBranch = state => export const shouldHideNewMrOption = (_state, getters, _rootState, rootGetters) =>
state.commitAction === consts.COMMIT_TO_CURRENT_BRANCH; !getters.isCreatingNewBranch &&
(rootGetters.hasMergeRequest ||
export const isCommittingToDefaultBranch = (_state, getters, _rootState, rootGetters) => (!rootGetters.hasMergeRequest && rootGetters.isOnDefaultBranch)) &&
getters.isCommittingToCurrentBranch && rootGetters.isOnDefaultBranch; rootGetters.canPushToBranch;
// prevent babel-plugin-rewire from generating an invalid default during karma tests // prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {}; export default () => {};
...@@ -3,4 +3,3 @@ export const UPDATE_COMMIT_ACTION = 'UPDATE_COMMIT_ACTION'; ...@@ -3,4 +3,3 @@ export const UPDATE_COMMIT_ACTION = 'UPDATE_COMMIT_ACTION';
export const UPDATE_NEW_BRANCH_NAME = 'UPDATE_NEW_BRANCH_NAME'; export const UPDATE_NEW_BRANCH_NAME = 'UPDATE_NEW_BRANCH_NAME';
export const UPDATE_LOADING = 'UPDATE_LOADING'; export const UPDATE_LOADING = 'UPDATE_LOADING';
export const TOGGLE_SHOULD_CREATE_MR = 'TOGGLE_SHOULD_CREATE_MR'; export const TOGGLE_SHOULD_CREATE_MR = 'TOGGLE_SHOULD_CREATE_MR';
export const INTERACT_WITH_NEW_MR = 'INTERACT_WITH_NEW_MR';
...@@ -24,7 +24,4 @@ export default { ...@@ -24,7 +24,4 @@ export default {
shouldCreateMR: shouldCreateMR === undefined ? !state.shouldCreateMR : shouldCreateMR, shouldCreateMR: shouldCreateMR === undefined ? !state.shouldCreateMR : shouldCreateMR,
}); });
}, },
[types.INTERACT_WITH_NEW_MR](state) {
Object.assign(state, { interactedWithNewMR: true });
},
}; };
...@@ -3,6 +3,5 @@ export default () => ({ ...@@ -3,6 +3,5 @@ export default () => ({
commitAction: '1', commitAction: '1',
newBranchName: '', newBranchName: '',
submitCommitLoading: false, submitCommitLoading: false,
shouldCreateMR: false, shouldCreateMR: true,
interactedWithNewMR: false,
}); });
---
title: Updated WebIDE default commit options
merge_request: 31449
author:
type: changed
...@@ -39,6 +39,10 @@ module QA ...@@ -39,6 +39,10 @@ module QA
element :commit_button element :commit_button
end end
view 'app/assets/javascripts/ide/components/commit_sidebar/new_merge_request_option.vue' do
element :start_new_mr_checkbox
end
def has_file?(file_name) def has_file?(file_name)
within_element(:file_list) do within_element(:file_list) do
page.has_content? file_name page.has_content? file_name
...@@ -100,6 +104,7 @@ module QA ...@@ -100,6 +104,7 @@ module QA
# animation is still in process even when the buttons have the # animation is still in process even when the buttons have the
# expected visibility. # expected visibility.
commit_success_msg_shown = retry_until do commit_success_msg_shown = retry_until do
uncheck_element :start_new_mr_checkbox
click_element :commit_button click_element :commit_button
wait(reload: false) do wait(reload: false) do
......
...@@ -32,10 +32,12 @@ describe 'Multi-file editor new directory', :js do ...@@ -32,10 +32,12 @@ describe 'Multi-file editor new directory', :js do
click_button('Create directory') click_button('Create directory')
end end
expect(page).to have_content('folder name')
first('.ide-tree-actions button').click first('.ide-tree-actions button').click
page.within('.modal-dialog') do page.within('.modal') do
find('.form-control').set('file name') find('.form-control').set('folder name/file name')
click_button('Create file') click_button('Create file')
end end
...@@ -44,13 +46,18 @@ describe 'Multi-file editor new directory', :js do ...@@ -44,13 +46,18 @@ describe 'Multi-file editor new directory', :js do
find('.js-ide-commit-mode').click find('.js-ide-commit-mode').click
find('.multi-file-commit-list-item').hover
click_button 'Stage' click_button 'Stage'
fill_in('commit-message', with: 'commit message ide') fill_in('commit-message', with: 'commit message ide')
find(:css, ".js-ide-commit-new-mr input").set(false)
wait_for_requests
page.within '.multi-file-commit-form' do page.within '.multi-file-commit-form' do
click_button('Commit') click_button('Commit')
wait_for_requests
end end
find('.js-ide-edit-mode').click find('.js-ide-edit-mode').click
......
...@@ -36,15 +36,20 @@ describe 'Multi-file editor new file', :js do ...@@ -36,15 +36,20 @@ describe 'Multi-file editor new file', :js do
find('.js-ide-commit-mode').click find('.js-ide-commit-mode').click
find('.multi-file-commit-list-item').hover
click_button 'Stage' click_button 'Stage'
fill_in('commit-message', with: 'commit message ide') fill_in('commit-message', with: 'commit message ide')
find(:css, ".js-ide-commit-new-mr input").set(false)
page.within '.multi-file-commit-form' do page.within '.multi-file-commit-form' do
click_button('Commit') click_button('Commit')
wait_for_requests
end end
find('.js-ide-edit-mode').click
expect(page).to have_content('file name') expect(page).to have_content('file name')
end end
end end
...@@ -62,12 +62,4 @@ describe('IDE commit module mutations', () => { ...@@ -62,12 +62,4 @@ describe('IDE commit module mutations', () => {
expect(state.shouldCreateMR).toBe(false); expect(state.shouldCreateMR).toBe(false);
}); });
}); });
describe('INTERACT_WITH_NEW_MR', () => {
it('sets interactedWithNewMR to true', () => {
mutations.INTERACT_WITH_NEW_MR(state);
expect(state.interactedWithNewMR).toBe(true);
});
});
}); });
import Vue from 'vue'; import Vue from 'vue';
import store from '~/ide/stores'; import { createStore } from '~/ide/stores';
import consts from '~/ide/stores/modules/commit/constants';
import commitActions from '~/ide/components/commit_sidebar/actions.vue'; import commitActions from '~/ide/components/commit_sidebar/actions.vue';
import consts from '~/ide/stores/modules/commit/constants';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { resetStore } from 'spec/ide/helpers'; import { projectData, branches } from 'spec/ide/mock_data';
import { projectData } from 'spec/ide/mock_data';
const ACTION_UPDATE_COMMIT_ACTION = 'commit/updateCommitAction';
describe('IDE commit sidebar actions', () => { describe('IDE commit sidebar actions', () => {
let store;
let vm; let vm;
const createComponent = ({
hasMR = false, const createComponent = ({ hasMR = false, currentBranchId = 'master' } = {}) => {
commitAction = consts.COMMIT_TO_NEW_BRANCH,
mergeRequestsEnabled = true,
currentBranchId = 'master',
shouldCreateMR = false,
} = {}) => {
const Component = Vue.extend(commitActions); const Component = Vue.extend(commitActions);
vm = createComponentWithStore(Component, store); vm = createComponentWithStore(Component, store);
vm.$store.state.currentBranchId = currentBranchId; vm.$store.state.currentBranchId = currentBranchId;
vm.$store.state.currentProjectId = 'abcproject'; vm.$store.state.currentProjectId = 'abcproject';
vm.$store.state.commit.commitAction = commitAction;
Vue.set(vm.$store.state.projects, 'abcproject', { ...projectData }); const proj = { ...projectData };
vm.$store.state.projects.abcproject.merge_requests_enabled = mergeRequestsEnabled; proj.branches[currentBranchId] = branches.find(branch => branch.name === currentBranchId);
vm.$store.state.commit.shouldCreateMR = shouldCreateMR;
Vue.set(vm.$store.state.projects, 'abcproject', proj);
if (hasMR) { if (hasMR) {
vm.$store.state.currentMergeRequestId = '1'; vm.$store.state.currentMergeRequestId = '1';
...@@ -33,13 +31,19 @@ describe('IDE commit sidebar actions', () => { ...@@ -33,13 +31,19 @@ describe('IDE commit sidebar actions', () => {
] = { foo: 'bar' }; ] = { foo: 'bar' };
} }
return vm.$mount(); vm.$mount();
return vm;
}; };
beforeEach(() => {
store = createStore();
spyOn(store, 'dispatch');
});
afterEach(() => { afterEach(() => {
vm.$destroy(); vm.$destroy();
vm = null;
resetStore(vm.$store);
}); });
it('renders 2 groups', () => { it('renders 2 groups', () => {
...@@ -73,4 +77,152 @@ describe('IDE commit sidebar actions', () => { ...@@ -73,4 +77,152 @@ describe('IDE commit sidebar actions', () => {
expect(vm.commitToCurrentBranchText).not.toContain(injectedSrc); expect(vm.commitToCurrentBranchText).not.toContain(injectedSrc);
}); });
}); });
describe('updateSelectedCommitAction', () => {
it('does not return anything if currentBranch does not exist', () => {
createComponent({ currentBranchId: null });
expect(vm.$store.dispatch).not.toHaveBeenCalled();
});
it('calls again after staged changes', done => {
createComponent({ currentBranchId: null });
vm.$store.state.currentBranchId = 'master';
vm.$store.state.changedFiles.push({});
vm.$store.state.stagedFiles.push({});
vm.$nextTick()
.then(() => {
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
jasmine.anything(),
);
})
.then(done)
.catch(done.fail);
});
describe('default branch', () => {
it('dispatches correct action for default branch', () => {
createComponent({
currentBranchId: 'master',
});
expect(vm.$store.dispatch).toHaveBeenCalledTimes(1);
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_NEW_BRANCH,
);
});
});
describe('protected branch', () => {
describe('with write access', () => {
it('dispatches correct action when MR exists', () => {
createComponent({
hasMR: true,
currentBranchId: 'protected/access',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_CURRENT_BRANCH,
);
});
it('dispatches correct action when MR does not exists', () => {
createComponent({
hasMR: false,
currentBranchId: 'protected/access',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_CURRENT_BRANCH,
);
});
});
describe('without write access', () => {
it('dispatches correct action when MR exists', () => {
createComponent({
hasMR: true,
currentBranchId: 'protected/no-access',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_NEW_BRANCH,
);
});
it('dispatches correct action when MR does not exists', () => {
createComponent({
hasMR: false,
currentBranchId: 'protected/no-access',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_NEW_BRANCH,
);
});
});
});
describe('regular branch', () => {
describe('with write access', () => {
it('dispatches correct action when MR exists', () => {
createComponent({
hasMR: true,
currentBranchId: 'regular',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_CURRENT_BRANCH,
);
});
it('dispatches correct action when MR does not exists', () => {
createComponent({
hasMR: false,
currentBranchId: 'regular',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_CURRENT_BRANCH,
);
});
});
describe('without write access', () => {
it('dispatches correct action when MR exists', () => {
createComponent({
hasMR: true,
currentBranchId: 'regular/no-access',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_NEW_BRANCH,
);
});
it('dispatches correct action when MR does not exists', () => {
createComponent({
hasMR: false,
currentBranchId: 'regular/no-access',
});
expect(vm.$store.dispatch).toHaveBeenCalledWith(
ACTION_UPDATE_COMMIT_ACTION,
consts.COMMIT_TO_NEW_BRANCH,
);
});
});
});
});
}); });
import Vue from 'vue'; import Vue from 'vue';
import store from '~/ide/stores'; import store from '~/ide/stores';
import consts from '~/ide/stores/modules/commit/constants';
import NewMergeRequestOption from '~/ide/components/commit_sidebar/new_merge_request_option.vue'; import NewMergeRequestOption from '~/ide/components/commit_sidebar/new_merge_request_option.vue';
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
import { projectData } from 'spec/ide/mock_data'; import { projectData, branches } from 'spec/ide/mock_data';
import { resetStore } from 'spec/ide/helpers'; import { resetStore } from 'spec/ide/helpers';
import consts from '../../../../../app/assets/javascripts/ide/stores/modules/commit/constants';
describe('create new MR checkbox', () => { describe('create new MR checkbox', () => {
let vm; let vm;
const createComponent = ({ const setMR = () => {
hasMR = false, vm.$store.state.currentMergeRequestId = '1';
commitAction = consts.COMMIT_TO_NEW_BRANCH, vm.$store.state.projects[store.state.currentProjectId].mergeRequests[
currentBranchId = 'master', store.state.currentMergeRequestId
} = {}) => { ] = { foo: 'bar' };
};
const createComponent = ({ currentBranchId = 'master', createNewBranch = false } = {}) => {
const Component = Vue.extend(NewMergeRequestOption); const Component = Vue.extend(NewMergeRequestOption);
vm = createComponentWithStore(Component, store); vm = createComponentWithStore(Component, store);
vm.$store.state.commit.commitAction = createNewBranch
? consts.COMMIT_TO_NEW_BRANCH
: consts.COMMIT_TO_CURRENT_BRANCH;
vm.$store.state.currentBranchId = currentBranchId; vm.$store.state.currentBranchId = currentBranchId;
vm.$store.state.currentProjectId = 'abcproject'; vm.$store.state.currentProjectId = 'abcproject';
vm.$store.state.commit.commitAction = commitAction;
Vue.set(vm.$store.state.projects, 'abcproject', { ...projectData });
if (hasMR) { const proj = JSON.parse(JSON.stringify(projectData));
vm.$store.state.currentMergeRequestId = '1'; proj.branches[currentBranchId] = branches.find(branch => branch.name === currentBranchId);
vm.$store.state.projects[store.state.currentProjectId].mergeRequests[
store.state.currentMergeRequestId Vue.set(vm.$store.state.projects, 'abcproject', proj);
] = { foo: 'bar' };
}
return vm.$mount(); return vm.$mount();
}; };
...@@ -38,30 +41,131 @@ describe('create new MR checkbox', () => { ...@@ -38,30 +41,131 @@ describe('create new MR checkbox', () => {
resetStore(vm.$store); resetStore(vm.$store);
}); });
it('is hidden when an MR already exists and committing to current branch', () => { describe('for default branch', () => {
createComponent({ describe('is rendered when pushing to a new branch', () => {
hasMR: true, beforeEach(() => {
commitAction: consts.COMMIT_TO_CURRENT_BRANCH, createComponent({
currentBranchId: 'feature', currentBranchId: 'master',
createNewBranch: true,
});
});
it('has NO new MR', () => {
expect(vm.$el.textContent).not.toBe('');
});
it('has new MR', done => {
setMR();
vm.$nextTick()
.then(() => {
expect(vm.$el.textContent).not.toBe('');
})
.then(done)
.catch(done.fail);
});
}); });
expect(vm.$el.textContent).toBe(''); describe('is NOT rendered when pushing to the same branch', () => {
beforeEach(() => {
createComponent({
currentBranchId: 'master',
createNewBranch: false,
});
});
it('has NO new MR', () => {
expect(vm.$el.textContent).toBe('');
});
it('has new MR', done => {
setMR();
vm.$nextTick()
.then(() => {
expect(vm.$el.textContent).toBe('');
})
.then(done)
.catch(done.fail);
});
});
}); });
it('does not hide checkbox if MR does not exist', () => { describe('for protected branch', () => {
createComponent({ hasMR: false }); describe('when user does not have the write access', () => {
beforeEach(() => {
createComponent({
currentBranchId: 'protected/no-access',
});
});
it('is rendered if MR does not exists', () => {
expect(vm.$el.textContent).not.toBe('');
});
it('is rendered if MR exists', done => {
setMR();
expect(vm.$el.querySelector('input[type="checkbox"]').hidden).toBe(false); vm.$nextTick()
.then(() => {
expect(vm.$el.textContent).not.toBe('');
})
.then(done)
.catch(done.fail);
});
});
describe('when user has the write access', () => {
beforeEach(() => {
createComponent({
currentBranchId: 'protected/access',
});
});
it('is rendered if MR does not exist', () => {
expect(vm.$el.textContent).not.toBe('');
});
it('is hidden if MR exists', done => {
setMR();
vm.$nextTick()
.then(() => {
expect(vm.$el.textContent).toBe('');
})
.then(done)
.catch(done.fail);
});
});
}); });
it('does not hide checkbox when creating a new branch', () => { describe('for regular branch', () => {
createComponent({ commitAction: consts.COMMIT_TO_NEW_BRANCH }); beforeEach(() => {
createComponent({
currentBranchId: 'regular',
});
});
expect(vm.$el.querySelector('input[type="checkbox"]').hidden).toBe(false); it('is rendered if no MR exists', () => {
expect(vm.$el.textContent).not.toBe('');
});
it('is hidden if MR exists', done => {
setMR();
vm.$nextTick()
.then(() => {
expect(vm.$el.textContent).toBe('');
})
.then(done)
.catch(done.fail);
});
}); });
it('dispatches toggleShouldCreateMR when clicking checkbox', () => { it('dispatches toggleShouldCreateMR when clicking checkbox', () => {
createComponent(); createComponent({
currentBranchId: 'regular',
});
const el = vm.$el.querySelector('input[type="checkbox"]'); const el = vm.$el.querySelector('input[type="checkbox"]');
spyOn(vm.$store, 'dispatch'); spyOn(vm.$store, 'dispatch');
el.dispatchEvent(new Event('change')); el.dispatchEvent(new Event('change'));
......
...@@ -176,23 +176,51 @@ export const branches = [ ...@@ -176,23 +176,51 @@ export const branches = [
committed_date: '2018-08-01T00:20:05Z', committed_date: '2018-08-01T00:20:05Z',
}, },
can_push: true, can_push: true,
protected: true,
default: true,
}, },
{ {
id: 2, id: 2,
name: 'feature/lorem-ipsum', name: 'protected/no-access',
commit: { commit: {
message: 'Update some stuff', message: 'Update some stuff',
committed_date: '2018-08-02T00:00:05Z', committed_date: '2018-08-02T00:00:05Z',
}, },
can_push: true, can_push: false,
protected: true,
default: false,
}, },
{ {
id: 3, id: 3,
name: 'feature/dolar-amit', name: 'protected/access',
commit: {
message: 'Update some stuff',
committed_date: '2018-08-02T00:00:05Z',
},
can_push: true,
protected: true,
default: false,
},
{
id: 4,
name: 'regular',
commit: { commit: {
message: 'Update some more stuff', message: 'Update some more stuff',
committed_date: '2018-06-30T00:20:05Z', committed_date: '2018-06-30T00:20:05Z',
}, },
can_push: true, can_push: true,
protected: false,
default: false,
},
{
id: 5,
name: 'regular/no-access',
commit: {
message: 'Update some more stuff',
committed_date: '2018-06-30T00:20:05Z',
},
can_push: false,
protected: false,
default: false,
}, },
]; ];
...@@ -221,4 +221,36 @@ describe('IDE store getters', () => { ...@@ -221,4 +221,36 @@ describe('IDE store getters', () => {
}); });
}); });
}); });
describe('canPushToBranch', () => {
it('returns false when no currentBranch exists', () => {
const localGetters = {
currentProject: undefined,
};
expect(getters.canPushToBranch({}, localGetters)).toBeFalsy();
});
it('returns true when can_push to currentBranch', () => {
const localGetters = {
currentProject: {
default_branch: 'master',
},
currentBranch: { can_push: true },
};
expect(getters.canPushToBranch({}, localGetters)).toBeTruthy();
});
it('returns false when !can_push to currentBranch', () => {
const localGetters = {
currentProject: {
default_branch: 'master',
},
currentBranch: { can_push: false },
};
expect(getters.canPushToBranch({}, localGetters)).toBeFalsy();
});
});
}); });
...@@ -57,6 +57,44 @@ describe('IDE commit module actions', () => { ...@@ -57,6 +57,44 @@ describe('IDE commit module actions', () => {
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
}); });
it('sets shouldCreateMR to true if "Create new MR" option is visible', done => {
store.state.shouldHideNewMrOption = false;
testAction(
actions.updateCommitAction,
{},
store.state,
[
{
type: mutationTypes.UPDATE_COMMIT_ACTION,
payload: { commitAction: jasmine.anything() },
},
{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: true },
],
[],
done,
);
});
it('sets shouldCreateMR to false if "Create new MR" option is hidden', done => {
store.state.shouldHideNewMrOption = true;
testAction(
actions.updateCommitAction,
{},
store.state,
[
{
type: mutationTypes.UPDATE_COMMIT_ACTION,
payload: { commitAction: jasmine.anything() },
},
{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR, payload: false },
],
[],
done,
);
});
}); });
describe('updateBranchName', () => { describe('updateBranchName', () => {
...@@ -541,147 +579,10 @@ describe('IDE commit module actions', () => { ...@@ -541,147 +579,10 @@ describe('IDE commit module actions', () => {
actions.toggleShouldCreateMR, actions.toggleShouldCreateMR,
{}, {},
store.state, store.state,
[ [{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR }],
{ type: mutationTypes.TOGGLE_SHOULD_CREATE_MR },
{ type: mutationTypes.INTERACT_WITH_NEW_MR },
],
[], [],
done, done,
); );
}); });
}); });
describe('setShouldCreateMR', () => {
beforeEach(() => {
store.state.projects = {
project: {
default_branch: 'master',
branches: {
master: {
name: 'master',
},
feature: {
name: 'feature',
},
},
},
};
store.state.currentProjectId = 'project';
});
it('sets to false when the current branch already has an MR', done => {
store.state.commit.currentMergeRequestId = 1;
store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
store.state.currentMergeRequestId = '1';
store.state.currentBranchId = 'feature';
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit.calls.allArgs()[0]).toEqual(
jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, false]),
);
done();
})
.catch(done.fail);
});
it('changes to false when current branch is the default branch and user has not interacted', done => {
store.state.commit.interactedWithNewMR = false;
store.state.currentBranchId = 'master';
store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit.calls.allArgs()[0]).toEqual(
jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, false]),
);
done();
})
.catch(done.fail);
});
it('changes to true when "create new branch" is selected and user has not interacted', done => {
store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
store.state.commit.interactedWithNewMR = false;
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit.calls.allArgs()[0]).toEqual(
jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, true]),
);
done();
})
.catch(done.fail);
});
it('does not change anything if user has interacted and comitting to new branch', done => {
store.state.commit.commitAction = consts.COMMIT_TO_NEW_BRANCH;
store.state.commit.interactedWithNewMR = true;
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit).not.toHaveBeenCalled();
done();
})
.catch(done.fail);
});
it('does not change anything if user has interacted and comitting to branch without MR', done => {
store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
store.state.commit.currentMergeRequestId = null;
store.state.commit.interactedWithNewMR = true;
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit).not.toHaveBeenCalled();
done();
})
.catch(done.fail);
});
it('still changes to false if hiding the checkbox', done => {
store.state.currentBranchId = 'feature';
store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
store.state.currentMergeRequestId = '1';
store.state.commit.interactedWithNewMR = true;
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit.calls.allArgs()[0]).toEqual(
jasmine.arrayContaining([`commit/${mutationTypes.TOGGLE_SHOULD_CREATE_MR}`, false]),
);
done();
})
.catch(done.fail);
});
it('does not change to false when on master and user has interacted even if MR exists', done => {
store.state.currentBranchId = 'master';
store.state.commit.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
store.state.currentMergeRequestId = '1';
store.state.commit.interactedWithNewMR = true;
spyOn(store, 'commit').and.callThrough();
store
.dispatch('commit/setShouldCreateMR')
.then(() => {
expect(store.commit).not.toHaveBeenCalled();
done();
})
.catch(done.fail);
});
});
}); });
import commitState from '~/ide/stores/modules/commit/state'; import commitState from '~/ide/stores/modules/commit/state';
import consts from '~/ide/stores/modules/commit/constants';
import * as getters from '~/ide/stores/modules/commit/getters'; import * as getters from '~/ide/stores/modules/commit/getters';
import consts from '~/ide/stores/modules/commit/constants';
describe('IDE commit module getters', () => { describe('IDE commit module getters', () => {
let state; let state;
...@@ -55,15 +55,15 @@ describe('IDE commit module getters', () => { ...@@ -55,15 +55,15 @@ describe('IDE commit module getters', () => {
}); });
}); });
it('defualts to currentBranchId', () => { it('defaults to currentBranchId when not committing to a new branch', () => {
expect(getters.branchName(state, null, rootState)).toBe('master'); localGetters.isCreatingNewBranch = false;
expect(getters.branchName(state, localGetters, rootState)).toBe('master');
}); });
describe('COMMIT_TO_NEW_BRANCH', () => { describe('commit to a new branch', () => {
beforeEach(() => { beforeEach(() => {
Object.assign(state, { localGetters.isCreatingNewBranch = true;
commitAction: consts.COMMIT_TO_NEW_BRANCH,
});
}); });
it('uses newBranchName when not empty', () => { it('uses newBranchName when not empty', () => {
...@@ -144,4 +144,152 @@ describe('IDE commit module getters', () => { ...@@ -144,4 +144,152 @@ describe('IDE commit module getters', () => {
}); });
}); });
}); });
describe('isCreatingNewBranch', () => {
it('returns false if NOT creating a new branch', () => {
state.commitAction = consts.COMMIT_TO_CURRENT_BRANCH;
expect(getters.isCreatingNewBranch(state)).toBeFalsy();
});
it('returns true if creating a new branch', () => {
state.commitAction = consts.COMMIT_TO_NEW_BRANCH;
expect(getters.isCreatingNewBranch(state)).toBeTruthy();
});
});
describe('shouldHideNewMrOption', () => {
let localGetters = {};
let rootGetters = {};
beforeEach(() => {
localGetters = {
isCreatingNewBranch: null,
};
rootGetters = {
isOnDefaultBranch: null,
hasMergeRequest: null,
canPushToBranch: null,
};
});
describe('NO existing MR for the branch', () => {
beforeEach(() => {
rootGetters.hasMergeRequest = false;
});
it('should never hide "New MR" option', () => {
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
});
});
describe('existing MR for the branch', () => {
beforeEach(() => {
rootGetters.hasMergeRequest = true;
});
it('should NOT hide "New MR" option if user can NOT push to the current branch', () => {
rootGetters.canPushToBranch = false;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
});
it('should hide "New MR" option if user can push to the current branch', () => {
rootGetters.canPushToBranch = true;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeTruthy();
});
});
describe('user can NOT push the branch', () => {
beforeEach(() => {
rootGetters.canPushToBranch = false;
});
it('should never hide "New MR" option', () => {
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
});
});
describe('user can push to the branch', () => {
beforeEach(() => {
rootGetters.canPushToBranch = true;
});
it('should NOT hide "New MR" option if there is NO existing MR for the current branch', () => {
rootGetters.hasMergeRequest = false;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
});
it('should hide "New MR" option if there is existing MR for the current branch', () => {
rootGetters.hasMergeRequest = true;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeTruthy();
});
});
describe('default branch', () => {
beforeEach(() => {
rootGetters.isOnDefaultBranch = true;
});
describe('committing to the same branch', () => {
beforeEach(() => {
localGetters.isCreatingNewBranch = false;
rootGetters.canPushToBranch = true;
});
it('should hide "New MR" when there is an existing MR', () => {
rootGetters.hasMergeRequest = true;
expect(
getters.shouldHideNewMrOption(state, localGetters, null, rootGetters),
).toBeTruthy();
});
it('should hide "New MR" when there is no existing MR', () => {
rootGetters.hasMergeRequest = false;
expect(
getters.shouldHideNewMrOption(state, localGetters, null, rootGetters),
).toBeTruthy();
});
});
describe('creating a new branch', () => {
beforeEach(() => {
localGetters.isCreatingNewBranch = true;
});
it('should NOT hide "New MR" option no matter existence of an MR or write access', () => {
rootGetters.hasMergeRequest = false;
rootGetters.canPushToBranch = true;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
rootGetters.hasMergeRequest = true;
rootGetters.canPushToBranch = true;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
rootGetters.hasMergeRequest = false;
rootGetters.canPushToBranch = false;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
});
});
});
it('should never hide "New MR" option when creating a new branch', () => {
localGetters.isCreatingNewBranch = true;
rootGetters.isOnDefaultBranch = false;
rootGetters.hasMergeRequest = true;
rootGetters.canPushToBranch = true;
expect(getters.shouldHideNewMrOption(state, localGetters, null, rootGetters)).toBeFalsy();
});
});
}); });
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