diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list.vue b/app/assets/javascripts/ide/components/commit_sidebar/list.vue deleted file mode 100644 index a8459b011df..00000000000 --- a/app/assets/javascripts/ide/components/commit_sidebar/list.vue +++ /dev/null @@ -1,65 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue deleted file mode 100644 index 6a0262f271b..00000000000 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_collapsed.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue b/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue deleted file mode 100644 index 742f746e02f..00000000000 --- a/app/assets/javascripts/ide/components/commit_sidebar/list_item.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide.vue b/app/assets/javascripts/ide/components/ide.vue deleted file mode 100644 index 89981ab2c65..00000000000 --- a/app/assets/javascripts/ide/components/ide.vue +++ /dev/null @@ -1,99 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide_context_bar.vue b/app/assets/javascripts/ide/components/ide_context_bar.vue deleted file mode 100644 index 9d933b8891d..00000000000 --- a/app/assets/javascripts/ide/components/ide_context_bar.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide_project_branches_tree.vue b/app/assets/javascripts/ide/components/ide_project_branches_tree.vue deleted file mode 100644 index 2fbff2bd789..00000000000 --- a/app/assets/javascripts/ide/components/ide_project_branches_tree.vue +++ /dev/null @@ -1,47 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide_project_tree.vue b/app/assets/javascripts/ide/components/ide_project_tree.vue deleted file mode 100644 index 32bf7175c88..00000000000 --- a/app/assets/javascripts/ide/components/ide_project_tree.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide_repo_tree.vue b/app/assets/javascripts/ide/components/ide_repo_tree.vue deleted file mode 100644 index 4a324264992..00000000000 --- a/app/assets/javascripts/ide/components/ide_repo_tree.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide_side_bar.vue b/app/assets/javascripts/ide/components/ide_side_bar.vue deleted file mode 100644 index 18b5059a17f..00000000000 --- a/app/assets/javascripts/ide/components/ide_side_bar.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/ide_status_bar.vue b/app/assets/javascripts/ide/components/ide_status_bar.vue deleted file mode 100644 index 97ae64b206d..00000000000 --- a/app/assets/javascripts/ide/components/ide_status_bar.vue +++ /dev/null @@ -1,66 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/new_branch_form.vue b/app/assets/javascripts/ide/components/new_branch_form.vue deleted file mode 100644 index 1e8d5bb6453..00000000000 --- a/app/assets/javascripts/ide/components/new_branch_form.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/new_dropdown/index.vue b/app/assets/javascripts/ide/components/new_dropdown/index.vue deleted file mode 100644 index ef653357f5f..00000000000 --- a/app/assets/javascripts/ide/components/new_dropdown/index.vue +++ /dev/null @@ -1,101 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue deleted file mode 100644 index 36cd825c6dd..00000000000 --- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue +++ /dev/null @@ -1,112 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/new_dropdown/upload.vue b/app/assets/javascripts/ide/components/new_dropdown/upload.vue deleted file mode 100644 index 6244737fa43..00000000000 --- a/app/assets/javascripts/ide/components/new_dropdown/upload.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_commit_section.vue b/app/assets/javascripts/ide/components/repo_commit_section.vue deleted file mode 100644 index 37f2cf30a29..00000000000 --- a/app/assets/javascripts/ide/components/repo_commit_section.vue +++ /dev/null @@ -1,171 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_edit_button.vue b/app/assets/javascripts/ide/components/repo_edit_button.vue deleted file mode 100644 index fe4320731d9..00000000000 --- a/app/assets/javascripts/ide/components/repo_edit_button.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue deleted file mode 100644 index f31cc12339b..00000000000 --- a/app/assets/javascripts/ide/components/repo_editor.vue +++ /dev/null @@ -1,136 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue deleted file mode 100644 index cbbab765e1c..00000000000 --- a/app/assets/javascripts/ide/components/repo_file.vue +++ /dev/null @@ -1,165 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_file_buttons.vue b/app/assets/javascripts/ide/components/repo_file_buttons.vue deleted file mode 100644 index aabc0d8eada..00000000000 --- a/app/assets/javascripts/ide/components/repo_file_buttons.vue +++ /dev/null @@ -1,60 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_loading_file.vue b/app/assets/javascripts/ide/components/repo_loading_file.vue deleted file mode 100644 index 79af8c0b0c7..00000000000 --- a/app/assets/javascripts/ide/components/repo_loading_file.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_prev_directory.vue b/app/assets/javascripts/ide/components/repo_prev_directory.vue deleted file mode 100644 index 7cd359ea4ed..00000000000 --- a/app/assets/javascripts/ide/components/repo_prev_directory.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_preview.vue b/app/assets/javascripts/ide/components/repo_preview.vue deleted file mode 100644 index a216269e292..00000000000 --- a/app/assets/javascripts/ide/components/repo_preview.vue +++ /dev/null @@ -1,71 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_tab.vue b/app/assets/javascripts/ide/components/repo_tab.vue deleted file mode 100644 index 5656081c598..00000000000 --- a/app/assets/javascripts/ide/components/repo_tab.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/components/repo_tabs.vue b/app/assets/javascripts/ide/components/repo_tabs.vue deleted file mode 100644 index ca363bba0ef..00000000000 --- a/app/assets/javascripts/ide/components/repo_tabs.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js deleted file mode 100644 index a7fb9e0588a..00000000000 --- a/app/assets/javascripts/ide/ide_router.js +++ /dev/null @@ -1,101 +0,0 @@ -import Vue from 'vue'; -import VueRouter from 'vue-router'; -import store from './stores'; -import flash from '../flash'; -import { - getTreeEntry, -} from './stores/utils'; - -Vue.use(VueRouter); - -/** - * Routes below /-/ide/: - -/project/h5bp/html5-boilerplate/blob/master -/project/h5bp/html5-boilerplate/blob/master/app/js/test.js - -/project/h5bp/html5-boilerplate/mr/123 -/project/h5bp/html5-boilerplate/mr/123/app/js/test.js - -/workspace/123 -/workspace/project/h5bp/html5-boilerplate/blob/my-special-branch -/workspace/project/h5bp/html5-boilerplate/mr/123 - -/ = /workspace - -/settings -*/ - -// Unfortunately Vue Router doesn't work without at least a fake component -// If you do only data handling -const EmptyRouterComponent = { - render(createElement) { - return createElement('div'); - }, -}; - -const router = new VueRouter({ - mode: 'history', - base: `${gon.relative_url_root}/-/ide/`, - routes: [ - { - path: '/project/:namespace/:project', - component: EmptyRouterComponent, - children: [ - { - path: ':targetmode/:branch/*', - component: EmptyRouterComponent, - }, - { - path: 'mr/:mrid', - component: EmptyRouterComponent, - }, - ], - }, - ], -}); - -router.beforeEach((to, from, next) => { - if (to.params.namespace && to.params.project) { - store.dispatch('getProjectData', { - namespace: to.params.namespace, - projectId: to.params.project, - }) - .then(() => { - const fullProjectId = `${to.params.namespace}/${to.params.project}`; - - if (to.params.branch) { - store.dispatch('getBranchData', { - projectId: fullProjectId, - branchId: to.params.branch, - }); - - store.dispatch('getTreeData', { - projectId: fullProjectId, - branch: to.params.branch, - endpoint: `/tree/${to.params.branch}`, - }) - .then(() => { - if (to.params[0]) { - const treeEntry = getTreeEntry(store, `${to.params.namespace}/${to.params.project}/${to.params.branch}`, to.params[0]); - if (treeEntry) { - store.dispatch('handleTreeEntryAction', treeEntry); - } - } - }) - .catch((e) => { - flash('Error while loading the branch files. Please try again.', 'alert', document, null, false, true); - throw e; - }); - } - }) - .catch((e) => { - flash('Error while loading the project data. Please try again.', 'alert', document, null, false, true); - throw e; - }); - } - - next(); -}); - -export default router; diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js deleted file mode 100644 index e8a19f47cee..00000000000 --- a/app/assets/javascripts/ide/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import Vue from 'vue'; -import ide from './components/ide.vue'; -import store from './stores'; -import router from './ide_router'; -import Translate from '../vue_shared/translate'; - -function initIde(el) { - if (!el) return null; - - return new Vue({ - el, - store, - router, - components: { - ide, - }, - render(createElement) { - return createElement('ide', { - props: { - emptyStateSvgPath: el.dataset.emptyStateSvgPath, - }, - }); - }, - }); -} - -const ideElement = document.getElementById('ide'); - -Vue.use(Translate); - -initIde(ideElement); diff --git a/app/assets/javascripts/ide/lib/common/disposable.js b/app/assets/javascripts/ide/lib/common/disposable.js deleted file mode 100644 index 84b29bdb600..00000000000 --- a/app/assets/javascripts/ide/lib/common/disposable.js +++ /dev/null @@ -1,14 +0,0 @@ -export default class Disposable { - constructor() { - this.disposers = new Set(); - } - - add(...disposers) { - disposers.forEach(disposer => this.disposers.add(disposer)); - } - - dispose() { - this.disposers.forEach(disposer => disposer.dispose()); - this.disposers.clear(); - } -} diff --git a/app/assets/javascripts/ide/lib/common/model.js b/app/assets/javascripts/ide/lib/common/model.js deleted file mode 100644 index 14d9fe4771e..00000000000 --- a/app/assets/javascripts/ide/lib/common/model.js +++ /dev/null @@ -1,64 +0,0 @@ -/* global monaco */ -import Disposable from './disposable'; - -export default class Model { - constructor(monaco, file) { - this.monaco = monaco; - this.disposable = new Disposable(); - this.file = file; - this.content = file.content !== '' ? file.content : file.raw; - - this.disposable.add( - this.originalModel = this.monaco.editor.createModel( - this.file.raw, - undefined, - new this.monaco.Uri(null, null, `original/${this.file.path}`), - ), - this.model = this.monaco.editor.createModel( - this.content, - undefined, - new this.monaco.Uri(null, null, this.file.path), - ), - ); - - this.events = new Map(); - } - - get url() { - return this.model.uri.toString(); - } - - get language() { - return this.model.getModeId(); - } - - get eol() { - return this.model.getEOL() === '\n' ? 'LF' : 'CRLF'; - } - - get path() { - return this.file.path; - } - - getModel() { - return this.model; - } - - getOriginalModel() { - return this.originalModel; - } - - onChange(cb) { - this.events.set( - this.path, - this.disposable.add( - this.model.onDidChangeContent(e => cb(this.model, e)), - ), - ); - } - - dispose() { - this.disposable.dispose(); - this.events.clear(); - } -} diff --git a/app/assets/javascripts/ide/lib/common/model_manager.js b/app/assets/javascripts/ide/lib/common/model_manager.js deleted file mode 100644 index fd462252795..00000000000 --- a/app/assets/javascripts/ide/lib/common/model_manager.js +++ /dev/null @@ -1,32 +0,0 @@ -import Disposable from './disposable'; -import Model from './model'; - -export default class ModelManager { - constructor(monaco) { - this.monaco = monaco; - this.disposable = new Disposable(); - this.models = new Map(); - } - - hasCachedModel(path) { - return this.models.has(path); - } - - addModel(file) { - if (this.hasCachedModel(file.path)) { - return this.models.get(file.path); - } - - const model = new Model(this.monaco, file); - this.models.set(model.path, model); - this.disposable.add(model); - - return model; - } - - dispose() { - // dispose of all the models - this.disposable.dispose(); - this.models.clear(); - } -} diff --git a/app/assets/javascripts/ide/lib/decorations/controller.js b/app/assets/javascripts/ide/lib/decorations/controller.js deleted file mode 100644 index 0954b7973c4..00000000000 --- a/app/assets/javascripts/ide/lib/decorations/controller.js +++ /dev/null @@ -1,43 +0,0 @@ -export default class DecorationsController { - constructor(editor) { - this.editor = editor; - this.decorations = new Map(); - this.editorDecorations = new Map(); - } - - getAllDecorationsForModel(model) { - if (!this.decorations.has(model.url)) return []; - - const modelDecorations = this.decorations.get(model.url); - const decorations = []; - - modelDecorations.forEach(val => decorations.push(...val)); - - return decorations; - } - - addDecorations(model, decorationsKey, decorations) { - const decorationMap = this.decorations.get(model.url) || new Map(); - - decorationMap.set(decorationsKey, decorations); - - this.decorations.set(model.url, decorationMap); - - this.decorate(model); - } - - decorate(model) { - const decorations = this.getAllDecorationsForModel(model); - const oldDecorations = this.editorDecorations.get(model.url) || []; - - this.editorDecorations.set( - model.url, - this.editor.instance.deltaDecorations(oldDecorations, decorations), - ); - } - - dispose() { - this.decorations.clear(); - this.editorDecorations.clear(); - } -} diff --git a/app/assets/javascripts/ide/lib/diff/controller.js b/app/assets/javascripts/ide/lib/diff/controller.js deleted file mode 100644 index dc0b1c95e59..00000000000 --- a/app/assets/javascripts/ide/lib/diff/controller.js +++ /dev/null @@ -1,71 +0,0 @@ -/* global monaco */ -import { throttle } from 'underscore'; -import DirtyDiffWorker from './diff_worker'; -import Disposable from '../common/disposable'; - -export const getDiffChangeType = (change) => { - if (change.modified) { - return 'modified'; - } else if (change.added) { - return 'added'; - } else if (change.removed) { - return 'removed'; - } - - return ''; -}; - -export const getDecorator = change => ({ - range: new monaco.Range( - change.lineNumber, - 1, - change.endLineNumber, - 1, - ), - options: { - isWholeLine: true, - linesDecorationsClassName: `dirty-diff dirty-diff-${getDiffChangeType(change)}`, - }, -}); - -export default class DirtyDiffController { - constructor(modelManager, decorationsController) { - this.disposable = new Disposable(); - this.editorSimpleWorker = null; - this.modelManager = modelManager; - this.decorationsController = decorationsController; - this.dirtyDiffWorker = new DirtyDiffWorker(); - this.throttledComputeDiff = throttle(this.computeDiff, 250); - this.decorate = this.decorate.bind(this); - - this.dirtyDiffWorker.addEventListener('message', this.decorate); - } - - attachModel(model) { - model.onChange(() => this.throttledComputeDiff(model)); - } - - computeDiff(model) { - this.dirtyDiffWorker.postMessage({ - path: model.path, - originalContent: model.getOriginalModel().getValue(), - newContent: model.getModel().getValue(), - }); - } - - reDecorate(model) { - this.decorationsController.decorate(model); - } - - decorate({ data }) { - const decorations = data.changes.map(change => getDecorator(change)); - this.decorationsController.addDecorations(data.path, 'dirtyDiff', decorations); - } - - dispose() { - this.disposable.dispose(); - - this.dirtyDiffWorker.removeEventListener('message', this.decorate); - this.dirtyDiffWorker.terminate(); - } -} diff --git a/app/assets/javascripts/ide/lib/diff/diff.js b/app/assets/javascripts/ide/lib/diff/diff.js deleted file mode 100644 index 0e37f5c4704..00000000000 --- a/app/assets/javascripts/ide/lib/diff/diff.js +++ /dev/null @@ -1,30 +0,0 @@ -import { diffLines } from 'diff'; - -// eslint-disable-next-line import/prefer-default-export -export const computeDiff = (originalContent, newContent) => { - const changes = diffLines(originalContent, newContent); - - let lineNumber = 1; - return changes.reduce((acc, change) => { - const findOnLine = acc.find(c => c.lineNumber === lineNumber); - - if (findOnLine) { - Object.assign(findOnLine, change, { - modified: true, - endLineNumber: (lineNumber + change.count) - 1, - }); - } else if ('added' in change || 'removed' in change) { - acc.push(Object.assign({}, change, { - lineNumber, - modified: undefined, - endLineNumber: (lineNumber + change.count) - 1, - })); - } - - if (!change.removed) { - lineNumber += change.count; - } - - return acc; - }, []); -}; diff --git a/app/assets/javascripts/ide/lib/diff/diff_worker.js b/app/assets/javascripts/ide/lib/diff/diff_worker.js deleted file mode 100644 index e74c4046330..00000000000 --- a/app/assets/javascripts/ide/lib/diff/diff_worker.js +++ /dev/null @@ -1,10 +0,0 @@ -import { computeDiff } from './diff'; - -self.addEventListener('message', (e) => { - const data = e.data; - - self.postMessage({ - path: data.path, - changes: computeDiff(data.originalContent, data.newContent), - }); -}); diff --git a/app/assets/javascripts/ide/lib/editor.js b/app/assets/javascripts/ide/lib/editor.js deleted file mode 100644 index 51255f15658..00000000000 --- a/app/assets/javascripts/ide/lib/editor.js +++ /dev/null @@ -1,110 +0,0 @@ -import _ from 'underscore'; -import DecorationsController from './decorations/controller'; -import DirtyDiffController from './diff/controller'; -import Disposable from './common/disposable'; -import ModelManager from './common/model_manager'; -import editorOptions from './editor_options'; - -export default class Editor { - static create(monaco) { - this.editorInstance = new Editor(monaco); - - return this.editorInstance; - } - - constructor(monaco) { - this.monaco = monaco; - this.currentModel = null; - this.instance = null; - this.dirtyDiffController = null; - this.disposable = new Disposable(); - - this.disposable.add( - this.modelManager = new ModelManager(this.monaco), - this.decorationsController = new DecorationsController(this), - ); - - this.debouncedUpdate = _.debounce(() => { - this.updateDimensions(); - }, 200); - window.addEventListener('resize', this.debouncedUpdate, false); - } - - createInstance(domElement) { - if (!this.instance) { - this.disposable.add( - this.instance = this.monaco.editor.create(domElement, { - model: null, - readOnly: false, - contextmenu: true, - scrollBeyondLastLine: false, - minimap: { - enabled: false, - }, - }), - this.dirtyDiffController = new DirtyDiffController( - this.modelManager, this.decorationsController, - ), - ); - } - } - - createModel(file) { - return this.modelManager.addModel(file); - } - - attachModel(model) { - this.instance.setModel(model.getModel()); - if (this.dirtyDiffController) this.dirtyDiffController.attachModel(model); - - this.currentModel = model; - - this.instance.updateOptions(editorOptions.reduce((acc, obj) => { - Object.keys(obj).forEach((key) => { - Object.assign(acc, { - [key]: obj[key](model), - }); - }); - return acc; - }, {})); - - if (this.dirtyDiffController) this.dirtyDiffController.reDecorate(model); - } - - clearEditor() { - if (this.instance) { - this.instance.setModel(null); - } - } - - dispose() { - this.disposable.dispose(); - window.removeEventListener('resize', this.debouncedUpdate); - - // dispose main monaco instance - if (this.instance) { - this.instance = null; - } - } - - updateDimensions() { - this.instance.layout(); - } - - setPosition({ lineNumber, column }) { - this.instance.revealPositionInCenter({ - lineNumber, - column, - }); - this.instance.setPosition({ - lineNumber, - column, - }); - } - - onPositionChange(cb) { - this.disposable.add( - this.instance.onDidChangeCursorPosition(e => cb(this.instance, e)), - ); - } -} diff --git a/app/assets/javascripts/ide/lib/editor_options.js b/app/assets/javascripts/ide/lib/editor_options.js deleted file mode 100644 index 701affc466e..00000000000 --- a/app/assets/javascripts/ide/lib/editor_options.js +++ /dev/null @@ -1,2 +0,0 @@ -export default [{ -}]; diff --git a/app/assets/javascripts/ide/monaco_loader.js b/app/assets/javascripts/ide/monaco_loader.js deleted file mode 100644 index 142a220097b..00000000000 --- a/app/assets/javascripts/ide/monaco_loader.js +++ /dev/null @@ -1,16 +0,0 @@ -import monacoContext from 'monaco-editor/dev/vs/loader'; - -monacoContext.require.config({ - paths: { - vs: `${__webpack_public_path__}monaco-editor/vs`, // eslint-disable-line camelcase - }, -}); - -// ignore CDN config and use local assets path for service worker which cannot be cross-domain -const relativeRootPath = (gon && gon.relative_url_root) || ''; -const monacoPath = `${relativeRootPath}/assets/webpack/monaco-editor/vs`; -window.MonacoEnvironment = { getWorkerUrl: () => `${monacoPath}/base/worker/workerMain.js` }; - -// eslint-disable-next-line no-underscore-dangle -window.__monaco_context__ = monacoContext; -export default monacoContext.require; diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js deleted file mode 100644 index 1fb24e93f2e..00000000000 --- a/app/assets/javascripts/ide/services/index.js +++ /dev/null @@ -1,47 +0,0 @@ -import Vue from 'vue'; -import VueResource from 'vue-resource'; -import Api from '../../api'; - -Vue.use(VueResource); - -export default { - getTreeData(endpoint) { - return Vue.http.get(endpoint, { params: { format: 'json' } }); - }, - getFileData(endpoint) { - return Vue.http.get(endpoint, { params: { format: 'json' } }); - }, - getRawFileData(file) { - if (file.tempFile) { - return Promise.resolve(file.content); - } - - if (file.raw) { - return Promise.resolve(file.raw); - } - - return Vue.http.get(file.rawPath, { params: { format: 'json' } }) - .then(res => res.text()); - }, - getProjectData(namespace, project) { - return Api.project(`${namespace}/${project}`); - }, - getBranchData(projectId, currentBranchId) { - return Api.branchSingle(projectId, currentBranchId); - }, - createBranch(projectId, payload) { - const url = Api.buildUrl(Api.createBranchPath).replace(':id', projectId); - - return Vue.http.post(url, payload); - }, - commit(projectId, payload) { - return Api.commitMultiple(projectId, payload); - }, - getTreeLastCommit(endpoint) { - return Vue.http.get(endpoint, { - params: { - format: 'json', - }, - }); - }, -}; diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js deleted file mode 100644 index 2c690b1f635..00000000000 --- a/app/assets/javascripts/ide/stores/actions.js +++ /dev/null @@ -1,196 +0,0 @@ -import Vue from 'vue'; -import { visitUrl } from '~/lib/utils/url_utility'; -import flash from '~/flash'; -import service from '../services'; -import * as types from './mutation_types'; -import { stripHtml } from '../../lib/utils/text_utility'; - -export const redirectToUrl = (_, url) => visitUrl(url); - -export const setInitialData = ({ commit }, data) => - commit(types.SET_INITIAL_DATA, data); - -export const closeDiscardPopup = ({ commit }) => - commit(types.TOGGLE_DISCARD_POPUP, false); - -export const discardAllChanges = ({ commit, getters, dispatch }) => { - const changedFiles = getters.changedFiles; - - changedFiles.forEach((file) => { - commit(types.DISCARD_FILE_CHANGES, file); - - if (file.tempFile) { - dispatch('closeFile', { file, force: true }); - } - }); -}; - -export const closeAllFiles = ({ state, dispatch }) => { - state.openFiles.forEach(file => dispatch('closeFile', { file })); -}; - -export const toggleEditMode = ( - { state, commit, getters, dispatch }, - force = false, -) => { - const changedFiles = getters.changedFiles; - - if (changedFiles.length && !force) { - commit(types.TOGGLE_DISCARD_POPUP, true); - } else { - commit(types.TOGGLE_EDIT_MODE); - commit(types.TOGGLE_DISCARD_POPUP, false); - dispatch('toggleBlobView'); - - if (!state.editMode) { - dispatch('discardAllChanges'); - } - } -}; - -export const toggleBlobView = ({ commit, state }) => { - if (state.editMode) { - commit(types.SET_EDIT_MODE); - } else { - commit(types.SET_PREVIEW_MODE); - } -}; - -export const setPanelCollapsedStatus = ({ commit }, { side, collapsed }) => { - if (side === 'left') { - commit(types.SET_LEFT_PANEL_COLLAPSED, collapsed); - } else { - commit(types.SET_RIGHT_PANEL_COLLAPSED, collapsed); - } -}; - -export const setResizingStatus = ({ commit }, resizing) => { - commit(types.SET_RESIZING_STATUS, resizing); -}; - -export const checkCommitStatus = ({ state }) => - service - .getBranchData(state.currentProjectId, state.currentBranchId) - .then(({ data }) => { - const { id } = data.commit; - const selectedBranch = - state.projects[state.currentProjectId].branches[state.currentBranchId]; - - if (selectedBranch.workingReference !== id) { - return true; - } - - return false; - }) - .catch(() => flash('Error checking branch data. Please try again.', 'alert', document, null, false, true)); - -export const commitChanges = ( - { commit, state, dispatch, getters }, - { payload, newMr }, -) => - service - .commit(state.currentProjectId, payload) - .then(({ data }) => { - const { branch } = payload; - if (!data.short_id) { - flash(data.message, 'alert', document, null, false, true); - return; - } - - const selectedProject = state.projects[state.currentProjectId]; - const lastCommit = { - commit_path: `${selectedProject.web_url}/commit/${data.id}`, - commit: { - message: data.message, - authored_date: data.committed_date, - }, - }; - - let commitMsg = `Your changes have been committed. Commit ${data.short_id}`; - if (data.stats) { - commitMsg += ` with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`; - } - - flash( - commitMsg, - 'notice', - document, - null, - false, - true); - window.dispatchEvent(new Event('resize')); - - if (newMr) { - dispatch('discardAllChanges'); - dispatch( - 'redirectToUrl', - `${selectedProject.web_url}/merge_requests/new?merge_request%5Bsource_branch%5D=${branch}`, - ); - } else { - commit(types.SET_BRANCH_WORKING_REFERENCE, { - projectId: state.currentProjectId, - branchId: state.currentBranchId, - reference: data.id, - }); - - getters.changedFiles.forEach((entry) => { - commit(types.SET_LAST_COMMIT_DATA, { - entry, - lastCommit, - }); - }); - - dispatch('discardAllChanges'); - - window.scrollTo(0, 0); - } - }) - .catch((err) => { - let errMsg = 'Error committing changes. Please try again.'; - if (err.response.data && err.response.data.message) { - errMsg += ` (${stripHtml(err.response.data.message)})`; - } - flash(errMsg, 'alert', document, null, false, true); - window.dispatchEvent(new Event('resize')); - }); - -export const createTempEntry = ( - { state, dispatch }, - { projectId, branchId, parent, name, type, content = '', base64 = false }, -) => { - const selectedParent = parent || state.trees[`${projectId}/${branchId}`]; - if (type === 'tree') { - dispatch('createTempTree', { - projectId, - branchId, - parent: selectedParent, - name, - }); - } else if (type === 'blob') { - dispatch('createTempFile', { - projectId, - branchId, - parent: selectedParent, - name, - base64, - content, - }); - } -}; - -export const scrollToTab = () => { - Vue.nextTick(() => { - const tabs = document.getElementById('tabs'); - - if (tabs) { - const tabEl = tabs.querySelector('.active .repo-tab'); - - tabEl.focus(); - } - }); -}; - -export * from './actions/tree'; -export * from './actions/file'; -export * from './actions/project'; -export * from './actions/branch'; diff --git a/app/assets/javascripts/ide/stores/actions/branch.js b/app/assets/javascripts/ide/stores/actions/branch.js deleted file mode 100644 index bc6fd2d4163..00000000000 --- a/app/assets/javascripts/ide/stores/actions/branch.js +++ /dev/null @@ -1,43 +0,0 @@ -import service from '../../services'; -import flash from '../../../flash'; -import * as types from '../mutation_types'; - -export const getBranchData = ( - { commit, state, dispatch }, - { projectId, branchId, force = false } = {}, -) => new Promise((resolve, reject) => { - if ((typeof state.projects[`${projectId}`] === 'undefined' || - !state.projects[`${projectId}`].branches[branchId]) - || force) { - service.getBranchData(`${projectId}`, branchId) - .then(({ data }) => { - const { id } = data.commit; - commit(types.SET_BRANCH, { projectPath: `${projectId}`, branchName: branchId, branch: data }); - commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id }); - resolve(data); - }) - .catch(() => { - flash('Error loading branch data. Please try again.', 'alert', document, null, false, true); - reject(new Error(`Branch not loaded - ${projectId}/${branchId}`)); - }); - } else { - resolve(state.projects[`${projectId}`].branches[branchId]); - } -}); - -export const createNewBranch = ({ state, commit }, branch) => service.createBranch( - state.currentProjectId, - { - branch, - ref: state.currentBranchId, - }, -) -.then(res => res.json()) -.then((data) => { - const branchName = data.name; - const url = location.href.replace(state.currentBranchId, branchName); - - if (this.$router) this.$router.push(url); - - commit(types.SET_CURRENT_BRANCH, branchName); -}); diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js deleted file mode 100644 index 670af2fb89e..00000000000 --- a/app/assets/javascripts/ide/stores/actions/file.js +++ /dev/null @@ -1,137 +0,0 @@ -import { normalizeHeaders } from '../../../lib/utils/common_utils'; -import flash from '../../../flash'; -import service from '../../services'; -import * as types from '../mutation_types'; -import router from '../../ide_router'; -import { - findEntry, - setPageTitle, - createTemp, - findIndexOfFile, -} from '../utils'; - -export const closeFile = ({ commit, state, dispatch }, { file, force = false }) => { - if ((file.changed || file.tempFile) && !force) return; - - const indexOfClosedFile = findIndexOfFile(state.openFiles, file); - const fileWasActive = file.active; - - commit(types.TOGGLE_FILE_OPEN, file); - commit(types.SET_FILE_ACTIVE, { file, active: false }); - - if (state.openFiles.length > 0 && fileWasActive) { - const nextIndexToOpen = indexOfClosedFile === 0 ? 0 : indexOfClosedFile - 1; - const nextFileToOpen = state.openFiles[nextIndexToOpen]; - - dispatch('setFileActive', nextFileToOpen); - } else if (!state.openFiles.length) { - router.push(`/project/${file.projectId}/tree/${file.branchId}/`); - } - - dispatch('getLastCommitData'); -}; - -export const setFileActive = ({ commit, state, getters, dispatch }, file) => { - const currentActiveFile = getters.activeFile; - - if (file.active) return; - - if (currentActiveFile) { - commit(types.SET_FILE_ACTIVE, { file: currentActiveFile, active: false }); - } - - commit(types.SET_FILE_ACTIVE, { file, active: true }); - dispatch('scrollToTab'); - - // reset hash for line highlighting - location.hash = ''; - - commit(types.SET_CURRENT_PROJECT, file.projectId); - commit(types.SET_CURRENT_BRANCH, file.branchId); -}; - -export const getFileData = ({ state, commit, dispatch }, file) => { - commit(types.TOGGLE_LOADING, file); - - service.getFileData(file.url) - .then((res) => { - const pageTitle = decodeURI(normalizeHeaders(res.headers)['PAGE-TITLE']); - - setPageTitle(pageTitle); - - return res.json(); - }) - .then((data) => { - commit(types.SET_FILE_DATA, { data, file }); - commit(types.TOGGLE_FILE_OPEN, file); - dispatch('setFileActive', file); - commit(types.TOGGLE_LOADING, file); - }) - .catch(() => { - commit(types.TOGGLE_LOADING, file); - flash('Error loading file data. Please try again.', 'alert', document, null, false, true); - }); -}; - -export const getRawFileData = ({ commit, dispatch }, file) => service.getRawFileData(file) - .then((raw) => { - commit(types.SET_FILE_RAW_DATA, { file, raw }); - }) - .catch(() => flash('Error loading file content. Please try again.', 'alert', document, null, false, true)); - -export const changeFileContent = ({ commit }, { file, content }) => { - commit(types.UPDATE_FILE_CONTENT, { file, content }); -}; - -export const setFileLanguage = ({ state, commit }, { fileLanguage }) => { - if (state.selectedFile) { - commit(types.SET_FILE_LANGUAGE, { file: state.selectedFile, fileLanguage }); - } -}; - -export const setFileEOL = ({ state, commit }, { eol }) => { - if (state.selectedFile) { - commit(types.SET_FILE_EOL, { file: state.selectedFile, eol }); - } -}; - -export const setEditorPosition = ({ state, commit }, { editorRow, editorColumn }) => { - if (state.selectedFile) { - commit(types.SET_FILE_POSITION, { file: state.selectedFile, editorRow, editorColumn }); - } -}; - -export const createTempFile = ({ state, commit, dispatch }, { projectId, branchId, parent, name, content = '', base64 = '' }) => { - const path = parent.path !== undefined ? parent.path : ''; - // We need to do the replacement otherwise the web_url + file.url duplicate - const newUrl = `/${projectId}/blob/${branchId}/${path}${path ? '/' : ''}${name}`; - const file = createTemp({ - projectId, - branchId, - name: name.replace(`${path}/`, ''), - path, - type: 'blob', - level: parent.level !== undefined ? parent.level + 1 : 0, - changed: true, - content, - base64, - url: newUrl, - }); - - if (findEntry(parent.tree, 'blob', file.name)) return flash(`The name "${file.name}" is already taken in this directory.`, 'alert', document, null, false, true); - - commit(types.CREATE_TMP_FILE, { - parent, - file, - }); - commit(types.TOGGLE_FILE_OPEN, file); - dispatch('setFileActive', file); - - if (!state.editMode && !file.base64) { - dispatch('toggleEditMode', true); - } - - router.push(`/project${file.url}`); - - return Promise.resolve(file); -}; diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js deleted file mode 100644 index faeceb430a2..00000000000 --- a/app/assets/javascripts/ide/stores/actions/project.js +++ /dev/null @@ -1,27 +0,0 @@ -import service from '../../services'; -import flash from '../../../flash'; -import * as types from '../mutation_types'; - -// eslint-disable-next-line import/prefer-default-export -export const getProjectData = ( - { commit, state, dispatch }, - { namespace, projectId, force = false } = {}, -) => new Promise((resolve, reject) => { - if (!state.projects[`${namespace}/${projectId}`] || force) { - commit(types.TOGGLE_LOADING, state); - service.getProjectData(namespace, projectId) - .then(res => res.data) - .then((data) => { - commit(types.TOGGLE_LOADING, state); - commit(types.SET_PROJECT, { projectPath: `${namespace}/${projectId}`, project: data }); - if (!state.currentProjectId) commit(types.SET_CURRENT_PROJECT, `${namespace}/${projectId}`); - resolve(data); - }) - .catch(() => { - flash('Error loading project data. Please try again.', 'alert', document, null, false, true); - reject(new Error(`Project not loaded ${namespace}/${projectId}`)); - }); - } else { - resolve(state.projects[`${namespace}/${projectId}`]); - } -}); diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js deleted file mode 100644 index 302ba45edee..00000000000 --- a/app/assets/javascripts/ide/stores/actions/tree.js +++ /dev/null @@ -1,188 +0,0 @@ -import { visitUrl } from '../../../lib/utils/url_utility'; -import { normalizeHeaders } from '../../../lib/utils/common_utils'; -import flash from '../../../flash'; -import service from '../../services'; -import * as types from '../mutation_types'; -import router from '../../ide_router'; -import { - setPageTitle, - findEntry, - createTemp, - createOrMergeEntry, -} from '../utils'; - -export const getTreeData = ( - { commit, state, dispatch }, - { endpoint, tree = null, projectId, branch, force = false } = {}, -) => new Promise((resolve, reject) => { - // We already have the base tree so we resolve immediately - if (!tree && state.trees[`${projectId}/${branch}`] && !force) { - resolve(); - } else { - if (tree) commit(types.TOGGLE_LOADING, tree); - const selectedProject = state.projects[projectId]; - // We are merging the web_url that we got on the project info with the endpoint - // we got on the tree entry, as both contain the projectId, we replace it in the tree endpoint - const completeEndpoint = selectedProject.web_url + (endpoint).replace(projectId, ''); - if (completeEndpoint && (!tree || !tree.tempFile)) { - service.getTreeData(completeEndpoint) - .then((res) => { - const pageTitle = decodeURI(normalizeHeaders(res.headers)['PAGE-TITLE']); - - setPageTitle(pageTitle); - - return res.json(); - }) - .then((data) => { - if (!state.isInitialRoot) { - commit(types.SET_ROOT, data.path === '/'); - } - - dispatch('updateDirectoryData', { data, tree, projectId, branch }); - const selectedTree = tree || state.trees[`${projectId}/${branch}`]; - - commit(types.SET_PARENT_TREE_URL, data.parent_tree_url); - commit(types.SET_LAST_COMMIT_URL, { tree: selectedTree, url: data.last_commit_path }); - if (tree) commit(types.TOGGLE_LOADING, selectedTree); - - const prevLastCommitPath = selectedTree.lastCommitPath; - if (prevLastCommitPath !== null) { - dispatch('getLastCommitData', selectedTree); - } - resolve(data); - }) - .catch((e) => { - flash('Error loading tree data. Please try again.', 'alert', document, null, false, true); - if (tree) commit(types.TOGGLE_LOADING, tree); - reject(e); - }); - } else { - resolve(); - } - } -}); - -export const toggleTreeOpen = ({ commit, dispatch }, { endpoint, tree }) => { - if (tree.opened) { - // send empty data to clear the tree - const data = { trees: [], blobs: [], submodules: [] }; - - dispatch('updateDirectoryData', { data, tree, projectId: tree.projectId, branchId: tree.branchId }); - } else { - dispatch('getTreeData', { endpoint, tree, projectId: tree.projectId, branch: tree.branchId }); - } - - commit(types.TOGGLE_TREE_OPEN, tree); -}; - -export const handleTreeEntryAction = ({ commit, dispatch }, row) => { - if (row.type === 'tree') { - dispatch('toggleTreeOpen', { - endpoint: row.url, - tree: row, - }); - } else if (row.type === 'submodule') { - commit(types.TOGGLE_LOADING, row); - visitUrl(row.url); - } else if (row.type === 'blob' && row.opened) { - dispatch('setFileActive', row); - } else { - dispatch('getFileData', row); - } -}; - -export const createTempTree = ( - { state, commit, dispatch }, - { projectId, branchId, parent, name }, -) => { - let selectedTree = parent; - const dirNames = name.replace(new RegExp(`^${state.path}/`), '').split('/'); - - dirNames.forEach((dirName) => { - const foundEntry = findEntry(selectedTree.tree, 'tree', dirName); - - if (!foundEntry) { - const path = selectedTree.path !== undefined ? selectedTree.path : ''; - const tmpEntry = createTemp({ - projectId, - branchId, - name: dirName, - path, - type: 'tree', - level: selectedTree.level !== undefined ? selectedTree.level + 1 : 0, - tree: [], - url: `/${projectId}/blob/${branchId}/${path}${path ? '/' : ''}${dirName}`, - }); - - commit(types.CREATE_TMP_TREE, { - parent: selectedTree, - tmpEntry, - }); - commit(types.TOGGLE_TREE_OPEN, tmpEntry); - - router.push(`/project${tmpEntry.url}`); - - selectedTree = tmpEntry; - } else { - selectedTree = foundEntry; - } - }); -}; - -export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = state) => { - if (!tree || tree.lastCommitPath === null || !tree.lastCommitPath) return; - - service.getTreeLastCommit(tree.lastCommitPath) - .then((res) => { - const lastCommitPath = normalizeHeaders(res.headers)['MORE-LOGS-URL'] || null; - - commit(types.SET_LAST_COMMIT_URL, { tree, url: lastCommitPath }); - - return res.json(); - }) - .then((data) => { - data.forEach((lastCommit) => { - const entry = findEntry(tree.tree, lastCommit.type, lastCommit.file_name); - - if (entry) { - commit(types.SET_LAST_COMMIT_DATA, { entry, lastCommit }); - } - }); - - dispatch('getLastCommitData', tree); - }) - .catch(() => flash('Error fetching log data.', 'alert', document, null, false, true)); -}; - -export const updateDirectoryData = ( - { commit, state }, - { data, tree, projectId, branch }, -) => { - if (!tree) { - const existingTree = state.trees[`${projectId}/${branch}`]; - if (!existingTree) { - commit(types.CREATE_TREE, { treePath: `${projectId}/${branch}` }); - } - } - - const selectedTree = tree || state.trees[`${projectId}/${branch}`]; - const level = selectedTree.level !== undefined ? selectedTree.level + 1 : 0; - const parentTreeUrl = data.parent_tree_url ? `${data.parent_tree_url}${data.path}` : state.endpoints.rootUrl; - const createEntry = (entry, type) => createOrMergeEntry({ - tree: selectedTree, - projectId: `${projectId}`, - branchId: branch, - entry, - level, - type, - parentTreeUrl, - }); - - const formattedData = [ - ...data.trees.map(t => createEntry(t, 'tree')), - ...data.submodules.map(m => createEntry(m, 'submodule')), - ...data.blobs.map(b => createEntry(b, 'blob')), - ]; - - commit(types.SET_DIRECTORY_DATA, { tree: selectedTree, data: formattedData }); -}; diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js deleted file mode 100644 index 6b51ccff817..00000000000 --- a/app/assets/javascripts/ide/stores/getters.js +++ /dev/null @@ -1,19 +0,0 @@ -export const changedFiles = state => state.openFiles.filter(file => file.changed); - -export const activeFile = state => state.openFiles.find(file => file.active) || null; - -export const activeFileExtension = (state) => { - const file = activeFile(state); - return file ? `.${file.path.split('.').pop()}` : ''; -}; - -export const canEditFile = (state) => { - const currentActiveFile = activeFile(state); - - return state.canCommit && - (currentActiveFile && !currentActiveFile.renderError && !currentActiveFile.binary); -}; - -export const addedFiles = state => changedFiles(state).filter(f => f.tempFile); - -export const modifiedFiles = state => changedFiles(state).filter(f => !f.tempFile); diff --git a/app/assets/javascripts/ide/stores/index.js b/app/assets/javascripts/ide/stores/index.js deleted file mode 100644 index 6ac9bfd8189..00000000000 --- a/app/assets/javascripts/ide/stores/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import Vue from 'vue'; -import Vuex from 'vuex'; -import state from './state'; -import * as actions from './actions'; -import * as getters from './getters'; -import mutations from './mutations'; - -Vue.use(Vuex); - -export default new Vuex.Store({ - state: state(), - actions, - mutations, - getters, -}); diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js deleted file mode 100644 index 69b218a5e7d..00000000000 --- a/app/assets/javascripts/ide/stores/mutation_types.js +++ /dev/null @@ -1,46 +0,0 @@ -export const SET_INITIAL_DATA = 'SET_INITIAL_DATA'; -export const TOGGLE_LOADING = 'TOGGLE_LOADING'; -export const SET_PARENT_TREE_URL = 'SET_PARENT_TREE_URL'; -export const SET_ROOT = 'SET_ROOT'; -export const SET_LAST_COMMIT_DATA = 'SET_LAST_COMMIT_DATA'; -export const SET_LEFT_PANEL_COLLAPSED = 'SET_LEFT_PANEL_COLLAPSED'; -export const SET_RIGHT_PANEL_COLLAPSED = 'SET_RIGHT_PANEL_COLLAPSED'; -export const SET_RESIZING_STATUS = 'SET_RESIZING_STATUS'; - -// Project Mutation Types -export const SET_PROJECT = 'SET_PROJECT'; -export const SET_CURRENT_PROJECT = 'SET_CURRENT_PROJECT'; -export const TOGGLE_PROJECT_OPEN = 'TOGGLE_PROJECT_OPEN'; - -// Branch Mutation Types -export const SET_BRANCH = 'SET_BRANCH'; -export const SET_BRANCH_WORKING_REFERENCE = 'SET_BRANCH_WORKING_REFERENCE'; -export const TOGGLE_BRANCH_OPEN = 'TOGGLE_BRANCH_OPEN'; - -// Tree mutation types -export const SET_DIRECTORY_DATA = 'SET_DIRECTORY_DATA'; -export const TOGGLE_TREE_OPEN = 'TOGGLE_TREE_OPEN'; -export const CREATE_TMP_TREE = 'CREATE_TMP_TREE'; -export const SET_LAST_COMMIT_URL = 'SET_LAST_COMMIT_URL'; -export const CREATE_TREE = 'CREATE_TREE'; - -// File mutation types -export const SET_FILE_DATA = 'SET_FILE_DATA'; -export const TOGGLE_FILE_OPEN = 'TOGGLE_FILE_OPEN'; -export const SET_FILE_ACTIVE = 'SET_FILE_ACTIVE'; -export const SET_FILE_RAW_DATA = 'SET_FILE_RAW_DATA'; -export const UPDATE_FILE_CONTENT = 'UPDATE_FILE_CONTENT'; -export const SET_FILE_LANGUAGE = 'SET_FILE_LANGUAGE'; -export const SET_FILE_POSITION = 'SET_FILE_POSITION'; -export const SET_FILE_EOL = 'SET_FILE_EOL'; -export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES'; -export const CREATE_TMP_FILE = 'CREATE_TMP_FILE'; - -// Viewer mutation types -export const SET_PREVIEW_MODE = 'SET_PREVIEW_MODE'; -export const SET_EDIT_MODE = 'SET_EDIT_MODE'; -export const TOGGLE_EDIT_MODE = 'TOGGLE_EDIT_MODE'; -export const TOGGLE_DISCARD_POPUP = 'TOGGLE_DISCARD_POPUP'; - -export const SET_CURRENT_BRANCH = 'SET_CURRENT_BRANCH'; - diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js deleted file mode 100644 index 03d81be10a1..00000000000 --- a/app/assets/javascripts/ide/stores/mutations.js +++ /dev/null @@ -1,70 +0,0 @@ -import * as types from './mutation_types'; -import projectMutations from './mutations/project'; -import fileMutations from './mutations/file'; -import treeMutations from './mutations/tree'; -import branchMutations from './mutations/branch'; - -export default { - [types.SET_INITIAL_DATA](state, data) { - Object.assign(state, data); - }, - [types.SET_PREVIEW_MODE](state) { - Object.assign(state, { - currentBlobView: 'repo-preview', - }); - }, - [types.SET_EDIT_MODE](state) { - Object.assign(state, { - currentBlobView: 'repo-editor', - }); - }, - [types.TOGGLE_LOADING](state, entry) { - Object.assign(entry, { - loading: !entry.loading, - }); - }, - [types.TOGGLE_EDIT_MODE](state) { - Object.assign(state, { - editMode: !state.editMode, - }); - }, - [types.TOGGLE_DISCARD_POPUP](state, discardPopupOpen) { - Object.assign(state, { - discardPopupOpen, - }); - }, - [types.SET_ROOT](state, isRoot) { - Object.assign(state, { - isRoot, - isInitialRoot: isRoot, - }); - }, - [types.SET_LEFT_PANEL_COLLAPSED](state, collapsed) { - Object.assign(state, { - leftPanelCollapsed: collapsed, - }); - }, - [types.SET_RIGHT_PANEL_COLLAPSED](state, collapsed) { - Object.assign(state, { - rightPanelCollapsed: collapsed, - }); - }, - [types.SET_RESIZING_STATUS](state, resizing) { - Object.assign(state, { - panelResizing: resizing, - }); - }, - [types.SET_LAST_COMMIT_DATA](state, { entry, lastCommit }) { - Object.assign(entry.lastCommit, { - id: lastCommit.commit.id, - url: lastCommit.commit_path, - message: lastCommit.commit.message, - author: lastCommit.commit.author_name, - updatedAt: lastCommit.commit.authored_date, - }); - }, - ...projectMutations, - ...fileMutations, - ...treeMutations, - ...branchMutations, -}; diff --git a/app/assets/javascripts/ide/stores/mutations/branch.js b/app/assets/javascripts/ide/stores/mutations/branch.js deleted file mode 100644 index 04b9582c5bb..00000000000 --- a/app/assets/javascripts/ide/stores/mutations/branch.js +++ /dev/null @@ -1,28 +0,0 @@ -import * as types from '../mutation_types'; - -export default { - [types.SET_CURRENT_BRANCH](state, currentBranchId) { - Object.assign(state, { - currentBranchId, - }); - }, - [types.SET_BRANCH](state, { projectPath, branchName, branch }) { - // Add client side properties - Object.assign(branch, { - treeId: `${projectPath}/${branchName}`, - active: true, - workingReference: '', - }); - - Object.assign(state.projects[projectPath], { - branches: { - [branchName]: branch, - }, - }); - }, - [types.SET_BRANCH_WORKING_REFERENCE](state, { projectId, branchId, reference }) { - Object.assign(state.projects[projectId].branches[branchId], { - workingReference: reference, - }); - }, -}; diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js deleted file mode 100644 index 72db1c180c9..00000000000 --- a/app/assets/javascripts/ide/stores/mutations/file.js +++ /dev/null @@ -1,74 +0,0 @@ -import * as types from '../mutation_types'; -import { findIndexOfFile } from '../utils'; - -export default { - [types.SET_FILE_ACTIVE](state, { file, active }) { - Object.assign(file, { - active, - }); - - Object.assign(state, { - selectedFile: file, - }); - }, - [types.TOGGLE_FILE_OPEN](state, file) { - Object.assign(file, { - opened: !file.opened, - }); - - if (file.opened) { - state.openFiles.push(file); - } else { - state.openFiles.splice(findIndexOfFile(state.openFiles, file), 1); - } - }, - [types.SET_FILE_DATA](state, { data, file }) { - Object.assign(file, { - blamePath: data.blame_path, - commitsPath: data.commits_path, - permalink: data.permalink, - rawPath: data.raw_path, - binary: data.binary, - html: data.html, - renderError: data.render_error, - }); - }, - [types.SET_FILE_RAW_DATA](state, { file, raw }) { - Object.assign(file, { - raw, - }); - }, - [types.UPDATE_FILE_CONTENT](state, { file, content }) { - const changed = content !== file.raw; - - Object.assign(file, { - content, - changed, - }); - }, - [types.SET_FILE_LANGUAGE](state, { file, fileLanguage }) { - Object.assign(file, { - fileLanguage, - }); - }, - [types.SET_FILE_EOL](state, { file, eol }) { - Object.assign(file, { - eol, - }); - }, - [types.SET_FILE_POSITION](state, { file, editorRow, editorColumn }) { - Object.assign(file, { - editorRow, - editorColumn, - }); - }, - [types.DISCARD_FILE_CHANGES](state, file) { - Object.assign(file, { - content: file.raw, - changed: false, - }); - }, - [types.CREATE_TMP_FILE](state, { file, parent }) { - parent.tree.push(file); - }, -}; diff --git a/app/assets/javascripts/ide/stores/mutations/project.js b/app/assets/javascripts/ide/stores/mutations/project.js deleted file mode 100644 index 2816562a919..00000000000 --- a/app/assets/javascripts/ide/stores/mutations/project.js +++ /dev/null @@ -1,23 +0,0 @@ -import * as types from '../mutation_types'; - -export default { - [types.SET_CURRENT_PROJECT](state, currentProjectId) { - Object.assign(state, { - currentProjectId, - }); - }, - [types.SET_PROJECT](state, { projectPath, project }) { - // Add client side properties - Object.assign(project, { - tree: [], - branches: {}, - active: true, - }); - - Object.assign(state, { - projects: Object.assign({}, state.projects, { - [projectPath]: project, - }), - }); - }, -}; diff --git a/app/assets/javascripts/ide/stores/mutations/tree.js b/app/assets/javascripts/ide/stores/mutations/tree.js deleted file mode 100644 index 4fe438ab465..00000000000 --- a/app/assets/javascripts/ide/stores/mutations/tree.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as types from '../mutation_types'; - -export default { - [types.TOGGLE_TREE_OPEN](state, tree) { - Object.assign(tree, { - opened: !tree.opened, - }); - }, - [types.CREATE_TREE](state, { treePath }) { - Object.assign(state, { - trees: Object.assign({}, state.trees, { - [treePath]: { - tree: [], - }, - }), - }); - }, - [types.SET_DIRECTORY_DATA](state, { data, tree }) { - Object.assign(tree, { - tree: data, - }); - }, - [types.SET_PARENT_TREE_URL](state, url) { - Object.assign(state, { - parentTreeUrl: url, - }); - }, - [types.SET_LAST_COMMIT_URL](state, { tree = state, url }) { - Object.assign(tree, { - lastCommitPath: url, - }); - }, - [types.CREATE_TMP_TREE](state, { parent, tmpEntry }) { - parent.tree.push(tmpEntry); - }, -}; diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js deleted file mode 100644 index 61d12096946..00000000000 --- a/app/assets/javascripts/ide/stores/state.js +++ /dev/null @@ -1,23 +0,0 @@ -export default () => ({ - canCommit: false, - currentProjectId: '', - currentBranchId: '', - currentBlobView: 'repo-editor', - discardPopupOpen: false, - editMode: true, - endpoints: {}, - isRoot: false, - isInitialRoot: false, - lastCommitPath: '', - loading: false, - onTopOfBranch: false, - openFiles: [], - selectedFile: null, - path: '', - parentTreeUrl: '', - trees: {}, - projects: {}, - leftPanelCollapsed: false, - rightPanelCollapsed: true, - panelResizing: false, -}); diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js deleted file mode 100644 index d556404faa5..00000000000 --- a/app/assets/javascripts/ide/stores/utils.js +++ /dev/null @@ -1,177 +0,0 @@ -import _ from 'underscore'; - -export const dataStructure = () => ({ - id: '', - key: '', - type: '', - projectId: '', - branchId: '', - name: '', - url: '', - path: '', - level: 0, - tempFile: false, - icon: '', - tree: [], - loading: false, - opened: false, - active: false, - changed: false, - lastCommitPath: '', - lastCommit: { - id: '', - url: '', - message: '', - updatedAt: '', - author: '', - }, - tree_url: '', - blamePath: '', - commitsPath: '', - permalink: '', - rawPath: '', - binary: false, - html: '', - raw: '', - content: '', - parentTreeUrl: '', - renderError: false, - base64: false, - editorRow: 1, - editorColumn: 1, - fileLanguage: '', - eol: '', -}); - -export const decorateData = (entity) => { - const { - id, - projectId, - branchId, - type, - url, - name, - icon, - tree_url, - path, - renderError, - content = '', - tempFile = false, - active = false, - opened = false, - changed = false, - parentTreeUrl = '', - level = 0, - base64 = false, - } = entity; - - return { - ...dataStructure(), - id, - projectId, - branchId, - key: `${name}-${type}-${id}`, - type, - name, - url, - tree_url, - path, - level, - tempFile, - icon: `fa-${icon}`, - opened, - active, - parentTreeUrl, - changed, - renderError, - content, - base64, - }; -}; - -/* - Takes the multi-dimensional tree and returns a flattened array. - This allows for the table to recursively render the table rows but keeps the data - structure nested to make it easier to add new files/directories. -*/ -export const treeList = (state, treeId) => { - const baseTree = state.trees[treeId]; - if (baseTree) { - const mapTree = arr => (!arr.tree || !arr.tree.length ? - [] : _.map(arr.tree, a => [a, mapTree(a)])); - - return _.chain(baseTree.tree) - .map(arr => [arr, mapTree(arr)]) - .flatten() - .value(); - } - return []; -}; - -export const getTree = state => (namespace, projectId, branch) => state.trees[`${namespace}/${projectId}/${branch}`]; - -export const getTreeEntry = (store, treeId, path) => { - const fileList = treeList(store.state, treeId); - return fileList ? fileList.find(file => file.path === path) : null; -}; - -export const findEntry = (tree, type, name) => tree.find( - f => f.type === type && f.name === name, -); - -export const findIndexOfFile = (state, file) => state.findIndex(f => f.path === file.path); - -export const setPageTitle = (title) => { - document.title = title; -}; - -export const createTemp = ({ - projectId, branchId, name, path, type, level, changed, content, base64, url, -}) => { - const treePath = path ? `${path}/${name}` : name; - - return decorateData({ - id: new Date().getTime().toString(), - projectId, - branchId, - name, - type, - tempFile: true, - path: treePath, - icon: type === 'tree' ? 'folder' : 'file-text-o', - changed, - content, - parentTreeUrl: '', - level, - base64, - renderError: base64, - url, - }); -}; - -export const createOrMergeEntry = ({ tree, - projectId, - branchId, - entry, - type, - parentTreeUrl, - level }) => { - const found = findEntry(tree.tree || tree, type, entry.name); - - if (found) { - return Object.assign({}, found, { - id: entry.id, - url: entry.url, - tempFile: false, - }); - } - - return decorateData({ - ...entry, - projectId, - branchId, - type, - parentTreeUrl, - level, - }); -}; diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb deleted file mode 100644 index 1ff25a45398..00000000000 --- a/app/controllers/ide_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -class IdeController < ApplicationController - layout 'nav_only' - - def index - end -end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 475341cf9b1..af9c8bf1bd3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -320,10 +320,6 @@ module ApplicationHelper cookies["sidebar_collapsed"] == "true" end - def show_new_ide? - cookies["new_repo"] == "true" && body_data_page != 'projects:show' - end - def locale_path asset_path("locale/#{Gitlab::I18n.locale}/app.js") end diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 0e806d16bc5..5ff09b23a78 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -33,20 +33,6 @@ module BlobHelper ref) end - def ide_edit_button(project = @project, ref = @ref, path = @path, options = {}) - return unless show_new_ide? - return unless blob = readable_blob(options, path, project, ref) - - common_classes = "btn js-edit-ide #{options[:extra_class]}" - - edit_button_tag(blob, - common_classes, - _('Web IDE'), - ide_edit_path(project, ref, path, options), - project, - ref) - end - def modify_file_button(project = @project, ref = @ref, path = @path, label:, action:, btn_class:, modal_type:) return unless current_user diff --git a/app/views/ide/index.html.haml b/app/views/ide/index.html.haml deleted file mode 100644 index 3dbdfc97654..00000000000 --- a/app/views/ide/index.html.haml +++ /dev/null @@ -1,11 +0,0 @@ -- @body_class = 'ide' -- page_title 'IDE' - -- content_for :page_specific_javascripts do - = webpack_bundle_tag 'common_vue' - = webpack_bundle_tag 'ide', force_same_domain: true - -#ide.ide-loading{ data: {"empty-state-svg-path" => image_path('illustrations/multi_file_editor_empty.svg')} } - .text-center - = icon('spinner spin 2x') - %h2.clgray= _('Loading the GitLab IDE...') diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml index 1b150ec3e5c..f93bb02acb9 100644 --- a/app/views/projects/blob/_header.html.haml +++ b/app/views/projects/blob/_header.html.haml @@ -12,7 +12,6 @@ .btn-group{ role: "group" }< = edit_blob_button - = ide_edit_button - if current_user = replace_blob_link = delete_blob_link diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index 39511435508..06bce52e709 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -72,11 +72,6 @@ #{ _('New tag') } .tree-controls - - if show_new_ide? - = succeed " " do - = link_to ide_edit_path(@project, @id), class: 'btn btn-default' do - = _('Web IDE') - = link_to s_('Commits|History'), project_commits_path(@project, @id), class: 'btn' = render 'projects/find_file_link' diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml index 479bd2cdb38..4c8c92d722a 100644 --- a/app/views/shared/_ref_switcher.html.haml +++ b/app/views/shared/_ref_switcher.html.haml @@ -1,6 +1,5 @@ - show_create = local_assigns.fetch(:show_create, false) -- show_new_branch_form = show_new_ide? && show_create && can?(current_user, :push_code, @project) - dropdown_toggle_text = @ref || @project.default_branch = form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do = hidden_field_tag :destination, destination @@ -16,14 +15,3 @@ = dropdown_filter _("Search branches and tags") = dropdown_content = dropdown_loading - - if show_new_branch_form - = dropdown_footer do - %ul.dropdown-footer-list - %li - %a.dropdown-toggle-page{ href: "#" } - Create new branch - - if show_new_branch_form - .dropdown-page-two - = dropdown_title("Create new branch", options: { back: true }) - = dropdown_content do - .js-new-branch-dropdown diff --git a/config/routes.rb b/config/routes.rb index e72ea1881cd..35fd76fb119 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -43,8 +43,6 @@ Rails.application.routes.draw do get 'liveness' => 'health#liveness' get 'readiness' => 'health#readiness' post 'storage_check' => 'health#storage_check' - get 'ide' => 'ide#index' - get 'ide/*vueroute' => 'ide#index', format: false resources :metrics, only: [:index] mount Peek::Railtie => '/peek' diff --git a/config/webpack.config.js b/config/webpack.config.js index cc098c8a3f9..19eeb497a14 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -47,7 +47,6 @@ function generateEntries() { common_vue: './vue_shared/vue_resource_interceptor.js', locale: './locale/index.js', main: './main.js', - ide: './ide/index.js', raven: './raven/index.js', webpack_runtime: './webpack.js', }; diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb deleted file mode 100644 index 0c67196f53e..00000000000 --- a/spec/features/projects/tree/create_directory_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'spec_helper' - -feature 'Multi-file editor new directory', :js do - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } - - before do - project.add_master(user) - sign_in(user) - - set_cookie('new_repo', 'true') - - visit project_tree_path(project, :master) - - wait_for_requests - - click_link('Web IDE') - - wait_for_requests - end - - after do - set_cookie('new_repo', 'false') - end - - it 'creates directory in current directory' do - find('.add-to-tree').click - - click_link('New directory') - - page.within('.modal') do - find('.form-control').set('folder name') - - click_button('Create directory') - end - - find('.add-to-tree').click - - click_link('New file') - - page.within('.modal-dialog') do - find('.form-control').set('file name') - - click_button('Create file') - end - - wait_for_requests - - find('.multi-file-commit-panel-collapse-btn').click - - fill_in('commit-message', with: 'commit message ide') - - click_button('Commit') - - expect(page).to have_content('folder name') - end -end diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb deleted file mode 100644 index 85f7318c05d..00000000000 --- a/spec/features/projects/tree/create_file_spec.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'spec_helper' - -feature 'Multi-file editor new file', :js do - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } - - before do - project.add_master(user) - sign_in(user) - - set_cookie('new_repo', 'true') - - visit project_tree_path(project, :master) - - wait_for_requests - - click_link('Web IDE') - - wait_for_requests - end - - after do - set_cookie('new_repo', 'false') - end - - it 'creates file in current directory' do - find('.add-to-tree').click - - click_link('New file') - - page.within('.modal') do - find('.form-control').set('file name') - - click_button('Create file') - end - - wait_for_requests - - find('.multi-file-commit-panel-collapse-btn').click - - fill_in('commit-message', with: 'commit message ide') - - click_button('Commit') - - expect(page).to have_content('file name') - end -end diff --git a/spec/features/projects/tree/upload_file_spec.rb b/spec/features/projects/tree/upload_file_spec.rb deleted file mode 100644 index f81e8677e92..00000000000 --- a/spec/features/projects/tree/upload_file_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'spec_helper' - -feature 'Multi-file editor upload file', :js do - let(:user) { create(:user) } - let(:project) { create(:project, :repository) } - let(:txt_file) { File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt') } - let(:img_file) { File.join(Rails.root, 'spec', 'fixtures', 'dk.png') } - - before do - project.add_master(user) - sign_in(user) - - set_cookie('new_repo', 'true') - - visit project_tree_path(project, :master) - - wait_for_requests - - click_link('Web IDE') - - wait_for_requests - end - - after do - set_cookie('new_repo', 'false') - end - - it 'uploads text file' do - find('.add-to-tree').click - - # make the field visible so capybara can use it - execute_script('document.querySelector("#file-upload").classList.remove("hidden")') - attach_file('file-upload', txt_file) - - find('.add-to-tree').click - - expect(page).to have_selector('.multi-file-tab', text: 'doc_sample.txt') - expect(find('.blob-editor-container .lines-content')['innerText']).to have_content(File.open(txt_file, &:readline)) - end - - it 'uploads image file' do - find('.add-to-tree').click - - # make the field visible so capybara can use it - execute_script('document.querySelector("#file-upload").classList.remove("hidden")') - attach_file('file-upload', img_file) - - find('.add-to-tree').click - - expect(page).to have_selector('.multi-file-tab', text: 'dk.png') - expect(page).not_to have_selector('.monaco-editor') - end -end diff --git a/spec/javascripts/repo/components/commit_sidebar/list_collapsed_spec.js b/spec/javascripts/repo/components/commit_sidebar/list_collapsed_spec.js deleted file mode 100644 index b509cedbe80..00000000000 --- a/spec/javascripts/repo/components/commit_sidebar/list_collapsed_spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import listCollapsed from '~/ide/components/commit_sidebar/list_collapsed.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { file } from '../../helpers'; - -describe('Multi-file editor commit sidebar list collapsed', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(listCollapsed); - - vm = createComponentWithStore(Component, store); - - vm.$store.state.openFiles.push(file('file1'), file('file2')); - vm.$store.state.openFiles[0].tempFile = true; - vm.$store.state.openFiles.forEach((f) => { - Object.assign(f, { - changed: true, - }); - }); - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders added & modified files count', () => { - expect(vm.$el.textContent.replace(/\s+/g, ' ').trim()).toBe('1 1'); - }); -}); diff --git a/spec/javascripts/repo/components/commit_sidebar/list_item_spec.js b/spec/javascripts/repo/components/commit_sidebar/list_item_spec.js deleted file mode 100644 index 6f1a1d874d3..00000000000 --- a/spec/javascripts/repo/components/commit_sidebar/list_item_spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import Vue from 'vue'; -import listItem from '~/ide/components/commit_sidebar/list_item.vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import { file } from '../../helpers'; - -describe('Multi-file editor commit sidebar list item', () => { - let vm; - let f; - - beforeEach(() => { - const Component = Vue.extend(listItem); - - f = file('test-file'); - - vm = mountComponent(Component, { - file: f, - }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders file path', () => { - expect(vm.$el.querySelector('.multi-file-commit-list-path').textContent.trim()).toBe(f.path); - }); - - 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'); - }); - }); - - describe('iconClass', () => { - it('returns modified when not a tempFile', () => { - expect(vm.iconClass).toContain('multi-file-modified'); - }); - - it('returns addition when not a tempFile', () => { - f.tempFile = true; - - expect(vm.iconClass).toContain('multi-file-addition'); - }); - }); - }); -}); diff --git a/spec/javascripts/repo/components/commit_sidebar/list_spec.js b/spec/javascripts/repo/components/commit_sidebar/list_spec.js deleted file mode 100644 index aeb9de9ace4..00000000000 --- a/spec/javascripts/repo/components/commit_sidebar/list_spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import commitSidebarList from '~/ide/components/commit_sidebar/list.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { file } from '../../helpers'; - -describe('Multi-file editor commit sidebar list', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(commitSidebarList); - - vm = createComponentWithStore(Component, store, { - title: 'Staged', - fileList: [], - }); - - vm.$store.state.rightPanelCollapsed = false; - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('empty file list', () => { - it('renders no changes text', () => { - expect(vm.$el.querySelector('.help-block').textContent.trim()).toBe('No changes'); - }); - }); - - 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('li').length).toBe(1); - }); - }); - - describe('collapsed', () => { - beforeEach((done) => { - vm.$store.state.rightPanelCollapsed = true; - - Vue.nextTick(done); - }); - - it('hides list', () => { - expect(vm.$el.querySelector('.list-unstyled')).toBeNull(); - expect(vm.$el.querySelector('.help-block')).toBeNull(); - }); - }); -}); diff --git a/spec/javascripts/repo/components/ide_context_bar_spec.js b/spec/javascripts/repo/components/ide_context_bar_spec.js deleted file mode 100644 index 935da259a99..00000000000 --- a/spec/javascripts/repo/components/ide_context_bar_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import ideContextBar from '~/ide/components/ide_context_bar.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; - -describe('Multi-file editor right context bar', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(ideContextBar); - - vm = createComponentWithStore(Component, store); - - vm.$store.state.rightPanelCollapsed = false; - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - }); - - describe('collapsed', () => { - beforeEach((done) => { - vm.$store.state.rightPanelCollapsed = true; - - Vue.nextTick(done); - }); - - it('adds collapsed class', () => { - expect(vm.$el.querySelector('.is-collapsed')).not.toBeNull(); - }); - - it('shows correct icon', () => { - expect(vm.currentIcon).toBe('angle-double-left'); - }); - }); - - it('clicking toggle collapse button collapses the bar', () => { - spyOn(vm, 'setPanelCollapsedStatus').and.returnValue(Promise.resolve()); - - vm.$el.querySelector('.multi-file-commit-panel-collapse-btn').click(); - - expect(vm.setPanelCollapsedStatus).toHaveBeenCalledWith({ - side: 'right', - collapsed: true, - }); - }); -}); diff --git a/spec/javascripts/repo/components/ide_repo_tree_spec.js b/spec/javascripts/repo/components/ide_repo_tree_spec.js deleted file mode 100644 index e3bbda514da..00000000000 --- a/spec/javascripts/repo/components/ide_repo_tree_spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import ideRepoTree from '~/ide/components/ide_repo_tree.vue'; -import { file, resetStore } from '../helpers'; - -describe('IdeRepoTree', () => { - let vm; - - beforeEach(() => { - const IdeRepoTree = Vue.extend(ideRepoTree); - - vm = new IdeRepoTree({ - store, - propsData: { - treeId: 'abcproject/mybranch', - }, - }); - - vm.$store.state.currentBranch = 'master'; - vm.$store.state.isRoot = true; - vm.$store.state.trees['abcproject/mybranch'] = { - tree: [file()], - }; - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders a sidebar', () => { - const tbody = vm.$el.querySelector('tbody'); - - expect(vm.$el.classList.contains('sidebar-mini')).toBeFalsy(); - expect(tbody.querySelector('.repo-file-options')).toBeFalsy(); - expect(tbody.querySelector('.prev-directory')).toBeFalsy(); - expect(tbody.querySelector('.loading-file')).toBeFalsy(); - expect(tbody.querySelector('.file')).toBeTruthy(); - }); - - it('renders 3 loading files if tree is loading', (done) => { - vm.treeId = '123'; - - Vue.nextTick(() => { - expect(vm.$el.querySelectorAll('.multi-file-loading-container').length).toEqual(3); - - done(); - }); - }); - - it('renders a prev directory if is not root', (done) => { - vm.$store.state.isRoot = false; - - Vue.nextTick(() => { - expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy(); - - done(); - }); - }); -}); diff --git a/spec/javascripts/repo/components/ide_side_bar_spec.js b/spec/javascripts/repo/components/ide_side_bar_spec.js deleted file mode 100644 index 79c3c8128e8..00000000000 --- a/spec/javascripts/repo/components/ide_side_bar_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import ideSidebar from '~/ide/components/ide_side_bar.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { resetStore } from '../helpers'; - -describe('IdeSidebar', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(ideSidebar); - - vm = createComponentWithStore(Component, store).$mount(); - - vm.$store.state.leftPanelCollapsed = false; - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders a sidebar', () => { - expect(vm.$el.querySelector('.multi-file-commit-panel-inner')).not.toBeNull(); - }); - - describe('collapsed', () => { - beforeEach((done) => { - vm.$store.state.leftPanelCollapsed = true; - - Vue.nextTick(done); - }); - - it('adds collapsed class', () => { - expect(vm.$el.classList).toContain('is-collapsed'); - }); - - it('shows correct icon', () => { - expect(vm.currentIcon).toBe('angle-double-right'); - }); - }); -}); diff --git a/spec/javascripts/repo/components/ide_spec.js b/spec/javascripts/repo/components/ide_spec.js deleted file mode 100644 index 18135177b5e..00000000000 --- a/spec/javascripts/repo/components/ide_spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import ide from '~/ide/components/ide.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { file, resetStore } from '../helpers'; - -describe('ide component', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(ide); - - vm = createComponentWithStore(Component, store, { - emptyStateSvgPath: 'svg', - }).$mount(); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('does not render panel right when no files open', () => { - expect(vm.$el.querySelector('.panel-right')).toBeNull(); - }); - - it('renders panel right when files are open', (done) => { - vm.$store.state.trees['abcproject/mybranch'] = { - tree: [file()], - }; - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.panel-right')).toBeNull(); - - done(); - }); - }); -}); diff --git a/spec/javascripts/repo/components/new_branch_form_spec.js b/spec/javascripts/repo/components/new_branch_form_spec.js deleted file mode 100644 index 82597fc75e8..00000000000 --- a/spec/javascripts/repo/components/new_branch_form_spec.js +++ /dev/null @@ -1,114 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import newBranchForm from '~/ide/components/new_branch_form.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { resetStore } from '../helpers'; - -describe('Multi-file editor new branch form', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(newBranchForm); - - vm = createComponentWithStore(Component, store); - - vm.$store.state.currentBranch = 'master'; - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - describe('template', () => { - it('renders submit as disabled', () => { - expect(vm.$el.querySelector('.btn').getAttribute('disabled')).toBe('disabled'); - }); - - it('enables the submit button when branch is not empty', (done) => { - vm.branchName = 'testing'; - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.btn').getAttribute('disabled')).toBeNull(); - - done(); - }); - }); - - it('displays current branch creating from', (done) => { - Vue.nextTick(() => { - expect(vm.$el.querySelector('p').textContent.replace(/\s+/g, ' ').trim()).toBe('Create from: master'); - - done(); - }); - }); - }); - - describe('submitNewBranch', () => { - beforeEach(() => { - spyOn(vm, 'createNewBranch').and.returnValue(Promise.resolve()); - }); - - it('sets to loading', () => { - vm.submitNewBranch(); - - expect(vm.loading).toBeTruthy(); - }); - - it('hides current flash element', (done) => { - vm.$refs.flashContainer.innerHTML = '
'; - - vm.submitNewBranch(); - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.flash-alert')).toBeNull(); - - done(); - }); - }); - - it('calls createdNewBranch with branchName', () => { - vm.branchName = 'testing'; - - vm.submitNewBranch(); - - expect(vm.createNewBranch).toHaveBeenCalledWith('testing'); - }); - }); - - describe('submitNewBranch with error', () => { - beforeEach(() => { - spyOn(vm, 'createNewBranch').and.returnValue(Promise.reject({ - json: () => Promise.resolve({ - message: 'error message', - }), - })); - }); - - it('sets loading to false', (done) => { - vm.loading = true; - - vm.submitNewBranch(); - - setTimeout(() => { - expect(vm.loading).toBeFalsy(); - - done(); - }); - }); - - it('creates flash element', (done) => { - vm.submitNewBranch(); - - setTimeout(() => { - expect(vm.$el.querySelector('.flash-alert')).not.toBeNull(); - expect(vm.$el.querySelector('.flash-alert').textContent.trim()).toBe('error message'); - - done(); - }); - }); - }); -}); diff --git a/spec/javascripts/repo/components/new_dropdown/index_spec.js b/spec/javascripts/repo/components/new_dropdown/index_spec.js deleted file mode 100644 index 4a8e4445e2f..00000000000 --- a/spec/javascripts/repo/components/new_dropdown/index_spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import newDropdown from '~/ide/components/new_dropdown/index.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { resetStore } from '../../helpers'; - -describe('new dropdown component', () => { - let vm; - - beforeEach(() => { - const component = Vue.extend(newDropdown); - - vm = createComponentWithStore(component, store, { - branch: 'master', - path: '', - }); - - vm.$store.state.currentProjectId = 'abcproject'; - vm.$store.state.path = ''; - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders new file, upload and new directory links', () => { - expect(vm.$el.querySelectorAll('a')[0].textContent.trim()).toBe('New file'); - expect(vm.$el.querySelectorAll('a')[1].textContent.trim()).toBe('Upload file'); - expect(vm.$el.querySelectorAll('a')[2].textContent.trim()).toBe('New directory'); - }); - - describe('createNewItem', () => { - it('sets modalType to blob when new file is clicked', () => { - vm.$el.querySelectorAll('a')[0].click(); - - expect(vm.modalType).toBe('blob'); - }); - - it('sets modalType to tree when new directory is clicked', () => { - vm.$el.querySelectorAll('a')[2].click(); - - expect(vm.modalType).toBe('tree'); - }); - - it('opens modal when link is clicked', (done) => { - vm.$el.querySelectorAll('a')[0].click(); - - Vue.nextTick(() => { - expect(vm.$el.querySelector('.modal')).not.toBeNull(); - - done(); - }); - }); - }); - - describe('hideModal', () => { - beforeAll((done) => { - vm.openModal = true; - Vue.nextTick(done); - }); - - it('closes modal after toggling', (done) => { - vm.hideModal(); - - Vue.nextTick() - .then(() => { - expect(vm.$el.querySelector('.modal')).toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - }); -}); diff --git a/spec/javascripts/repo/components/new_dropdown/modal_spec.js b/spec/javascripts/repo/components/new_dropdown/modal_spec.js deleted file mode 100644 index d6a1fdd115c..00000000000 --- a/spec/javascripts/repo/components/new_dropdown/modal_spec.js +++ /dev/null @@ -1,237 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import service from '~/ide/services'; -import modal from '~/ide/components/new_dropdown/modal.vue'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { file, resetStore } from '../../helpers'; - -describe('new file modal component', () => { - const Component = Vue.extend(modal); - let vm; - let projectTree; - - beforeEach(() => { - spyOn(service, 'getProjectData').and.returnValue(Promise.resolve({ - data: { - id: '123', - }, - })); - - spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ - data: { - commit: { - id: '123branch', - }, - }, - })); - - spyOn(service, 'getTreeData').and.returnValue(Promise.resolve({ - headers: { - 'page-title': 'test', - }, - json: () => Promise.resolve({ - last_commit_path: 'last_commit_path', - parent_tree_url: 'parent_tree_url', - path: '/', - trees: [{ name: 'tree' }], - blobs: [{ name: 'blob' }], - submodules: [{ name: 'submodule' }], - }), - })); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - ['tree', 'blob'].forEach((type) => { - describe(type, () => { - beforeEach(() => { - store.state.projects.abcproject = { - web_url: '', - }; - store.state.trees = []; - store.state.trees['abcproject/mybranch'] = { - tree: [], - }; - projectTree = store.state.trees['abcproject/mybranch']; - store.state.currentProjectId = 'abcproject'; - - vm = createComponentWithStore(Component, store, { - type, - branchId: 'master', - path: '', - parent: projectTree, - }); - - vm.entryName = 'testing'; - - vm.$mount(); - }); - - it(`sets modal title as ${type}`, () => { - const title = type === 'tree' ? 'directory' : 'file'; - - expect(vm.$el.querySelector('.modal-title').textContent.trim()).toBe(`Create new ${title}`); - }); - - it(`sets button label as ${type}`, () => { - const title = type === 'tree' ? 'directory' : 'file'; - - expect(vm.$el.querySelector('.btn-success').textContent.trim()).toBe(`Create ${title}`); - }); - - it(`sets form label as ${type}`, () => { - const title = type === 'tree' ? 'Directory' : 'File'; - - expect(vm.$el.querySelector('.label-light').textContent.trim()).toBe(`${title} name`); - }); - - describe('createEntryInStore', () => { - it('calls createTempEntry', () => { - spyOn(vm, 'createTempEntry'); - - vm.createEntryInStore(); - - expect(vm.createTempEntry).toHaveBeenCalledWith({ - projectId: 'abcproject', - branchId: 'master', - parent: projectTree, - name: 'testing', - type, - }); - }); - - it('sets editMode to true', (done) => { - vm.createEntryInStore(); - - setTimeout(() => { - expect(vm.$store.state.editMode).toBeTruthy(); - - done(); - }); - }); - - it('toggles blob view', (done) => { - vm.createEntryInStore(); - - setTimeout(() => { - expect(vm.$store.state.currentBlobView).toBe('repo-editor'); - - done(); - }); - }); - - it('opens newly created file', (done) => { - if (type === 'blob') { - vm.createEntryInStore(); - - setTimeout(() => { - expect(vm.$store.state.openFiles.length).toBe(1); - expect(vm.$store.state.openFiles[0].name).toBe(type === 'blob' ? 'testing' : '.gitkeep'); - - done(); - }); - } else { - done(); - } - }); - - if (type === 'blob') { - it('creates new file', (done) => { - vm.createEntryInStore(); - - setTimeout(() => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe('testing'); - expect(baseTree[0].type).toBe('blob'); - expect(baseTree[0].tempFile).toBeTruthy(); - - done(); - }); - }); - - it('does not create temp file when file already exists', (done) => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - baseTree.push(file('testing', '1', type)); - - vm.createEntryInStore(); - - setTimeout(() => { - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe('testing'); - expect(baseTree[0].type).toBe('blob'); - expect(baseTree[0].tempFile).toBeFalsy(); - - done(); - }); - }); - } else { - it('creates new tree', () => { - vm.createEntryInStore(); - - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe('testing'); - expect(baseTree[0].type).toBe('tree'); - expect(baseTree[0].tempFile).toBeTruthy(); - }); - - it('creates multiple trees when entryName has slashes', () => { - vm.entryName = 'app/test'; - vm.createEntryInStore(); - - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe('app'); - }); - - it('creates tree in existing tree', () => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - baseTree.push(file('app', '1', 'tree')); - - vm.entryName = 'app/test'; - vm.createEntryInStore(); - - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe('app'); - expect(baseTree[0].tempFile).toBeFalsy(); - expect(baseTree[0].tree[0].tempFile).toBeTruthy(); - expect(baseTree[0].tree[0].name).toBe('test'); - }); - - it('does not create new tree when already exists', () => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - baseTree.push(file('app', '1', 'tree')); - - vm.entryName = 'app'; - vm.createEntryInStore(); - - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe('app'); - expect(baseTree[0].tempFile).toBeFalsy(); - expect(baseTree[0].tree.length).toBe(0); - }); - } - }); - }); - }); - - it('focuses field on mount', () => { - document.body.innerHTML += '
'; - - vm = createComponentWithStore(Component, store, { - type: 'tree', - projectId: 'abcproject', - branchId: 'master', - path: '', - }).$mount('.js-test'); - - expect(document.activeElement).toBe(vm.$refs.fieldName); - - vm.$el.remove(); - }); -}); diff --git a/spec/javascripts/repo/components/new_dropdown/upload_spec.js b/spec/javascripts/repo/components/new_dropdown/upload_spec.js deleted file mode 100644 index ee8aab3a252..00000000000 --- a/spec/javascripts/repo/components/new_dropdown/upload_spec.js +++ /dev/null @@ -1,158 +0,0 @@ -import Vue from 'vue'; -import upload from '~/ide/components/new_dropdown/upload.vue'; -import store from '~/ide/stores'; -import service from '~/ide/services'; -import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper'; -import { resetStore } from '../../helpers'; - -describe('new dropdown upload', () => { - let vm; - let projectTree; - - beforeEach(() => { - spyOn(service, 'getProjectData').and.returnValue(Promise.resolve({ - data: { - id: '123', - }, - })); - - spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ - data: { - commit: { - id: '123branch', - }, - }, - })); - - spyOn(service, 'getTreeData').and.returnValue(Promise.resolve({ - headers: { - 'page-title': 'test', - }, - json: () => Promise.resolve({ - last_commit_path: 'last_commit_path', - parent_tree_url: 'parent_tree_url', - path: '/', - trees: [{ name: 'tree' }], - blobs: [{ name: 'blob' }], - submodules: [{ name: 'submodule' }], - }), - })); - - const Component = Vue.extend(upload); - - store.state.projects.abcproject = { - web_url: '', - }; - store.state.currentProjectId = 'abcproject'; - store.state.trees = []; - store.state.trees['abcproject/mybranch'] = { - tree: [], - }; - projectTree = store.state.trees['abcproject/mybranch']; - - vm = createComponentWithStore(Component, store, { - branchId: 'master', - path: '', - parent: projectTree, - }); - - vm.entryName = 'testing'; - - vm.$mount(); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - describe('readFile', () => { - beforeEach(() => { - spyOn(FileReader.prototype, 'readAsText'); - spyOn(FileReader.prototype, 'readAsDataURL'); - }); - - it('calls readAsText for text files', () => { - const file = { - type: 'text/html', - }; - - vm.readFile(file); - - expect(FileReader.prototype.readAsText).toHaveBeenCalledWith(file); - }); - - it('calls readAsDataURL for non-text files', () => { - const file = { - type: 'images/png', - }; - - vm.readFile(file); - - expect(FileReader.prototype.readAsDataURL).toHaveBeenCalledWith(file); - }); - }); - - describe('createFile', () => { - const target = { - result: 'content', - }; - const binaryTarget = { - result: 'base64,base64content', - }; - const file = { - name: 'file', - }; - - it('creates new file', (done) => { - vm.createFile(target, file, true); - - vm.$nextTick(() => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe(file.name); - expect(baseTree[0].content).toBe(target.result); - - done(); - }); - }); - - it('creates new file in path', (done) => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - const tree = { - type: 'tree', - name: 'testing', - path: 'testing', - tree: [], - }; - baseTree.push(tree); - - vm.parent = tree; - vm.createFile(target, file, true); - - vm.$nextTick(() => { - expect(baseTree.length).toBe(1); - expect(baseTree[0].tree[0].name).toBe(file.name); - expect(baseTree[0].tree[0].content).toBe(target.result); - expect(baseTree[0].tree[0].path).toBe(`testing/${file.name}`); - - done(); - }); - }); - - it('splits content on base64 if binary', (done) => { - vm.createFile(binaryTarget, file, false); - - vm.$nextTick(() => { - const baseTree = vm.$store.state.trees['abcproject/mybranch'].tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].name).toBe(file.name); - expect(baseTree[0].content).toBe(binaryTarget.result.split('base64,')[1]); - expect(baseTree[0].base64).toBe(true); - - done(); - }); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_commit_section_spec.js b/spec/javascripts/repo/components/repo_commit_section_spec.js deleted file mode 100644 index 934ada9dec2..00000000000 --- a/spec/javascripts/repo/components/repo_commit_section_spec.js +++ /dev/null @@ -1,140 +0,0 @@ -import Vue from 'vue'; -import * as urlUtils from '~/lib/utils/url_utility'; -import store from '~/ide/stores'; -import service from '~/ide/services'; -import repoCommitSection from '~/ide/components/repo_commit_section.vue'; -import getSetTimeoutPromise from 'spec/helpers/set_timeout_promise_helper'; -import { file, resetStore } from '../helpers'; - -describe('RepoCommitSection', () => { - let vm; - - function createComponent() { - const RepoCommitSection = Vue.extend(repoCommitSection); - - const comp = new RepoCommitSection({ - store, - }).$mount(); - - comp.$store.state.currentProjectId = 'abcproject'; - comp.$store.state.currentBranchId = 'master'; - comp.$store.state.projects.abcproject = { - web_url: '', - branches: { - master: { - workingReference: '1', - }, - }, - }; - - comp.$store.state.rightPanelCollapsed = false; - comp.$store.state.currentBranch = 'master'; - comp.$store.state.openFiles = [file('file1'), file('file2')]; - comp.$store.state.openFiles.forEach(f => Object.assign(f, { - changed: true, - content: 'testing', - })); - - return comp.$mount(); - } - - beforeEach((done) => { - vm = createComponent(); - - spyOn(service, 'getTreeData').and.returnValue(Promise.resolve({ - headers: { - 'page-title': 'test', - }, - json: () => Promise.resolve({ - last_commit_path: 'last_commit_path', - parent_tree_url: 'parent_tree_url', - path: '/', - trees: [{ name: 'tree' }], - blobs: [{ name: 'blob' }], - submodules: [{ name: 'submodule' }], - }), - })); - - Vue.nextTick(done); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders a commit section', () => { - const changedFileElements = [...vm.$el.querySelectorAll('.multi-file-commit-list li')]; - const submitCommit = vm.$el.querySelector('form .btn'); - - expect(vm.$el.querySelector('.multi-file-commit-form')).not.toBeNull(); - expect(changedFileElements.length).toEqual(2); - - changedFileElements.forEach((changedFile, i) => { - expect(changedFile.textContent.trim()).toEqual(vm.$store.getters.changedFiles[i].path); - }); - - expect(submitCommit.disabled).toBeTruthy(); - expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeNull(); - }); - - describe('when submitting', () => { - let changedFiles; - - beforeEach(() => { - vm.commitMessage = 'testing'; - changedFiles = JSON.parse(JSON.stringify(vm.$store.getters.changedFiles)); - - spyOn(service, 'commit').and.returnValue(Promise.resolve({ - data: { - short_id: '1', - stats: {}, - }, - })); - }); - - it('allows you to submit', () => { - expect(vm.$el.querySelector('form .btn').disabled).toBeTruthy(); - }); - - it('submits commit', (done) => { - vm.makeCommit(); - - // Wait for the branch check to finish - getSetTimeoutPromise() - .then(() => Vue.nextTick()) - .then(() => { - const args = service.commit.calls.allArgs()[0]; - const { commit_message, actions, branch: payloadBranch } = args[1]; - - expect(commit_message).toBe('testing'); - expect(actions.length).toEqual(2); - expect(payloadBranch).toEqual('master'); - expect(actions[0].action).toEqual('update'); - expect(actions[1].action).toEqual('update'); - expect(actions[0].content).toEqual(changedFiles[0].content); - expect(actions[1].content).toEqual(changedFiles[1].content); - expect(actions[0].file_path).toEqual(changedFiles[0].path); - expect(actions[1].file_path).toEqual(changedFiles[1].path); - }) - .then(done) - .catch(done.fail); - }); - - it('redirects to MR creation page if start new MR checkbox checked', (done) => { - spyOn(urlUtils, 'visitUrl'); - vm.startNewMR = true; - - vm.makeCommit(); - - getSetTimeoutPromise() - .then(() => Vue.nextTick()) - .then(() => { - expect(urlUtils.visitUrl).toHaveBeenCalled(); - }) - .then(done) - .catch(done.fail); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_edit_button_spec.js b/spec/javascripts/repo/components/repo_edit_button_spec.js deleted file mode 100644 index 2895b794506..00000000000 --- a/spec/javascripts/repo/components/repo_edit_button_spec.js +++ /dev/null @@ -1,83 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoEditButton from '~/ide/components/repo_edit_button.vue'; -import { file, resetStore } from '../helpers'; - -describe('RepoEditButton', () => { - let vm; - - beforeEach(() => { - const f = file(); - const RepoEditButton = Vue.extend(repoEditButton); - - vm = new RepoEditButton({ - store, - }); - - f.active = true; - vm.$store.dispatch('setInitialData', { - canCommit: true, - onTopOfBranch: true, - }); - vm.$store.state.openFiles.push(f); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders an edit button', () => { - vm.$mount(); - - expect(vm.$el.querySelector('.btn')).not.toBeNull(); - expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Cancel edit'); - }); - - it('renders edit button with cancel text', () => { - vm.$store.state.editMode = true; - - vm.$mount(); - - expect(vm.$el.querySelector('.btn')).not.toBeNull(); - expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Cancel edit'); - }); - - it('toggles edit mode on click', (done) => { - vm.$mount(); - - vm.$el.querySelector('.btn').click(); - - vm.$nextTick(() => { - expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Edit'); - - done(); - }); - }); - - describe('discardPopupOpen', () => { - beforeEach(() => { - vm.$store.state.discardPopupOpen = true; - vm.$store.state.editMode = true; - vm.$store.state.openFiles[0].changed = true; - - vm.$mount(); - }); - - it('renders popup', () => { - expect(vm.$el.querySelector('.modal')).not.toBeNull(); - }); - - it('removes all changed files', (done) => { - vm.$el.querySelector('.btn-warning').click(); - - vm.$nextTick(() => { - expect(vm.$store.getters.changedFiles.length).toBe(0); - expect(vm.$el.querySelector('.modal')).toBeNull(); - - done(); - }); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_editor_spec.js b/spec/javascripts/repo/components/repo_editor_spec.js deleted file mode 100644 index e7b2ed08acd..00000000000 --- a/spec/javascripts/repo/components/repo_editor_spec.js +++ /dev/null @@ -1,60 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoEditor from '~/ide/components/repo_editor.vue'; -import monacoLoader from '~/ide/monaco_loader'; -import { file, resetStore } from '../helpers'; - -describe('RepoEditor', () => { - let vm; - - beforeEach((done) => { - const f = file(); - const RepoEditor = Vue.extend(repoEditor); - - vm = new RepoEditor({ - store, - }); - - f.active = true; - f.tempFile = true; - vm.$store.state.openFiles.push(f); - vm.$store.getters.activeFile.html = 'testing'; - vm.monaco = true; - - vm.$mount(); - - monacoLoader(['vs/editor/editor.main'], () => { - setTimeout(done, 0); - }); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders an ide container', (done) => { - Vue.nextTick(() => { - expect(vm.shouldHideEditor).toBeFalsy(); - - done(); - }); - }); - - describe('when open file is binary and not raw', () => { - beforeEach((done) => { - vm.$store.getters.activeFile.binary = true; - - Vue.nextTick(done); - }); - - it('does not render the IDE', () => { - expect(vm.shouldHideEditor).toBeTruthy(); - }); - - it('shows activeFile html', () => { - expect(vm.$el.textContent).toContain('testing'); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_file_buttons_spec.js b/spec/javascripts/repo/components/repo_file_buttons_spec.js deleted file mode 100644 index 115569a9117..00000000000 --- a/spec/javascripts/repo/components/repo_file_buttons_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoFileButtons from '~/ide/components/repo_file_buttons.vue'; -import { file, resetStore } from '../helpers'; - -describe('RepoFileButtons', () => { - const activeFile = file(); - let vm; - - function createComponent() { - const RepoFileButtons = Vue.extend(repoFileButtons); - - activeFile.rawPath = 'test'; - activeFile.blamePath = 'test'; - activeFile.commitsPath = 'test'; - activeFile.active = true; - store.state.openFiles.push(activeFile); - - return new RepoFileButtons({ - store, - }).$mount(); - } - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders Raw, Blame, History, Permalink and Preview toggle', (done) => { - vm = createComponent(); - - vm.$nextTick(() => { - const raw = vm.$el.querySelector('.raw'); - const blame = vm.$el.querySelector('.blame'); - const history = vm.$el.querySelector('.history'); - - expect(raw.href).toMatch(`/${activeFile.rawPath}`); - expect(raw.textContent.trim()).toEqual('Raw'); - expect(blame.href).toMatch(`/${activeFile.blamePath}`); - expect(blame.textContent.trim()).toEqual('Blame'); - expect(history.href).toMatch(`/${activeFile.commitsPath}`); - expect(history.textContent.trim()).toEqual('History'); - expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink'); - - done(); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_file_spec.js b/spec/javascripts/repo/components/repo_file_spec.js deleted file mode 100644 index 27b55ed1f87..00000000000 --- a/spec/javascripts/repo/components/repo_file_spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoFile from '~/ide/components/repo_file.vue'; -import { file, resetStore } from '../helpers'; - -describe('RepoFile', () => { - const updated = 'updated'; - let vm; - - function createComponent(propsData) { - const RepoFile = Vue.extend(repoFile); - - return new RepoFile({ - store, - propsData, - }).$mount(); - } - - afterEach(() => { - resetStore(vm.$store); - }); - - it('renders link, icon and name', () => { - const RepoFile = Vue.extend(repoFile); - vm = new RepoFile({ - store, - propsData: { - file: file('t4'), - }, - }); - spyOn(vm, 'timeFormated').and.returnValue(updated); - vm.$mount(); - - const name = vm.$el.querySelector('.repo-file-name'); - - expect(name.href).toMatch(''); - expect(name.textContent.trim()).toEqual(vm.file.name); - }); - - it('does render if hasFiles is true and is loading tree', () => { - vm = createComponent({ - file: file('t1'), - }); - - expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy(); - }); - - it('does not render commit message and datetime if mini', (done) => { - vm = createComponent({ - file: file('t2'), - }); - vm.$store.state.openFiles.push(vm.file); - - vm.$nextTick(() => { - expect(vm.$el.querySelector('.commit-message')).toBeFalsy(); - expect(vm.$el.querySelector('.commit-update')).toBeFalsy(); - - done(); - }); - }); - - it('fires clickFile when the link is clicked', () => { - vm = createComponent({ - file: file('t3'), - }); - - spyOn(vm, 'clickFile'); - - vm.$el.click(); - - expect(vm.clickFile).toHaveBeenCalledWith(vm.file); - }); - - describe('submodule', () => { - let f; - - beforeEach(() => { - f = file('submodule name', '123456789'); - f.type = 'submodule'; - - vm = createComponent({ - file: f, - }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders submodule short ID', () => { - expect(vm.$el.querySelector('.commit-sha').textContent.trim()).toBe('12345678'); - }); - - it('renders ID next to submodule name', () => { - expect(vm.$el.querySelector('td').textContent.replace(/\s+/g, ' ')).toContain('submodule name @ 12345678'); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_loading_file_spec.js b/spec/javascripts/repo/components/repo_loading_file_spec.js deleted file mode 100644 index 18366fb89bc..00000000000 --- a/spec/javascripts/repo/components/repo_loading_file_spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoLoadingFile from '~/ide/components/repo_loading_file.vue'; -import { resetStore } from '../helpers'; - -describe('RepoLoadingFile', () => { - let vm; - - function createComponent() { - const RepoLoadingFile = Vue.extend(repoLoadingFile); - - return new RepoLoadingFile({ - store, - }).$mount(); - } - - function assertLines(lines) { - lines.forEach((line, n) => { - const index = n + 1; - expect(line.classList.contains(`skeleton-line-${index}`)).toBeTruthy(); - }); - } - - function assertColumns(columns) { - columns.forEach((column) => { - const container = column.querySelector('.animation-container'); - const lines = [...container.querySelectorAll(':scope > div')]; - - expect(container).toBeTruthy(); - expect(lines.length).toEqual(6); - assertLines(lines); - }); - } - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders 3 columns of animated LoC', () => { - vm = createComponent(); - const columns = [...vm.$el.querySelectorAll('td')]; - - expect(columns.length).toEqual(3); - assertColumns(columns); - }); - - it('renders 1 column of animated LoC if isMini', (done) => { - vm = createComponent(); - vm.$store.state.leftPanelCollapsed = true; - vm.$store.state.openFiles.push('test'); - - vm.$nextTick(() => { - const columns = [...vm.$el.querySelectorAll('td')]; - - expect(columns.length).toEqual(1); - assertColumns(columns); - - done(); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_prev_directory_spec.js b/spec/javascripts/repo/components/repo_prev_directory_spec.js deleted file mode 100644 index ff26cab2262..00000000000 --- a/spec/javascripts/repo/components/repo_prev_directory_spec.js +++ /dev/null @@ -1,45 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoPrevDirectory from '~/ide/components/repo_prev_directory.vue'; -import { resetStore } from '../helpers'; - -describe('RepoPrevDirectory', () => { - let vm; - const parentLink = 'parent'; - function createComponent() { - const RepoPrevDirectory = Vue.extend(repoPrevDirectory); - - const comp = new RepoPrevDirectory({ - store, - }); - - comp.$store.state.parentTreeUrl = parentLink; - - return comp.$mount(); - } - - beforeEach(() => { - vm = createComponent(); - }); - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders a prev dir link', () => { - const link = vm.$el.querySelector('a'); - - expect(link.href).toMatch(`/${parentLink}`); - expect(link.textContent).toEqual('...'); - }); - - it('clicking row triggers getTreeData', () => { - spyOn(vm, 'getTreeData'); - - vm.$el.querySelector('td').click(); - - expect(vm.getTreeData).toHaveBeenCalledWith({ endpoint: parentLink }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_preview_spec.js b/spec/javascripts/repo/components/repo_preview_spec.js deleted file mode 100644 index e90837e4cb2..00000000000 --- a/spec/javascripts/repo/components/repo_preview_spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoPreview from '~/ide/components/repo_preview.vue'; -import { file, resetStore } from '../helpers'; - -describe('RepoPreview', () => { - let vm; - - function createComponent() { - const f = file(); - const RepoPreview = Vue.extend(repoPreview); - - const comp = new RepoPreview({ - store, - }); - - f.active = true; - f.html = 'test'; - - comp.$store.state.openFiles.push(f); - - return comp.$mount(); - } - - afterEach(() => { - vm.$destroy(); - - resetStore(vm.$store); - }); - - it('renders a div with the activeFile html', () => { - vm = createComponent(); - - expect(vm.$el.tagName).toEqual('DIV'); - expect(vm.$el.innerHTML).toContain('test'); - }); -}); diff --git a/spec/javascripts/repo/components/repo_tab_spec.js b/spec/javascripts/repo/components/repo_tab_spec.js deleted file mode 100644 index 933e8d3a06a..00000000000 --- a/spec/javascripts/repo/components/repo_tab_spec.js +++ /dev/null @@ -1,108 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoTab from '~/ide/components/repo_tab.vue'; -import { file, resetStore } from '../helpers'; - -describe('RepoTab', () => { - let vm; - - function createComponent(propsData) { - const RepoTab = Vue.extend(repoTab); - - return new RepoTab({ - store, - propsData, - }).$mount(); - } - - afterEach(() => { - resetStore(vm.$store); - }); - - it('renders a close link and a name link', () => { - vm = createComponent({ - tab: file(), - }); - vm.$store.state.openFiles.push(vm.tab); - const close = vm.$el.querySelector('.multi-file-tab-close'); - const name = vm.$el.querySelector(`[title="${vm.tab.url}"]`); - - expect(close.querySelector('.fa-times')).toBeTruthy(); - expect(name.textContent.trim()).toEqual(vm.tab.name); - }); - - it('fires clickFile when the link is clicked', () => { - vm = createComponent({ - tab: file(), - }); - - spyOn(vm, 'clickFile'); - - vm.$el.click(); - - expect(vm.clickFile).toHaveBeenCalledWith(vm.tab); - }); - - it('calls closeFile when clicking close button', () => { - vm = createComponent({ - tab: file(), - }); - - spyOn(vm, 'closeFile'); - - vm.$el.querySelector('.multi-file-tab-close').click(); - - expect(vm.closeFile).toHaveBeenCalledWith({ file: vm.tab }); - }); - - it('renders an fa-circle icon if tab is changed', () => { - const tab = file('changedFile'); - tab.changed = true; - vm = createComponent({ - tab, - }); - - expect(vm.$el.querySelector('.multi-file-tab-close .fa-circle')).not.toBeNull(); - }); - - describe('methods', () => { - describe('closeTab', () => { - it('does not close tab if is changed', (done) => { - const tab = file('closeFile'); - tab.changed = true; - tab.opened = true; - vm = createComponent({ - tab, - }); - vm.$store.state.openFiles.push(tab); - vm.$store.dispatch('setFileActive', tab); - - vm.$el.querySelector('.multi-file-tab-close').click(); - - vm.$nextTick(() => { - expect(tab.opened).toBeTruthy(); - - done(); - }); - }); - - it('closes tab when clicking close btn', (done) => { - const tab = file('lose'); - tab.opened = true; - vm = createComponent({ - tab, - }); - vm.$store.state.openFiles.push(tab); - vm.$store.dispatch('setFileActive', tab); - - vm.$el.querySelector('.multi-file-tab-close').click(); - - vm.$nextTick(() => { - expect(tab.opened).toBeFalsy(); - - done(); - }); - }); - }); - }); -}); diff --git a/spec/javascripts/repo/components/repo_tabs_spec.js b/spec/javascripts/repo/components/repo_tabs_spec.js deleted file mode 100644 index 2c363364d70..00000000000 --- a/spec/javascripts/repo/components/repo_tabs_spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import repoTabs from '~/ide/components/repo_tabs.vue'; -import { file, resetStore } from '../helpers'; - -describe('RepoTabs', () => { - const openedFiles = [file('open1'), file('open2')]; - let vm; - - function createComponent() { - const RepoTabs = Vue.extend(repoTabs); - - return new RepoTabs({ - store, - }).$mount(); - } - - afterEach(() => { - resetStore(vm.$store); - }); - - it('renders a list of tabs', (done) => { - vm = createComponent(); - openedFiles[0].active = true; - vm.$store.state.openFiles = openedFiles; - - vm.$nextTick(() => { - const tabs = [...vm.$el.querySelectorAll('.multi-file-tab')]; - - expect(tabs.length).toEqual(2); - expect(tabs[0].classList.contains('active')).toBeTruthy(); - expect(tabs[1].classList.contains('active')).toBeFalsy(); - - done(); - }); - }); -}); diff --git a/spec/javascripts/repo/helpers.js b/spec/javascripts/repo/helpers.js deleted file mode 100644 index ac43d221198..00000000000 --- a/spec/javascripts/repo/helpers.js +++ /dev/null @@ -1,16 +0,0 @@ -import { decorateData } from '~/ide/stores/utils'; -import state from '~/ide/stores/state'; - -export const resetStore = (store) => { - store.replaceState(state()); -}; - -export const file = (name = 'name', id = name, type = '') => decorateData({ - id, - type, - icon: 'icon', - url: 'url', - name, - path: name, - lastCommit: {}, -}); diff --git a/spec/javascripts/repo/lib/common/disposable_spec.js b/spec/javascripts/repo/lib/common/disposable_spec.js deleted file mode 100644 index af12ca15369..00000000000 --- a/spec/javascripts/repo/lib/common/disposable_spec.js +++ /dev/null @@ -1,44 +0,0 @@ -import Disposable from '~/ide/lib/common/disposable'; - -describe('Multi-file editor library disposable class', () => { - let instance; - let disposableClass; - - beforeEach(() => { - instance = new Disposable(); - - disposableClass = { - dispose: jasmine.createSpy('dispose'), - }; - }); - - afterEach(() => { - instance.dispose(); - }); - - describe('add', () => { - it('adds disposable classes', () => { - instance.add(disposableClass); - - expect(instance.disposers.size).toBe(1); - }); - }); - - describe('dispose', () => { - beforeEach(() => { - instance.add(disposableClass); - }); - - it('calls dispose on all cached disposers', () => { - instance.dispose(); - - expect(disposableClass.dispose).toHaveBeenCalled(); - }); - - it('clears cached disposers', () => { - instance.dispose(); - - expect(instance.disposers.size).toBe(0); - }); - }); -}); diff --git a/spec/javascripts/repo/lib/common/model_manager_spec.js b/spec/javascripts/repo/lib/common/model_manager_spec.js deleted file mode 100644 index 563c2e33834..00000000000 --- a/spec/javascripts/repo/lib/common/model_manager_spec.js +++ /dev/null @@ -1,81 +0,0 @@ -/* global monaco */ -import monacoLoader from '~/ide/monaco_loader'; -import ModelManager from '~/ide/lib/common/model_manager'; -import { file } from '../../helpers'; - -describe('Multi-file editor library model manager', () => { - let instance; - - beforeEach((done) => { - monacoLoader(['vs/editor/editor.main'], () => { - instance = new ModelManager(monaco); - - done(); - }); - }); - - afterEach(() => { - instance.dispose(); - }); - - describe('addModel', () => { - it('caches model', () => { - instance.addModel(file()); - - expect(instance.models.size).toBe(1); - }); - - it('caches model by file path', () => { - instance.addModel(file('path-name')); - - expect(instance.models.keys().next().value).toBe('path-name'); - }); - - it('adds model into disposable', () => { - spyOn(instance.disposable, 'add').and.callThrough(); - - instance.addModel(file()); - - expect(instance.disposable.add).toHaveBeenCalled(); - }); - - it('returns cached model', () => { - spyOn(instance.models, 'get').and.callThrough(); - - instance.addModel(file()); - instance.addModel(file()); - - expect(instance.models.get).toHaveBeenCalled(); - }); - }); - - describe('hasCachedModel', () => { - it('returns false when no models exist', () => { - expect(instance.hasCachedModel('path')).toBeFalsy(); - }); - - it('returns true when model exists', () => { - instance.addModel(file('path-name')); - - expect(instance.hasCachedModel('path-name')).toBeTruthy(); - }); - }); - - describe('dispose', () => { - it('clears cached models', () => { - instance.addModel(file()); - - instance.dispose(); - - expect(instance.models.size).toBe(0); - }); - - it('calls disposable dispose', () => { - spyOn(instance.disposable, 'dispose').and.callThrough(); - - instance.dispose(); - - expect(instance.disposable.dispose).toHaveBeenCalled(); - }); - }); -}); diff --git a/spec/javascripts/repo/lib/common/model_spec.js b/spec/javascripts/repo/lib/common/model_spec.js deleted file mode 100644 index 878a4a3f3fe..00000000000 --- a/spec/javascripts/repo/lib/common/model_spec.js +++ /dev/null @@ -1,84 +0,0 @@ -/* global monaco */ -import monacoLoader from '~/ide/monaco_loader'; -import Model from '~/ide/lib/common/model'; -import { file } from '../../helpers'; - -describe('Multi-file editor library model', () => { - let model; - - beforeEach((done) => { - monacoLoader(['vs/editor/editor.main'], () => { - model = new Model(monaco, file('path')); - - done(); - }); - }); - - afterEach(() => { - model.dispose(); - }); - - it('creates original model & new model', () => { - expect(model.originalModel).not.toBeNull(); - expect(model.model).not.toBeNull(); - }); - - describe('path', () => { - it('returns file path', () => { - expect(model.path).toBe('path'); - }); - }); - - describe('getModel', () => { - it('returns model', () => { - expect(model.getModel()).toBe(model.model); - }); - }); - - describe('getOriginalModel', () => { - it('returns original model', () => { - expect(model.getOriginalModel()).toBe(model.originalModel); - }); - }); - - describe('onChange', () => { - it('caches event by path', () => { - model.onChange(() => {}); - - expect(model.events.size).toBe(1); - expect(model.events.keys().next().value).toBe('path'); - }); - - it('calls callback on change', (done) => { - const spy = jasmine.createSpy(); - model.onChange(spy); - - model.getModel().setValue('123'); - - setTimeout(() => { - expect(spy).toHaveBeenCalledWith(model.getModel(), jasmine.anything()); - done(); - }); - }); - }); - - describe('dispose', () => { - it('calls disposable dispose', () => { - spyOn(model.disposable, 'dispose').and.callThrough(); - - model.dispose(); - - expect(model.disposable.dispose).toHaveBeenCalled(); - }); - - it('clears events', () => { - model.onChange(() => {}); - - expect(model.events.size).toBe(1); - - model.dispose(); - - expect(model.events.size).toBe(0); - }); - }); -}); diff --git a/spec/javascripts/repo/lib/decorations/controller_spec.js b/spec/javascripts/repo/lib/decorations/controller_spec.js deleted file mode 100644 index fea12d74dca..00000000000 --- a/spec/javascripts/repo/lib/decorations/controller_spec.js +++ /dev/null @@ -1,120 +0,0 @@ -/* global monaco */ -import monacoLoader from '~/ide/monaco_loader'; -import editor from '~/ide/lib/editor'; -import DecorationsController from '~/ide/lib/decorations/controller'; -import Model from '~/ide/lib/common/model'; -import { file } from '../../helpers'; - -describe('Multi-file editor library decorations controller', () => { - let editorInstance; - let controller; - let model; - - beforeEach((done) => { - monacoLoader(['vs/editor/editor.main'], () => { - editorInstance = editor.create(monaco); - editorInstance.createInstance(document.createElement('div')); - - controller = new DecorationsController(editorInstance); - model = new Model(monaco, file('path')); - - done(); - }); - }); - - afterEach(() => { - model.dispose(); - editorInstance.dispose(); - controller.dispose(); - }); - - describe('getAllDecorationsForModel', () => { - it('returns empty array when no decorations exist for model', () => { - const decorations = controller.getAllDecorationsForModel(model); - - expect(decorations).toEqual([]); - }); - - it('returns decorations by model URL', () => { - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - - const decorations = controller.getAllDecorationsForModel(model); - - expect(decorations[0]).toEqual({ decoration: 'decorationValue' }); - }); - }); - - describe('addDecorations', () => { - it('caches decorations in a new map', () => { - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - - expect(controller.decorations.size).toBe(1); - }); - - it('does not create new cache model', () => { - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue2' }]); - - expect(controller.decorations.size).toBe(1); - }); - - it('caches decorations by model URL', () => { - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - - expect(controller.decorations.size).toBe(1); - expect(controller.decorations.keys().next().value).toBe('path'); - }); - - it('calls decorate method', () => { - spyOn(controller, 'decorate'); - - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - - expect(controller.decorate).toHaveBeenCalled(); - }); - }); - - describe('decorate', () => { - it('sets decorations on editor instance', () => { - spyOn(controller.editor.instance, 'deltaDecorations'); - - controller.decorate(model); - - expect(controller.editor.instance.deltaDecorations).toHaveBeenCalledWith([], []); - }); - - it('caches decorations', () => { - spyOn(controller.editor.instance, 'deltaDecorations').and.returnValue([]); - - controller.decorate(model); - - expect(controller.editorDecorations.size).toBe(1); - }); - - it('caches decorations by model URL', () => { - spyOn(controller.editor.instance, 'deltaDecorations').and.returnValue([]); - - controller.decorate(model); - - expect(controller.editorDecorations.keys().next().value).toBe('path'); - }); - }); - - describe('dispose', () => { - it('clears cached decorations', () => { - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - - controller.dispose(); - - expect(controller.decorations.size).toBe(0); - }); - - it('clears cached editorDecorations', () => { - controller.addDecorations(model, 'key', [{ decoration: 'decorationValue' }]); - - controller.dispose(); - - expect(controller.editorDecorations.size).toBe(0); - }); - }); -}); diff --git a/spec/javascripts/repo/lib/diff/controller_spec.js b/spec/javascripts/repo/lib/diff/controller_spec.js deleted file mode 100644 index 1d55c165260..00000000000 --- a/spec/javascripts/repo/lib/diff/controller_spec.js +++ /dev/null @@ -1,176 +0,0 @@ -/* global monaco */ -import monacoLoader from '~/ide/monaco_loader'; -import editor from '~/ide/lib/editor'; -import ModelManager from '~/ide/lib/common/model_manager'; -import DecorationsController from '~/ide/lib/decorations/controller'; -import DirtyDiffController, { getDiffChangeType, getDecorator } from '~/ide/lib/diff/controller'; -import { computeDiff } from '~/ide/lib/diff/diff'; -import { file } from '../../helpers'; - -describe('Multi-file editor library dirty diff controller', () => { - let editorInstance; - let controller; - let modelManager; - let decorationsController; - let model; - - beforeEach((done) => { - monacoLoader(['vs/editor/editor.main'], () => { - editorInstance = editor.create(monaco); - editorInstance.createInstance(document.createElement('div')); - - modelManager = new ModelManager(monaco); - decorationsController = new DecorationsController(editorInstance); - - model = modelManager.addModel(file()); - - controller = new DirtyDiffController(modelManager, decorationsController); - - done(); - }); - }); - - afterEach(() => { - controller.dispose(); - model.dispose(); - decorationsController.dispose(); - editorInstance.dispose(); - }); - - describe('getDiffChangeType', () => { - ['added', 'removed', 'modified'].forEach((type) => { - it(`returns ${type}`, () => { - const change = { - [type]: true, - }; - - expect(getDiffChangeType(change)).toBe(type); - }); - }); - }); - - describe('getDecorator', () => { - ['added', 'removed', 'modified'].forEach((type) => { - it(`returns with linesDecorationsClassName for ${type}`, () => { - const change = { - [type]: true, - }; - - expect( - getDecorator(change).options.linesDecorationsClassName, - ).toBe(`dirty-diff dirty-diff-${type}`); - }); - - it('returns with line numbers', () => { - const change = { - lineNumber: 1, - endLineNumber: 2, - [type]: true, - }; - - const range = getDecorator(change).range; - - expect(range.startLineNumber).toBe(1); - expect(range.endLineNumber).toBe(2); - expect(range.startColumn).toBe(1); - expect(range.endColumn).toBe(1); - }); - }); - }); - - describe('attachModel', () => { - it('adds change event callback', () => { - spyOn(model, 'onChange'); - - controller.attachModel(model); - - expect(model.onChange).toHaveBeenCalled(); - }); - - it('calls throttledComputeDiff on change', () => { - spyOn(controller, 'throttledComputeDiff'); - - controller.attachModel(model); - - model.getModel().setValue('123'); - - expect(controller.throttledComputeDiff).toHaveBeenCalled(); - }); - }); - - describe('computeDiff', () => { - it('posts to worker', () => { - spyOn(controller.dirtyDiffWorker, 'postMessage'); - - controller.computeDiff(model); - - expect(controller.dirtyDiffWorker.postMessage).toHaveBeenCalledWith({ - path: model.path, - originalContent: '', - newContent: '', - }); - }); - }); - - describe('reDecorate', () => { - it('calls decorations controller decorate', () => { - spyOn(controller.decorationsController, 'decorate'); - - controller.reDecorate(model); - - expect(controller.decorationsController.decorate).toHaveBeenCalledWith(model); - }); - }); - - describe('decorate', () => { - it('adds decorations into decorations controller', () => { - spyOn(controller.decorationsController, 'addDecorations'); - - controller.decorate({ data: { changes: [], path: 'path' } }); - - expect(controller.decorationsController.addDecorations).toHaveBeenCalledWith('path', 'dirtyDiff', jasmine.anything()); - }); - - it('adds decorations into editor', () => { - const spy = spyOn(controller.decorationsController.editor.instance, 'deltaDecorations'); - - controller.decorate({ data: { changes: computeDiff('123', '1234'), path: 'path' } }); - - expect(spy).toHaveBeenCalledWith([], [{ - range: new monaco.Range( - 1, 1, 1, 1, - ), - options: { - isWholeLine: true, - linesDecorationsClassName: 'dirty-diff dirty-diff-modified', - }, - }]); - }); - }); - - describe('dispose', () => { - it('calls disposable dispose', () => { - spyOn(controller.disposable, 'dispose').and.callThrough(); - - controller.dispose(); - - expect(controller.disposable.dispose).toHaveBeenCalled(); - }); - - it('terminates worker', () => { - spyOn(controller.dirtyDiffWorker, 'terminate').and.callThrough(); - - controller.dispose(); - - expect(controller.dirtyDiffWorker.terminate).toHaveBeenCalled(); - }); - - it('removes worker event listener', () => { - spyOn(controller.dirtyDiffWorker, 'removeEventListener').and.callThrough(); - - controller.dispose(); - - expect(controller.dirtyDiffWorker.removeEventListener).toHaveBeenCalledWith('message', jasmine.anything()); - }); - }); -}); diff --git a/spec/javascripts/repo/lib/diff/diff_spec.js b/spec/javascripts/repo/lib/diff/diff_spec.js deleted file mode 100644 index 57f3ac3d365..00000000000 --- a/spec/javascripts/repo/lib/diff/diff_spec.js +++ /dev/null @@ -1,80 +0,0 @@ -import { computeDiff } from '~/ide/lib/diff/diff'; - -describe('Multi-file editor library diff calculator', () => { - describe('computeDiff', () => { - it('returns empty array if no changes', () => { - const diff = computeDiff('123', '123'); - - expect(diff).toEqual([]); - }); - - describe('modified', () => { - it('', () => { - const diff = computeDiff('123', '1234')[0]; - - expect(diff.added).toBeTruthy(); - expect(diff.modified).toBeTruthy(); - expect(diff.removed).toBeUndefined(); - }); - - it('', () => { - const diff = computeDiff('123\n123\n123', '123\n1234\n123')[0]; - - expect(diff.added).toBeTruthy(); - expect(diff.modified).toBeTruthy(); - expect(diff.removed).toBeUndefined(); - expect(diff.lineNumber).toBe(2); - }); - }); - - describe('added', () => { - it('', () => { - const diff = computeDiff('123', '123\n123')[0]; - - expect(diff.added).toBeTruthy(); - expect(diff.modified).toBeUndefined(); - expect(diff.removed).toBeUndefined(); - }); - - it('', () => { - const diff = computeDiff('123\n123\n123', '123\n123\n1234\n123')[0]; - - expect(diff.added).toBeTruthy(); - expect(diff.modified).toBeUndefined(); - expect(diff.removed).toBeUndefined(); - expect(diff.lineNumber).toBe(3); - }); - }); - - describe('removed', () => { - it('', () => { - const diff = computeDiff('123', '')[0]; - - expect(diff.added).toBeUndefined(); - expect(diff.modified).toBeUndefined(); - expect(diff.removed).toBeTruthy(); - }); - - it('', () => { - const diff = computeDiff('123\n123\n123', '123\n123')[0]; - - expect(diff.added).toBeUndefined(); - expect(diff.modified).toBeTruthy(); - expect(diff.removed).toBeTruthy(); - expect(diff.lineNumber).toBe(2); - }); - }); - - it('includes line number of change', () => { - const diff = computeDiff('123', '')[0]; - - expect(diff.lineNumber).toBe(1); - }); - - it('includes end line number of change', () => { - const diff = computeDiff('123', '')[0]; - - expect(diff.endLineNumber).toBe(1); - }); - }); -}); diff --git a/spec/javascripts/repo/lib/editor_options_spec.js b/spec/javascripts/repo/lib/editor_options_spec.js deleted file mode 100644 index edbf5450dce..00000000000 --- a/spec/javascripts/repo/lib/editor_options_spec.js +++ /dev/null @@ -1,7 +0,0 @@ -import editorOptions from '~/ide/lib/editor_options'; - -describe('Multi-file editor library editor options', () => { - it('returns an array', () => { - expect(editorOptions).toEqual(jasmine.any(Array)); - }); -}); diff --git a/spec/javascripts/repo/lib/editor_spec.js b/spec/javascripts/repo/lib/editor_spec.js deleted file mode 100644 index 8d51d48a782..00000000000 --- a/spec/javascripts/repo/lib/editor_spec.js +++ /dev/null @@ -1,128 +0,0 @@ -/* global monaco */ -import monacoLoader from '~/ide/monaco_loader'; -import editor from '~/ide/lib/editor'; -import { file } from '../helpers'; - -describe('Multi-file editor library', () => { - let instance; - - beforeEach((done) => { - monacoLoader(['vs/editor/editor.main'], () => { - instance = editor.create(monaco); - - done(); - }); - }); - - afterEach(() => { - instance.dispose(); - }); - - it('creates instance of editor', () => { - expect(editor.editorInstance).not.toBeNull(); - }); - - describe('createInstance', () => { - let el; - - beforeEach(() => { - el = document.createElement('div'); - }); - - it('creates editor instance', () => { - spyOn(instance.monaco.editor, 'create').and.callThrough(); - - instance.createInstance(el); - - expect(instance.monaco.editor.create).toHaveBeenCalled(); - }); - - it('creates dirty diff controller', () => { - instance.createInstance(el); - - expect(instance.dirtyDiffController).not.toBeNull(); - }); - }); - - describe('createModel', () => { - it('calls model manager addModel', () => { - spyOn(instance.modelManager, 'addModel'); - - instance.createModel('FILE'); - - expect(instance.modelManager.addModel).toHaveBeenCalledWith('FILE'); - }); - }); - - describe('attachModel', () => { - let model; - - beforeEach(() => { - instance.createInstance(document.createElement('div')); - - model = instance.createModel(file()); - }); - - it('sets the current model on the instance', () => { - instance.attachModel(model); - - expect(instance.currentModel).toBe(model); - }); - - it('attaches the model to the current instance', () => { - spyOn(instance.instance, 'setModel'); - - instance.attachModel(model); - - expect(instance.instance.setModel).toHaveBeenCalledWith(model.getModel()); - }); - - it('attaches the model to the dirty diff controller', () => { - spyOn(instance.dirtyDiffController, 'attachModel'); - - instance.attachModel(model); - - expect(instance.dirtyDiffController.attachModel).toHaveBeenCalledWith(model); - }); - - it('re-decorates with the dirty diff controller', () => { - spyOn(instance.dirtyDiffController, 'reDecorate'); - - instance.attachModel(model); - - expect(instance.dirtyDiffController.reDecorate).toHaveBeenCalledWith(model); - }); - }); - - describe('clearEditor', () => { - it('resets the editor model', () => { - instance.createInstance(document.createElement('div')); - - spyOn(instance.instance, 'setModel'); - - instance.clearEditor(); - - expect(instance.instance.setModel).toHaveBeenCalledWith(null); - }); - }); - - describe('dispose', () => { - it('calls disposble dispose method', () => { - spyOn(instance.disposable, 'dispose').and.callThrough(); - - instance.dispose(); - - expect(instance.disposable.dispose).toHaveBeenCalled(); - }); - - it('resets instance', () => { - instance.createInstance(document.createElement('div')); - - expect(instance.instance).not.toBeNull(); - - instance.dispose(); - - expect(instance.instance).toBeNull(); - }); - }); -}); diff --git a/spec/javascripts/repo/monaco_loader_spec.js b/spec/javascripts/repo/monaco_loader_spec.js deleted file mode 100644 index b8ac36972aa..00000000000 --- a/spec/javascripts/repo/monaco_loader_spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import monacoContext from 'monaco-editor/dev/vs/loader'; -import monacoLoader from '~/ide/monaco_loader'; - -describe('MonacoLoader', () => { - it('calls require.config and exports require', () => { - expect(monacoContext.require.getConfig()).toEqual(jasmine.objectContaining({ - paths: { - vs: `${__webpack_public_path__}monaco-editor/vs`, // eslint-disable-line camelcase - }, - })); - expect(monacoLoader).toBe(monacoContext.require); - }); -}); diff --git a/spec/javascripts/repo/stores/actions/branch_spec.js b/spec/javascripts/repo/stores/actions/branch_spec.js deleted file mode 100644 index 00d16fd790d..00000000000 --- a/spec/javascripts/repo/stores/actions/branch_spec.js +++ /dev/null @@ -1,44 +0,0 @@ -import store from '~/ide/stores'; -import service from '~/ide/services'; -import { resetStore } from '../../helpers'; - -describe('Multi-file store branch actions', () => { - afterEach(() => { - resetStore(store); - }); - - describe('createNewBranch', () => { - beforeEach(() => { - spyOn(service, 'createBranch').and.returnValue(Promise.resolve({ - json: () => ({ - name: 'testing', - }), - })); - spyOn(history, 'pushState'); - - store.state.currentProjectId = 'abcproject'; - store.state.currentBranchId = 'testing'; - store.state.projects.abcproject = { - branches: { - master: { - workingReference: '1', - }, - }, - }; - }); - - it('creates new branch', (done) => { - store.dispatch('createNewBranch', 'master') - .then(() => { - expect(store.state.currentBranchId).toBe('testing'); - expect(service.createBranch).toHaveBeenCalledWith('abcproject', { - branch: 'master', - ref: 'testing', - }); - - done(); - }) - .catch(done.fail); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/actions/file_spec.js b/spec/javascripts/repo/stores/actions/file_spec.js deleted file mode 100644 index e2d8f002e27..00000000000 --- a/spec/javascripts/repo/stores/actions/file_spec.js +++ /dev/null @@ -1,431 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import service from '~/ide/services'; -import { file, resetStore } from '../../helpers'; - -describe('Multi-file store file actions', () => { - afterEach(() => { - resetStore(store); - }); - - describe('closeFile', () => { - let localFile; - let getLastCommitDataSpy; - let oldGetLastCommitData; - - beforeEach(() => { - getLastCommitDataSpy = jasmine.createSpy('getLastCommitData'); - oldGetLastCommitData = store._actions.getLastCommitData; // eslint-disable-line - store._actions.getLastCommitData = [getLastCommitDataSpy]; // eslint-disable-line - - localFile = file('testFile'); - localFile.active = true; - localFile.opened = true; - localFile.parentTreeUrl = 'parentTreeUrl'; - - store.state.openFiles.push(localFile); - }); - - afterEach(() => { - store._actions.getLastCommitData = oldGetLastCommitData; // eslint-disable-line - }); - - it('closes open files', (done) => { - store.dispatch('closeFile', { file: localFile }) - .then(() => { - expect(localFile.opened).toBeFalsy(); - expect(localFile.active).toBeFalsy(); - expect(store.state.openFiles.length).toBe(0); - - done(); - }).catch(done.fail); - }); - - it('does not close file if has changed', (done) => { - localFile.changed = true; - - store.dispatch('closeFile', { file: localFile }) - .then(() => { - expect(localFile.opened).toBeTruthy(); - expect(localFile.active).toBeTruthy(); - expect(store.state.openFiles.length).toBe(1); - - done(); - }).catch(done.fail); - }); - - it('does not close file if temp file', (done) => { - localFile.tempFile = true; - - store.dispatch('closeFile', { file: localFile }) - .then(() => { - expect(localFile.opened).toBeTruthy(); - expect(localFile.active).toBeTruthy(); - expect(store.state.openFiles.length).toBe(1); - - done(); - }).catch(done.fail); - }); - - it('force closes a changed file', (done) => { - localFile.changed = true; - - store.dispatch('closeFile', { file: localFile, force: true }) - .then(() => { - expect(localFile.opened).toBeFalsy(); - expect(localFile.active).toBeFalsy(); - expect(store.state.openFiles.length).toBe(0); - - done(); - }).catch(done.fail); - }); - - it('sets next file as active', (done) => { - const f = file('otherfile'); - store.state.openFiles.push(f); - - expect(f.active).toBeFalsy(); - - store.dispatch('closeFile', { file: localFile }) - .then(() => { - expect(f.active).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('calls getLastCommitData', (done) => { - store.dispatch('closeFile', { file: localFile }) - .then(() => { - expect(getLastCommitDataSpy).toHaveBeenCalled(); - - done(); - }).catch(done.fail); - }); - }); - - describe('setFileActive', () => { - let scrollToTabSpy; - let oldScrollToTab; - - beforeEach(() => { - scrollToTabSpy = jasmine.createSpy('scrollToTab'); - oldScrollToTab = store._actions.scrollToTab; // eslint-disable-line - store._actions.scrollToTab = [scrollToTabSpy]; // eslint-disable-line - }); - - afterEach(() => { - store._actions.scrollToTab = oldScrollToTab; // eslint-disable-line - }); - - it('calls scrollToTab', (done) => { - store.dispatch('setFileActive', file('setThisActive')) - .then(() => { - expect(scrollToTabSpy).toHaveBeenCalled(); - - done(); - }).catch(done.fail); - }); - - it('sets the file active', (done) => { - const localFile = file('activeFile'); - - store.dispatch('setFileActive', localFile) - .then(() => { - expect(localFile.active).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('returns early if file is already active', (done) => { - const localFile = file('earlyActive'); - localFile.active = true; - - store.dispatch('setFileActive', localFile) - .then(() => { - expect(scrollToTabSpy).not.toHaveBeenCalled(); - - done(); - }).catch(done.fail); - }); - - it('sets current active file to not active', (done) => { - const localFile = file('currentActive'); - localFile.active = true; - store.state.openFiles.push(localFile); - - store.dispatch('setFileActive', file('newActive')) - .then(() => { - expect(localFile.active).toBeFalsy(); - - done(); - }).catch(done.fail); - }); - - it('resets location.hash for line highlighting', (done) => { - location.hash = 'test'; - - store.dispatch('setFileActive', file('otherActive')) - .then(() => { - expect(location.hash).not.toBe('test'); - - done(); - }).catch(done.fail); - }); - }); - - describe('getFileData', () => { - let localFile; - - beforeEach(() => { - spyOn(service, 'getFileData').and.returnValue(Promise.resolve({ - headers: { - 'page-title': 'testing getFileData', - }, - json: () => Promise.resolve({ - blame_path: 'blame_path', - commits_path: 'commits_path', - permalink: 'permalink', - raw_path: 'raw_path', - binary: false, - html: '123', - render_error: '', - }), - })); - - localFile = file('newCreate'); - localFile.url = 'getFileDataURL'; - }); - - afterEach(() => { - store.dispatch('closeFile', { - file: localFile, - force: true, - }); - }); - - it('calls the service', (done) => { - store.dispatch('getFileData', localFile) - .then(() => { - expect(service.getFileData).toHaveBeenCalledWith('getFileDataURL'); - - done(); - }).catch(done.fail); - }); - - it('sets the file data', (done) => { - store.dispatch('getFileData', localFile) - .then(Vue.nextTick) - .then(() => { - expect(localFile.blamePath).toBe('blame_path'); - - done(); - }).catch(done.fail); - }); - - it('sets document title', (done) => { - store.dispatch('getFileData', localFile) - .then(() => { - expect(document.title).toBe('testing getFileData'); - - done(); - }).catch(done.fail); - }); - - it('sets the file as active', (done) => { - store.dispatch('getFileData', localFile) - .then(Vue.nextTick) - .then(() => { - expect(localFile.active).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('adds the file to open files', (done) => { - store.dispatch('getFileData', localFile) - .then(Vue.nextTick) - .then(() => { - expect(store.state.openFiles.length).toBe(1); - expect(store.state.openFiles[0].name).toBe(localFile.name); - - done(); - }).catch(done.fail); - }); - - it('toggles the file loading', (done) => { - store.dispatch('getFileData', localFile) - .then(() => { - expect(localFile.loading).toBeTruthy(); - - return Vue.nextTick(); - }) - .then(() => { - expect(localFile.loading).toBeFalsy(); - - done(); - }).catch(done.fail); - }); - }); - - describe('getRawFileData', () => { - let tmpFile; - - beforeEach(() => { - spyOn(service, 'getRawFileData').and.returnValue(Promise.resolve('raw')); - - tmpFile = file('tmpFile'); - }); - - it('calls getRawFileData service method', (done) => { - store.dispatch('getRawFileData', tmpFile) - .then(() => { - expect(service.getRawFileData).toHaveBeenCalledWith(tmpFile); - - done(); - }).catch(done.fail); - }); - - it('updates file raw data', (done) => { - store.dispatch('getRawFileData', tmpFile) - .then(() => { - expect(tmpFile.raw).toBe('raw'); - - done(); - }).catch(done.fail); - }); - }); - - describe('changeFileContent', () => { - let tmpFile; - - beforeEach(() => { - tmpFile = file('tmpFile'); - }); - - it('updates file content', (done) => { - store.dispatch('changeFileContent', { - file: tmpFile, - content: 'content', - }) - .then(() => { - expect(tmpFile.content).toBe('content'); - - done(); - }).catch(done.fail); - }); - }); - - describe('createTempFile', () => { - let projectTree; - - beforeEach(() => { - document.body.innerHTML += '
'; - - store.state.currentProjectId = 'abcproject'; - store.state.currentBranchId = 'master'; - store.state.projects.abcproject = { - branches: { - master: { - workingReference: '1', - }, - }, - }; - - store.state.trees['abcproject/mybranch'] = { - tree: [], - }; - - projectTree = store.state.trees['abcproject/mybranch']; - }); - - afterEach(() => { - document.querySelector('.flash-container').remove(); - }); - - it('creates temp file', (done) => { - store.dispatch('createTempFile', { - name: 'test', - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - }).then((f) => { - expect(f.tempFile).toBeTruthy(); - expect(store.state.trees['abcproject/mybranch'].tree.length).toBe(1); - - done(); - }).catch(done.fail); - }); - - it('adds tmp file to open files', (done) => { - store.dispatch('createTempFile', { - name: 'test', - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - }).then((f) => { - expect(store.state.openFiles.length).toBe(1); - expect(store.state.openFiles[0].name).toBe(f.name); - - done(); - }).catch(done.fail); - }); - - it('sets tmp file as active', (done) => { - store.dispatch('createTempFile', { - name: 'test', - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - }).then((f) => { - expect(f.active).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('enters edit mode if file is not base64', (done) => { - store.dispatch('createTempFile', { - name: 'test', - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - }).then(() => { - expect(store.state.editMode).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('creates flash message is file already exists', (done) => { - store.state.trees['abcproject/mybranch'].tree.push(file('test', '1', 'blob')); - - store.dispatch('createTempFile', { - name: 'test', - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - }).then(() => { - expect(document.querySelector('.flash-alert')).not.toBeNull(); - - done(); - }).catch(done.fail); - }); - - it('increases level of file', (done) => { - store.state.trees['abcproject/mybranch'].level = 1; - - store.dispatch('createTempFile', { - name: 'test', - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - }).then((f) => { - expect(f.level).toBe(2); - - done(); - }).catch(done.fail); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/actions/tree_spec.js b/spec/javascripts/repo/stores/actions/tree_spec.js deleted file mode 100644 index 65351dbb7d9..00000000000 --- a/spec/javascripts/repo/stores/actions/tree_spec.js +++ /dev/null @@ -1,350 +0,0 @@ -import Vue from 'vue'; -import store from '~/ide/stores'; -import service from '~/ide/services'; -import { file, resetStore } from '../../helpers'; - -describe('Multi-file store tree actions', () => { - let projectTree; - - const basicCallParameters = { - endpoint: 'rootEndpoint', - projectId: 'abcproject', - branch: 'master', - }; - - beforeEach(() => { - store.state.currentProjectId = 'abcproject'; - store.state.currentBranchId = 'master'; - store.state.projects.abcproject = { - web_url: '', - branches: { - master: { - workingReference: '1', - }, - }, - }; - }); - - afterEach(() => { - resetStore(store); - }); - - describe('getTreeData', () => { - beforeEach(() => { - spyOn(service, 'getTreeData').and.returnValue(Promise.resolve({ - headers: { - 'page-title': 'test', - }, - json: () => Promise.resolve({ - last_commit_path: 'last_commit_path', - parent_tree_url: 'parent_tree_url', - path: '/', - trees: [{ name: 'tree' }], - blobs: [{ name: 'blob' }], - submodules: [{ name: 'submodule' }], - }), - })); - }); - - it('calls service getTreeData', (done) => { - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - expect(service.getTreeData).toHaveBeenCalledWith('rootEndpoint'); - - done(); - }).catch(done.fail); - }); - - it('adds data into tree', (done) => { - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - projectTree = store.state.trees['abcproject/master']; - expect(projectTree.tree.length).toBe(3); - expect(projectTree.tree[0].type).toBe('tree'); - expect(projectTree.tree[1].type).toBe('submodule'); - expect(projectTree.tree[2].type).toBe('blob'); - - done(); - }).catch(done.fail); - }); - - it('sets parent tree URL', (done) => { - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - expect(store.state.parentTreeUrl).toBe('parent_tree_url'); - - done(); - }).catch(done.fail); - }); - - it('sets last commit path', (done) => { - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - expect(store.state.trees['abcproject/master'].lastCommitPath).toBe('last_commit_path'); - - done(); - }).catch(done.fail); - }); - - it('sets root if not currently at root', (done) => { - store.state.isInitialRoot = false; - - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - expect(store.state.isInitialRoot).toBeTruthy(); - expect(store.state.isRoot).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('sets page title', (done) => { - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - expect(document.title).toBe('test'); - - done(); - }).catch(done.fail); - }); - - it('calls getLastCommitData if prevLastCommitPath is not null', (done) => { - const getLastCommitDataSpy = jasmine.createSpy('getLastCommitData'); - const oldGetLastCommitData = store._actions.getLastCommitData; // eslint-disable-line - store._actions.getLastCommitData = [getLastCommitDataSpy]; // eslint-disable-line - store.state.prevLastCommitPath = 'test'; - - store.dispatch('getTreeData', basicCallParameters) - .then(() => { - expect(getLastCommitDataSpy).toHaveBeenCalledWith(projectTree); - - store._actions.getLastCommitData = oldGetLastCommitData; // eslint-disable-line - - done(); - }).catch(done.fail); - }); - }); - - describe('toggleTreeOpen', () => { - let oldGetTreeData; - let getTreeDataSpy; - let tree; - - beforeEach(() => { - getTreeDataSpy = jasmine.createSpy('getTreeData'); - - oldGetTreeData = store._actions.getTreeData; // eslint-disable-line - store._actions.getTreeData = [getTreeDataSpy]; // eslint-disable-line - - tree = { - projectId: 'abcproject', - branchId: 'master', - opened: false, - tree: [], - }; - }); - - afterEach(() => { - store._actions.getTreeData = oldGetTreeData; // eslint-disable-line - }); - - it('toggles the tree open', (done) => { - store.dispatch('toggleTreeOpen', { - endpoint: 'test', - tree, - }).then(() => { - expect(tree.opened).toBeTruthy(); - - done(); - }).catch(done.fail); - }); - - it('calls getTreeData if tree is closed', (done) => { - store.dispatch('toggleTreeOpen', { - endpoint: 'test', - tree, - }).then(() => { - expect(getTreeDataSpy).toHaveBeenCalledWith({ - projectId: 'abcproject', - branch: 'master', - endpoint: 'test', - tree, - }); - - done(); - }).catch(done.fail); - }); - - it('resets entries tree', (done) => { - Object.assign(tree, { - opened: true, - tree: ['a'], - }); - - store.dispatch('toggleTreeOpen', { - endpoint: 'test', - tree, - }).then(() => { - expect(tree.tree.length).toBe(0); - - done(); - }).catch(done.fail); - }); - }); - - describe('createTempTree', () => { - beforeEach(() => { - store.state.trees['abcproject/mybranch'] = { - tree: [], - }; - projectTree = store.state.trees['abcproject/mybranch']; - }); - - it('creates temp tree', (done) => { - store.dispatch('createTempTree', { - projectId: store.state.currentProjectId, - branchId: store.state.currentBranchId, - name: 'test', - parent: projectTree, - }) - .then(() => { - expect(projectTree.tree[0].name).toBe('test'); - expect(projectTree.tree[0].type).toBe('tree'); - - done(); - }).catch(done.fail); - }); - - it('creates new folder inside another tree', (done) => { - const tree = { - type: 'tree', - name: 'testing', - tree: [], - }; - - projectTree.tree.push(tree); - - store.dispatch('createTempTree', { - projectId: store.state.currentProjectId, - branchId: store.state.currentBranchId, - name: 'testing/test', - parent: projectTree, - }) - .then(() => { - expect(projectTree.tree[0].name).toBe('testing'); - expect(projectTree.tree[0].tree[0].tempFile).toBeTruthy(); - expect(projectTree.tree[0].tree[0].name).toBe('test'); - expect(projectTree.tree[0].tree[0].type).toBe('tree'); - - done(); - }).catch(done.fail); - }); - - it('does not create new tree if already exists', (done) => { - const tree = { - type: 'tree', - name: 'testing', - endpoint: 'test', - tree: [], - }; - - projectTree.tree.push(tree); - - store.dispatch('createTempTree', { - projectId: store.state.currentProjectId, - branchId: store.state.currentBranchId, - name: 'testing/test', - parent: projectTree, - }) - .then(() => { - expect(projectTree.tree[0].name).toBe('testing'); - expect(projectTree.tree[0].tempFile).toBeUndefined(); - - done(); - }).catch(done.fail); - }); - }); - - describe('getLastCommitData', () => { - beforeEach(() => { - spyOn(service, 'getTreeLastCommit').and.returnValue(Promise.resolve({ - headers: { - 'more-logs-url': null, - }, - json: () => Promise.resolve([{ - type: 'tree', - file_name: 'testing', - commit: { - message: 'commit message', - authored_date: '123', - }, - }]), - })); - - store.state.trees['abcproject/mybranch'] = { - tree: [], - }; - - projectTree = store.state.trees['abcproject/mybranch']; - projectTree.tree.push(file('testing', '1', 'tree')); - projectTree.lastCommitPath = 'lastcommitpath'; - }); - - it('calls service with lastCommitPath', (done) => { - store.dispatch('getLastCommitData', projectTree) - .then(() => { - expect(service.getTreeLastCommit).toHaveBeenCalledWith('lastcommitpath'); - - done(); - }).catch(done.fail); - }); - - it('updates trees last commit data', (done) => { - store.dispatch('getLastCommitData', projectTree) - .then(Vue.nextTick) - .then(() => { - expect(projectTree.tree[0].lastCommit.message).toBe('commit message'); - - done(); - }).catch(done.fail); - }); - - it('does not update entry if not found', (done) => { - projectTree.tree[0].name = 'a'; - - store.dispatch('getLastCommitData', projectTree) - .then(Vue.nextTick) - .then(() => { - expect(projectTree.tree[0].lastCommit.message).not.toBe('commit message'); - - done(); - }).catch(done.fail); - }); - }); - - describe('updateDirectoryData', () => { - it('adds data into tree', (done) => { - const tree = { - tree: [], - }; - const data = { - trees: [{ name: 'tree' }], - submodules: [{ name: 'submodule' }], - blobs: [{ name: 'blob' }], - }; - - store.dispatch('updateDirectoryData', { - data, - tree, - }).then(() => { - expect(tree.tree[0].name).toBe('tree'); - expect(tree.tree[0].type).toBe('tree'); - expect(tree.tree[1].name).toBe('submodule'); - expect(tree.tree[1].type).toBe('submodule'); - expect(tree.tree[2].name).toBe('blob'); - expect(tree.tree[2].type).toBe('blob'); - - done(); - }).catch(done.fail); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/actions_spec.js b/spec/javascripts/repo/stores/actions_spec.js deleted file mode 100644 index f678967b092..00000000000 --- a/spec/javascripts/repo/stores/actions_spec.js +++ /dev/null @@ -1,432 +0,0 @@ -import Vue from 'vue'; -import * as urlUtils from '~/lib/utils/url_utility'; -import store from '~/ide/stores'; -import service from '~/ide/services'; -import { resetStore, file } from '../helpers'; - -describe('Multi-file store actions', () => { - afterEach(() => { - resetStore(store); - }); - - describe('redirectToUrl', () => { - it('calls visitUrl', (done) => { - spyOn(urlUtils, 'visitUrl'); - - store.dispatch('redirectToUrl', 'test') - .then(() => { - expect(urlUtils.visitUrl).toHaveBeenCalledWith('test'); - - done(); - }) - .catch(done.fail); - }); - }); - - describe('setInitialData', () => { - it('commits initial data', (done) => { - store.dispatch('setInitialData', { canCommit: true }) - .then(() => { - expect(store.state.canCommit).toBeTruthy(); - done(); - }) - .catch(done.fail); - }); - }); - - describe('closeDiscardPopup', () => { - it('closes the discard popup', (done) => { - store.dispatch('closeDiscardPopup', false) - .then(() => { - expect(store.state.discardPopupOpen).toBeFalsy(); - - done(); - }) - .catch(done.fail); - }); - }); - - describe('discardAllChanges', () => { - beforeEach(() => { - store.state.openFiles.push(file('discardAll')); - store.state.openFiles[0].changed = true; - }); - }); - - describe('closeAllFiles', () => { - beforeEach(() => { - store.state.openFiles.push(file('closeAll')); - store.state.openFiles[0].opened = true; - }); - - it('closes all open files', (done) => { - store.dispatch('closeAllFiles') - .then(() => { - expect(store.state.openFiles.length).toBe(0); - - done(); - }) - .catch(done.fail); - }); - }); - - 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('discardChanges')); - 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('forceClose')); - 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('discard'); - store.state.editMode = true; - 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', () => { - it('sets edit mode view if in edit mode', (done) => { - 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) => { - store.state.editMode = false; - - store.dispatch('toggleBlobView') - .then(() => { - expect(store.state.currentBlobView).toBe('repo-preview'); - - done(); - }) - .catch(done.fail); - }); - }); - - describe('checkCommitStatus', () => { - beforeEach(() => { - store.state.currentProjectId = 'abcproject'; - store.state.currentBranchId = 'master'; - store.state.projects.abcproject = { - branches: { - master: { - workingReference: '1', - }, - }, - }; - }); - - it('calls service', (done) => { - spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ - data: { - commit: { id: '123' }, - }, - })); - - store.dispatch('checkCommitStatus') - .then(() => { - expect(service.getBranchData).toHaveBeenCalledWith('abcproject', 'master'); - - done(); - }) - .catch(done.fail); - }); - - it('returns true if current ref does not equal returned ID', (done) => { - spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ - data: { - commit: { id: '123' }, - }, - })); - - store.dispatch('checkCommitStatus') - .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({ - data: { - commit: { id: '1' }, - }, - })); - - store.dispatch('checkCommitStatus') - .then((val) => { - expect(val).toBeFalsy(); - - done(); - }) - .catch(done.fail); - }); - }); - - describe('commitChanges', () => { - let payload; - - beforeEach(() => { - spyOn(window, 'scrollTo'); - - document.body.innerHTML += '
'; - - store.state.currentProjectId = 'abcproject'; - store.state.currentBranchId = 'master'; - store.state.projects.abcproject = { - web_url: 'webUrl', - branches: { - master: { - workingReference: '1', - }, - }, - }; - - payload = { - branch: 'master', - }; - }); - - afterEach(() => { - document.querySelector('.flash-container').remove(); - }); - - describe('success', () => { - beforeEach(() => { - spyOn(service, 'commit').and.returnValue(Promise.resolve({ - data: { - 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('abcproject', 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('changed'); - const f = file('newfile'); - 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('scrolls to top of page', (done) => { - store.dispatch('commitChanges', { payload, newMr: false }) - .then(() => { - expect(window.scrollTo).toHaveBeenCalledWith(0, 0); - - done(); - }).catch(done.fail); - }); - - it('redirects to new merge request page', (done) => { - spyOn(urlUtils, 'visitUrl'); - - store.dispatch('commitChanges', { payload, newMr: true }) - .then(() => { - expect(urlUtils.visitUrl).toHaveBeenCalledWith('webUrl/merge_requests/new?merge_request%5Bsource_branch%5D=master'); - - done(); - }).catch(done.fail); - }); - }); - - describe('failed', () => { - beforeEach(() => { - spyOn(service, 'commit').and.returnValue(Promise.resolve({ - data: { - 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', () => { - beforeEach(() => { - store.state.trees['abcproject/mybranch'] = { - tree: [], - }; - store.state.projects.abcproject = { - web_url: '', - }; - }); - - it('creates a temp tree', (done) => { - const projectTree = store.state.trees['abcproject/mybranch']; - - store.dispatch('createTempEntry', { - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - name: 'test', - type: 'tree', - }) - .then(() => { - const baseTree = projectTree.tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].tempFile).toBeTruthy(); - expect(baseTree[0].type).toBe('tree'); - - done(); - }) - .catch(done.fail); - }); - - it('creates temp file', (done) => { - const projectTree = store.state.trees['abcproject/mybranch']; - - store.dispatch('createTempEntry', { - projectId: 'abcproject', - branchId: 'mybranch', - parent: projectTree, - name: 'test', - type: 'blob', - }) - .then(() => { - const baseTree = projectTree.tree; - expect(baseTree.length).toBe(1); - expect(baseTree[0].tempFile).toBeTruthy(); - expect(baseTree[0].type).toBe('blob'); - - done(); - }) - .catch(done.fail); - }); - }); - - describe('popHistoryState', () => { - - }); - - describe('scrollToTab', () => { - it('focuses the current active element', (done) => { - document.body.innerHTML += '
'; - const el = document.querySelector('.repo-tab'); - spyOn(el, 'focus'); - - store.dispatch('scrollToTab') - .then(() => { - setTimeout(() => { - expect(el.focus).toHaveBeenCalled(); - - document.getElementById('tabs').remove(); - - done(); - }); - }) - .catch(done.fail); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/getters_spec.js b/spec/javascripts/repo/stores/getters_spec.js deleted file mode 100644 index d0d5934f29a..00000000000 --- a/spec/javascripts/repo/stores/getters_spec.js +++ /dev/null @@ -1,114 +0,0 @@ -import * as getters from '~/ide/stores/getters'; -import state from '~/ide/stores/state'; -import { file } from '../helpers'; - -describe('Multi-file store getters', () => { - let localState; - - beforeEach(() => { - localState = state(); - }); - - describe('changedFiles', () => { - it('returns a list of changed opened files', () => { - localState.openFiles.push(file()); - localState.openFiles.push(file('changed')); - localState.openFiles[1].changed = true; - - const changedFiles = getters.changedFiles(localState); - - expect(changedFiles.length).toBe(1); - expect(changedFiles[0].name).toBe('changed'); - }); - }); - - describe('activeFile', () => { - it('returns the current active file', () => { - localState.openFiles.push(file()); - localState.openFiles.push(file('active')); - localState.openFiles[1].active = true; - - expect(getters.activeFile(localState).name).toBe('active'); - }); - - it('returns undefined if no active files are found', () => { - localState.openFiles.push(file()); - localState.openFiles.push(file('active')); - - expect(getters.activeFile(localState)).toBeNull(); - }); - }); - - describe('activeFileExtension', () => { - it('returns the file extension for the current active file', () => { - localState.openFiles.push(file('active')); - localState.openFiles[0].active = true; - localState.openFiles[0].path = 'test.js'; - - expect(getters.activeFileExtension(localState)).toBe('.js'); - - localState.openFiles[0].path = 'test.es6.js'; - - expect(getters.activeFileExtension(localState)).toBe('.js'); - }); - }); - - describe('canEditFile', () => { - beforeEach(() => { - localState.onTopOfBranch = true; - localState.canCommit = true; - - localState.openFiles.push(file()); - localState.openFiles[0].active = true; - }); - - it('returns true if user can commit and has open files', () => { - expect(getters.canEditFile(localState)).toBeTruthy(); - }); - - it('returns false if user can commit and has no open files', () => { - localState.openFiles = []; - - expect(getters.canEditFile(localState)).toBeFalsy(); - }); - - it('returns false if user can commit and active file is binary', () => { - localState.openFiles[0].binary = true; - - expect(getters.canEditFile(localState)).toBeFalsy(); - }); - - it('returns false if user cant commit', () => { - localState.canCommit = false; - - expect(getters.canEditFile(localState)).toBeFalsy(); - }); - }); - - describe('modifiedFiles', () => { - it('returns a list of modified files', () => { - localState.openFiles.push(file()); - localState.openFiles.push(file('changed')); - localState.openFiles[1].changed = true; - - const modifiedFiles = getters.modifiedFiles(localState); - - expect(modifiedFiles.length).toBe(1); - expect(modifiedFiles[0].name).toBe('changed'); - }); - }); - - describe('addedFiles', () => { - it('returns a list of added files', () => { - localState.openFiles.push(file()); - localState.openFiles.push(file('added')); - localState.openFiles[1].changed = true; - localState.openFiles[1].tempFile = true; - - const modifiedFiles = getters.addedFiles(localState); - - expect(modifiedFiles.length).toBe(1); - expect(modifiedFiles[0].name).toBe('added'); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/mutations/branch_spec.js b/spec/javascripts/repo/stores/mutations/branch_spec.js deleted file mode 100644 index a7167537ef2..00000000000 --- a/spec/javascripts/repo/stores/mutations/branch_spec.js +++ /dev/null @@ -1,18 +0,0 @@ -import mutations from '~/ide/stores/mutations/branch'; -import state from '~/ide/stores/state'; - -describe('Multi-file store branch mutations', () => { - let localState; - - beforeEach(() => { - localState = state(); - }); - - describe('SET_CURRENT_BRANCH', () => { - it('sets currentBranch', () => { - mutations.SET_CURRENT_BRANCH(localState, 'master'); - - expect(localState.currentBranchId).toBe('master'); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/mutations/file_spec.js b/spec/javascripts/repo/stores/mutations/file_spec.js deleted file mode 100644 index 6e204ef0404..00000000000 --- a/spec/javascripts/repo/stores/mutations/file_spec.js +++ /dev/null @@ -1,131 +0,0 @@ -import mutations from '~/ide/stores/mutations/file'; -import state from '~/ide/stores/state'; -import { file } from '../../helpers'; - -describe('Multi-file store file mutations', () => { - let localState; - let localFile; - - beforeEach(() => { - localState = state(); - localFile = file(); - }); - - describe('SET_FILE_ACTIVE', () => { - it('sets the file active', () => { - mutations.SET_FILE_ACTIVE(localState, { - file: localFile, - active: true, - }); - - expect(localFile.active).toBeTruthy(); - }); - }); - - describe('TOGGLE_FILE_OPEN', () => { - beforeEach(() => { - mutations.TOGGLE_FILE_OPEN(localState, localFile); - }); - - it('adds into opened files', () => { - expect(localFile.opened).toBeTruthy(); - expect(localState.openFiles.length).toBe(1); - }); - - it('removes from opened files', () => { - mutations.TOGGLE_FILE_OPEN(localState, localFile); - - expect(localFile.opened).toBeFalsy(); - expect(localState.openFiles.length).toBe(0); - }); - }); - - describe('SET_FILE_DATA', () => { - it('sets extra file data', () => { - mutations.SET_FILE_DATA(localState, { - data: { - blame_path: 'blame', - commits_path: 'commits', - permalink: 'permalink', - raw_path: 'raw', - binary: true, - html: 'html', - render_error: 'render_error', - }, - file: localFile, - }); - - expect(localFile.blamePath).toBe('blame'); - expect(localFile.commitsPath).toBe('commits'); - expect(localFile.permalink).toBe('permalink'); - expect(localFile.rawPath).toBe('raw'); - expect(localFile.binary).toBeTruthy(); - expect(localFile.html).toBe('html'); - expect(localFile.renderError).toBe('render_error'); - }); - }); - - describe('SET_FILE_RAW_DATA', () => { - it('sets raw data', () => { - mutations.SET_FILE_RAW_DATA(localState, { - file: localFile, - raw: 'testing', - }); - - expect(localFile.raw).toBe('testing'); - }); - }); - - describe('UPDATE_FILE_CONTENT', () => { - beforeEach(() => { - localFile.raw = 'test'; - }); - - it('sets content', () => { - mutations.UPDATE_FILE_CONTENT(localState, { - file: localFile, - content: 'test', - }); - - expect(localFile.content).toBe('test'); - }); - - it('sets changed if content does not match raw', () => { - mutations.UPDATE_FILE_CONTENT(localState, { - file: localFile, - content: 'testing', - }); - - expect(localFile.content).toBe('testing'); - expect(localFile.changed).toBeTruthy(); - }); - }); - - describe('DISCARD_FILE_CHANGES', () => { - beforeEach(() => { - localFile.content = 'test'; - localFile.changed = true; - }); - - it('resets content and changed', () => { - mutations.DISCARD_FILE_CHANGES(localState, localFile); - - expect(localFile.content).toBe(''); - expect(localFile.changed).toBeFalsy(); - }); - }); - - describe('CREATE_TMP_FILE', () => { - it('adds file into parent tree', () => { - const f = file('tmpFile'); - - mutations.CREATE_TMP_FILE(localState, { - file: f, - parent: localFile, - }); - - expect(localFile.tree.length).toBe(1); - expect(localFile.tree[0].name).toBe(f.name); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/mutations/tree_spec.js b/spec/javascripts/repo/stores/mutations/tree_spec.js deleted file mode 100644 index e6ca8ea139e..00000000000 --- a/spec/javascripts/repo/stores/mutations/tree_spec.js +++ /dev/null @@ -1,71 +0,0 @@ -import mutations from '~/ide/stores/mutations/tree'; -import state from '~/ide/stores/state'; -import { file } from '../../helpers'; - -describe('Multi-file store tree mutations', () => { - let localState; - let localTree; - - beforeEach(() => { - localState = state(); - localTree = file(); - }); - - describe('TOGGLE_TREE_OPEN', () => { - it('toggles tree open', () => { - mutations.TOGGLE_TREE_OPEN(localState, localTree); - - expect(localTree.opened).toBeTruthy(); - - mutations.TOGGLE_TREE_OPEN(localState, localTree); - - expect(localTree.opened).toBeFalsy(); - }); - }); - - describe('SET_DIRECTORY_DATA', () => { - const data = [{ - name: 'tree', - }, - { - name: 'submodule', - }, - { - name: 'blob', - }]; - - it('adds directory data', () => { - mutations.SET_DIRECTORY_DATA(localState, { - data, - tree: localState, - }); - - expect(localState.tree.length).toBe(3); - expect(localState.tree[0].name).toBe('tree'); - expect(localState.tree[1].name).toBe('submodule'); - expect(localState.tree[2].name).toBe('blob'); - }); - }); - - describe('SET_PARENT_TREE_URL', () => { - it('sets the parent tree url', () => { - mutations.SET_PARENT_TREE_URL(localState, 'test'); - - expect(localState.parentTreeUrl).toBe('test'); - }); - }); - - describe('CREATE_TMP_TREE', () => { - it('adds tree into parent tree', () => { - const tmpEntry = file('tmpTree'); - - mutations.CREATE_TMP_TREE(localState, { - tmpEntry, - parent: localTree, - }); - - expect(localTree.tree.length).toBe(1); - expect(localTree.tree[0].name).toBe(tmpEntry.name); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/mutations_spec.js b/spec/javascripts/repo/stores/mutations_spec.js deleted file mode 100644 index 5fd8ad94972..00000000000 --- a/spec/javascripts/repo/stores/mutations_spec.js +++ /dev/null @@ -1,125 +0,0 @@ -import mutations from '~/ide/stores/mutations'; -import state from '~/ide/stores/state'; -import { file } from '../helpers'; - -describe('Multi-file store mutations', () => { - let localState; - let entry; - - beforeEach(() => { - localState = state(); - entry = file(); - }); - - describe('SET_INITIAL_DATA', () => { - it('sets all initial data', () => { - mutations.SET_INITIAL_DATA(localState, { - test: 'test', - }); - - expect(localState.test).toBe('test'); - }); - }); - - describe('SET_PREVIEW_MODE', () => { - it('sets currentBlobView to repo-preview', () => { - mutations.SET_PREVIEW_MODE(localState); - - expect(localState.currentBlobView).toBe('repo-preview'); - - localState.currentBlobView = 'testing'; - - mutations.SET_PREVIEW_MODE(localState); - - expect(localState.currentBlobView).toBe('repo-preview'); - }); - }); - - describe('SET_EDIT_MODE', () => { - it('sets currentBlobView to repo-editor', () => { - mutations.SET_EDIT_MODE(localState); - - expect(localState.currentBlobView).toBe('repo-editor'); - - localState.currentBlobView = 'testing'; - - mutations.SET_EDIT_MODE(localState); - - expect(localState.currentBlobView).toBe('repo-editor'); - }); - }); - - describe('TOGGLE_LOADING', () => { - it('toggles loading of entry', () => { - mutations.TOGGLE_LOADING(localState, entry); - - expect(entry.loading).toBeTruthy(); - - mutations.TOGGLE_LOADING(localState, entry); - - expect(entry.loading).toBeFalsy(); - }); - }); - - describe('TOGGLE_EDIT_MODE', () => { - it('toggles editMode', () => { - mutations.TOGGLE_EDIT_MODE(localState); - - expect(localState.editMode).toBeFalsy(); - - mutations.TOGGLE_EDIT_MODE(localState); - - expect(localState.editMode).toBeTruthy(); - }); - }); - - describe('TOGGLE_DISCARD_POPUP', () => { - it('sets discardPopupOpen', () => { - mutations.TOGGLE_DISCARD_POPUP(localState, true); - - expect(localState.discardPopupOpen).toBeTruthy(); - - mutations.TOGGLE_DISCARD_POPUP(localState, false); - - expect(localState.discardPopupOpen).toBeFalsy(); - }); - }); - - describe('SET_ROOT', () => { - it('sets isRoot & initialRoot', () => { - mutations.SET_ROOT(localState, true); - - expect(localState.isRoot).toBeTruthy(); - expect(localState.isInitialRoot).toBeTruthy(); - - mutations.SET_ROOT(localState, false); - - expect(localState.isRoot).toBeFalsy(); - expect(localState.isInitialRoot).toBeFalsy(); - }); - }); - - describe('SET_LEFT_PANEL_COLLAPSED', () => { - it('sets left panel collapsed', () => { - mutations.SET_LEFT_PANEL_COLLAPSED(localState, true); - - expect(localState.leftPanelCollapsed).toBeTruthy(); - - mutations.SET_LEFT_PANEL_COLLAPSED(localState, false); - - expect(localState.leftPanelCollapsed).toBeFalsy(); - }); - }); - - describe('SET_RIGHT_PANEL_COLLAPSED', () => { - it('sets right panel collapsed', () => { - mutations.SET_RIGHT_PANEL_COLLAPSED(localState, true); - - expect(localState.rightPanelCollapsed).toBeTruthy(); - - mutations.SET_RIGHT_PANEL_COLLAPSED(localState, false); - - expect(localState.rightPanelCollapsed).toBeFalsy(); - }); - }); -}); diff --git a/spec/javascripts/repo/stores/utils_spec.js b/spec/javascripts/repo/stores/utils_spec.js deleted file mode 100644 index 89745a2029e..00000000000 --- a/spec/javascripts/repo/stores/utils_spec.js +++ /dev/null @@ -1,119 +0,0 @@ -import * as utils from '~/ide/stores/utils'; -import state from '~/ide/stores/state'; -import { file } from '../helpers'; - -describe('Multi-file store utils', () => { - describe('setPageTitle', () => { - it('sets the document page title', () => { - utils.setPageTitle('test'); - - expect(document.title).toBe('test'); - }); - }); - - describe('treeList', () => { - let localState; - - beforeEach(() => { - localState = state(); - }); - - it('returns flat tree list', () => { - localState.trees = []; - localState.trees['abcproject/mybranch'] = { - tree: [], - }; - const baseTree = localState.trees['abcproject/mybranch'].tree; - baseTree.push(file('1')); - baseTree[0].tree.push(file('2')); - baseTree[0].tree[0].tree.push(file('3')); - - const treeList = utils.treeList(localState, 'abcproject/mybranch'); - - expect(treeList.length).toBe(3); - expect(treeList[1].name).toBe(baseTree[0].tree[0].name); - expect(treeList[2].name).toBe(baseTree[0].tree[0].tree[0].name); - }); - }); - - describe('createTemp', () => { - it('creates temp tree', () => { - const tmp = utils.createTemp({ - name: 'test', - path: 'test', - type: 'tree', - level: 0, - changed: false, - content: '', - base64: '', - }); - - expect(tmp.tempFile).toBeTruthy(); - expect(tmp.icon).toBe('fa-folder'); - }); - - it('creates temp file', () => { - const tmp = utils.createTemp({ - name: 'test', - path: 'test', - type: 'blob', - level: 0, - changed: false, - content: '', - base64: '', - }); - - expect(tmp.tempFile).toBeTruthy(); - expect(tmp.icon).toBe('fa-file-text-o'); - }); - }); - - describe('findIndexOfFile', () => { - let localState; - - beforeEach(() => { - localState = [{ - path: '1', - }, { - path: '2', - }]; - }); - - it('finds in the index of an entry by path', () => { - const index = utils.findIndexOfFile(localState, { - path: '2', - }); - - expect(index).toBe(1); - }); - }); - - describe('findEntry', () => { - let localState; - - beforeEach(() => { - localState = { - tree: [{ - type: 'tree', - name: 'test', - }, { - type: 'blob', - name: 'file', - }], - }; - }); - - it('returns an entry found by name', () => { - const foundEntry = utils.findEntry(localState.tree, 'tree', 'test'); - - expect(foundEntry.type).toBe('tree'); - expect(foundEntry.name).toBe('test'); - }); - - it('returns undefined when no entry found', () => { - const foundEntry = utils.findEntry(localState.tree, 'blob', 'test'); - - expect(foundEntry).toBeUndefined(); - }); - }); -});