Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-08-30 12:43:41 +0300
committerPhil Hughes <me@iamphill.com>2018-09-07 10:24:01 +0300
commit5b84c2fbc270a0072ddf067742ab268926eb087e (patch)
tree7420e57370e2f338a3067708af43cd9f556829b2
parentd6410a0335d70cfdc3ed95275a491973d3961f0d (diff)
added component specs
-rw-r--r--app/assets/javascripts/ide/components/file_templates/bar.vue25
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/modal.vue8
-rw-r--r--app/assets/javascripts/ide/stores/index.js2
-rw-r--r--app/assets/javascripts/ide/stores/modules/file_templates/index.js4
-rw-r--r--app/assets/stylesheets/page_bundles/ide.scss10
-rw-r--r--spec/javascripts/ide/components/file_templates/bar_spec.js115
-rw-r--r--spec/javascripts/ide/components/file_templates/dropdown_spec.js201
-rw-r--r--spec/javascripts/ide/helpers.js2
8 files changed, 345 insertions, 22 deletions
diff --git a/app/assets/javascripts/ide/components/file_templates/bar.vue b/app/assets/javascripts/ide/components/file_templates/bar.vue
index 055eeadb3f7..db1a4138d05 100644
--- a/app/assets/javascripts/ide/components/file_templates/bar.vue
+++ b/app/assets/javascripts/ide/components/file_templates/bar.vue
@@ -15,9 +15,7 @@ export default {
},
},
watch: {
- activeFile: {
- handler: 'setInitialType',
- },
+ activeFile: 'setInitialType',
},
mounted() {
this.setInitialType();
@@ -38,9 +36,12 @@ export default {
selectTemplateType(type) {
this.setSelectedTemplateType(type);
},
- selecteTemplate(template) {
+ selectTemplate(template) {
this.fetchTemplate(template);
},
+ undo() {
+ this.undoFileTemplate();
+ },
},
};
</script>
@@ -63,29 +64,17 @@ export default {
:searchable="true"
:title="__('File templates')"
class="mr-2"
- @click="selecteTemplate"
+ @click="selectTemplate"
/>
<transition name="fade">
<button
v-show="updateSuccess"
type="button"
class="btn btn-default"
- @click="undoFileTemplate"
+ @click="undo"
>
{{ __('Undo') }}
</button>
</transition>
</div>
</template>
-
-<style>
-.ide-file-templates {
- padding: 8px 16px;
- background-color: #fafafa;
- border-bottom: 1px solid #eaeaea;
-}
-
-.ide-file-templates .dropdown {
- min-width: 180px;
-}
-</style>
diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
index c6fa5eb3246..bcd53ac1ba2 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
@@ -51,6 +51,9 @@ export default {
return __('Create file');
},
+ isCreatingNew() {
+ return this.entryModal.type !== modalTypes.rename;
+ },
},
methods: {
...mapActions(['createTempEntry', 'renameEntry']),
@@ -110,7 +113,10 @@ export default {
class="form-control"
placeholder="/dir/file_name"
/>
- <ul class="prepend-top-default list-inline">
+ <ul
+ v-if="isCreatingNew"
+ class="prepend-top-default list-inline"
+ >
<li
v-for="(template, index) in templateTypes"
:key="index"
diff --git a/app/assets/javascripts/ide/stores/index.js b/app/assets/javascripts/ide/stores/index.js
index 3af39ce62fd..877d88bb060 100644
--- a/app/assets/javascripts/ide/stores/index.js
+++ b/app/assets/javascripts/ide/stores/index.js
@@ -23,7 +23,7 @@ export const createStore = () =>
pipelines,
mergeRequests,
branches,
- fileTemplates,
+ fileTemplates: fileTemplates(),
},
});
diff --git a/app/assets/javascripts/ide/stores/modules/file_templates/index.js b/app/assets/javascripts/ide/stores/modules/file_templates/index.js
index dfa5ef54413..383ff5db392 100644
--- a/app/assets/javascripts/ide/stores/modules/file_templates/index.js
+++ b/app/assets/javascripts/ide/stores/modules/file_templates/index.js
@@ -3,10 +3,10 @@ import * as actions from './actions';
import * as getters from './getters';
import mutations from './mutations';
-export default {
+export default () => ({
namespaced: true,
actions,
state: createState(),
getters,
mutations,
-};
+});
diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss
index 5ff4e487d04..1d1c614ef8d 100644
--- a/app/assets/stylesheets/page_bundles/ide.scss
+++ b/app/assets/stylesheets/page_bundles/ide.scss
@@ -1442,3 +1442,13 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding;
top: 50%;
transform: translateY(-50%);
}
+
+.ide-file-templates {
+ padding: $grid-size $gl-padding;
+ background-color: $gray-light;
+ border-bottom: 1px solid $white-dark;
+
+ .dropdown {
+ min-width: 180px;
+ }
+}
diff --git a/spec/javascripts/ide/components/file_templates/bar_spec.js b/spec/javascripts/ide/components/file_templates/bar_spec.js
new file mode 100644
index 00000000000..ceafedbf9d7
--- /dev/null
+++ b/spec/javascripts/ide/components/file_templates/bar_spec.js
@@ -0,0 +1,115 @@
+import Vue from 'vue';
+import { createStore } from '~/ide/stores';
+import Bar from '~/ide/components/file_templates/bar.vue';
+import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { resetStore, file } from '../../helpers';
+
+describe('IDE file templates bar component', () => {
+ let Component;
+ let vm;
+
+ beforeAll(() => {
+ Component = Vue.extend(Bar);
+ });
+
+ beforeEach(() => {
+ const store = createStore();
+
+ store.state.openFiles.push({
+ ...file('file'),
+ opened: true,
+ active: true,
+ });
+
+ vm = createComponentWithStore(Component, store).$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ resetStore(vm.$store);
+ });
+
+ describe('template type dropdown', () => {
+ it('renders dropdown component', () => {
+ expect(vm.$el.querySelector('.dropdown').textContent).toContain('Choose a type');
+ });
+
+ it('calls setSelectedTemplateType when clicking item', () => {
+ spyOn(vm, 'setSelectedTemplateType');
+
+ vm.$el.querySelector('.dropdown-content button').click();
+
+ expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({
+ name: '.gitlab-ci.yml',
+ key: 'gitlab_ci_ymls',
+ });
+ });
+ });
+
+ describe('template dropdown', () => {
+ beforeEach(done => {
+ vm.$store.state.fileTemplates.templates = [
+ {
+ name: 'test',
+ },
+ ];
+ vm.$store.state.fileTemplates.selectedTemplateType = {
+ name: '.gitlab-ci.yml',
+ key: 'gitlab_ci_ymls',
+ };
+
+ vm.$nextTick(done);
+ });
+
+ it('renders dropdown component', () => {
+ expect(vm.$el.querySelectorAll('.dropdown')[1].textContent).toContain('Choose a template');
+ });
+
+ it('calls fetchTemplate on click', () => {
+ spyOn(vm, 'fetchTemplate');
+
+ vm.$el
+ .querySelectorAll('.dropdown-content')[1]
+ .querySelector('button')
+ .click();
+
+ expect(vm.fetchTemplate).toHaveBeenCalledWith({
+ name: 'test',
+ });
+ });
+ });
+
+ it('shows undo button if updateSuccess is true', done => {
+ vm.$store.state.fileTemplates.updateSuccess = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.btn-default').style.display).not.toBe('none');
+
+ done();
+ });
+ });
+
+ it('calls undoFileTemplate when clicking undo button', () => {
+ spyOn(vm, 'undoFileTemplate');
+
+ vm.$el.querySelector('.btn-default').click();
+
+ expect(vm.undoFileTemplate).toHaveBeenCalled();
+ });
+
+ it('calls setSelectedTemplateType if activeFile name matches a template', done => {
+ spyOn(vm, 'setSelectedTemplateType');
+ vm.$store.state.openFiles[0].name = '.gitlab-ci.yml';
+
+ vm.setInitialType();
+
+ vm.$nextTick(() => {
+ expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({
+ name: '.gitlab-ci.yml',
+ key: 'gitlab_ci_ymls',
+ });
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/file_templates/dropdown_spec.js b/spec/javascripts/ide/components/file_templates/dropdown_spec.js
new file mode 100644
index 00000000000..db824cfab6e
--- /dev/null
+++ b/spec/javascripts/ide/components/file_templates/dropdown_spec.js
@@ -0,0 +1,201 @@
+import $ from 'jquery';
+import Vue from 'vue';
+import { createStore } from '~/ide/stores';
+import Dropdown from '~/ide/components/file_templates/dropdown.vue';
+import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { resetStore } from '../../helpers';
+
+describe('IDE file templates dropdown component', () => {
+ let Component;
+ let vm;
+
+ beforeAll(() => {
+ Component = Vue.extend(Dropdown);
+ });
+
+ beforeEach(() => {
+ const store = createStore();
+
+ vm = createComponentWithStore(Component, store, {
+ label: 'Test',
+ }).$mount();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ resetStore(vm.$store);
+ });
+
+ describe('async', () => {
+ beforeEach(() => {
+ vm.async = true;
+ });
+
+ it('calls async store method on Bootstrap dropdown event', () => {
+ spyOn(vm, 'fetchTemplateTypes');
+
+ $(vm.$el).trigger('show.bs.dropdown');
+
+ expect(vm.fetchTemplateTypes).toHaveBeenCalled();
+ });
+
+ it('renders templates when async', done => {
+ vm.$store.state.fileTemplates.templates = [
+ {
+ name: 'test',
+ },
+ ];
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.dropdown-content').textContent).toContain('test');
+
+ done();
+ });
+ });
+
+ it('renders loading icon when isLoading is true', done => {
+ vm.$store.state.fileTemplates.isLoading = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
+
+ done();
+ });
+ });
+
+ it('searches template data', () => {
+ vm.$store.state.fileTemplates.templates = [
+ {
+ name: 'test',
+ },
+ ];
+ vm.searchable = true;
+ vm.search = 'hello';
+
+ expect(vm.outputData).toEqual([]);
+ });
+
+ it('does not filter data is searchable is false', () => {
+ vm.$store.state.fileTemplates.templates = [
+ {
+ name: 'test',
+ },
+ ];
+ vm.search = 'hello';
+
+ expect(vm.outputData).toEqual([
+ {
+ name: 'test',
+ },
+ ]);
+ });
+
+ it('calls clickItem on click', done => {
+ spyOn(vm, 'clickItem');
+
+ vm.$store.state.fileTemplates.templates = [
+ {
+ name: 'test',
+ },
+ ];
+
+ vm.$nextTick(() => {
+ vm.$el.querySelector('.dropdown-content button').click();
+
+ expect(vm.clickItem).toHaveBeenCalledWith({
+ name: 'test',
+ });
+
+ done();
+ });
+ });
+
+ it('renders input when searchable is true', done => {
+ vm.searchable = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.dropdown-input')).not.toBe(null);
+
+ done();
+ });
+ });
+
+ it('does not render input when searchable is true & showLoading is true', done => {
+ vm.searchable = true;
+ vm.$store.state.fileTemplates.isLoading = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.dropdown-input')).toBe(null);
+
+ done();
+ });
+ });
+ });
+
+ describe('sync', () => {
+ beforeEach(done => {
+ vm.data = [
+ {
+ name: 'test sync',
+ },
+ ];
+
+ vm.$nextTick(done);
+ });
+
+ it('renders props data', () => {
+ expect(vm.$el.querySelector('.dropdown-content').textContent).toContain('test sync');
+ });
+
+ it('renders input when searchable is true', done => {
+ vm.searchable = true;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.dropdown-input')).not.toBe(null);
+
+ done();
+ });
+ });
+
+ it('calls clickItem on click', done => {
+ spyOn(vm, 'clickItem');
+
+ vm.$nextTick(() => {
+ vm.$el.querySelector('.dropdown-content button').click();
+
+ expect(vm.clickItem).toHaveBeenCalledWith({
+ name: 'test sync',
+ });
+
+ done();
+ });
+ });
+
+ it('searches template data', () => {
+ vm.searchable = true;
+ vm.search = 'hello';
+
+ expect(vm.outputData).toEqual([]);
+ });
+
+ it('does not filter data is searchable is false', () => {
+ vm.search = 'hello';
+
+ expect(vm.outputData).toEqual([
+ {
+ name: 'test sync',
+ },
+ ]);
+ });
+
+ it('renders dropdown title', done => {
+ vm.title = 'Test title';
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.dropdown-title').textContent).toContain('Test title');
+
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/ide/helpers.js b/spec/javascripts/ide/helpers.js
index c11c482fef8..3ce9c9fcda1 100644
--- a/spec/javascripts/ide/helpers.js
+++ b/spec/javascripts/ide/helpers.js
@@ -5,6 +5,7 @@ import commitState from '~/ide/stores/modules/commit/state';
import mergeRequestsState from '~/ide/stores/modules/merge_requests/state';
import pipelinesState from '~/ide/stores/modules/pipelines/state';
import branchesState from '~/ide/stores/modules/branches/state';
+import fileTemplatesState from '~/ide/stores/modules/file_templates/state';
export const resetStore = store => {
const newState = {
@@ -13,6 +14,7 @@ export const resetStore = store => {
mergeRequests: mergeRequestsState(),
pipelines: pipelinesState(),
branches: branchesState(),
+ fileTemplates: fileTemplatesState(),
};
store.replaceState(newState);
};