Commit bc303216 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch 'himkp-33441' into 'master'

Stage all changes by default in Web IDE

See merge request gitlab-org/gitlab!21067
parents c8af18ef 8bc86a58
...@@ -6,6 +6,7 @@ import CommitMessageField from './message_field.vue'; ...@@ -6,6 +6,7 @@ import CommitMessageField from './message_field.vue';
import Actions from './actions.vue'; import Actions from './actions.vue';
import SuccessMessage from './success_message.vue'; import SuccessMessage from './success_message.vue';
import { activityBarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants'; import { activityBarViews, MAX_WINDOW_HEIGHT_COMPACT } from '../../constants';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
components: { components: {
...@@ -14,6 +15,7 @@ export default { ...@@ -14,6 +15,7 @@ export default {
CommitMessageField, CommitMessageField,
SuccessMessage, SuccessMessage,
}, },
mixins: [glFeatureFlagsMixin()],
data() { data() {
return { return {
isCompact: true, isCompact: true,
...@@ -27,9 +29,13 @@ export default { ...@@ -27,9 +29,13 @@ export default {
...mapGetters('commit', ['discardDraftButtonDisabled', 'preBuiltCommitMessage']), ...mapGetters('commit', ['discardDraftButtonDisabled', 'preBuiltCommitMessage']),
overviewText() { overviewText() {
return sprintf( return sprintf(
__( this.glFeatures.stageAllByDefault
'<strong>%{changedFilesLength} unstaged</strong> and <strong>%{stagedFilesLength} staged</strong> changes', ? __(
), '<strong>%{stagedFilesLength} staged</strong> and <strong>%{changedFilesLength} unstaged</strong> changes',
)
: __(
'<strong>%{changedFilesLength} unstaged</strong> and <strong>%{stagedFilesLength} staged</strong> changes',
),
{ {
stagedFilesLength: this.stagedFiles.length, stagedFilesLength: this.stagedFiles.length,
changedFilesLength: this.changedFiles.length, changedFilesLength: this.changedFiles.length,
...@@ -39,6 +45,10 @@ export default { ...@@ -39,6 +45,10 @@ export default {
commitButtonText() { commitButtonText() {
return this.stagedFiles.length ? __('Commit') : __('Stage & Commit'); return this.stagedFiles.length ? __('Commit') : __('Stage & Commit');
}, },
currentViewIsCommitView() {
return this.currentActivityView === activityBarViews.commit;
},
}, },
watch: { watch: {
currentActivityView() { currentActivityView() {
...@@ -46,27 +56,26 @@ export default { ...@@ -46,27 +56,26 @@ export default {
this.isCompact = false; this.isCompact = false;
} else { } else {
this.isCompact = !( this.isCompact = !(
this.currentActivityView === activityBarViews.commit && this.currentViewIsCommitView && window.innerHeight >= MAX_WINDOW_HEIGHT_COMPACT
window.innerHeight >= MAX_WINDOW_HEIGHT_COMPACT
); );
} }
}, },
lastCommitMsg() {
this.isCompact =
this.currentActivityView !== activityBarViews.commit && this.lastCommitMsg === '';
},
}, },
methods: { methods: {
...mapActions(['updateActivityBarView']), ...mapActions(['updateActivityBarView']),
...mapActions('commit', ['updateCommitMessage', 'discardDraft', 'commitChanges']), ...mapActions('commit', ['updateCommitMessage', 'discardDraft', 'commitChanges']),
toggleIsSmall() { toggleIsCompact() {
this.updateActivityBarView(activityBarViews.commit) if (this.currentViewIsCommitView) {
.then(() => { this.isCompact = !this.isCompact;
this.isCompact = !this.isCompact; } else {
}) this.updateActivityBarView(activityBarViews.commit)
.catch(e => { .then(() => {
throw e; this.isCompact = false;
}); })
.catch(e => {
throw e;
});
}
}, },
beforeEnterTransition() { beforeEnterTransition() {
const elHeight = this.isCompact const elHeight = this.isCompact
...@@ -114,7 +123,7 @@ export default { ...@@ -114,7 +123,7 @@ export default {
:disabled="!hasChanges" :disabled="!hasChanges"
type="button" type="button"
class="btn btn-primary btn-sm btn-block qa-begin-commit-button" class="btn btn-primary btn-sm btn-block qa-begin-commit-button"
@click="toggleIsSmall" @click="toggleIsCompact"
> >
{{ __('Commit…') }} {{ __('Commit…') }}
</button> </button>
...@@ -148,7 +157,7 @@ export default { ...@@ -148,7 +157,7 @@ export default {
v-else v-else
type="button" type="button"
class="btn btn-default btn-sm float-right" class="btn btn-default btn-sm float-right"
@click="toggleIsSmall" @click="toggleIsCompact"
> >
{{ __('Collapse') }} {{ __('Collapse') }}
</button> </button>
......
...@@ -6,6 +6,7 @@ import Icon from '~/vue_shared/components/icon.vue'; ...@@ -6,6 +6,7 @@ import Icon from '~/vue_shared/components/icon.vue';
import ChangedFileIcon from '~/vue_shared/components/changed_file_icon.vue'; import ChangedFileIcon from '~/vue_shared/components/changed_file_icon.vue';
import NewDropdown from './new_dropdown/index.vue'; import NewDropdown from './new_dropdown/index.vue';
import MrFileIcon from './mr_file_icon.vue'; import MrFileIcon from './mr_file_icon.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
name: 'FileRowExtra', name: 'FileRowExtra',
...@@ -18,6 +19,7 @@ export default { ...@@ -18,6 +19,7 @@ export default {
ChangedFileIcon, ChangedFileIcon,
MrFileIcon, MrFileIcon,
}, },
mixins: [glFeatureFlagsMixin()],
props: { props: {
file: { file: {
type: Object, type: Object,
...@@ -55,10 +57,15 @@ export default { ...@@ -55,10 +57,15 @@ export default {
return n__('%d staged change', '%d staged changes', this.folderStagedCount); return n__('%d staged change', '%d staged changes', this.folderStagedCount);
} }
return sprintf(__('%{unstaged} unstaged and %{staged} staged changes'), { return sprintf(
unstaged: this.folderUnstagedCount, this.glFeatures.stageAllByDefault
staged: this.folderStagedCount, ? __('%{staged} staged and %{unstaged} unstaged changes')
}); : __('%{unstaged} unstaged and %{staged} staged changes'),
{
unstaged: this.folderUnstagedCount,
staged: this.folderStagedCount,
},
);
}, },
showTreeChangesCount() { showTreeChangesCount() {
return this.isTree && this.changesCount > 0 && !this.file.opened; return this.isTree && this.changesCount > 0 && !this.file.opened;
......
...@@ -51,7 +51,7 @@ export const setResizingStatus = ({ commit }, resizing) => { ...@@ -51,7 +51,7 @@ export const setResizingStatus = ({ commit }, resizing) => {
}; };
export const createTempEntry = ( export const createTempEntry = (
{ state, commit, dispatch }, { state, commit, dispatch, getters },
{ name, type, content = '', base64 = false, binary = false, rawPath = '' }, { name, type, content = '', base64 = false, binary = false, rawPath = '' },
) => { ) => {
const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name; const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name;
...@@ -92,7 +92,11 @@ export const createTempEntry = ( ...@@ -92,7 +92,11 @@ export const createTempEntry = (
if (type === 'blob') { if (type === 'blob') {
commit(types.TOGGLE_FILE_OPEN, file.path); commit(types.TOGGLE_FILE_OPEN, file.path);
commit(types.ADD_FILE_TO_CHANGED, file.path);
if (gon.features?.stageAllByDefault)
commit(types.STAGE_CHANGE, { path: file.path, diffInfo: getters.getDiffInfo(file.path) });
else commit(types.ADD_FILE_TO_CHANGED, file.path);
dispatch('setFileActive', file.path); dispatch('setFileActive', file.path);
dispatch('triggerFilesChange'); dispatch('triggerFilesChange');
dispatch('burstUnusedSeal'); dispatch('burstUnusedSeal');
...@@ -238,7 +242,7 @@ export const deleteEntry = ({ commit, dispatch, state }, path) => { ...@@ -238,7 +242,7 @@ export const deleteEntry = ({ commit, dispatch, state }, path) => {
export const resetOpenFiles = ({ commit }) => commit(types.RESET_OPEN_FILES); export const resetOpenFiles = ({ commit }) => commit(types.RESET_OPEN_FILES);
export const renameEntry = ({ dispatch, commit, state }, { path, name, parentPath }) => { export const renameEntry = ({ dispatch, commit, state, getters }, { path, name, parentPath }) => {
const entry = state.entries[path]; const entry = state.entries[path];
const newPath = parentPath ? `${parentPath}/${name}` : name; const newPath = parentPath ? `${parentPath}/${name}` : name;
const existingParent = parentPath && state.entries[parentPath]; const existingParent = parentPath && state.entries[parentPath];
...@@ -268,7 +272,10 @@ export const renameEntry = ({ dispatch, commit, state }, { path, name, parentPat ...@@ -268,7 +272,10 @@ export const renameEntry = ({ dispatch, commit, state }, { path, name, parentPat
if (isReset) { if (isReset) {
commit(types.REMOVE_FILE_FROM_STAGED_AND_CHANGED, newEntry); commit(types.REMOVE_FILE_FROM_STAGED_AND_CHANGED, newEntry);
} else if (!isInChanges) { } else if (!isInChanges) {
commit(types.ADD_FILE_TO_CHANGED, newPath); if (gon.features?.stageAllByDefault)
commit(types.STAGE_CHANGE, { path: newPath, diffInfo: getters.getDiffInfo(newPath) });
else commit(types.ADD_FILE_TO_CHANGED, newPath);
dispatch('burstUnusedSeal'); dispatch('burstUnusedSeal');
} }
......
...@@ -147,7 +147,7 @@ export const getRawFileData = ({ state, commit, dispatch, getters }, { path }) = ...@@ -147,7 +147,7 @@ export const getRawFileData = ({ state, commit, dispatch, getters }, { path }) =
}); });
}; };
export const changeFileContent = ({ commit, dispatch, state }, { path, content }) => { export const changeFileContent = ({ commit, dispatch, state, getters }, { path, content }) => {
const file = state.entries[path]; const file = state.entries[path];
commit(types.UPDATE_FILE_CONTENT, { commit(types.UPDATE_FILE_CONTENT, {
path, path,
...@@ -157,7 +157,9 @@ export const changeFileContent = ({ commit, dispatch, state }, { path, content } ...@@ -157,7 +157,9 @@ export const changeFileContent = ({ commit, dispatch, state }, { path, content }
const indexOfChangedFile = state.changedFiles.findIndex(f => f.path === path); const indexOfChangedFile = state.changedFiles.findIndex(f => f.path === path);
if (file.changed && indexOfChangedFile === -1) { if (file.changed && indexOfChangedFile === -1) {
commit(types.ADD_FILE_TO_CHANGED, path); if (gon.features?.stageAllByDefault)
commit(types.STAGE_CHANGE, { path, diffInfo: getters.getDiffInfo(path) });
else commit(types.ADD_FILE_TO_CHANGED, path);
} else if (!file.changed && !file.tempFile && indexOfChangedFile !== -1) { } else if (!file.changed && !file.tempFile && indexOfChangedFile !== -1) {
commit(types.REMOVE_FILE_FROM_CHANGED, path); commit(types.REMOVE_FILE_FROM_CHANGED, path);
} }
......
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
class IdeController < ApplicationController class IdeController < ApplicationController
layout 'fullscreen' layout 'fullscreen'
before_action do
push_frontend_feature_flag(:stage_all_by_default, default_enabled: true)
end
def index def index
Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count
end end
......
---
title: Stage all changes by default in Web IDE
merge_request: 21067
author:
type: added
...@@ -46,12 +46,16 @@ Single file editing is based on the [Ace Editor](https://ace.c9.io). ...@@ -46,12 +46,16 @@ Single file editing is based on the [Ace Editor](https://ace.c9.io).
## Stage and commit changes ## Stage and commit changes
After making your changes, click the **Commit** button in the bottom left to After making your changes, click the **Commit** button in the bottom left to
review the list of changed files. Click on each file to review the changes and review the list of changed files. If you're using GitLab 12.6 or older versions,
click the tick icon to stage the file. click on each file to review the changes and tick the item to stage a file.
![Review changes](img/review_changes_v12_3.png) From [GitLab 12.7 onwards](https://gitlab.com/gitlab-org/gitlab/issues/33441),
all your files will be automatically staged. You still have the option to unstage
changes in case you want to submit them in multiple smaller commits. To unstage
a change, simply click the **Unstage** button when a staged file is open, or click
the undo icon next to **Staged changes** to unstage all changes.
Once you have staged some changes, you can add a commit message, commit the Once you have finalized your changes, you can add a commit message, commit the
staged changes and directly create a merge request. In case you don't have write staged changes and directly create a merge request. In case you don't have write
access to the selected branch, you will see a warning, but still be able to create access to the selected branch, you will see a warning, but still be able to create
a new branch and start a merge request. a new branch and start a merge request.
......
...@@ -379,6 +379,9 @@ msgstr "" ...@@ -379,6 +379,9 @@ msgstr ""
msgid "%{spanStart}in%{spanEnd} %{errorFn}" msgid "%{spanStart}in%{spanEnd} %{errorFn}"
msgstr "" msgstr ""
msgid "%{staged} staged and %{unstaged} unstaged changes"
msgstr ""
msgid "%{start} to %{end}" msgid "%{start} to %{end}"
msgstr "" msgstr ""
...@@ -700,6 +703,9 @@ msgstr "" ...@@ -700,6 +703,9 @@ msgstr ""
msgid "<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors." msgid "<strong>%{pushes}</strong> pushes, more than <strong>%{commits}</strong> commits by <strong>%{people}</strong> contributors."
msgstr "" msgstr ""
msgid "<strong>%{stagedFilesLength} staged</strong> and <strong>%{changedFilesLength} unstaged</strong> changes"
msgstr ""
msgid "<strong>Deletes</strong> source branch" msgid "<strong>Deletes</strong> source branch"
msgstr "" msgstr ""
......
...@@ -84,16 +84,13 @@ module QA ...@@ -84,16 +84,13 @@ module QA
end end
def commit_changes def commit_changes
# Clicking :begin_commit_button the first time switches from the # Clicking :begin_commit_button switches from the
# edit to the commit view # edit to the commit view
click_element :begin_commit_button click_element :begin_commit_button
active_element? :commit_mode_tab active_element? :commit_mode_tab
# We need to click :begin_commit_button again # After clicking :begin_commit_button, there is an animation
click_element :begin_commit_button # that hides :begin_commit_button and shows :commit_button
# After clicking :begin_commit_button the 2nd time there is an
# animation that hides :begin_commit_button and shows :commit_button
# #
# Wait for the animation to complete before clicking :commit_button # Wait for the animation to complete before clicking :commit_button
# otherwise the click will quietly do nothing. # otherwise the click will quietly do nothing.
...@@ -102,9 +99,6 @@ module QA ...@@ -102,9 +99,6 @@ module QA
has_element?(:commit_button) has_element?(:commit_button)
end end
# At this point we're ready to commit and the button should be
# labelled "Stage & Commit"
#
# Click :commit_button and keep retrying just in case part of the # Click :commit_button and keep retrying just in case part of the
# 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.
......
...@@ -46,8 +46,6 @@ describe 'Multi-file editor new directory', :js do ...@@ -46,8 +46,6 @@ describe 'Multi-file editor new directory', :js do
find('.js-ide-commit-mode').click find('.js-ide-commit-mode').click
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) find(:css, ".js-ide-commit-new-mr input").set(false)
......
...@@ -36,8 +36,6 @@ describe 'Multi-file editor new file', :js do ...@@ -36,8 +36,6 @@ describe 'Multi-file editor new file', :js do
find('.js-ide-commit-mode').click find('.js-ide-commit-mode').click
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) find(:css, ".js-ide-commit-new-mr input").set(false)
......
...@@ -514,6 +514,8 @@ describe('IDE store file actions', () => { ...@@ -514,6 +514,8 @@ describe('IDE store file actions', () => {
describe('changeFileContent', () => { describe('changeFileContent', () => {
let tmpFile; let tmpFile;
const callAction = (content = 'content\n') =>
store.dispatch('changeFileContent', { path: tmpFile.path, content });
beforeEach(() => { beforeEach(() => {
tmpFile = file('tmpFile'); tmpFile = file('tmpFile');
...@@ -523,11 +525,7 @@ describe('IDE store file actions', () => { ...@@ -523,11 +525,7 @@ describe('IDE store file actions', () => {
}); });
it('updates file content', done => { it('updates file content', done => {
store callAction()
.dispatch('changeFileContent', {
path: tmpFile.path,
content: 'content\n',
})
.then(() => { .then(() => {
expect(tmpFile.content).toBe('content\n'); expect(tmpFile.content).toBe('content\n');
...@@ -537,11 +535,7 @@ describe('IDE store file actions', () => { ...@@ -537,11 +535,7 @@ describe('IDE store file actions', () => {
}); });
it('adds a newline to the end of the file if it doesnt already exist', done => { it('adds a newline to the end of the file if it doesnt already exist', done => {
store callAction('content')
.dispatch('changeFileContent', {
path: tmpFile.path,
content: 'content',
})
.then(() => { .then(() => {
expect(tmpFile.content).toBe('content\n'); expect(tmpFile.content).toBe('content\n');
...@@ -551,11 +545,7 @@ describe('IDE store file actions', () => { ...@@ -551,11 +545,7 @@ describe('IDE store file actions', () => {
}); });
it('adds file into changedFiles array', done => { it('adds file into changedFiles array', done => {
store callAction()
.dispatch('changeFileContent', {
path: tmpFile.path,
content: 'content',
})
.then(() => { .then(() => {
expect(store.state.changedFiles.length).toBe(1); expect(store.state.changedFiles.length).toBe(1);
...@@ -564,7 +554,7 @@ describe('IDE store file actions', () => { ...@@ -564,7 +554,7 @@ describe('IDE store file actions', () => {
.catch(done.fail); .catch(done.fail);
}); });
it('adds file once into changedFiles array', done => { it('adds file not more than once into changedFiles array', done => {
store store
.dispatch('changeFileContent', { .dispatch('changeFileContent', {
path: tmpFile.path, path: tmpFile.path,
...@@ -604,6 +594,52 @@ describe('IDE store file actions', () => { ...@@ -604,6 +594,52 @@ describe('IDE store file actions', () => {
.catch(done.fail); .catch(done.fail);
}); });
describe('when `gon.feature.stageAllByDefault` is true', () => {
const originalGonFeatures = Object.assign({}, gon.features);
beforeAll(() => {
gon.features = { stageAllByDefault: true };
});
afterAll(() => {
gon.features = originalGonFeatures;
});
it('adds file into stagedFiles array', done => {
store
.dispatch('changeFileContent', {
path: tmpFile.path,
content: 'content',
})
.then(() => {
expect(store.state.stagedFiles.length).toBe(1);
done();
})
.catch(done.fail);
});
it('adds file not more than once into stagedFiles array', done => {
store
.dispatch('changeFileContent', {
path: tmpFile.path,
content: 'content',
})
.then(() =>
store.dispatch('changeFileContent', {
path: tmpFile.path,
content: 'content 123',
}),
)
.then(() => {
expect(store.state.stagedFiles.length).toBe(1);
done();
})
.catch(done.fail);
});
});
it('bursts unused seal', done => { it('bursts unused seal', done => {
store store
.dispatch('changeFileContent', { .dispatch('changeFileContent', {
......
...@@ -33,6 +33,12 @@ describe('IDE commit form', () => { ...@@ -33,6 +33,12 @@ describe('IDE commit form', () => {
}); });
describe('compact', () => { describe('compact', () => {
beforeEach(done => {
vm.isCompact = true;
vm.$nextTick(done);
});
it('renders commit button in compact mode', () => { it('renders commit button in compact mode', () => {
expect(vm.$el.querySelector('.btn-primary')).not.toBeNull(); expect(vm.$el.querySelector('.btn-primary')).not.toBeNull();
expect(vm.$el.querySelector('.btn-primary').textContent).toContain('Commit'); expect(vm.$el.querySelector('.btn-primary').textContent).toContain('Commit');
...@@ -61,7 +67,7 @@ describe('IDE commit form', () => { ...@@ -61,7 +67,7 @@ describe('IDE commit form', () => {
}); });
}); });
it('toggles activity bar vie when clicking commit button', done => { it('toggles activity bar view when clicking commit button', done => {
vm.$el.querySelector('.btn-primary').click(); vm.$el.querySelector('.btn-primary').click();
vm.$nextTick(() => { vm.$nextTick(() => {
...@@ -104,6 +110,17 @@ describe('IDE commit form', () => { ...@@ -104,6 +110,17 @@ describe('IDE commit form', () => {
}); });
}); });
it('always opens itself in full view current activity view is not commit view when clicking commit button', done => {
vm.$el.querySelector('.btn-primary').click();
vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(activityBarViews.commit);
expect(vm.isCompact).toBe(false);
done();
});
});
describe('discard draft button', () => { describe('discard draft button', () => {
it('hidden when commitMessage is empty', () => { it('hidden when commitMessage is empty', () => {
expect(vm.$el.querySelector('.btn-default').textContent).toContain('Collapse'); expect(vm.$el.querySelector('.btn-default').textContent).toContain('Collapse');
......
...@@ -225,6 +225,35 @@ describe('Multi-file store actions', () => { ...@@ -225,6 +225,35 @@ describe('Multi-file store actions', () => {
.catch(done.fail); .catch(done.fail);
}); });
describe('when `gon.feature.stageAllByDefault` is true', () => {
const originalGonFeatures = Object.assign({}, gon.features);
beforeAll(() => {
gon.features = { stageAllByDefault: true };
});
afterAll(() => {
gon.features = originalGonFeatures;
});
it('adds tmp file to staged files', done => {
const name = 'test';
store
.dispatch('createTempEntry', {
name,
branchId: 'mybranch',
type: 'blob',
})
.then(() => {
expect(store.state.stagedFiles).toEqual([jasmine.objectContaining({ name })]);
done();
})
.catch(done.fail);
});
});
it('adds tmp file to open files', done => { it('adds tmp file to open files', done => {
const name = 'test'; const name = 'test';
...@@ -255,41 +284,25 @@ describe('Multi-file store actions', () => { ...@@ -255,41 +284,25 @@ describe('Multi-file store actions', () => {
type: 'blob', type: 'blob',
}) })
.then(() => { .then(() => {
const f = store.state.entries[name]; expect(store.state.changedFiles).toEqual([
jasmine.objectContaining({ name, tempFile: true }),
expect(store.state.changedFiles.length).toBe(1); ]);
expect(store.state.changedFiles[0].name).toBe(f.name);
done(); done();
}) })
.catch(done.fail); .catch(done.fail);
}); });
it('sets tmp file as active', done => { it('sets tmp file as active', () => {
testAction( const dispatch = jasmine.createSpy();
createTempEntry, const commit = jasmine.createSpy();
{
name: 'test', createTempEntry(
branchId: 'mybranch', { state: store.state, getters: store.getters, dispatch, commit },
type: 'blob', { name: 'test', branchId: 'mybranch', type: 'blob' },
},
store.state,
[
{ type: types.CREATE_TMP_ENTRY, payload: jasmine.any(Object) },
{ type: types.TOGGLE_FILE_OPEN, payload: 'test' },
{ type: types.ADD_FILE_TO_CHANGED, payload: 'test' },
],
jasmine.arrayContaining([
{
type: 'setFileActive',
payload: 'test',
},
{
type: 'triggerFilesChange',
},
]),
done,
); );
expect(dispatch).toHaveBeenCalledWith('setFileActive', 'test');
}); });
it('creates flash message if file already exists', done => { it('creates flash message if file already exists', done => {
...@@ -800,6 +813,33 @@ describe('Multi-file store actions', () => { ...@@ -800,6 +813,33 @@ describe('Multi-file store actions', () => {
}); });
}); });
describe('when `gon.feature.stageAllByDefault` is true', () => {
const originalGonFeatures = Object.assign({}, gon.features);
beforeAll(() => {
gon.features = { stageAllByDefault: true };
});
afterAll(() => {
gon.features = originalGonFeatures;
});
it('by default renames an entry and stages it', () => {
const dispatch = jasmine.createSpy();
const commit = jasmine.createSpy();
renameEntry(
{ dispatch, commit, state: store.state, getters: store.getters },
{ path: 'orig', name: 'renamed' },
);
expect(commit.calls.allArgs()).toEqual([
[types.RENAME_ENTRY, { path: 'orig', name: 'renamed', parentPath: undefined }],
[types.STAGE_CHANGE, jasmine.objectContaining({ path: 'renamed' })],
]);
});
});
it('by default renames an entry and adds to changed', done => { it('by default renames an entry and adds to changed', done => {
testAction( testAction(
renameEntry, renameEntry,
...@@ -819,12 +859,12 @@ describe('Multi-file store actions', () => { ...@@ -819,12 +859,12 @@ describe('Multi-file store actions', () => {
payload: 'renamed', payload: 'renamed',
}, },
], ],
[{ type: 'burstUnusedSeal' }, { type: 'triggerFilesChange' }], jasmine.any(Object),
done, done,
); );
}); });
it('if not changed, completely unstages entry if renamed to original', done => { it('if not changed, completely unstages and discards entry if renamed to original', done => {
testAction( testAction(
renameEntry, renameEntry,
{ path: 'renamed', name: 'orig' }, { path: 'renamed', name: 'orig' },
......
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