added component specs

This commit is contained in:
Phil Hughes 2018-08-30 10:43:41 +01:00
parent d6410a0335
commit 5b84c2fbc2
No known key found for this signature in database
GPG key ID: 32245528C52E0F9F
8 changed files with 345 additions and 22 deletions

View file

@ -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>

View file

@ -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"

View file

@ -23,7 +23,7 @@ export const createStore = () =>
pipelines, pipelines,
mergeRequests, mergeRequests,
branches, branches,
fileTemplates, fileTemplates: fileTemplates(),
}, },
}); });

View file

@ -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,
}; });

View file

@ -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;
}
}

View 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();
});
});
});

View 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();
});
});
});
});

View file

@ -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);
}; };