summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-22 09:08:26 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-22 09:08:26 +0000
commit9dab4d7b6492628eb9222f14954fdd8889bd6e34 (patch)
treeae7723aff502efd04449be1692b4488cbd198de7 /spec
parentf0fa9f7acf4c23f9a9fb4903fd7c41678a20c028 (diff)
downloadgitlab-ce-9dab4d7b6492628eb9222f14954fdd8889bd6e34.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/static_site_editor_controller_spec.rb7
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js110
-rw-r--r--spec/frontend/design_management/pages/index_spec.js8
-rw-r--r--spec/frontend/pipelines/pipelines_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/modal_copy_button_spec.js11
-rw-r--r--spec/graphql/resolvers/projects_resolver_spec.rb4
-rw-r--r--spec/lib/gitlab/error_tracking_spec.rb98
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