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>2019-10-01 00:06:41 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-01 00:06:41 +0300
commit08f4ce10c04d705148a7e14556443b9e3aee6821 (patch)
treeba58b29874803db12ebec690fb4416b6208ee750 /spec
parentb4cdff15ca53312ccbbafe4effac85b1ee4420ae (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/issues/issues_tabs_spec.rb56
-rw-r--r--spec/frontend/performance_bar/components/detailed_metric_spec.js111
-rw-r--r--spec/frontend/performance_bar/components/performance_bar_app_spec.js20
-rw-r--r--spec/frontend/performance_bar/components/request_selector_spec.js64
-rw-r--r--spec/frontend/performance_bar/components/request_warning_spec.js33
-rw-r--r--spec/javascripts/performance_bar/components/detailed_metric_spec.js109
-rw-r--r--spec/javascripts/performance_bar/components/performance_bar_app_spec.js29
-rw-r--r--spec/javascripts/performance_bar/components/request_selector_spec.js46
-rw-r--r--spec/support/helpers/kubernetes_helpers.rb27
9 files changed, 253 insertions, 242 deletions
diff --git a/spec/features/issues/issues_tabs_spec.rb b/spec/features/issues/issues_tabs_spec.rb
deleted file mode 100644
index 66d55dd9021..00000000000
--- a/spec/features/issues/issues_tabs_spec.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe 'Issue page tabs', :js do
- let(:user) { create(:user) }
- let(:project) { create(:project, :public) }
- let(:issue) { create(:issue, author: user, assignees: [user], project: project) }
-
- describe 'discussions tab counter' do
- before do
- stub_licensed_features(design_management: true)
- stub_feature_flags(design_management_flag: true)
- allow(Ability).to receive(:allowed?) { true }
- end
-
- subject do
- sign_in(user)
-
- visit project_issue_path(project, issue)
-
- wait_for_requests
-
- find('#discussion')
- end
-
- context 'new issue' do
- it 'displays count of 0' do
- is_expected.to have_content('Discussion 0')
- end
- end
-
- context 'issue with 2 system notes and 1 discussion' do
- let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: project, note: "This is good") }
-
- before do
- create(:system_note, noteable: issue, project: project, author: user, note: 'description updated')
- create(:system_note, noteable: issue, project: project, author: user, note: 'description updated')
- end
-
- it 'displays count of 1' do
- is_expected.to have_content('Discussion 1')
- end
-
- context 'with 1 reply' do
- before do
- create(:note, noteable: issue, in_reply_to: discussion, discussion_id: discussion.discussion_id, note: 'I also think this is good')
- end
-
- it 'displays count of 2' do
- is_expected.to have_content('Discussion 2')
- end
- end
- end
- end
-end
diff --git a/spec/frontend/performance_bar/components/detailed_metric_spec.js b/spec/frontend/performance_bar/components/detailed_metric_spec.js
new file mode 100644
index 00000000000..74f242431a1
--- /dev/null
+++ b/spec/frontend/performance_bar/components/detailed_metric_spec.js
@@ -0,0 +1,111 @@
+import DetailedMetric from '~/performance_bar/components/detailed_metric.vue';
+import RequestWarning from '~/performance_bar/components/request_warning.vue';
+import { shallowMount } from '@vue/test-utils';
+
+describe('detailedMetric', () => {
+ const createComponent = props =>
+ shallowMount(DetailedMetric, {
+ propsData: {
+ ...props,
+ },
+ });
+
+ describe('when the current request has no details', () => {
+ const wrapper = createComponent({
+ currentRequest: {},
+ metric: 'gitaly',
+ header: 'Gitaly calls',
+ details: 'details',
+ keys: ['feature', 'request'],
+ });
+
+ it('does not render the element', () => {
+ expect(wrapper.isEmpty()).toBe(true);
+ });
+ });
+
+ describe('when the current request has details', () => {
+ const requestDetails = [
+ { duration: '100', feature: 'find_commit', request: 'abcdef', backtrace: ['hello', 'world'] },
+ { duration: '23', feature: 'rebase_in_progress', request: '', backtrace: ['world', 'hello'] },
+ ];
+
+ describe('with a default metric name', () => {
+ const wrapper = createComponent({
+ currentRequest: {
+ details: {
+ gitaly: {
+ duration: '123ms',
+ calls: '456',
+ details: requestDetails,
+ warnings: ['gitaly calls: 456 over 30'],
+ },
+ },
+ },
+ metric: 'gitaly',
+ header: 'Gitaly calls',
+ keys: ['feature', 'request'],
+ });
+
+ it('displays details', () => {
+ expect(wrapper.text().replace(/\s+/g, ' ')).toContain('123ms / 456');
+ });
+
+ it('adds a modal with a table of the details', () => {
+ wrapper
+ .findAll('.performance-bar-modal td:nth-child(1)')
+ .wrappers.forEach((duration, index) => {
+ expect(duration.text()).toContain(requestDetails[index].duration);
+ });
+
+ wrapper
+ .findAll('.performance-bar-modal td:nth-child(2)')
+ .wrappers.forEach((feature, index) => {
+ expect(feature.text()).toContain(requestDetails[index].feature);
+ });
+
+ wrapper
+ .findAll('.performance-bar-modal td:nth-child(2)')
+ .wrappers.forEach((request, index) => {
+ expect(request.text()).toContain(requestDetails[index].request);
+ });
+
+ expect(wrapper.find('.text-expander.js-toggle-button')).not.toBeNull();
+
+ wrapper.findAll('.performance-bar-modal td:nth-child(2)').wrappers.forEach(request => {
+ expect(request.text()).toContain('world');
+ });
+ });
+
+ it('displays the metric title', () => {
+ expect(wrapper.text()).toContain('gitaly');
+ });
+
+ it('displays request warnings', () => {
+ expect(wrapper.find(RequestWarning).exists()).toBe(true);
+ });
+ });
+
+ describe('when using a custom metric title', () => {
+ const wrapper = createComponent({
+ currentRequest: {
+ details: {
+ gitaly: {
+ duration: '123ms',
+ calls: '456',
+ details: requestDetails,
+ },
+ },
+ },
+ metric: 'gitaly',
+ title: 'custom',
+ header: 'Gitaly calls',
+ keys: ['feature', 'request'],
+ });
+
+ it('displays the custom title', () => {
+ expect(wrapper.text()).toContain('custom');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/performance_bar/components/performance_bar_app_spec.js b/spec/frontend/performance_bar/components/performance_bar_app_spec.js
new file mode 100644
index 00000000000..ba403dd6209
--- /dev/null
+++ b/spec/frontend/performance_bar/components/performance_bar_app_spec.js
@@ -0,0 +1,20 @@
+import PerformanceBarApp from '~/performance_bar/components/performance_bar_app.vue';
+import PerformanceBarStore from '~/performance_bar/stores/performance_bar_store';
+import { shallowMount } from '@vue/test-utils';
+
+describe('performance bar app', () => {
+ const store = new PerformanceBarStore();
+ const wrapper = shallowMount(PerformanceBarApp, {
+ propsData: {
+ store,
+ env: 'development',
+ requestId: '123',
+ peekUrl: '/-/peek/results',
+ profileUrl: '?lineprofiler=true',
+ },
+ });
+
+ it('sets the class to match the environment', () => {
+ expect(wrapper.element.getAttribute('class')).toContain('development');
+ });
+});
diff --git a/spec/frontend/performance_bar/components/request_selector_spec.js b/spec/frontend/performance_bar/components/request_selector_spec.js
new file mode 100644
index 00000000000..a4ed55fbf15
--- /dev/null
+++ b/spec/frontend/performance_bar/components/request_selector_spec.js
@@ -0,0 +1,64 @@
+import RequestSelector from '~/performance_bar/components/request_selector.vue';
+import { shallowMount } from '@vue/test-utils';
+
+describe('request selector', () => {
+ const requests = [
+ {
+ id: '123',
+ url: 'https://gitlab.com/',
+ hasWarnings: false,
+ },
+ {
+ id: '456',
+ url: 'https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/1',
+ hasWarnings: false,
+ },
+ {
+ id: '789',
+ url: 'https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/1.json?serializer=widget',
+ hasWarnings: false,
+ },
+ {
+ id: 'abc',
+ url: 'https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/1/discussions.json',
+ hasWarnings: true,
+ },
+ ];
+
+ const wrapper = shallowMount(RequestSelector, {
+ propsData: {
+ requests,
+ currentRequest: requests[1],
+ },
+ });
+
+ function optionText(requestId) {
+ return wrapper
+ .find(`[value='${requestId}']`)
+ .text()
+ .trim();
+ }
+
+ it('displays the last component of the path', () => {
+ expect(optionText(requests[2].id)).toEqual('1.json?serializer=widget');
+ });
+
+ it('keeps the last two components of the path when the last component is numeric', () => {
+ expect(optionText(requests[1].id)).toEqual('merge_requests/1');
+ });
+
+ it('ignores trailing slashes', () => {
+ expect(optionText(requests[0].id)).toEqual('gitlab.com');
+ });
+
+ it('has a warning icon if any requests have warnings', () => {
+ expect(wrapper.find('span > gl-emoji').element.dataset.name).toEqual('warning');
+ });
+
+ it('adds a warning glyph to requests with warnings', () => {
+ const requestValue = wrapper.find('[value="abc"]').text();
+
+ expect(requestValue).toContain('discussions.json');
+ expect(requestValue).toContain('(!)');
+ });
+});
diff --git a/spec/frontend/performance_bar/components/request_warning_spec.js b/spec/frontend/performance_bar/components/request_warning_spec.js
new file mode 100644
index 00000000000..6d8bfba56f6
--- /dev/null
+++ b/spec/frontend/performance_bar/components/request_warning_spec.js
@@ -0,0 +1,33 @@
+import RequestWarning from '~/performance_bar/components/request_warning.vue';
+import { shallowMount } from '@vue/test-utils';
+
+describe('request warning', () => {
+ const htmlId = 'request-123';
+
+ describe('when the request has warnings', () => {
+ const wrapper = shallowMount(RequestWarning, {
+ propsData: {
+ htmlId,
+ warnings: ['gitaly calls: 30 over 10', 'gitaly duration: 1500 over 1000'],
+ },
+ });
+
+ it('adds a warning emoji with the correct ID', () => {
+ expect(wrapper.find('span[id]').attributes('id')).toEqual(htmlId);
+ expect(wrapper.find('span[id] gl-emoji').element.dataset.name).toEqual('warning');
+ });
+ });
+
+ describe('when the request does not have warnings', () => {
+ const wrapper = shallowMount(RequestWarning, {
+ propsData: {
+ htmlId,
+ warnings: [],
+ },
+ });
+
+ it('does nothing', () => {
+ expect(wrapper.isEmpty()).toBe(true);
+ });
+ });
+});
diff --git a/spec/javascripts/performance_bar/components/detailed_metric_spec.js b/spec/javascripts/performance_bar/components/detailed_metric_spec.js
deleted file mode 100644
index 0486b5fa3db..00000000000
--- a/spec/javascripts/performance_bar/components/detailed_metric_spec.js
+++ /dev/null
@@ -1,109 +0,0 @@
-import Vue from 'vue';
-import detailedMetric from '~/performance_bar/components/detailed_metric.vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-
-describe('detailedMetric', () => {
- let vm;
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('when the current request has no details', () => {
- beforeEach(() => {
- vm = mountComponent(Vue.extend(detailedMetric), {
- currentRequest: {},
- metric: 'gitaly',
- header: 'Gitaly calls',
- details: 'details',
- keys: ['feature', 'request'],
- });
- });
-
- it('does not render the element', () => {
- expect(vm.$el.innerHTML).toEqual(undefined);
- });
- });
-
- describe('when the current request has details', () => {
- const requestDetails = [
- { duration: '100', feature: 'find_commit', request: 'abcdef', backtrace: ['hello', 'world'] },
- { duration: '23', feature: 'rebase_in_progress', request: '', backtrace: ['world', 'hello'] },
- ];
-
- beforeEach(() => {
- vm = mountComponent(Vue.extend(detailedMetric), {
- currentRequest: {
- details: {
- gitaly: {
- duration: '123ms',
- calls: '456',
- details: requestDetails,
- },
- },
- },
- metric: 'gitaly',
- header: 'Gitaly calls',
- keys: ['feature', 'request'],
- });
- });
-
- it('diplays details', () => {
- expect(vm.$el.innerText.replace(/\s+/g, ' ')).toContain('123ms / 456');
- });
-
- it('adds a modal with a table of the details', () => {
- vm.$el
- .querySelectorAll('.performance-bar-modal td:nth-child(1)')
- .forEach((duration, index) => {
- expect(duration.innerText).toContain(requestDetails[index].duration);
- });
-
- vm.$el
- .querySelectorAll('.performance-bar-modal td:nth-child(2)')
- .forEach((feature, index) => {
- expect(feature.innerText).toContain(requestDetails[index].feature);
- });
-
- vm.$el
- .querySelectorAll('.performance-bar-modal td:nth-child(2)')
- .forEach((request, index) => {
- expect(request.innerText).toContain(requestDetails[index].request);
- });
-
- expect(vm.$el.querySelector('.text-expander.js-toggle-button')).not.toBeNull();
-
- vm.$el.querySelectorAll('.performance-bar-modal td:nth-child(2)').forEach(request => {
- expect(request.innerText).toContain('world');
- });
- });
-
- it('displays the metric title', () => {
- expect(vm.$el.innerText).toContain('gitaly');
- });
-
- describe('when using a custom metric title', () => {
- beforeEach(() => {
- vm = mountComponent(Vue.extend(detailedMetric), {
- currentRequest: {
- details: {
- gitaly: {
- duration: '123ms',
- calls: '456',
- details: requestDetails,
- },
- },
- },
- metric: 'gitaly',
- title: 'custom',
- header: 'Gitaly calls',
- keys: ['feature', 'request'],
- });
- });
-
- it('displays the custom title', () => {
- expect(vm.$el.innerText).toContain('custom');
- });
- });
- });
-});
diff --git a/spec/javascripts/performance_bar/components/performance_bar_app_spec.js b/spec/javascripts/performance_bar/components/performance_bar_app_spec.js
deleted file mode 100644
index 7926db44429..00000000000
--- a/spec/javascripts/performance_bar/components/performance_bar_app_spec.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import Vue from 'vue';
-import performanceBarApp from '~/performance_bar/components/performance_bar_app.vue';
-import PerformanceBarStore from '~/performance_bar/stores/performance_bar_store';
-
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-
-describe('performance bar app', () => {
- let vm;
-
- beforeEach(() => {
- const store = new PerformanceBarStore();
-
- vm = mountComponent(Vue.extend(performanceBarApp), {
- store,
- env: 'development',
- requestId: '123',
- peekUrl: '/-/peek/results',
- profileUrl: '?lineprofiler=true',
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('sets the class to match the environment', () => {
- expect(vm.$el.getAttribute('class')).toContain('development');
- });
-});
diff --git a/spec/javascripts/performance_bar/components/request_selector_spec.js b/spec/javascripts/performance_bar/components/request_selector_spec.js
deleted file mode 100644
index 3c2169de877..00000000000
--- a/spec/javascripts/performance_bar/components/request_selector_spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import Vue from 'vue';
-import requestSelector from '~/performance_bar/components/request_selector.vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-
-describe('request selector', () => {
- const requests = [
- { id: '123', url: 'https://gitlab.com/' },
- {
- id: '456',
- url: 'https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/1',
- },
- {
- id: '789',
- url: 'https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/1.json?serializer=widget',
- },
- ];
-
- let vm;
-
- beforeEach(() => {
- vm = mountComponent(Vue.extend(requestSelector), {
- requests,
- currentRequest: requests[1],
- });
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- function optionText(requestId) {
- return vm.$el.querySelector(`[value='${requestId}']`).innerText.trim();
- }
-
- it('displays the last component of the path', () => {
- expect(optionText(requests[2].id)).toEqual('1.json?serializer=widget');
- });
-
- it('keeps the last two components of the path when the last component is numeric', () => {
- expect(optionText(requests[1].id)).toEqual('merge_requests/1');
- });
-
- it('ignores trailing slashes', () => {
- expect(optionText(requests[0].id)).toEqual('gitlab.com');
- });
-});
diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb
index 538a5b8ef3c..36391543768 100644
--- a/spec/support/helpers/kubernetes_helpers.rb
+++ b/spec/support/helpers/kubernetes_helpers.rb
@@ -11,6 +11,10 @@ module KubernetesHelpers
kube_response(kube_pods_body)
end
+ def kube_pod_response
+ kube_response(kube_pod)
+ end
+
def kube_logs_response
kube_response(kube_logs_body)
end
@@ -63,11 +67,30 @@ module KubernetesHelpers
WebMock.stub_request(:get, pods_url).to_return(response || kube_pods_response)
end
- def stub_kubeclient_logs(pod_name, namespace, status: nil)
+ def stub_kubeclient_pod_details(pod, namespace, status: nil)
stub_kubeclient_discover(service.api_url)
- logs_url = service.api_url + "/api/v1/namespaces/#{namespace}/pods/#{pod_name}/log?tailLines=#{Clusters::Platforms::Kubernetes::LOGS_LIMIT}"
+
+ pod_url = service.api_url + "/api/v1/namespaces/#{namespace}/pods/#{pod}"
response = { status: status } if status
+ WebMock.stub_request(:get, pod_url).to_return(response || kube_pod_response)
+ end
+
+ def stub_kubeclient_logs(pod_name, namespace, container: nil, status: nil, message: nil)
+ stub_kubeclient_discover(service.api_url)
+
+ if container
+ container_query_param = "container=#{container}&"
+ end
+
+ logs_url = service.api_url + "/api/v1/namespaces/#{namespace}/pods/#{pod_name}" \
+ "/log?#{container_query_param}tailLines=#{Clusters::Platforms::Kubernetes::LOGS_LIMIT}"
+
+ if status
+ response = { status: status }
+ response[:body] = { message: message }.to_json if message
+ end
+
WebMock.stub_request(:get, logs_url).to_return(response || kube_logs_response)
end