From f82af4bdcf19328d763aeb39d9d77a45c9cb9547 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 2 Nov 2017 09:50:01 +0000 Subject: Added tests to multi-file Vuex store --- spec/javascripts/repo/stores/actions_spec.js | 215 +++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 spec/javascripts/repo/stores/actions_spec.js (limited to 'spec/javascripts/repo/stores/actions_spec.js') diff --git a/spec/javascripts/repo/stores/actions_spec.js b/spec/javascripts/repo/stores/actions_spec.js new file mode 100644 index 00000000000..12ac23d113d --- /dev/null +++ b/spec/javascripts/repo/stores/actions_spec.js @@ -0,0 +1,215 @@ +import * as actions from '~/repo/stores/actions'; +import state from '~/repo/stores/state'; +import service from '~/repo/services'; +import testAction, { testWithDispatch } from '../../helpers/vuex_action_helper'; +import { file } from '../helpers'; + +describe('Multi-file store actions', () => { + let localState; + + beforeEach(() => { + localState = state(); + }); + + describe('redirectToUrl', () => { + it('calls visitUrl', () => { + spyOn(gl.utils, 'visitUrl'); + + actions.redirectToUrl('test'); + + expect(gl.utils.visitUrl).toHaveBeenCalledWith('test'); + }); + }); + + describe('setInitialData', () => { + it('commits initial data', (done) => { + testAction( + actions.setInitialData, + { canCommit: true }, + localState, + [ + { type: 'SET_INITIAL_DATA', payload: { canCommit: true } }, + ], + done, + ); + }); + }); + + describe('closeDiscardPopup', () => { + it('closes the discard popup', (done) => { + testAction( + actions.closeDiscardPopup, + false, + localState, + [ + { type: 'TOGGLE_DISCARD_POPUP', payload: false }, + ], + done, + ); + }); + }); + + describe('discardAllChanges', () => { + beforeEach(() => { + localState.openFiles.push(file()); + localState.openFiles[0].changed = true; + }); + }); + + describe('closeAllFiles', () => { + beforeEach(() => { + localState.openFiles.push(file()); + localState.openFiles[0].changed = true; + }); + + it('closes all open files', (done) => { + testWithDispatch( + actions.closeAllFiles, + localState.openFiles[0], + localState, + [ + { type: 'closeFile', payload: { file: localState.openFiles[0] } }, + ], + done, + ); + }); + }); + + describe('toggleEditMode', () => { + + }); + + describe('toggleBlobView', () => { + it('sets edit mode view if in edit mode', (done) => { + localState.editMode = true; + + testAction( + actions.toggleBlobView, + null, + localState, + [ + { type: 'SET_EDIT_MODE' }, + ], + done, + ); + }); + + it('sets preview mode view if not in edit mode', (done) => { + testAction( + actions.toggleBlobView, + null, + localState, + [ + { type: 'SET_PREVIEW_MODE' }, + ], + done, + ); + }); + }); + + describe('checkCommitStatus', () => { + beforeEach(() => { + localState.project.id = 2; + localState.currentBranch = 'master'; + localState.currentRef = '1'; + }); + + it('calls service', () => { + spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ + commit: { id: '123' }, + })); + + actions.checkCommitStatus({ state: localState }); + + expect(service.getBranchData).toHaveBeenCalledWith(2, 'master'); + }); + + it('returns true if current ref does not equal returned ID', (done) => { + spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ + commit: { id: '123' }, + })); + + actions.checkCommitStatus({ state: localState }) + .then((val) => { + expect(val).toBeTruthy(); + + done(); + }) + .catch(done.fail); + }); + + it('returns false if current ref equals returned ID', (done) => { + spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ + commit: { id: '1' }, + })); + + actions.checkCommitStatus({ state: localState }) + .then((val) => { + expect(val).toBeFalsy(); + + done(); + }) + .catch(done.fail); + }); + }); + + describe('commitChanges', () => { + + }); + + describe('createTempEntry', () => { + it('creates a temp tree', (done) => { + testWithDispatch( + actions.createTempEntry, + { name: 'test', type: 'tree' }, + localState, + [ + { type: 'createTempTree', payload: 'test' }, + ], + done, + ); + }); + + it('creates temp file', (done) => { + testWithDispatch( + actions.createTempEntry, + { name: 'test', type: 'blob' }, + localState, + [ + { + type: 'createTempFile', + payload: { + tree: localState, + name: 'test', + base64: false, + content: '', + }, + }, + ], + done, + ); + }); + }); + + describe('popHistoryState', () => { + + }); + + describe('scrollToTab', () => { + it('focuses the current active element', (done) => { + document.body.innerHTML += '
'; + const el = document.querySelector('.repo-tab'); + spyOn(el, 'focus'); + + actions.scrollToTab(); + + setTimeout(() => { + expect(el.focus).toHaveBeenCalled(); + + document.getElementById('tabs').remove(); + + done(); + }); + }); + }); +}); -- cgit v1.2.1 From 8ccbfa2f26431ff2c001660da5e7629d35d98169 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 6 Nov 2017 13:07:59 +0000 Subject: test updates --- spec/javascripts/repo/stores/actions_spec.js | 199 +++++++++++++-------------- 1 file changed, 96 insertions(+), 103 deletions(-) (limited to 'spec/javascripts/repo/stores/actions_spec.js') diff --git a/spec/javascripts/repo/stores/actions_spec.js b/spec/javascripts/repo/stores/actions_spec.js index 12ac23d113d..af2f28be5f6 100644 --- a/spec/javascripts/repo/stores/actions_spec.js +++ b/spec/javascripts/repo/stores/actions_spec.js @@ -1,77 +1,70 @@ -import * as actions from '~/repo/stores/actions'; -import state from '~/repo/stores/state'; +import store from '~/repo/stores'; import service from '~/repo/services'; -import testAction, { testWithDispatch } from '../../helpers/vuex_action_helper'; -import { file } from '../helpers'; +import { resetStore, file } from '../helpers'; describe('Multi-file store actions', () => { - let localState; - - beforeEach(() => { - localState = state(); + afterEach(() => { + resetStore(store); }); describe('redirectToUrl', () => { - it('calls visitUrl', () => { + it('calls visitUrl', (done) => { spyOn(gl.utils, 'visitUrl'); - actions.redirectToUrl('test'); + store.dispatch('redirectToUrl', 'test') + .then(() => { + expect(gl.utils.visitUrl).toHaveBeenCalledWith('test'); - expect(gl.utils.visitUrl).toHaveBeenCalledWith('test'); + done(); + }) + .catch(done.fail); }); }); describe('setInitialData', () => { it('commits initial data', (done) => { - testAction( - actions.setInitialData, - { canCommit: true }, - localState, - [ - { type: 'SET_INITIAL_DATA', payload: { canCommit: true } }, - ], - done, - ); + store.dispatch('setInitialData', { canCommit: true }) + .then(() => { + expect(store.state.canCommit).toBeTruthy(); + done(); + }) + .catch(done.fail); }); }); describe('closeDiscardPopup', () => { it('closes the discard popup', (done) => { - testAction( - actions.closeDiscardPopup, - false, - localState, - [ - { type: 'TOGGLE_DISCARD_POPUP', payload: false }, - ], - done, - ); + store.dispatch('closeDiscardPopup', false) + .then(() => { + expect(store.state.discardPopupOpen).toBeFalsy(); + + done(); + }) + .catch(done.fail); }); }); describe('discardAllChanges', () => { beforeEach(() => { - localState.openFiles.push(file()); - localState.openFiles[0].changed = true; + store.state.openFiles.push(file()); + store.state.openFiles[0].changed = true; }); }); describe('closeAllFiles', () => { beforeEach(() => { - localState.openFiles.push(file()); - localState.openFiles[0].changed = true; + store.state.openFiles.push(file()); + store.state.openFiles[0].opened = true; }); it('closes all open files', (done) => { - testWithDispatch( - actions.closeAllFiles, - localState.openFiles[0], - localState, - [ - { type: 'closeFile', payload: { file: localState.openFiles[0] } }, - ], - done, - ); + store.dispatch('closeAllFiles') + .then(() => { + expect(store.state.openFiles.length).toBe(0); + + done(); + }) + .catch(done.fail); }); }); @@ -81,47 +74,47 @@ describe('Multi-file store actions', () => { describe('toggleBlobView', () => { it('sets edit mode view if in edit mode', (done) => { - localState.editMode = true; - - testAction( - actions.toggleBlobView, - null, - localState, - [ - { type: 'SET_EDIT_MODE' }, - ], - done, - ); + store.state.editMode = true; + + store.dispatch('toggleBlobView') + .then(() => { + expect(store.state.currentBlobView).toBe('repo-editor'); + + done(); + }) + .catch(done.fail); }); it('sets preview mode view if not in edit mode', (done) => { - testAction( - actions.toggleBlobView, - null, - localState, - [ - { type: 'SET_PREVIEW_MODE' }, - ], - done, - ); + store.dispatch('toggleBlobView') + .then(() => { + expect(store.state.currentBlobView).toBe('repo-preview'); + + done(); + }) + .catch(done.fail); }); }); describe('checkCommitStatus', () => { beforeEach(() => { - localState.project.id = 2; - localState.currentBranch = 'master'; - localState.currentRef = '1'; + store.state.project.id = 2; + store.state.currentBranch = 'master'; + store.state.currentRef = '1'; }); - it('calls service', () => { + it('calls service', (done) => { spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ commit: { id: '123' }, })); - actions.checkCommitStatus({ state: localState }); + store.dispatch('checkCommitStatus') + .then(() => { + expect(service.getBranchData).toHaveBeenCalledWith(2, 'master'); - expect(service.getBranchData).toHaveBeenCalledWith(2, 'master'); + done(); + }) + .catch(done.fail); }); it('returns true if current ref does not equal returned ID', (done) => { @@ -129,7 +122,7 @@ describe('Multi-file store actions', () => { commit: { id: '123' }, })); - actions.checkCommitStatus({ state: localState }) + store.dispatch('checkCommitStatus') .then((val) => { expect(val).toBeTruthy(); @@ -143,7 +136,7 @@ describe('Multi-file store actions', () => { commit: { id: '1' }, })); - actions.checkCommitStatus({ state: localState }) + store.dispatch('checkCommitStatus') .then((val) => { expect(val).toBeFalsy(); @@ -159,35 +152,33 @@ describe('Multi-file store actions', () => { describe('createTempEntry', () => { it('creates a temp tree', (done) => { - testWithDispatch( - actions.createTempEntry, - { name: 'test', type: 'tree' }, - localState, - [ - { type: 'createTempTree', payload: 'test' }, - ], - done, - ); + store.dispatch('createTempEntry', { + name: 'test', + type: 'tree', + }) + .then(() => { + expect(store.state.tree.length).toBe(1); + expect(store.state.tree[0].tempFile).toBeTruthy(); + expect(store.state.tree[0].type).toBe('tree'); + + done(); + }) + .catch(done.fail); }); it('creates temp file', (done) => { - testWithDispatch( - actions.createTempEntry, - { name: 'test', type: 'blob' }, - localState, - [ - { - type: 'createTempFile', - payload: { - tree: localState, - name: 'test', - base64: false, - content: '', - }, - }, - ], - done, - ); + store.dispatch('createTempEntry', { + name: 'test', + type: 'blob', + }) + .then(() => { + expect(store.state.tree.length).toBe(1); + expect(store.state.tree[0].tempFile).toBeTruthy(); + expect(store.state.tree[0].type).toBe('blob'); + + done(); + }) + .catch(done.fail); }); }); @@ -201,15 +192,17 @@ describe('Multi-file store actions', () => { const el = document.querySelector('.repo-tab'); spyOn(el, 'focus'); - actions.scrollToTab(); + store.dispatch('scrollToTab') + .then(() => { + setTimeout(() => { + expect(el.focus).toHaveBeenCalled(); - setTimeout(() => { - expect(el.focus).toHaveBeenCalled(); + document.getElementById('tabs').remove(); - document.getElementById('tabs').remove(); - - done(); - }); + done(); + }); + }) + .catch(done.fail); }); }); }); -- cgit v1.2.1 From 76152c0f8e7b8c4d7e147cd0f38147125e34cccd Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 10 Nov 2017 17:40:20 +0000 Subject: added missing specs --- spec/javascripts/repo/stores/actions_spec.js | 211 +++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) (limited to 'spec/javascripts/repo/stores/actions_spec.js') diff --git a/spec/javascripts/repo/stores/actions_spec.js b/spec/javascripts/repo/stores/actions_spec.js index af2f28be5f6..f2a7a698912 100644 --- a/spec/javascripts/repo/stores/actions_spec.js +++ b/spec/javascripts/repo/stores/actions_spec.js @@ -1,3 +1,4 @@ +import Vue from 'vue'; import store from '~/repo/stores'; import service from '~/repo/services'; import { resetStore, file } from '../helpers'; @@ -69,7 +70,72 @@ describe('Multi-file store actions', () => { }); describe('toggleEditMode', () => { + it('toggles edit mode', (done) => { + store.state.editMode = true; + + store.dispatch('toggleEditMode') + .then(() => { + expect(store.state.editMode).toBeFalsy(); + + done(); + }).catch(done.fail); + }); + it('sets preview mode', (done) => { + store.state.currentBlobView = 'repo-editor'; + store.state.editMode = true; + + store.dispatch('toggleEditMode') + .then(Vue.nextTick) + .then(() => { + expect(store.state.currentBlobView).toBe('repo-preview'); + + done(); + }).catch(done.fail); + }); + + it('opens discard popup if there are changed files', (done) => { + store.state.editMode = true; + store.state.openFiles.push(file()); + store.state.openFiles[0].changed = true; + + store.dispatch('toggleEditMode') + .then(() => { + expect(store.state.discardPopupOpen).toBeTruthy(); + + done(); + }).catch(done.fail); + }); + + it('can force closed if there are changed files', (done) => { + store.state.editMode = true; + store.state.openFiles.push(file()); + store.state.openFiles[0].changed = true; + + store.dispatch('toggleEditMode', true) + .then(() => { + expect(store.state.discardPopupOpen).toBeFalsy(); + expect(store.state.editMode).toBeFalsy(); + + done(); + }).catch(done.fail); + }); + + it('discards file changes', (done) => { + const f = file(); + store.state.editMode = true; + store.state.tree.push(f); + store.state.openFiles.push(f); + f.changed = true; + + store.dispatch('toggleEditMode', true) + .then(Vue.nextTick) + .then(() => { + expect(f.changed).toBeFalsy(); + + done(); + }).catch(done.fail); + }); }); describe('toggleBlobView', () => { @@ -147,7 +213,152 @@ describe('Multi-file store actions', () => { }); describe('commitChanges', () => { + let payload; + + beforeEach(() => { + spyOn(window, 'scrollTo'); + + document.body.innerHTML += '
'; + store.state.project.id = 123; + payload = { + branch: 'master', + }; + }); + + afterEach(() => { + document.querySelector('.flash-container').remove(); + }); + + describe('success', () => { + beforeEach(() => { + spyOn(service, 'commit').and.returnValue(Promise.resolve({ + id: '123456', + short_id: '123', + message: 'test message', + committed_date: 'date', + stats: { + additions: '1', + deletions: '2', + }, + })); + }); + + it('calls service', (done) => { + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + expect(service.commit).toHaveBeenCalledWith(123, payload); + + done(); + }).catch(done.fail); + }); + + it('shows flash notice', (done) => { + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + const alert = document.querySelector('.flash-container'); + + expect(alert.querySelector('.flash-notice')).not.toBeNull(); + expect(alert.textContent.trim()).toBe( + 'Your changes have been committed. Commit 123 with 1 additions, 2 deletions.', + ); + + done(); + }).catch(done.fail); + }); + + it('adds commit data to changed files', (done) => { + const changedFile = file(); + const f = file(); + changedFile.changed = true; + + store.state.openFiles.push(changedFile, f); + + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + expect(changedFile.lastCommit.message).toBe('test message'); + expect(f.lastCommit.message).not.toBe('test message'); + + done(); + }).catch(done.fail); + }); + + it('toggles edit mode', (done) => { + store.state.editMode = true; + + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + expect(store.state.editMode).toBeFalsy(); + + done(); + }).catch(done.fail); + }); + + it('closes all files', (done) => { + store.state.openFiles.push(file()); + store.state.openFiles[0].opened = true; + + store.dispatch('commitChanges', { payload, newMr: false }) + .then(Vue.nextTick) + .then(() => { + expect(store.state.openFiles.length).toBe(0); + + done(); + }).catch(done.fail); + }); + + it('scrolls to top of page', (done) => { + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + expect(window.scrollTo).toHaveBeenCalledWith(0, 0); + + done(); + }).catch(done.fail); + }); + + it('updates commit ref', (done) => { + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + expect(store.state.currentRef).toBe('123456'); + + done(); + }).catch(done.fail); + }); + + it('redirects to new merge request page', (done) => { + spyOn(gl.utils, 'visitUrl'); + + store.state.endpoints.newMergeRequestUrl = 'newMergeRequestUrl?branch='; + + store.dispatch('commitChanges', { payload, newMr: true }) + .then(() => { + expect(gl.utils.visitUrl).toHaveBeenCalledWith('newMergeRequestUrl?branch=master'); + + done(); + }).catch(done.fail); + }); + }); + + describe('failed', () => { + beforeEach(() => { + spyOn(service, 'commit').and.returnValue(Promise.resolve({ + message: 'failed message', + })); + }); + + it('shows failed message', (done) => { + store.dispatch('commitChanges', { payload, newMr: false }) + .then(() => { + const alert = document.querySelector('.flash-container'); + + expect(alert.textContent.trim()).toBe( + 'failed message', + ); + + done(); + }).catch(done.fail); + }); + }); }); describe('createTempEntry', () => { -- cgit v1.2.1