diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-22 09:08:26 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-22 09:08:26 +0000 |
commit | 9dab4d7b6492628eb9222f14954fdd8889bd6e34 (patch) | |
tree | ae7723aff502efd04449be1692b4488cbd198de7 /spec | |
parent | f0fa9f7acf4c23f9a9fb4903fd7c41678a20c028 (diff) | |
download | gitlab-ce-9dab4d7b6492628eb9222f14954fdd8889bd6e34.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
7 files changed, 129 insertions, 110 deletions
diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb index 6ea730cbf27..867b2b51039 100644 --- a/spec/controllers/projects/static_site_editor_controller_spec.rb +++ b/spec/controllers/projects/static_site_editor_controller_spec.rb @@ -105,7 +105,8 @@ RSpec.describe Projects::StaticSiteEditorController do foo: 'bar' } }, - a_boolean: true + a_boolean: true, + a_nil: nil } end @@ -130,6 +131,10 @@ RSpec.describe Projects::StaticSiteEditorController do it 'serializes data values which are hashes to JSON' do expect(assigns_data[:a_hash]).to eq('{"a_deeper_hash":{"foo":"bar"}}') end + + it 'serializes data values which are nil to an empty string' do + expect(assigns_data[:a_nil]).to eq('') + end end end end diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js index d9f7146d258..d0c14c4c7eb 100644 --- a/spec/frontend/design_management/pages/design/index_spec.js +++ b/spec/frontend/design_management/pages/design/index_spec.js @@ -24,7 +24,13 @@ import mockAllVersions from '../../mock_data/all_versions'; jest.mock('~/flash'); const focusInput = jest.fn(); - +const mutate = jest.fn().mockResolvedValue(); +const mockPageLayoutElement = { + classList: { + add: jest.fn(), + remove: jest.fn(), + }, +}; const DesignReplyForm = { template: '<div><textarea ref="textarea"></textarea></div>', methods: { @@ -37,6 +43,32 @@ const mockDesignNoDiscussions = { nodes: [], }, }; +const newComment = 'new comment'; +const annotationCoordinates = { + x: 10, + y: 10, + width: 100, + height: 100, +}; +const createDiscussionMutationVariables = { + mutation: createImageDiffNoteMutation, + update: expect.anything(), + variables: { + input: { + body: newComment, + noteableId: design.id, + position: { + headSha: 'headSha', + baseSha: 'baseSha', + startSha: 'startSha', + paths: { + newPath: 'full-design-path', + }, + ...annotationCoordinates, + }, + }, + }, +}; const localVue = createLocalVue(); localVue.use(VueRouter); @@ -45,35 +77,6 @@ describe('Design management design index page', () => { let wrapper; let router; - const newComment = 'new comment'; - const annotationCoordinates = { - x: 10, - y: 10, - width: 100, - height: 100, - }; - const createDiscussionMutationVariables = { - mutation: createImageDiffNoteMutation, - update: expect.anything(), - variables: { - input: { - body: newComment, - noteableId: design.id, - position: { - headSha: 'headSha', - baseSha: 'baseSha', - startSha: 'startSha', - paths: { - newPath: 'full-design-path', - }, - ...annotationCoordinates, - }, - }, - }, - }; - - const mutate = jest.fn().mockResolvedValue(); - const findDiscussionForm = () => wrapper.find(DesignReplyForm); const findSidebar = () => wrapper.find(DesignSidebar); const findDesignPresentation = () => wrapper.find(DesignPresentation); @@ -122,19 +125,44 @@ describe('Design management design index page', () => { wrapper.destroy(); }); - describe('when navigating', () => { - it('applies fullscreen layout', () => { - const mockEl = { - classList: { - add: jest.fn(), - remove: jest.fn(), - }, - }; - jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockEl); + describe('when navigating to component', () => { + it('applies fullscreen layout class', () => { + jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement); createComponent({ loading: true }); - expect(mockEl.classList.add).toHaveBeenCalledTimes(1); - expect(mockEl.classList.add).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST); + expect(mockPageLayoutElement.classList.add).toHaveBeenCalledTimes(1); + expect(mockPageLayoutElement.classList.add).toHaveBeenCalledWith( + ...DESIGN_DETAIL_LAYOUT_CLASSLIST, + ); + }); + }); + + describe('when navigating within the component', () => { + it('`scale` prop of DesignPresentation component is 1', async () => { + jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement); + createComponent({ loading: false }, { data: { design, scale: 2 } }); + + await wrapper.vm.$nextTick(); + expect(findDesignPresentation().props('scale')).toBe(2); + + DesignIndex.beforeRouteUpdate.call(wrapper.vm, {}, {}, jest.fn()); + await wrapper.vm.$nextTick(); + + expect(findDesignPresentation().props('scale')).toBe(1); + }); + }); + + describe('when navigating away from component', () => { + it('removes fullscreen layout class', async () => { + jest.spyOn(utils, 'getPageLayoutElement').mockReturnValue(mockPageLayoutElement); + createComponent({ loading: true }); + + wrapper.vm.$options.beforeRouteLeave[0].call(wrapper.vm, {}, {}, jest.fn()); + + expect(mockPageLayoutElement.classList.remove).toHaveBeenCalledTimes(1); + expect(mockPageLayoutElement.classList.remove).toHaveBeenCalledWith( + ...DESIGN_DETAIL_LAYOUT_CLASSLIST, + ); }); }); diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js index 27a91b11448..279403789f1 100644 --- a/spec/frontend/design_management/pages/index_spec.js +++ b/spec/frontend/design_management/pages/index_spec.js @@ -19,7 +19,6 @@ import { import { deprecatedCreateFlash as createFlash } from '~/flash'; import createRouter from '~/design_management/router'; import * as utils from '~/design_management/utils/design_management_utils'; -import { DESIGN_DETAIL_LAYOUT_CLASSLIST } from '~/design_management/constants'; import { designListQueryResponse, designUploadMutationCreatedResponse, @@ -682,13 +681,6 @@ describe('Design management index page', () => { }); describe('when navigating', () => { - it('ensures fullscreen layout is not applied', () => { - createComponent({ loading: true }); - - expect(mockPageEl.classList.remove).toHaveBeenCalledTimes(1); - expect(mockPageEl.classList.remove).toHaveBeenCalledWith(...DESIGN_DETAIL_LAYOUT_CLASSLIST); - }); - it('should trigger a scrollIntoView method if designs route is detected', () => { router.replace({ path: '/designs', diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js index 1298a2a1524..5e04f9a6433 100644 --- a/spec/frontend/pipelines/pipelines_spec.js +++ b/spec/frontend/pipelines/pipelines_spec.js @@ -74,7 +74,6 @@ describe('Pipelines', () => { const createComponent = (props = defaultProps, methods) => { wrapper = mount(PipelinesComponent, { - provide: { glFeatures: { filterPipelinesSearch: true } }, propsData: { store: new Store(), projectId: '21', diff --git a/spec/frontend/vue_shared/components/modal_copy_button_spec.js b/spec/frontend/vue_shared/components/modal_copy_button_spec.js index e5a8860f42e..ca9f8ff54d4 100644 --- a/spec/frontend/vue_shared/components/modal_copy_button_spec.js +++ b/spec/frontend/vue_shared/components/modal_copy_button_spec.js @@ -1,9 +1,7 @@ -import Vue from 'vue'; -import { shallowMount } from '@vue/test-utils'; -import modalCopyButton from '~/vue_shared/components/modal_copy_button.vue'; +import { shallowMount, createWrapper } from '@vue/test-utils'; +import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue'; describe('modal copy button', () => { - const Component = Vue.extend(modalCopyButton); let wrapper; afterEach(() => { @@ -11,16 +9,18 @@ describe('modal copy button', () => { }); beforeEach(() => { - wrapper = shallowMount(Component, { + wrapper = shallowMount(ModalCopyButton, { propsData: { text: 'copy me', title: 'Copy this value', + id: 'test-id', }, }); }); describe('clipboard', () => { it('should fire a `success` event on click', () => { + const root = createWrapper(wrapper.vm.$root); document.execCommand = jest.fn(() => true); window.getSelection = jest.fn(() => ({ toString: jest.fn(() => 'test'), @@ -31,6 +31,7 @@ describe('modal copy button', () => { return wrapper.vm.$nextTick().then(() => { expect(wrapper.emitted().success).not.toBeEmpty(); expect(document.execCommand).toHaveBeenCalledWith('copy'); + expect(root.emitted('bv::hide::tooltip')).toEqual([['test-id']]); }); }); it("should propagate the clipboard error event if execCommand doesn't work", () => { diff --git a/spec/graphql/resolvers/projects_resolver_spec.rb b/spec/graphql/resolvers/projects_resolver_spec.rb index 83a26062957..3de54c7e410 100644 --- a/spec/graphql/resolvers/projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects_resolver_spec.rb @@ -134,8 +134,8 @@ RSpec.describe Resolvers::ProjectsResolver do is_expected.to eq([named_project3, named_project1, named_project2]) end - it 'returns projects not in order of similarity to search if flag is off' do - is_expected.not_to eq([named_project3, named_project1, named_project2]) + it 'returns projects in any order if flag is off' do + is_expected.to match_array([named_project3, named_project1, named_project2]) end end end diff --git a/spec/lib/gitlab/error_tracking_spec.rb b/spec/lib/gitlab/error_tracking_spec.rb index 68a46b11487..2cc9ff36c99 100644 --- a/spec/lib/gitlab/error_tracking_spec.rb +++ b/spec/lib/gitlab/error_tracking_spec.rb @@ -198,39 +198,47 @@ RSpec.describe Gitlab::ErrorTracking do end describe '.track_exception' do - let(:extra) { { issue_url: issue_url, some_other_info: 'info' } } - - subject(:track_exception) { described_class.track_exception(exception, extra) } - - before do - allow(Raven).to receive(:capture_exception).and_call_original - allow(Gitlab::ErrorTracking::Logger).to receive(:error) - end - it 'calls Raven.capture_exception' do - track_exception + expected_extras = { + some_other_info: 'info', + issue_url: issue_url + } - expect(Raven).to have_received(:capture_exception) - .with(exception, - tags: a_hash_including(correlation_id: 'cid'), - extra: a_hash_including(some_other_info: 'info', issue_url: issue_url)) + expected_tags = { + correlation_id: 'cid' + } + + expect(Raven).to receive(:capture_exception) + .with(exception, + tags: a_hash_including(expected_tags), + extra: a_hash_including(expected_extras)) + + described_class.track_exception( + exception, + issue_url: issue_url, + some_other_info: 'info' + ) end it 'calls Gitlab::ErrorTracking::Logger.error with formatted payload' do - track_exception + expect(Gitlab::ErrorTracking::Logger).to receive(:error) + .with(a_hash_including(*expected_payload_includes)) - expect(Gitlab::ErrorTracking::Logger).to have_received(:error) - .with(a_hash_including(*expected_payload_includes)) + described_class.track_exception( + exception, + issue_url: issue_url, + some_other_info: 'info' + ) end context 'with filterable parameters' do let(:extra) { { test: 1, my_token: 'test' } } it 'filters parameters' do - track_exception + expect(Gitlab::ErrorTracking::Logger).to receive(:error).with( + hash_including({ 'extra.test' => 1, 'extra.my_token' => '[FILTERED]' })) - expect(Gitlab::ErrorTracking::Logger).to have_received(:error) - .with(hash_including({ 'extra.test' => 1, 'extra.my_token' => '[FILTERED]' })) + described_class.track_exception(exception, extra) end end @@ -239,58 +247,44 @@ RSpec.describe Gitlab::ErrorTracking do let(:exception) { double(message: 'bang!', sentry_extra_data: extra_info, backtrace: caller) } it 'includes the extra data from the exception in the tracking information' do - track_exception + expect(Raven).to receive(:capture_exception) + .with(exception, a_hash_including(extra: a_hash_including(extra_info))) - expect(Raven).to have_received(:capture_exception) - .with(exception, a_hash_including(extra: a_hash_including(extra_info))) + described_class.track_exception(exception) end end context 'the exception implements :sentry_extra_data, which returns nil' do let(:exception) { double(message: 'bang!', sentry_extra_data: nil, backtrace: caller) } - let(:extra) { { issue_url: issue_url } } it 'just includes the other extra info' do - track_exception + extra_info = { issue_url: issue_url } + expect(Raven).to receive(:capture_exception) + .with(exception, a_hash_including(extra: a_hash_including(extra_info))) - expect(Raven).to have_received(:capture_exception) - .with(exception, a_hash_including(extra: a_hash_including(extra))) + described_class.track_exception(exception, extra_info) end end context 'with sidekiq args' do - context 'when the args does not have anything sensitive' do - let(:extra) { { sidekiq: { 'class' => 'PostReceive', 'args' => [1, { 'id' => 2, 'name' => 'hello' }, 'some-value', 'another-value'] } } } + it 'ensures extra.sidekiq.args is a string' do + extra = { sidekiq: { 'class' => 'PostReceive', 'args' => [1, { 'id' => 2, 'name' => 'hello' }, 'some-value', 'another-value'] } } - it 'ensures extra.sidekiq.args is a string' do - track_exception + expect(Gitlab::ErrorTracking::Logger).to receive(:error).with( + hash_including({ 'extra.sidekiq' => { 'class' => 'PostReceive', 'args' => ['1', '{"id"=>2, "name"=>"hello"}', 'some-value', 'another-value'] } })) - expect(Gitlab::ErrorTracking::Logger).to have_received(:error).with( - hash_including({ 'extra.sidekiq' => { 'class' => 'PostReceive', 'args' => ['1', '{"id"=>2, "name"=>"hello"}', 'some-value', 'another-value'] } })) - end + described_class.track_exception(exception, extra) end - context 'when the args has sensitive information' do - let(:extra) { { sidekiq: { 'class' => 'UnknownWorker', 'args' => ['sensitive string', 1, 2] } } } - - it 'filters sensitive arguments before sending' do - track_exception - - expect(sentry_event.dig('extra', 'sidekiq', 'args')).to eq(['[FILTERED]', 1, 2]) - expect(Gitlab::ErrorTracking::Logger).to have_received(:error).with( - hash_including('extra.sidekiq' => { 'class' => 'UnknownWorker', 'args' => ['[FILTERED]', '1', '2'] })) - end - end - end + it 'filters sensitive arguments before sending' do + extra = { sidekiq: { 'class' => 'UnknownWorker', 'args' => ['sensitive string', 1, 2] } } - context 'when the error is kind of an `ActiveRecord::StatementInvalid`' do - let(:exception) { ActiveRecord::StatementInvalid.new(sql: 'SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."foo" = $1') } + expect(Gitlab::ErrorTracking::Logger).to receive(:error).with( + hash_including('extra.sidekiq' => { 'class' => 'UnknownWorker', 'args' => ['[FILTERED]', '1', '2'] })) - it 'injects the normalized sql query into extra' do - track_exception + described_class.track_exception(exception, extra) - expect(Raven).to have_received(:capture_exception) - .with(exception, a_hash_including(extra: a_hash_including(sql: 'SELECT "users".* FROM "users" WHERE "users"."id" = $2 AND "users"."foo" = $1'))) + expect(sentry_event.dig('extra', 'sidekiq', 'args')).to eq(['[FILTERED]', 1, 2]) end end end |