summaryrefslogtreecommitdiff
path: root/spec/javascripts/repo/components
diff options
context:
space:
mode:
authorMike Greiling <mike@pixelcog.com>2017-10-29 20:51:34 -0500
committerMike Greiling <mike@pixelcog.com>2017-10-29 20:51:34 -0500
commit6a92dff2bc368aa362a0e239f9fcf953ad4e9e52 (patch)
tree458a7621335bf04895223cd9789729d0e3e68a13 /spec/javascripts/repo/components
parent40ee89bc7da8b1c0500f2358d2548f2395bc2323 (diff)
parent1aae91cf24606275834d6e17279ce14c1074dade (diff)
downloadgitlab-ce-6a92dff2bc368aa362a0e239f9fcf953ad4e9e52.tar.gz
Merge branch 'master' into sh-headless-chrome-support
* master: (96 commits) Fetch the merged branches at once Merging EE doc into CE Avoid using Rugged in Gitlab::Git::Wiki#preview_slug Cache commits on the repository model Remove groups_select from global namespace & simplifies the code Change default disabled merge request widget message to "Merge is not allowed yet" Semi-linear history merge is now available in CE. Remove repetitive karma spec Improve spec to check hidden component Rename to shouldShowUsername Add KubernetesService#default_namespace tests Revert "Merge branch '36670-remove-edit-form' into 'master'" Fix bitbucket login Remove duped tests Add path attribute to WikiFile class Make local_branches OPT_OUT Clarify the language around External Group membership with SAML SSO to clarify that this will NOT add users to GitLab Groups. Added ssh fingerprint, gitlab ci and pages information in an instance configuration page Fix the incorrect value being used to set GL_USERNAME on hooks Resolve "Remove overzealous tooltips in projects page tabs" ...
Diffstat (limited to 'spec/javascripts/repo/components')
-rw-r--r--spec/javascripts/repo/components/new_branch_form_spec.js122
-rw-r--r--spec/javascripts/repo/components/new_dropdown/index_spec.js191
-rw-r--r--spec/javascripts/repo/components/new_dropdown/modal_spec.js76
-rw-r--r--spec/javascripts/repo/components/repo_file_buttons_spec.js27
-rw-r--r--spec/javascripts/repo/components/repo_file_spec.js1
-rw-r--r--spec/javascripts/repo/components/repo_spec.js96
6 files changed, 496 insertions, 17 deletions
diff --git a/spec/javascripts/repo/components/new_branch_form_spec.js b/spec/javascripts/repo/components/new_branch_form_spec.js
new file mode 100644
index 00000000000..c9c5ce096fc
--- /dev/null
+++ b/spec/javascripts/repo/components/new_branch_form_spec.js
@@ -0,0 +1,122 @@
+import Vue from 'vue';
+import newBranchForm from '~/repo/components/new_branch_form.vue';
+import eventHub from '~/repo/event_hub';
+import RepoStore from '~/repo/stores/repo_store';
+import createComponent from '../../helpers/vue_mount_component_helper';
+
+describe('Multi-file editor new branch form', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(newBranchForm);
+
+ RepoStore.currentBranch = 'master';
+
+ vm = createComponent(Component, {
+ currentBranch: RepoStore.currentBranch,
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ RepoStore.currentBranch = '';
+ });
+
+ 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', () => {
+ it('sets to loading', () => {
+ vm.submitNewBranch();
+
+ expect(vm.loading).toBeTruthy();
+ });
+
+ it('hides current flash element', (done) => {
+ vm.$refs.flashContainer.innerHTML = '<div class="flash-alert"></div>';
+
+ vm.submitNewBranch();
+
+ Vue.nextTick(() => {
+ expect(vm.$el.querySelector('.flash-alert')).toBeNull();
+
+ done();
+ });
+ });
+
+ it('emits an event with branchName', () => {
+ spyOn(eventHub, '$emit');
+
+ vm.branchName = 'testing';
+
+ vm.submitNewBranch();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('createNewBranch', 'testing');
+ });
+ });
+
+ describe('showErrorMessage', () => {
+ it('sets loading to false', () => {
+ vm.loading = true;
+
+ vm.showErrorMessage();
+
+ expect(vm.loading).toBeFalsy();
+ });
+
+ it('creates flash element', () => {
+ vm.showErrorMessage('error message');
+
+ expect(vm.$el.querySelector('.flash-alert')).not.toBeNull();
+ expect(vm.$el.querySelector('.flash-alert').textContent.trim()).toBe('error message');
+ });
+ });
+
+ describe('createdNewBranch', () => {
+ it('set loading to false', () => {
+ vm.loading = true;
+
+ vm.createdNewBranch();
+
+ expect(vm.loading).toBeFalsy();
+ });
+
+ it('resets branch name', () => {
+ vm.branchName = 'testing';
+
+ vm.createdNewBranch();
+
+ expect(vm.branchName).toBe('');
+ });
+
+ it('sets the dropdown toggle text', () => {
+ vm.dropdownText = document.createElement('span');
+
+ vm.createdNewBranch('branch name');
+
+ expect(vm.dropdownText.textContent).toBe('branch name');
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/new_dropdown/index_spec.js b/spec/javascripts/repo/components/new_dropdown/index_spec.js
new file mode 100644
index 00000000000..ddbfdab582d
--- /dev/null
+++ b/spec/javascripts/repo/components/new_dropdown/index_spec.js
@@ -0,0 +1,191 @@
+import Vue from 'vue';
+import newDropdown from '~/repo/components/new_dropdown/index.vue';
+import RepoStore from '~/repo/stores/repo_store';
+import RepoHelper from '~/repo/helpers/repo_helper';
+import eventHub from '~/repo/event_hub';
+import createComponent from '../../../helpers/vue_mount_component_helper';
+
+describe('new dropdown component', () => {
+ let vm;
+
+ beforeEach(() => {
+ const component = Vue.extend(newDropdown);
+
+ vm = createComponent(component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ RepoStore.files = [];
+ RepoStore.openedFiles = [];
+ RepoStore.setViewToPreview();
+ });
+
+ it('renders new file and new directory links', () => {
+ expect(vm.$el.querySelectorAll('a')[0].textContent.trim()).toBe('New file');
+ expect(vm.$el.querySelectorAll('a')[1].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')[1].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('toggleModalOpen', () => {
+ it('closes modal after toggling', (done) => {
+ vm.toggleModalOpen();
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.modal')).not.toBeNull();
+ })
+ .then(vm.toggleModalOpen)
+ .then(() => {
+ expect(vm.$el.querySelector('.modal')).toBeNull();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('createEntryInStore', () => {
+ ['tree', 'blob'].forEach((type) => {
+ describe(type, () => {
+ it('closes modal after creating file', () => {
+ vm.openModal = true;
+
+ eventHub.$emit('createNewEntry', 'testing', type);
+
+ expect(vm.openModal).toBeFalsy();
+ });
+
+ it('sets editMode to true', () => {
+ eventHub.$emit('createNewEntry', 'testing', type);
+
+ expect(RepoStore.editMode).toBeTruthy();
+ });
+
+ it('toggles blob view', () => {
+ eventHub.$emit('createNewEntry', 'testing', type);
+
+ expect(RepoStore.isPreviewView()).toBeFalsy();
+ });
+
+ it('adds file into activeFiles', () => {
+ eventHub.$emit('createNewEntry', 'testing', type);
+
+ expect(RepoStore.openedFiles.length).toBe(1);
+ });
+
+ it(`creates ${type} in the current stores path`, () => {
+ RepoStore.path = 'testing';
+
+ eventHub.$emit('createNewEntry', 'testing/app', type);
+
+ expect(RepoStore.files[0].path).toBe('testing/app');
+ expect(RepoStore.files[0].name).toBe('app');
+
+ if (type === 'tree') {
+ expect(RepoStore.files[0].files.length).toBe(1);
+ }
+
+ RepoStore.path = '';
+ });
+ });
+ });
+
+ describe('file', () => {
+ it('creates new file', () => {
+ eventHub.$emit('createNewEntry', 'testing', 'blob');
+
+ expect(RepoStore.files.length).toBe(1);
+ expect(RepoStore.files[0].name).toBe('testing');
+ expect(RepoStore.files[0].type).toBe('blob');
+ expect(RepoStore.files[0].tempFile).toBeTruthy();
+ });
+
+ it('does not create temp file when file already exists', () => {
+ RepoStore.files.push(RepoHelper.serializeRepoEntity('blob', {
+ name: 'testing',
+ }));
+
+ eventHub.$emit('createNewEntry', 'testing', 'blob');
+
+ expect(RepoStore.files.length).toBe(1);
+ expect(RepoStore.files[0].name).toBe('testing');
+ expect(RepoStore.files[0].type).toBe('blob');
+ expect(RepoStore.files[0].tempFile).toBeUndefined();
+ });
+ });
+
+ describe('tree', () => {
+ it('creates new tree', () => {
+ eventHub.$emit('createNewEntry', 'testing', 'tree');
+
+ expect(RepoStore.files.length).toBe(1);
+ expect(RepoStore.files[0].name).toBe('testing');
+ expect(RepoStore.files[0].type).toBe('tree');
+ expect(RepoStore.files[0].tempFile).toBeTruthy();
+ expect(RepoStore.files[0].files.length).toBe(1);
+ expect(RepoStore.files[0].files[0].name).toBe('.gitkeep');
+ });
+
+ it('creates multiple trees when entryName has slashes', () => {
+ eventHub.$emit('createNewEntry', 'app/test', 'tree');
+
+ expect(RepoStore.files.length).toBe(1);
+ expect(RepoStore.files[0].name).toBe('app');
+ expect(RepoStore.files[0].files[0].name).toBe('test');
+ expect(RepoStore.files[0].files[0].files[0].name).toBe('.gitkeep');
+ });
+
+ it('creates tree in existing tree', () => {
+ RepoStore.files.push(RepoHelper.serializeRepoEntity('tree', {
+ name: 'app',
+ }));
+
+ eventHub.$emit('createNewEntry', 'app/test', 'tree');
+
+ expect(RepoStore.files.length).toBe(1);
+ expect(RepoStore.files[0].name).toBe('app');
+ expect(RepoStore.files[0].tempFile).toBeUndefined();
+ expect(RepoStore.files[0].files[0].tempFile).toBeTruthy();
+ expect(RepoStore.files[0].files[0].name).toBe('test');
+ expect(RepoStore.files[0].files[0].files[0].name).toBe('.gitkeep');
+ });
+
+ it('does not create new tree when already exists', () => {
+ RepoStore.files.push(RepoHelper.serializeRepoEntity('tree', {
+ name: 'app',
+ }));
+
+ eventHub.$emit('createNewEntry', 'app', 'tree');
+
+ expect(RepoStore.files.length).toBe(1);
+ expect(RepoStore.files[0].name).toBe('app');
+ expect(RepoStore.files[0].tempFile).toBeUndefined();
+ expect(RepoStore.files[0].files.length).toBe(0);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/new_dropdown/modal_spec.js b/spec/javascripts/repo/components/new_dropdown/modal_spec.js
new file mode 100644
index 00000000000..4c5cdc47c6e
--- /dev/null
+++ b/spec/javascripts/repo/components/new_dropdown/modal_spec.js
@@ -0,0 +1,76 @@
+import Vue from 'vue';
+import RepoStore from '~/repo/stores/repo_store';
+import modal from '~/repo/components/new_dropdown/modal.vue';
+import eventHub from '~/repo/event_hub';
+import createComponent from '../../../helpers/vue_mount_component_helper';
+
+describe('new file modal component', () => {
+ const Component = Vue.extend(modal);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+
+ RepoStore.files = [];
+ RepoStore.openedFiles = [];
+ RepoStore.setViewToPreview();
+ });
+
+ ['tree', 'blob'].forEach((type) => {
+ describe(type, () => {
+ beforeEach(() => {
+ vm = createComponent(Component, {
+ type,
+ currentPath: RepoStore.path,
+ });
+ });
+
+ 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`);
+ });
+ });
+ });
+
+ it('focuses field on mount', () => {
+ document.body.innerHTML += '<div class="js-test"></div>';
+
+ vm = createComponent(Component, {
+ type: 'tree',
+ currentPath: RepoStore.path,
+ }, '.js-test');
+
+ expect(document.activeElement).toBe(vm.$refs.fieldName);
+
+ vm.$el.remove();
+ });
+
+ describe('createEntryInStore', () => {
+ it('emits createNewEntry event', () => {
+ spyOn(eventHub, '$emit');
+
+ vm = createComponent(Component, {
+ type: 'tree',
+ currentPath: RepoStore.path,
+ });
+ vm.entryName = 'testing';
+
+ vm.createEntryInStore();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith('createNewEntry', 'testing', 'tree');
+ });
+ });
+});
diff --git a/spec/javascripts/repo/components/repo_file_buttons_spec.js b/spec/javascripts/repo/components/repo_file_buttons_spec.js
index 701c260224f..111c83ee50d 100644
--- a/spec/javascripts/repo/components/repo_file_buttons_spec.js
+++ b/spec/javascripts/repo/components/repo_file_buttons_spec.js
@@ -3,6 +3,15 @@ import repoFileButtons from '~/repo/components/repo_file_buttons.vue';
import RepoStore from '~/repo/stores/repo_store';
describe('RepoFileButtons', () => {
+ const activeFile = {
+ extension: 'md',
+ url: 'url',
+ raw_path: 'raw_path',
+ blame_path: 'blame_path',
+ commits_path: 'commits_path',
+ permalink: 'permalink',
+ };
+
function createComponent() {
const RepoFileButtons = Vue.extend(repoFileButtons);
@@ -14,14 +23,6 @@ describe('RepoFileButtons', () => {
});
it('renders Raw, Blame, History, Permalink and Preview toggle', () => {
- const activeFile = {
- extension: 'md',
- url: 'url',
- raw_path: 'raw_path',
- blame_path: 'blame_path',
- commits_path: 'commits_path',
- permalink: 'permalink',
- };
const activeFileLabel = 'activeFileLabel';
RepoStore.openedFiles = new Array(1);
RepoStore.activeFile = activeFile;
@@ -34,7 +35,6 @@ describe('RepoFileButtons', () => {
const blame = vm.$el.querySelector('.blame');
const history = vm.$el.querySelector('.history');
- expect(vm.$el.id).toEqual('repo-file-buttons');
expect(raw.href).toMatch(`/${activeFile.raw_path}`);
expect(raw.textContent.trim()).toEqual('Raw');
expect(blame.href).toMatch(`/${activeFile.blame_path}`);
@@ -46,10 +46,6 @@ describe('RepoFileButtons', () => {
});
it('triggers rawPreviewToggle on preview click', () => {
- const activeFile = {
- extension: 'md',
- url: 'url',
- };
RepoStore.openedFiles = new Array(1);
RepoStore.activeFile = activeFile;
RepoStore.editMode = true;
@@ -65,10 +61,7 @@ describe('RepoFileButtons', () => {
});
it('does not render preview toggle if not canPreview', () => {
- const activeFile = {
- extension: 'abcd',
- url: 'url',
- };
+ activeFile.extension = 'js';
RepoStore.openedFiles = new Array(1);
RepoStore.activeFile = activeFile;
diff --git a/spec/javascripts/repo/components/repo_file_spec.js b/spec/javascripts/repo/components/repo_file_spec.js
index 107f6797f8a..8403df9be64 100644
--- a/spec/javascripts/repo/components/repo_file_spec.js
+++ b/spec/javascripts/repo/components/repo_file_spec.js
@@ -7,6 +7,7 @@ import { file } from '../mock_data';
describe('RepoFile', () => {
const updated = 'updated';
const otherFile = {
+ id: 'test',
html: '<p class="file-content">html</p>',
pageTitle: 'otherpageTitle',
};
diff --git a/spec/javascripts/repo/components/repo_spec.js b/spec/javascripts/repo/components/repo_spec.js
new file mode 100644
index 00000000000..3558a155728
--- /dev/null
+++ b/spec/javascripts/repo/components/repo_spec.js
@@ -0,0 +1,96 @@
+import Vue from 'vue';
+import repo from '~/repo/components/repo.vue';
+import RepoStore from '~/repo/stores/repo_store';
+import Service from '~/repo/services/repo_service';
+import eventHub from '~/repo/event_hub';
+import createComponent from '../../helpers/vue_mount_component_helper';
+
+describe('repo component', () => {
+ let vm;
+
+ beforeEach(() => {
+ const Component = Vue.extend(repo);
+
+ RepoStore.currentBranch = 'master';
+
+ vm = createComponent(Component);
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+
+ RepoStore.currentBranch = '';
+ });
+
+ describe('createNewBranch', () => {
+ beforeEach(() => {
+ spyOn(history, 'pushState');
+ });
+
+ describe('success', () => {
+ beforeEach(() => {
+ spyOn(Service, 'createBranch').and.returnValue(Promise.resolve({
+ data: {
+ name: 'test',
+ },
+ }));
+ });
+
+ it('calls createBranch with branchName', () => {
+ eventHub.$emit('createNewBranch', 'test');
+
+ expect(Service.createBranch).toHaveBeenCalledWith({
+ branch: 'test',
+ ref: RepoStore.currentBranch,
+ });
+ });
+
+ it('pushes new history state', (done) => {
+ RepoStore.currentBranch = 'master';
+
+ spyOn(vm, 'getCurrentLocation').and.returnValue('http://test.com/master');
+
+ eventHub.$emit('createNewBranch', 'test');
+
+ setTimeout(() => {
+ expect(history.pushState).toHaveBeenCalledWith(jasmine.anything(), '', 'http://test.com/test');
+ done();
+ });
+ });
+
+ it('updates stores currentBranch', (done) => {
+ eventHub.$emit('createNewBranch', 'test');
+
+ setTimeout(() => {
+ expect(RepoStore.currentBranch).toBe('test');
+
+ done();
+ });
+ });
+ });
+
+ describe('failure', () => {
+ beforeEach(() => {
+ spyOn(Service, 'createBranch').and.returnValue(Promise.reject({
+ response: {
+ data: {
+ message: 'test',
+ },
+ },
+ }));
+ });
+
+ it('emits createNewBranchError event', (done) => {
+ spyOn(eventHub, '$emit').and.callThrough();
+
+ eventHub.$emit('createNewBranch', 'test');
+
+ setTimeout(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('createNewBranchError', 'test');
+
+ done();
+ });
+ });
+ });
+ });
+});