From c08d9c22569d1c9e7c7737e183969593394133d9 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 3 Apr 2020 15:09:56 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../ide/components/commit_sidebar/actions_spec.js | 141 ++++++++++++++ .../components/commit_sidebar/empty_state_spec.js | 29 +++ .../ide/components/commit_sidebar/form_spec.js | 196 +++++++++++++++++++ .../commit_sidebar/list_collapsed_spec.js | 72 +++++++ .../components/commit_sidebar/list_item_spec.js | 144 ++++++++++++++ .../ide/components/commit_sidebar/list_spec.js | 54 ++++++ .../new_merge_request_option_spec.js | 210 +++++++++++++++++++++ .../commit_sidebar/success_message_spec.js | 35 ++++ 8 files changed, 881 insertions(+) create mode 100644 spec/frontend/ide/components/commit_sidebar/actions_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/empty_state_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/form_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/list_item_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/list_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/success_message_spec.js (limited to 'spec/frontend/ide') diff --git a/spec/frontend/ide/components/commit_sidebar/actions_spec.js b/spec/frontend/ide/components/commit_sidebar/actions_spec.js new file mode 100644 index 00000000000..b3b98a64891 --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/actions_spec.js @@ -0,0 +1,141 @@ +import Vue from 'vue'; +import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; +import { projectData, branches } from 'jest/ide/mock_data'; +import { createStore } from '~/ide/stores'; +import commitActions from '~/ide/components/commit_sidebar/actions.vue'; +import consts from '~/ide/stores/modules/commit/constants'; + +const ACTION_UPDATE_COMMIT_ACTION = 'commit/updateCommitAction'; + +const BRANCH_DEFAULT = 'master'; +const BRANCH_PROTECTED = 'protected/access'; +const BRANCH_PROTECTED_NO_ACCESS = 'protected/no-access'; +const BRANCH_REGULAR = 'regular'; +const BRANCH_REGULAR_NO_ACCESS = 'regular/no-access'; + +describe('IDE commit sidebar actions', () => { + let store; + let vm; + + const createComponent = ({ hasMR = false, currentBranchId = 'master' } = {}) => { + const Component = Vue.extend(commitActions); + + vm = createComponentWithStore(Component, store); + + vm.$store.state.currentBranchId = currentBranchId; + vm.$store.state.currentProjectId = 'abcproject'; + + const proj = { ...projectData }; + proj.branches[currentBranchId] = branches.find(branch => branch.name === currentBranchId); + + Vue.set(vm.$store.state.projects, 'abcproject', proj); + + if (hasMR) { + vm.$store.state.currentMergeRequestId = '1'; + vm.$store.state.projects[store.state.currentProjectId].mergeRequests[ + store.state.currentMergeRequestId + ] = { foo: 'bar' }; + } + + vm.$mount(); + + return vm; + }; + + beforeEach(() => { + store = createStore(); + jest.spyOn(store, 'dispatch').mockImplementation(() => {}); + }); + + afterEach(() => { + vm.$destroy(); + vm = null; + }); + + it('renders 2 groups', () => { + createComponent(); + + expect(vm.$el.querySelectorAll('input[type="radio"]').length).toBe(2); + }); + + it('renders current branch text', () => { + createComponent(); + + expect(vm.$el.textContent).toContain('Commit to master branch'); + }); + + it('hides merge request option when project merge requests are disabled', done => { + createComponent({ mergeRequestsEnabled: false }); + + vm.$nextTick(() => { + expect(vm.$el.querySelectorAll('input[type="radio"]').length).toBe(2); + expect(vm.$el.textContent).not.toContain('Create a new branch and merge request'); + + done(); + }); + }); + + describe('commitToCurrentBranchText', () => { + it('escapes current branch', () => { + const injectedSrc = ''; + createComponent({ currentBranchId: 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('is not called on mount if there is already a selected commitAction', () => { + store.state.commitAction = '1'; + 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, + expect.anything(), + ); + }) + .then(done) + .catch(done.fail); + }); + + it.each` + input | expectedOption + ${{ currentBranchId: BRANCH_DEFAULT }} | ${consts.COMMIT_TO_NEW_BRANCH} + ${{ currentBranchId: BRANCH_PROTECTED, hasMR: true }} | ${consts.COMMIT_TO_CURRENT_BRANCH} + ${{ currentBranchId: BRANCH_PROTECTED, hasMR: false }} | ${consts.COMMIT_TO_CURRENT_BRANCH} + ${{ currentBranchId: BRANCH_PROTECTED_NO_ACCESS, hasMR: true }} | ${consts.COMMIT_TO_NEW_BRANCH} + ${{ currentBranchId: BRANCH_PROTECTED_NO_ACCESS, hasMR: false }} | ${consts.COMMIT_TO_NEW_BRANCH} + ${{ currentBranchId: BRANCH_REGULAR, hasMR: true }} | ${consts.COMMIT_TO_CURRENT_BRANCH} + ${{ currentBranchId: BRANCH_REGULAR, hasMR: false }} | ${consts.COMMIT_TO_CURRENT_BRANCH} + ${{ currentBranchId: BRANCH_REGULAR_NO_ACCESS, hasMR: true }} | ${consts.COMMIT_TO_NEW_BRANCH} + ${{ currentBranchId: BRANCH_REGULAR_NO_ACCESS, hasMR: false }} | ${consts.COMMIT_TO_NEW_BRANCH} + `( + 'with $input, it dispatches update commit action with $expectedOption', + ({ input, expectedOption }) => { + createComponent(input); + + expect(vm.$store.dispatch.mock.calls).toEqual([ + [ACTION_UPDATE_COMMIT_ACTION, expectedOption], + ]); + }, + ); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js b/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js new file mode 100644 index 00000000000..16d0b354a30 --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/empty_state_spec.js @@ -0,0 +1,29 @@ +import Vue from 'vue'; +import store from '~/ide/stores'; +import emptyState from '~/ide/components/commit_sidebar/empty_state.vue'; +import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper'; +import { resetStore } from '../../helpers'; + +describe('IDE commit panel empty state', () => { + let vm; + + beforeEach(() => { + const Component = Vue.extend(emptyState); + + Vue.set(store.state, 'noChangesStateSvgPath', 'no-changes'); + + vm = createComponentWithStore(Component, store); + + vm.$mount(); + }); + + afterEach(() => { + vm.$destroy(); + + resetStore(vm.$store); + }); + + it('renders no changes text when last commit message is empty', () => { + expect(vm.$el.textContent).toContain('No changes'); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/form_spec.js b/spec/frontend/ide/components/commit_sidebar/form_spec.js new file mode 100644 index 00000000000..dfde69ab2df --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/form_spec.js @@ -0,0 +1,196 @@ +import Vue from 'vue'; +import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import { projectData } from 'jest/ide/mock_data'; +import store from '~/ide/stores'; +import CommitForm from '~/ide/components/commit_sidebar/form.vue'; +import { leftSidebarViews } from '~/ide/constants'; +import { resetStore } from '../../helpers'; + +describe('IDE commit form', () => { + const Component = Vue.extend(CommitForm); + let vm; + + beforeEach(() => { + store.state.changedFiles.push('test'); + store.state.currentProjectId = 'abcproject'; + store.state.currentBranchId = 'master'; + Vue.set(store.state.projects, 'abcproject', { ...projectData }); + + vm = createComponentWithStore(Component, store).$mount(); + }); + + afterEach(() => { + vm.$destroy(); + + resetStore(vm.$store); + }); + + it('enables button when has changes', () => { + expect(vm.$el.querySelector('[disabled]')).toBe(null); + }); + + describe('compact', () => { + beforeEach(done => { + vm.isCompact = true; + + vm.$nextTick(done); + }); + + it('renders commit button in compact mode', () => { + expect(vm.$el.querySelector('.btn-primary')).not.toBeNull(); + expect(vm.$el.querySelector('.btn-primary').textContent).toContain('Commit'); + }); + + it('does not render form', () => { + expect(vm.$el.querySelector('form')).toBeNull(); + }); + + it('renders overview text', done => { + vm.$store.state.stagedFiles.push('test'); + + vm.$nextTick(() => { + expect(vm.$el.querySelector('p').textContent).toContain('1 changed file'); + done(); + }); + }); + + it('shows form when clicking commit button', done => { + vm.$el.querySelector('.btn-primary').click(); + + vm.$nextTick(() => { + expect(vm.$el.querySelector('form')).not.toBeNull(); + + done(); + }); + }); + + it('toggles activity bar view when clicking commit button', done => { + vm.$el.querySelector('.btn-primary').click(); + + vm.$nextTick(() => { + expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name); + + done(); + }); + }); + + it('collapses if lastCommitMsg is set to empty and current view is not commit view', done => { + store.state.lastCommitMsg = 'abc'; + store.state.currentActivityView = leftSidebarViews.edit.name; + + vm.$nextTick(() => { + // if commit message is set, form is uncollapsed + expect(vm.isCompact).toBe(false); + + store.state.lastCommitMsg = ''; + + vm.$nextTick(() => { + // collapsed when set to empty + expect(vm.isCompact).toBe(true); + + done(); + }); + }); + }); + }); + + describe('full', () => { + beforeEach(done => { + vm.isCompact = false; + + vm.$nextTick(done); + }); + + it('updates commitMessage in store on input', done => { + const textarea = vm.$el.querySelector('textarea'); + + textarea.value = 'testing commit message'; + + textarea.dispatchEvent(new Event('input')); + + waitForPromises() + .then(() => { + expect(vm.$store.state.commit.commitMessage).toBe('testing commit message'); + }) + .then(done) + .catch(done.fail); + }); + + it('updating currentActivityView not to commit view sets compact mode', done => { + store.state.currentActivityView = 'a'; + + vm.$nextTick(() => { + expect(vm.isCompact).toBe(true); + + done(); + }); + }); + + 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(leftSidebarViews.commit.name); + expect(vm.isCompact).toBe(false); + + done(); + }); + }); + + describe('discard draft button', () => { + it('hidden when commitMessage is empty', () => { + expect(vm.$el.querySelector('.btn-default').textContent).toContain('Collapse'); + }); + + it('resets commitMessage when clicking discard button', done => { + vm.$store.state.commit.commitMessage = 'testing commit message'; + + waitForPromises() + .then(() => { + vm.$el.querySelector('.btn-default').click(); + }) + .then(Vue.nextTick) + .then(() => { + expect(vm.$store.state.commit.commitMessage).not.toBe('testing commit message'); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('when submitting', () => { + beforeEach(() => { + jest.spyOn(vm, 'commitChanges').mockImplementation(() => {}); + vm.$store.state.stagedFiles.push('test'); + }); + + it('calls commitChanges', done => { + vm.$store.state.commit.commitMessage = 'testing commit message'; + + waitForPromises() + .then(() => { + vm.$el.querySelector('.btn-success').click(); + }) + .then(Vue.nextTick) + .then(() => { + expect(vm.commitChanges).toHaveBeenCalled(); + }) + .then(done) + .catch(done.fail); + }); + }); + }); + + describe('commitButtonText', () => { + it('returns commit text when staged files exist', () => { + vm.$store.state.stagedFiles.push('testing'); + + expect(vm.commitButtonText).toBe('Commit'); + }); + + it('returns stage & commit text when staged files do not exist', () => { + expect(vm.commitButtonText).toBe('Stage & Commit'); + }); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js b/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js new file mode 100644 index 00000000000..45372d18965 --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/list_collapsed_spec.js @@ -0,0 +1,72 @@ +import Vue from 'vue'; +import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; +import store from '~/ide/stores'; +import listCollapsed from '~/ide/components/commit_sidebar/list_collapsed.vue'; +import { file } from '../../helpers'; +import { removeWhitespace } from '../../../helpers/text_helper'; + +describe('Multi-file editor commit sidebar list collapsed', () => { + let vm; + + beforeEach(() => { + const Component = Vue.extend(listCollapsed); + + vm = createComponentWithStore(Component, store, { + files: [ + { + ...file('file1'), + tempFile: true, + }, + file('file2'), + ], + iconName: 'staged', + title: 'Staged', + }); + + vm.$mount(); + }); + + afterEach(() => { + vm.$destroy(); + }); + + it('renders added & modified files count', () => { + expect(removeWhitespace(vm.$el.textContent).trim()).toBe('1 1'); + }); + + describe('addedFilesLength', () => { + it('returns an length of temp files', () => { + expect(vm.addedFilesLength).toBe(1); + }); + }); + + describe('modifiedFilesLength', () => { + it('returns an length of modified files', () => { + expect(vm.modifiedFilesLength).toBe(1); + }); + }); + + describe('addedFilesIconClass', () => { + it('includes multi-file-addition when addedFiles is not empty', () => { + expect(vm.addedFilesIconClass).toContain('multi-file-addition'); + }); + + it('excludes multi-file-addition when addedFiles is empty', () => { + vm.files = []; + + expect(vm.addedFilesIconClass).not.toContain('multi-file-addition'); + }); + }); + + describe('modifiedFilesClass', () => { + it('includes multi-file-modified when addedFiles is not empty', () => { + expect(vm.modifiedFilesClass).toContain('multi-file-modified'); + }); + + it('excludes multi-file-modified when addedFiles is empty', () => { + vm.files = []; + + expect(vm.modifiedFilesClass).not.toContain('multi-file-modified'); + }); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/list_item_spec.js b/spec/frontend/ide/components/commit_sidebar/list_item_spec.js new file mode 100644 index 00000000000..ebb41448905 --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/list_item_spec.js @@ -0,0 +1,144 @@ +import Vue from 'vue'; +import { trimText } from 'helpers/text_helper'; +import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; +import store from '~/ide/stores'; +import listItem from '~/ide/components/commit_sidebar/list_item.vue'; +import router from '~/ide/ide_router'; +import { file, resetStore } from '../../helpers'; + +describe('Multi-file editor commit sidebar list item', () => { + let vm; + let f; + let findPathEl; + + beforeEach(() => { + const Component = Vue.extend(listItem); + + f = file('test-file'); + + store.state.entries[f.path] = f; + + vm = createComponentWithStore(Component, store, { + file: f, + activeFileKey: `staged-${f.key}`, + }).$mount(); + + findPathEl = vm.$el.querySelector('.multi-file-commit-list-path'); + }); + + afterEach(() => { + vm.$destroy(); + + resetStore(store); + }); + + const findPathText = () => trimText(findPathEl.textContent); + + it('renders file path', () => { + expect(findPathText()).toContain(f.path); + }); + + it('correctly renders renamed entries', done => { + Vue.set(vm.file, 'prevName', 'Old name'); + + vm.$nextTick() + .then(() => { + expect(findPathText()).toEqual(`Old name → ${f.name}`); + }) + .then(done) + .catch(done.fail); + }); + + it('correctly renders entry, the name of which did not change after rename (as within a folder)', done => { + Vue.set(vm.file, 'prevName', f.name); + + vm.$nextTick() + .then(() => { + expect(findPathText()).toEqual(f.name); + }) + .then(done) + .catch(done.fail); + }); + + it('opens a closed file in the editor when clicking the file path', done => { + jest.spyOn(vm, 'openPendingTab'); + jest.spyOn(router, 'push').mockImplementation(() => {}); + + findPathEl.click(); + + setImmediate(() => { + expect(vm.openPendingTab).toHaveBeenCalled(); + expect(router.push).toHaveBeenCalled(); + + done(); + }); + }); + + it('calls updateViewer with diff when clicking file', done => { + jest.spyOn(vm, 'openFileInEditor'); + jest.spyOn(vm, 'updateViewer'); + jest.spyOn(router, 'push').mockImplementation(() => {}); + + findPathEl.click(); + + setImmediate(() => { + expect(vm.updateViewer).toHaveBeenCalledWith('diff'); + + done(); + }); + }); + + describe('computed', () => { + describe('iconName', () => { + it('returns modified when not a tempFile', () => { + expect(vm.iconName).toBe('file-modified'); + }); + + it('returns addition when not a tempFile', () => { + f.tempFile = true; + + expect(vm.iconName).toBe('file-addition'); + }); + + it('returns deletion', () => { + f.deleted = true; + + expect(vm.iconName).toBe('file-deletion'); + }); + }); + + describe('iconClass', () => { + it('returns modified when not a tempFile', () => { + expect(vm.iconClass).toContain('ide-file-modified'); + }); + + it('returns addition when not a tempFile', () => { + f.tempFile = true; + + expect(vm.iconClass).toContain('ide-file-addition'); + }); + + it('returns deletion', () => { + f.deleted = true; + + expect(vm.iconClass).toContain('ide-file-deletion'); + }); + }); + }); + + describe('is active', () => { + it('does not add active class when dont keys match', () => { + expect(vm.$el.querySelector('.is-active')).toBe(null); + }); + + it('adds active class when keys match', done => { + vm.keyPrefix = 'staged'; + + vm.$nextTick(() => { + expect(vm.$el.querySelector('.is-active')).not.toBe(null); + + done(); + }); + }); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/list_spec.js b/spec/frontend/ide/components/commit_sidebar/list_spec.js new file mode 100644 index 00000000000..ee209487665 --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/list_spec.js @@ -0,0 +1,54 @@ +import Vue from 'vue'; +import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; +import store from '~/ide/stores'; +import commitSidebarList from '~/ide/components/commit_sidebar/list.vue'; +import { file, resetStore } from '../../helpers'; + +describe('Multi-file editor commit sidebar list', () => { + let vm; + + beforeEach(() => { + const Component = Vue.extend(commitSidebarList); + + vm = createComponentWithStore(Component, store, { + title: 'Staged', + fileList: [], + iconName: 'staged', + action: 'stageAllChanges', + actionBtnText: 'stage all', + actionBtnIcon: 'history', + activeFileKey: 'staged-testing', + keyPrefix: 'staged', + }); + + vm.$store.state.rightPanelCollapsed = false; + + vm.$mount(); + }); + + afterEach(() => { + vm.$destroy(); + + resetStore(vm.$store); + }); + + describe('with a list of files', () => { + beforeEach(done => { + const f = file('file name'); + f.changed = true; + vm.fileList.push(f); + + Vue.nextTick(done); + }); + + it('renders list', () => { + expect(vm.$el.querySelectorAll('.multi-file-commit-list > li').length).toBe(1); + }); + }); + + describe('empty files array', () => { + it('renders no changes text when empty', () => { + expect(vm.$el.textContent).toContain('No changes'); + }); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js b/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js new file mode 100644 index 00000000000..7cbf5ebc61a --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js @@ -0,0 +1,210 @@ +import Vue from 'vue'; +import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; +import { projectData, branches } from 'jest/ide/mock_data'; +import NewMergeRequestOption from '~/ide/components/commit_sidebar/new_merge_request_option.vue'; +import { createStore } from '~/ide/stores'; +import { PERMISSION_CREATE_MR } from '~/ide/constants'; +import consts from '~/ide/stores/modules/commit/constants'; + +describe('create new MR checkbox', () => { + let store; + let vm; + + const setMR = () => { + vm.$store.state.currentMergeRequestId = '1'; + vm.$store.state.projects[store.state.currentProjectId].mergeRequests[ + store.state.currentMergeRequestId + ] = { foo: 'bar' }; + }; + + const setPermissions = permissions => { + store.state.projects[store.state.currentProjectId].userPermissions = permissions; + }; + + const createComponent = ({ currentBranchId = 'master', createNewBranch = false } = {}) => { + const Component = Vue.extend(NewMergeRequestOption); + + 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; + + store.state.projects.abcproject.branches[currentBranchId] = branches.find( + branch => branch.name === currentBranchId, + ); + + return vm.$mount(); + }; + + const findInput = () => vm.$el.querySelector('input[type="checkbox"]'); + const findLabel = () => vm.$el.querySelector('.js-ide-commit-new-mr'); + + beforeEach(() => { + store = createStore(); + + store.state.currentProjectId = 'abcproject'; + + const proj = JSON.parse(JSON.stringify(projectData)); + proj.userPermissions[PERMISSION_CREATE_MR] = true; + Vue.set(store.state.projects, 'abcproject', proj); + }); + + afterEach(() => { + vm.$destroy(); + }); + + describe('for default branch', () => { + describe('is rendered when pushing to a new branch', () => { + beforeEach(() => { + createComponent({ + 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); + }); + }); + + 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); + }); + }); + }); + + describe('for protected branch', () => { + 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(); + + 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); + }); + }); + }); + + describe('for regular branch', () => { + beforeEach(() => { + createComponent({ + currentBranchId: 'regular', + }); + }); + + 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('shows enablded checkbox', () => { + expect(findLabel().classList.contains('is-disabled')).toBe(false); + expect(findInput().disabled).toBe(false); + }); + }); + + describe('when user cannot create MR', () => { + beforeEach(() => { + setPermissions({ [PERMISSION_CREATE_MR]: false }); + + createComponent({ currentBranchId: 'regular' }); + }); + + it('disabled checkbox', () => { + expect(findLabel().classList.contains('is-disabled')).toBe(true); + expect(findInput().disabled).toBe(true); + }); + }); + + it('dispatches toggleShouldCreateMR when clicking checkbox', () => { + createComponent({ + currentBranchId: 'regular', + }); + const el = vm.$el.querySelector('input[type="checkbox"]'); + jest.spyOn(vm.$store, 'dispatch').mockImplementation(() => {}); + el.dispatchEvent(new Event('change')); + + expect(vm.$store.dispatch.mock.calls).toEqual( + expect.arrayContaining([['commit/toggleShouldCreateMR', expect.any(Object)]]), + ); + }); +}); diff --git a/spec/frontend/ide/components/commit_sidebar/success_message_spec.js b/spec/frontend/ide/components/commit_sidebar/success_message_spec.js new file mode 100644 index 00000000000..e1a432b81be --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/success_message_spec.js @@ -0,0 +1,35 @@ +import Vue from 'vue'; +import store from '~/ide/stores'; +import successMessage from '~/ide/components/commit_sidebar/success_message.vue'; +import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper'; +import { resetStore } from '../../helpers'; + +describe('IDE commit panel successful commit state', () => { + let vm; + + beforeEach(() => { + const Component = Vue.extend(successMessage); + + vm = createComponentWithStore(Component, store, { + committedStateSvgPath: 'committed-state', + }); + + vm.$mount(); + }); + + afterEach(() => { + vm.$destroy(); + + resetStore(vm.$store); + }); + + it('renders last commit message when it exists', done => { + vm.$store.state.lastCommitMsg = 'testing commit message'; + + Vue.nextTick(() => { + expect(vm.$el.textContent).toContain('testing commit message'); + + done(); + }); + }); +}); -- cgit v1.2.3