added component specs
This commit is contained in:
parent
d6410a0335
commit
5b84c2fbc2
8 changed files with 345 additions and 22 deletions
|
@ -15,9 +15,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
activeFile: {
|
activeFile: 'setInitialType',
|
||||||
handler: 'setInitialType',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setInitialType();
|
this.setInitialType();
|
||||||
|
@ -38,9 +36,12 @@ export default {
|
||||||
selectTemplateType(type) {
|
selectTemplateType(type) {
|
||||||
this.setSelectedTemplateType(type);
|
this.setSelectedTemplateType(type);
|
||||||
},
|
},
|
||||||
selecteTemplate(template) {
|
selectTemplate(template) {
|
||||||
this.fetchTemplate(template);
|
this.fetchTemplate(template);
|
||||||
},
|
},
|
||||||
|
undo() {
|
||||||
|
this.undoFileTemplate();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -63,29 +64,17 @@ export default {
|
||||||
:searchable="true"
|
:searchable="true"
|
||||||
:title="__('File templates')"
|
:title="__('File templates')"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
@click="selecteTemplate"
|
@click="selectTemplate"
|
||||||
/>
|
/>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<button
|
<button
|
||||||
v-show="updateSuccess"
|
v-show="updateSuccess"
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-default"
|
class="btn btn-default"
|
||||||
@click="undoFileTemplate"
|
@click="undo"
|
||||||
>
|
>
|
||||||
{{ __('Undo') }}
|
{{ __('Undo') }}
|
||||||
</button>
|
</button>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style>
|
|
||||||
.ide-file-templates {
|
|
||||||
padding: 8px 16px;
|
|
||||||
background-color: #fafafa;
|
|
||||||
border-bottom: 1px solid #eaeaea;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ide-file-templates .dropdown {
|
|
||||||
min-width: 180px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -51,6 +51,9 @@ export default {
|
||||||
|
|
||||||
return __('Create file');
|
return __('Create file');
|
||||||
},
|
},
|
||||||
|
isCreatingNew() {
|
||||||
|
return this.entryModal.type !== modalTypes.rename;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['createTempEntry', 'renameEntry']),
|
...mapActions(['createTempEntry', 'renameEntry']),
|
||||||
|
@ -110,7 +113,10 @@ export default {
|
||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="/dir/file_name"
|
placeholder="/dir/file_name"
|
||||||
/>
|
/>
|
||||||
<ul class="prepend-top-default list-inline">
|
<ul
|
||||||
|
v-if="isCreatingNew"
|
||||||
|
class="prepend-top-default list-inline"
|
||||||
|
>
|
||||||
<li
|
<li
|
||||||
v-for="(template, index) in templateTypes"
|
v-for="(template, index) in templateTypes"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
|
@ -23,7 +23,7 @@ export const createStore = () =>
|
||||||
pipelines,
|
pipelines,
|
||||||
mergeRequests,
|
mergeRequests,
|
||||||
branches,
|
branches,
|
||||||
fileTemplates,
|
fileTemplates: fileTemplates(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ import * as actions from './actions';
|
||||||
import * as getters from './getters';
|
import * as getters from './getters';
|
||||||
import mutations from './mutations';
|
import mutations from './mutations';
|
||||||
|
|
||||||
export default {
|
export default () => ({
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
actions,
|
actions,
|
||||||
state: createState(),
|
state: createState(),
|
||||||
getters,
|
getters,
|
||||||
mutations,
|
mutations,
|
||||||
};
|
});
|
||||||
|
|
|
@ -1442,3 +1442,13 @@ $ide-tree-text-start: $ide-activity-bar-width + $ide-tree-padding;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
115
spec/javascripts/ide/components/file_templates/bar_spec.js
Normal file
115
spec/javascripts/ide/components/file_templates/bar_spec.js
Normal file
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
201
spec/javascripts/ide/components/file_templates/dropdown_spec.js
Normal file
201
spec/javascripts/ide/components/file_templates/dropdown_spec.js
Normal file
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -5,6 +5,7 @@ import commitState from '~/ide/stores/modules/commit/state';
|
||||||
import mergeRequestsState from '~/ide/stores/modules/merge_requests/state';
|
import mergeRequestsState from '~/ide/stores/modules/merge_requests/state';
|
||||||
import pipelinesState from '~/ide/stores/modules/pipelines/state';
|
import pipelinesState from '~/ide/stores/modules/pipelines/state';
|
||||||
import branchesState from '~/ide/stores/modules/branches/state';
|
import branchesState from '~/ide/stores/modules/branches/state';
|
||||||
|
import fileTemplatesState from '~/ide/stores/modules/file_templates/state';
|
||||||
|
|
||||||
export const resetStore = store => {
|
export const resetStore = store => {
|
||||||
const newState = {
|
const newState = {
|
||||||
|
@ -13,6 +14,7 @@ export const resetStore = store => {
|
||||||
mergeRequests: mergeRequestsState(),
|
mergeRequests: mergeRequestsState(),
|
||||||
pipelines: pipelinesState(),
|
pipelines: pipelinesState(),
|
||||||
branches: branchesState(),
|
branches: branchesState(),
|
||||||
|
fileTemplates: fileTemplatesState(),
|
||||||
};
|
};
|
||||||
store.replaceState(newState);
|
store.replaceState(newState);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue