diff options
Diffstat (limited to 'spec/frontend')
3 files changed, 239 insertions, 80 deletions
diff --git a/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js b/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js new file mode 100644 index 00000000000..ad69984fd35 --- /dev/null +++ b/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js @@ -0,0 +1,83 @@ +import Vuex from 'vuex'; +import { mount, createLocalVue } from '@vue/test-utils'; +import { createStore } from '~/ide/stores'; +import EditorHeader from '~/ide/components/commit_sidebar/editor_header.vue'; +import { file } from '../../helpers'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('IDE commit editor header', () => { + let wrapper; + let f; + let store; + + const findDiscardModal = () => wrapper.find({ ref: 'discardModal' }); + const findDiscardButton = () => wrapper.find({ ref: 'discardButton' }); + const findActionButton = () => wrapper.find({ ref: 'actionButton' }); + + beforeEach(() => { + f = file('file'); + store = createStore(); + + wrapper = mount(EditorHeader, { + store, + localVue, + sync: false, + propsData: { + activeFile: f, + }, + }); + + jest.spyOn(wrapper.vm, 'stageChange').mockImplementation(); + jest.spyOn(wrapper.vm, 'unstageChange').mockImplementation(); + jest.spyOn(wrapper.vm, 'discardFileChanges').mockImplementation(); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + it('renders button to discard & stage', () => { + expect(wrapper.vm.$el.querySelectorAll('.btn').length).toBe(2); + }); + + describe('discard button', () => { + let modal; + + beforeEach(() => { + modal = findDiscardModal(); + + jest.spyOn(modal.vm, 'show'); + + findDiscardButton().trigger('click'); + }); + + it('opens a dialog confirming discard', () => { + expect(modal.vm.show).toHaveBeenCalled(); + }); + + it('calls discardFileChanges if dialog result is confirmed', () => { + modal.vm.$emit('ok'); + + expect(wrapper.vm.discardFileChanges).toHaveBeenCalledWith(f.path); + }); + }); + + describe('stage/unstage button', () => { + it('unstages the file if it was already staged', () => { + f.staged = true; + + findActionButton().trigger('click'); + + expect(wrapper.vm.unstageChange).toHaveBeenCalledWith(f.path); + }); + + it('stages the file if it was not staged', () => { + findActionButton().trigger('click'); + + expect(wrapper.vm.stageChange).toHaveBeenCalledWith(f.path); + }); + }); +}); diff --git a/spec/frontend/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js b/spec/frontend/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js new file mode 100644 index 00000000000..fb50b31a3da --- /dev/null +++ b/spec/frontend/sentry_error_stack_trace/components/sentry_error_stack_trace_spec.js @@ -0,0 +1,85 @@ +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import Vuex from 'vuex'; +import { GlLoadingIcon } from '@gitlab/ui'; +import Stacktrace from '~/error_tracking/components/stacktrace.vue'; +import SentryErrorStackTrace from '~/sentry_error_stack_trace/components/sentry_error_stack_trace.vue'; + +const localVue = createLocalVue(); +localVue.use(Vuex); + +describe('Sentry Error Stack Trace', () => { + let actions; + let getters; + let store; + let wrapper; + + function mountComponent({ + stubs = { + stacktrace: Stacktrace, + }, + } = {}) { + wrapper = shallowMount(SentryErrorStackTrace, { + localVue, + stubs, + store, + propsData: { + issueStackTracePath: '/stacktrace', + }, + }); + } + + beforeEach(() => { + actions = { + startPollingStacktrace: () => {}, + }; + + getters = { + stacktrace: () => [{ context: [1, 2], lineNo: 53, filename: 'index.js' }], + }; + + const state = { + stacktraceData: {}, + loadingStacktrace: true, + }; + + store = new Vuex.Store({ + modules: { + details: { + namespaced: true, + actions, + getters, + state, + }, + }, + }); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + }); + + describe('loading', () => { + it('should show spinner while loading', () => { + mountComponent(); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + expect(wrapper.find(Stacktrace).exists()).toBe(false); + }); + }); + + describe('Stack trace', () => { + it('should show stacktrace', () => { + store.state.details.loadingStacktrace = false; + mountComponent({ stubs: {} }); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(wrapper.find(Stacktrace).exists()).toBe(true); + }); + + it('should not show stacktrace if it does not exist', () => { + store.state.details.loadingStacktrace = false; + expect(wrapper.find(GlLoadingIcon).exists()).toBe(false); + expect(wrapper.find(Stacktrace).exists()).toBe(false); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js index f2e743cc1f6..440ad1ca40f 100644 --- a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js +++ b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js @@ -29,23 +29,40 @@ describe('User Popover Component', () => { wrapper.destroy(); }); + const findUserStatus = () => wrapper.find('.js-user-status'); + const findTarget = () => document.querySelector('.js-user-link'); + + const createWrapper = (props = {}, options = {}) => { + wrapper = shallowMount(UserPopover, { + propsData: { + ...DEFAULT_PROPS, + target: findTarget(), + ...props, + }, + sync: false, + ...options, + }); + }; + describe('Empty', () => { beforeEach(() => { - wrapper = shallowMount(UserPopover, { - propsData: { - target: document.querySelector('.js-user-link'), - user: { - name: null, - username: null, - location: null, - bio: null, - organization: null, - status: null, + createWrapper( + {}, + { + propsData: { + target: findTarget(), + user: { + name: null, + username: null, + location: null, + bio: null, + organization: null, + status: null, + }, }, + attachToDocument: true, }, - attachToDocument: true, - sync: false, - }); + ); }); it('should return skeleton loaders', () => { @@ -55,13 +72,7 @@ describe('User Popover Component', () => { describe('basic data', () => { it('should show basic fields', () => { - wrapper = shallowMount(UserPopover, { - propsData: { - ...DEFAULT_PROPS, - target: document.querySelector('.js-user-link'), - }, - sync: false, - }); + createWrapper(); expect(wrapper.text()).toContain(DEFAULT_PROPS.user.name); expect(wrapper.text()).toContain(DEFAULT_PROPS.user.username); @@ -77,64 +88,38 @@ describe('User Popover Component', () => { describe('job data', () => { it('should show only bio if no organization is available', () => { - const testProps = Object.assign({}, DEFAULT_PROPS); - testProps.user.bio = 'Engineer'; + const user = { ...DEFAULT_PROPS.user, bio: 'Engineer' }; - wrapper = shallowMount(UserPopover, { - propsData: { - ...testProps, - target: document.querySelector('.js-user-link'), - }, - sync: false, - }); + createWrapper({ user }); expect(wrapper.text()).toContain('Engineer'); }); it('should show only organization if no bio is available', () => { - const testProps = Object.assign({}, DEFAULT_PROPS); - testProps.user.organization = 'GitLab'; + const user = { ...DEFAULT_PROPS.user, organization: 'GitLab' }; - wrapper = shallowMount(UserPopover, { - propsData: { - ...testProps, - target: document.querySelector('.js-user-link'), - }, - sync: false, - }); + createWrapper({ user }); expect(wrapper.text()).toContain('GitLab'); }); it('should display bio and organization in separate lines', () => { - const testProps = Object.assign({}, DEFAULT_PROPS); - testProps.user.bio = 'Engineer'; - testProps.user.organization = 'GitLab'; - - wrapper = shallowMount(UserPopover, { - propsData: { - ...DEFAULT_PROPS, - target: document.querySelector('.js-user-link'), - }, - sync: false, - }); + const user = { ...DEFAULT_PROPS.user, bio: 'Engineer', organization: 'GitLab' }; + + createWrapper({ user }); expect(wrapper.find('.js-bio').text()).toContain('Engineer'); expect(wrapper.find('.js-organization').text()).toContain('GitLab'); }); it('should not encode special characters in bio and organization', () => { - const testProps = Object.assign({}, DEFAULT_PROPS); - testProps.user.bio = 'Manager & Team Lead'; - testProps.user.organization = 'Me & my <funky> Company'; - - wrapper = shallowMount(UserPopover, { - propsData: { - ...DEFAULT_PROPS, - target: document.querySelector('.js-user-link'), - }, - sync: false, - }); + const user = { + ...DEFAULT_PROPS.user, + bio: 'Manager & Team Lead', + organization: 'Me & my <funky> Company', + }; + + createWrapper({ user }); expect(wrapper.find('.js-bio').text()).toContain('Manager & Team Lead'); expect(wrapper.find('.js-organization').text()).toContain('Me & my <funky> Company'); @@ -153,35 +138,41 @@ describe('User Popover Component', () => { describe('status data', () => { it('should show only message', () => { - const testProps = Object.assign({}, DEFAULT_PROPS); - testProps.user.status = { message_html: 'Hello World' }; + const user = { ...DEFAULT_PROPS.user, status: { message_html: 'Hello World' } }; - wrapper = shallowMount(UserPopover, { - propsData: { - ...DEFAULT_PROPS, - target: document.querySelector('.js-user-link'), - }, - sync: false, - }); + createWrapper({ user }); + expect(findUserStatus().exists()).toBe(true); expect(wrapper.text()).toContain('Hello World'); }); it('should show message and emoji', () => { - const testProps = Object.assign({}, DEFAULT_PROPS); - testProps.user.status = { emoji: 'basketball_player', message_html: 'Hello World' }; - - wrapper = shallowMount(UserPopover, { - propsData: { - ...DEFAULT_PROPS, - target: document.querySelector('.js-user-link'), - status: { emoji: 'basketball_player', message_html: 'Hello World' }, - }, - sync: false, - }); + const user = { + ...DEFAULT_PROPS.user, + status: { emoji: 'basketball_player', message_html: 'Hello World' }, + }; + + createWrapper({ user }); + expect(findUserStatus().exists()).toBe(true); expect(wrapper.text()).toContain('Hello World'); expect(wrapper.html()).toContain('<gl-emoji data-name="basketball_player"'); }); + + it('hides the div when status is null', () => { + const user = { ...DEFAULT_PROPS.user, status: null }; + + createWrapper({ user }); + + expect(findUserStatus().exists()).toBe(false); + }); + + it('hides the div when status is empty', () => { + const user = { ...DEFAULT_PROPS.user, status: { emoji: '', message_html: '' } }; + + createWrapper({ user }); + + expect(findUserStatus().exists()).toBe(false); + }); }); }); |