Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-14 21:08:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-14 21:08:45 +0300
commit26a50872e9da9509c52c70f74dc21698fec906db (patch)
treeb1bd36bd72e701e346ef880fc7a905f6186525e7 /spec
parentb3a736ed88a1db0391cd9881e70b987bab7d89d1 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/concerns/metrics_dashboard_spec.rb20
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb2
-rw-r--r--spec/frontend/blob/components/blob_content_error_spec.js27
-rw-r--r--spec/frontend/blob/components/blob_content_spec.js70
-rw-r--r--spec/frontend/blob/components/blob_header_default_actions_spec.js9
-rw-r--r--spec/frontend/blob/components/mock_data.js46
-rw-r--r--spec/frontend/snippets/components/snippet_blob_view_spec.js117
-rw-r--r--spec/frontend/vue_shared/components/blob_viewers/__snapshots__/simple_viewer_spec.js.snap86
-rw-r--r--spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js27
-rw-r--r--spec/frontend/vue_shared/components/blob_viewers/simple_viewer_spec.js81
-rw-r--r--spec/helpers/environments_helper_spec.rb2
11 files changed, 453 insertions, 34 deletions
diff --git a/spec/controllers/concerns/metrics_dashboard_spec.rb b/spec/controllers/concerns/metrics_dashboard_spec.rb
index 466021d6ecd..4e42171e3d3 100644
--- a/spec/controllers/concerns/metrics_dashboard_spec.rb
+++ b/spec/controllers/concerns/metrics_dashboard_spec.rb
@@ -45,6 +45,7 @@ describe MetricsDashboard do
it 'returns the specified dashboard' do
expect(json_response['dashboard']['dashboard']).to eq('Environment metrics')
expect(json_response).not_to have_key('all_dashboards')
+ expect(json_response).not_to have_key('metrics_data')
end
context 'when the params are in an alternate format' do
@@ -53,6 +54,25 @@ describe MetricsDashboard do
it 'returns the specified dashboard' do
expect(json_response['dashboard']['dashboard']).to eq('Environment metrics')
expect(json_response).not_to have_key('all_dashboards')
+ expect(json_response).not_to have_key('metrics_data')
+ end
+ end
+
+ context 'when environment for dashboard is available' do
+ let(:params) { { environment: environment } }
+
+ before do
+ allow(controller).to receive(:project).and_return(project)
+ allow(controller).to receive(:environment).and_return(environment)
+ allow(controller)
+ .to receive(:metrics_dashboard_params)
+ .and_return(params)
+ end
+
+ it 'returns the specified dashboard' do
+ expect(json_response['dashboard']['dashboard']).to eq('Environment metrics')
+ expect(json_response).not_to have_key('all_dashboards')
+ expect(json_response).to have_key('metrics_data')
end
end
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 7f0f8e36564..6c63b220322 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -489,7 +489,7 @@ describe Projects::EnvironmentsController do
end
shared_examples_for '200 response' do
- let(:expected_keys) { %w(dashboard status) }
+ let(:expected_keys) { %w(dashboard status metrics_data) }
it_behaves_like 'correctly formatted response', :ok
end
diff --git a/spec/frontend/blob/components/blob_content_error_spec.js b/spec/frontend/blob/components/blob_content_error_spec.js
new file mode 100644
index 00000000000..58a9ee761df
--- /dev/null
+++ b/spec/frontend/blob/components/blob_content_error_spec.js
@@ -0,0 +1,27 @@
+import { shallowMount } from '@vue/test-utils';
+import BlobContentError from '~/blob/components/blob_content_error.vue';
+
+describe('Blob Content Error component', () => {
+ let wrapper;
+ const viewerError = '<h1 id="error">Foo Error</h1>';
+
+ function createComponent() {
+ wrapper = shallowMount(BlobContentError, {
+ propsData: {
+ viewerError,
+ },
+ });
+ }
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the passed error without transformations', () => {
+ expect(wrapper.html()).toContain(viewerError);
+ });
+});
diff --git a/spec/frontend/blob/components/blob_content_spec.js b/spec/frontend/blob/components/blob_content_spec.js
new file mode 100644
index 00000000000..6a130c9c43d
--- /dev/null
+++ b/spec/frontend/blob/components/blob_content_spec.js
@@ -0,0 +1,70 @@
+import { shallowMount } from '@vue/test-utils';
+import BlobContent from '~/blob/components/blob_content.vue';
+import BlobContentError from '~/blob/components/blob_content_error.vue';
+import {
+ RichViewerMock,
+ SimpleViewerMock,
+ RichBlobContentMock,
+ SimpleBlobContentMock,
+} from './mock_data';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { RichViewer, SimpleViewer } from '~/vue_shared/components/blob_viewers';
+
+describe('Blob Content component', () => {
+ let wrapper;
+
+ function createComponent(propsData = {}, activeViewer = SimpleViewerMock) {
+ wrapper = shallowMount(BlobContent, {
+ propsData: {
+ loading: false,
+ activeViewer,
+ ...propsData,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('rendering', () => {
+ it('renders loader if `loading: true`', () => {
+ createComponent({ loading: true });
+ expect(wrapper.contains(GlLoadingIcon)).toBe(true);
+ expect(wrapper.contains(BlobContentError)).toBe(false);
+ expect(wrapper.contains(RichViewer)).toBe(false);
+ expect(wrapper.contains(SimpleViewer)).toBe(false);
+ });
+
+ it('renders error if there is any in the viewer', () => {
+ const renderError = 'Oops';
+ const viewer = Object.assign({}, SimpleViewerMock, { renderError });
+ createComponent({}, viewer);
+ expect(wrapper.contains(GlLoadingIcon)).toBe(false);
+ expect(wrapper.contains(BlobContentError)).toBe(true);
+ expect(wrapper.contains(RichViewer)).toBe(false);
+ expect(wrapper.contains(SimpleViewer)).toBe(false);
+ });
+
+ it.each`
+ type | mock | viewer
+ ${'simple'} | ${SimpleViewerMock} | ${SimpleViewer}
+ ${'rich'} | ${RichViewerMock} | ${RichViewer}
+ `(
+ 'renders $type viewer when activeViewer is $type and no loading or error detected',
+ ({ mock, viewer }) => {
+ createComponent({}, mock);
+ expect(wrapper.contains(viewer)).toBe(true);
+ },
+ );
+
+ it.each`
+ content | mock | viewer
+ ${SimpleBlobContentMock.plainData} | ${SimpleViewerMock} | ${SimpleViewer}
+ ${RichBlobContentMock.richData} | ${RichViewerMock} | ${RichViewer}
+ `('renders correct content that is passed to the component', ({ content, mock, viewer }) => {
+ createComponent({ content }, mock);
+ expect(wrapper.find(viewer).html()).toContain(content);
+ });
+ });
+});
diff --git a/spec/frontend/blob/components/blob_header_default_actions_spec.js b/spec/frontend/blob/components/blob_header_default_actions_spec.js
index 5da0d40ab14..39d627e71c5 100644
--- a/spec/frontend/blob/components/blob_header_default_actions_spec.js
+++ b/spec/frontend/blob/components/blob_header_default_actions_spec.js
@@ -67,13 +67,4 @@ describe('Blob Header Default Actions', () => {
expect(buttons.at(0).attributes('disabled')).toBeTruthy();
});
});
-
- describe('functionally', () => {
- it('emits an event when a Copy Contents button is clicked', () => {
- jest.spyOn(wrapper.vm, '$emit');
- buttons.at(0).vm.$emit('click');
-
- expect(wrapper.vm.$emit).toHaveBeenCalledWith('copy');
- });
- });
});
diff --git a/spec/frontend/blob/components/mock_data.js b/spec/frontend/blob/components/mock_data.js
index 4f7b297aba0..bfcca14324f 100644
--- a/spec/frontend/blob/components/mock_data.js
+++ b/spec/frontend/blob/components/mock_data.js
@@ -1,29 +1,43 @@
+import { SIMPLE_BLOB_VIEWER, RICH_BLOB_VIEWER } from '~/blob/components/constants';
+
+export const SimpleViewerMock = {
+ collapsed: false,
+ loadingPartialName: 'loading',
+ renderError: null,
+ tooLarge: false,
+ type: SIMPLE_BLOB_VIEWER,
+ fileType: 'text',
+};
+
+export const RichViewerMock = {
+ collapsed: false,
+ loadingPartialName: 'loading',
+ renderError: null,
+ tooLarge: false,
+ type: RICH_BLOB_VIEWER,
+ fileType: 'markdown',
+};
+
export const Blob = {
binary: false,
- highlightedData:
- '<h1 data-sourcepos="1:1-1:19" dir="auto">\n<a id="user-content-this-one-is-dummy" class="anchor" href="#this-one-is-dummy" aria-hidden="true"></a>This one is dummy</h1>\n<h2 data-sourcepos="3:1-3:21" dir="auto">\n<a id="user-content-and-has-sub-header" class="anchor" href="#and-has-sub-header" aria-hidden="true"></a>And has sub-header</h2>\n<p data-sourcepos="5:1-5:27" dir="auto">Even some stupid text here</p>',
name: 'dummy.md',
path: 'dummy.md',
rawPath: '/flightjs/flight/snippets/51/raw',
size: 75,
simpleViewer: {
- collapsed: false,
- fileType: 'text',
- loadAsync: true,
- loadingPartialName: 'loading',
- renderError: null,
- tooLarge: false,
- type: 'simple',
+ ...SimpleViewerMock,
},
richViewer: {
- collapsed: false,
- fileType: 'markup',
- loadAsync: true,
- loadingPartialName: 'loading',
- renderError: null,
- tooLarge: false,
- type: 'rich',
+ ...RichViewerMock,
},
};
+export const RichBlobContentMock = {
+ richData: '<h1>Rich</h1>',
+};
+
+export const SimpleBlobContentMock = {
+ plainData: 'Plain',
+};
+
export default {};
diff --git a/spec/frontend/snippets/components/snippet_blob_view_spec.js b/spec/frontend/snippets/components/snippet_blob_view_spec.js
index efc1c6dcef9..c4f1dd0ca35 100644
--- a/spec/frontend/snippets/components/snippet_blob_view_spec.js
+++ b/spec/frontend/snippets/components/snippet_blob_view_spec.js
@@ -1,14 +1,18 @@
-import { shallowMount } from '@vue/test-utils';
+import { mount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui';
import SnippetBlobView from '~/snippets/components/snippet_blob_view.vue';
import BlobHeader from '~/blob/components/blob_header.vue';
import BlobEmbeddable from '~/blob/components/blob_embeddable.vue';
+import BlobContent from '~/blob/components/blob_content.vue';
+import { RichViewer, SimpleViewer } from '~/vue_shared/components/blob_viewers';
import {
SNIPPET_VISIBILITY_PRIVATE,
SNIPPET_VISIBILITY_INTERNAL,
SNIPPET_VISIBILITY_PUBLIC,
} from '~/snippets/constants';
+import { Blob as BlobMock, SimpleViewerMock, RichViewerMock } from 'jest/blob/components/mock_data';
+
describe('Blob Embeddable', () => {
let wrapper;
const snippet = {
@@ -16,27 +20,42 @@ describe('Blob Embeddable', () => {
webUrl: 'https://foo.bar',
visibilityLevel: SNIPPET_VISIBILITY_PUBLIC,
};
+ const dataMock = {
+ blob: BlobMock,
+ activeViewerType: SimpleViewerMock.type,
+ };
- function createComponent(props = {}, loading = false) {
+ function createComponent(
+ props = {},
+ data = dataMock,
+ blobLoading = false,
+ contentLoading = false,
+ ) {
const $apollo = {
queries: {
blob: {
- loading,
+ loading: blobLoading,
+ },
+ blobContent: {
+ loading: contentLoading,
},
},
};
- wrapper = shallowMount(SnippetBlobView, {
+ wrapper = mount(SnippetBlobView, {
propsData: {
snippet: {
...snippet,
...props,
},
},
+ data() {
+ return {
+ ...data,
+ };
+ },
mocks: { $apollo },
});
-
- wrapper.vm.$apollo.queries.blob.loading = false;
}
afterEach(() => {
@@ -48,6 +67,7 @@ describe('Blob Embeddable', () => {
createComponent();
expect(wrapper.find(BlobEmbeddable).exists()).toBe(true);
expect(wrapper.find(BlobHeader).exists()).toBe(true);
+ expect(wrapper.find(BlobContent).exists()).toBe(true);
});
it.each([SNIPPET_VISIBILITY_INTERNAL, SNIPPET_VISIBILITY_PRIVATE, 'foo'])(
@@ -68,9 +88,92 @@ describe('Blob Embeddable', () => {
});
it('shows loading icon while blob data is in flight', () => {
- createComponent({}, true);
+ createComponent({}, dataMock, true);
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
expect(wrapper.find('.snippet-file-content').exists()).toBe(false);
});
+
+ it('sets simple viewer correctly', () => {
+ createComponent();
+ expect(wrapper.find(SimpleViewer).exists()).toBe(true);
+ });
+
+ it('sets rich viewer correctly', () => {
+ const data = Object.assign({}, dataMock, {
+ activeViewerType: RichViewerMock.type,
+ });
+ createComponent({}, data);
+ expect(wrapper.find(RichViewer).exists()).toBe(true);
+ });
+
+ it('correctly switches viewer type', () => {
+ createComponent();
+ expect(wrapper.find(SimpleViewer).exists()).toBe(true);
+
+ wrapper.vm.switchViewer(RichViewerMock.type);
+
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(wrapper.find(RichViewer).exists()).toBe(true);
+ wrapper.vm.switchViewer(SimpleViewerMock.type);
+ })
+ .then(() => {
+ expect(wrapper.find(SimpleViewer).exists()).toBe(true);
+ });
+ });
+
+ describe('URLS with hash', () => {
+ beforeEach(() => {
+ window.location.hash = '#LC2';
+ });
+
+ afterEach(() => {
+ window.location.hash = '';
+ });
+
+ it('renders simple viewer by default if URL contains hash', () => {
+ createComponent();
+
+ expect(wrapper.vm.activeViewerType).toBe(SimpleViewerMock.type);
+ expect(wrapper.find(SimpleViewer).exists()).toBe(true);
+ });
+
+ describe('switchViewer()', () => {
+ it('by default switches to the passed viewer', () => {
+ createComponent();
+
+ wrapper.vm.switchViewer(RichViewerMock.type);
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(wrapper.vm.activeViewerType).toBe(RichViewerMock.type);
+ expect(wrapper.find(RichViewer).exists()).toBe(true);
+
+ wrapper.vm.switchViewer(SimpleViewerMock.type);
+ })
+ .then(() => {
+ expect(wrapper.vm.activeViewerType).toBe(SimpleViewerMock.type);
+ expect(wrapper.find(SimpleViewer).exists()).toBe(true);
+ });
+ });
+
+ it('respects hash over richViewer in the blob when corresponding parameter is passed', () => {
+ createComponent(
+ {},
+ {
+ blob: BlobMock,
+ },
+ );
+ expect(wrapper.vm.blob.richViewer).toEqual(expect.any(Object));
+
+ wrapper.vm.switchViewer(RichViewerMock.type, true);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.activeViewerType).toBe(SimpleViewerMock.type);
+ expect(wrapper.find(SimpleViewer).exists()).toBe(true);
+ });
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/blob_viewers/__snapshots__/simple_viewer_spec.js.snap b/spec/frontend/vue_shared/components/blob_viewers/__snapshots__/simple_viewer_spec.js.snap
new file mode 100644
index 00000000000..87f2a8f9eff
--- /dev/null
+++ b/spec/frontend/vue_shared/components/blob_viewers/__snapshots__/simple_viewer_spec.js.snap
@@ -0,0 +1,86 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Blob Simple Viewer component rendering matches the snapshot 1`] = `
+<div
+ class="file-content code js-syntax-highlight qa-file-content"
+>
+ <div
+ class="line-numbers"
+ >
+ <a
+ class="diff-line-num js-line-number"
+ data-line-number="1"
+ href="#LC1"
+ id="L1"
+ >
+ <gl-icon-stub
+ name="link"
+ size="12"
+ />
+
+ 1
+
+ </a>
+ <a
+ class="diff-line-num js-line-number"
+ data-line-number="2"
+ href="#LC2"
+ id="L2"
+ >
+ <gl-icon-stub
+ name="link"
+ size="12"
+ />
+
+ 2
+
+ </a>
+ <a
+ class="diff-line-num js-line-number"
+ data-line-number="3"
+ href="#LC3"
+ id="L3"
+ >
+ <gl-icon-stub
+ name="link"
+ size="12"
+ />
+
+ 3
+
+ </a>
+ </div>
+
+ <div
+ class="blob-content"
+ >
+ <pre
+ class="code highlight"
+ >
+ <code
+ id="blob-code-content"
+ >
+ <span
+ id="LC1"
+ >
+ First
+ </span>
+
+
+ <span
+ id="LC2"
+ >
+ Second
+ </span>
+
+
+ <span
+ id="LC3"
+ >
+ Third
+ </span>
+ </code>
+ </pre>
+ </div>
+</div>
+`;
diff --git a/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
new file mode 100644
index 00000000000..17ea78b5826
--- /dev/null
+++ b/spec/frontend/vue_shared/components/blob_viewers/rich_viewer_spec.js
@@ -0,0 +1,27 @@
+import { shallowMount } from '@vue/test-utils';
+import RichViewer from '~/vue_shared/components/blob_viewers/rich_viewer.vue';
+
+describe('Blob Rich Viewer component', () => {
+ let wrapper;
+ const content = '<h1 id="markdown">Foo Bar</h1>';
+
+ function createComponent() {
+ wrapper = shallowMount(RichViewer, {
+ propsData: {
+ content,
+ },
+ });
+ }
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders the passed content without transformations', () => {
+ expect(wrapper.html()).toContain(content);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/blob_viewers/simple_viewer_spec.js b/spec/frontend/vue_shared/components/blob_viewers/simple_viewer_spec.js
new file mode 100644
index 00000000000..d12bfc5c686
--- /dev/null
+++ b/spec/frontend/vue_shared/components/blob_viewers/simple_viewer_spec.js
@@ -0,0 +1,81 @@
+import { shallowMount } from '@vue/test-utils';
+import SimpleViewer from '~/vue_shared/components/blob_viewers/simple_viewer.vue';
+import { HIGHLIGHT_CLASS_NAME } from '~/vue_shared/components/blob_viewers/constants';
+
+describe('Blob Simple Viewer component', () => {
+ let wrapper;
+ const contentMock = `<span id="LC1">First</span>\n<span id="LC2">Second</span>\n<span id="LC3">Third</span>`;
+
+ function createComponent(content = contentMock) {
+ wrapper = shallowMount(SimpleViewer, {
+ propsData: {
+ content,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('does not fail if content is empty', () => {
+ const spy = jest.spyOn(window.console, 'error');
+ createComponent('');
+ expect(spy).not.toHaveBeenCalled();
+ });
+
+ describe('rendering', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('matches the snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('renders exactly three lines', () => {
+ expect(wrapper.findAll('.js-line-number')).toHaveLength(3);
+ });
+
+ it('renders the content without transformations', () => {
+ expect(wrapper.html()).toContain(contentMock);
+ });
+ });
+
+ describe('functionality', () => {
+ const scrollIntoViewMock = jest.fn();
+ HTMLElement.prototype.scrollIntoView = scrollIntoViewMock;
+
+ beforeEach(() => {
+ window.location.hash = '#LC2';
+ createComponent();
+ });
+
+ afterEach(() => {
+ window.location.hash = '';
+ });
+
+ it('scrolls to requested line when rendered', () => {
+ const linetoBeHighlighted = wrapper.find('#LC2');
+ expect(scrollIntoViewMock).toHaveBeenCalled();
+ expect(wrapper.vm.highlightedLine).toBe(linetoBeHighlighted.element);
+ expect(linetoBeHighlighted.classes()).toContain(HIGHLIGHT_CLASS_NAME);
+ });
+
+ it('switches highlighting when another line is selected', () => {
+ const currentlyHighlighted = wrapper.find('#LC2');
+ const hash = '#LC3';
+ const linetoBeHighlighted = wrapper.find(hash);
+
+ expect(wrapper.vm.highlightedLine).toBe(currentlyHighlighted.element);
+
+ wrapper.vm.scrollToLine(hash);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(wrapper.vm.highlightedLine).toBe(linetoBeHighlighted.element);
+ expect(currentlyHighlighted.classes()).not.toContain(HIGHLIGHT_CLASS_NAME);
+ expect(linetoBeHighlighted.classes()).toContain(HIGHLIGHT_CLASS_NAME);
+ });
+ });
+ });
+});
diff --git a/spec/helpers/environments_helper_spec.rb b/spec/helpers/environments_helper_spec.rb
index ca0360b363e..b72fbc9fd3c 100644
--- a/spec/helpers/environments_helper_spec.rb
+++ b/spec/helpers/environments_helper_spec.rb
@@ -20,7 +20,7 @@ describe EnvironmentsHelper do
expect(metrics_data).to include(
'settings-path' => edit_project_service_path(project, 'prometheus'),
'clusters-path' => project_clusters_path(project),
- 'current-environment-name': environment.name,
+ 'current-environment-name' => environment.name,
'documentation-path' => help_page_path('administration/monitoring/prometheus/index.md'),
'empty-getting-started-svg-path' => match_asset_path('/assets/illustrations/monitoring/getting_started.svg'),
'empty-loading-svg-path' => match_asset_path('/assets/illustrations/monitoring/loading.svg'),