Commit bd8a202d authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 59a34981
......@@ -6,7 +6,7 @@ const newClusterViews = [':clusters:new', ':clusters:create_gcp', ':clusters:cre
const isProjectLevelCluster = page => page.startsWith('project:clusters');
export default (document, gon) => {
export default document => {
const { page } = document.body.dataset;
const isNewClusterView = newClusterViews.some(view => page.endsWith(view));
......@@ -19,17 +19,15 @@ export default (document, gon) => {
initGkeDropdowns();
if (gon.features.createEksClusters) {
import(/* webpackChunkName: 'eks_cluster' */ '~/create_cluster/eks_cluster')
.then(({ default: initCreateEKSCluster }) => {
const el = document.querySelector('.js-create-eks-cluster-form-container');
import(/* webpackChunkName: 'eks_cluster' */ '~/create_cluster/eks_cluster')
.then(({ default: initCreateEKSCluster }) => {
const el = document.querySelector('.js-create-eks-cluster-form-container');
if (el) {
initCreateEKSCluster(el);
}
})
.catch(() => {});
}
if (el) {
initCreateEKSCluster(el);
}
})
.catch(() => {});
if (isProjectLevelCluster(page)) {
initGkeNamespace();
......
......@@ -12,9 +12,6 @@ class Clusters::ClustersController < Clusters::BaseController
before_action :authorize_update_cluster!, only: [:update]
before_action :authorize_admin_cluster!, only: [:destroy, :clear_cache]
before_action :update_applications_status, only: [:cluster_status]
before_action only: [:new, :create_gcp] do
push_frontend_feature_flag(:create_eks_clusters)
end
before_action only: [:show] do
push_frontend_feature_flag(:enable_cluster_application_elastic_stack)
push_frontend_feature_flag(:enable_cluster_application_crossplane)
......@@ -42,8 +39,6 @@ class Clusters::ClustersController < Clusters::BaseController
end
def new
return unless Feature.enabled?(:create_eks_clusters)
if params[:provider] == 'aws'
@aws_role = current_user.aws_role || Aws::Role.new
@aws_role.ensure_role_external_id!
......@@ -113,6 +108,7 @@ class Clusters::ClustersController < Clusters::BaseController
generate_gcp_authorize_url
validate_gcp_token
user_cluster
params[:provider] = 'gcp'
render :new, locals: { active_tab: 'create' }
end
......@@ -277,8 +273,7 @@ class Clusters::ClustersController < Clusters::BaseController
end
def generate_gcp_authorize_url
params = Feature.enabled?(:create_eks_clusters) ? { provider: :gke } : {}
state = generate_session_key_redirect(clusterable.new_path(params).to_s)
state = generate_session_key_redirect(clusterable.new_path(provider: :gcp).to_s)
@authorize_url = GoogleApi::CloudPlatform::Client.new(
nil, callback_google_api_auth_url,
......
......@@ -26,13 +26,13 @@ module Projects
def delete_tags(tags_to_delete, tags_by_digest)
deleted_digests = group_by_digest(tags_to_delete).select do |digest, tags|
delete_tag_digest(digest, tags, tags_by_digest[digest])
delete_tag_digest(tags, tags_by_digest[digest])
end
deleted_digests.values.flatten
end
def delete_tag_digest(digest, tags, other_tags)
def delete_tag_digest(tags, other_tags)
# Issue: https://gitlab.com/gitlab-org/gitlab-foss/issues/21405
# we have to remove all tags due
# to Docker Distribution bug unable
......
......@@ -24,32 +24,36 @@ module Projects
dummy_manifest = container_repository.client.generate_empty_manifest(container_repository.path)
return error('could not generate manifest') if dummy_manifest.nil?
# update the manifests of the tags with the new dummy image
deleted_tags = []
tag_digests = []
deleted_tags = replace_tag_manifests(container_repository, dummy_manifest, tag_names)
# Deletes the dummy image
# All created tag digests are the same since they all have the same dummy image.
# a single delete is sufficient to remove all tags with it
if deleted_tags.any? && container_repository.delete_tag_by_digest(deleted_tags.values.first)
success(deleted: deleted_tags.keys)
else
error('could not delete tags')
end
end
# update the manifests of the tags with the new dummy image
def replace_tag_manifests(container_repository, dummy_manifest, tag_names)
deleted_tags = {}
tag_names.each do |name|
digest = container_repository.client.put_tag(container_repository.path, name, dummy_manifest)
next unless digest
deleted_tags << name
tag_digests << digest
deleted_tags[name] = digest
end
# make sure the digests are the same (it should always be)
tag_digests.uniq!
digests = deleted_tags.values.uniq
# rubocop: disable CodeReuse/ActiveRecord
Gitlab::Sentry.track_exception(ArgumentError.new('multiple tag digests')) if tag_digests.many?
Gitlab::Sentry.track_exception(ArgumentError.new('multiple tag digests')) if digests.many?
# Deletes the dummy image
# All created tag digests are the same since they all have the same dummy image.
# a single delete is sufficient to remove all tags with it
if tag_digests.any? && container_repository.delete_tag_by_digest(tag_digests.first)
success(deleted: deleted_tags)
else
error('could not delete tags')
end
deleted_tags
end
end
end
......
......@@ -8,5 +8,5 @@
= render_if_exists 'admin/application_settings/slack'
= render 'admin/application_settings/third_party_offers'
= render 'admin/application_settings/snowplow'
= render 'admin/application_settings/eks' if Feature.enabled?(:create_eks_clusters)
= render 'admin/application_settings/eks'
= render 'clusters/clusters/gcp/header'
- if @valid_gcp_token
= render 'clusters/clusters/gcp/form'
- elsif @authorize_url
= render 'clusters/clusters/gcp/signin_with_google_button'
- else
= render 'clusters/clusters/gcp/gcp_not_configured'
.signin-with-google
- create_account_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: 'https://accounts.google.com/SignUpWithoutGmail?service=cloudconsole&continue=https%3A%2F%2Fconsole.cloud.google.com%2Ffreetrial%3Futm_campaign%3D2018_cpanel%26utm_source%3Dgitlab%26utm_medium%3Dreferral' }
= link_to(image_tag('auth_buttons/signin_with_google.png', width: '191px', alt: _('Sign in with Google')), @authorize_url)
= s_('or %{link_start}create a new Google account%{link_end}').html_safe % { link_start: create_account_link, link_end: '</a>'.html_safe }
- breadcrumb_title _('Kubernetes')
- page_title _('Kubernetes Cluster')
- create_eks_enabled = Feature.enabled?(:create_eks_clusters)
- active_tab = local_assigns.fetch(:active_tab, 'create')
= javascript_include_tag 'https://apis.google.com/js/api.js'
......@@ -14,21 +13,14 @@
%li.nav-item{ role: 'presentation' }
%a.nav-link{ href: '#create-cluster-pane', id: 'create-cluster-tab', class: active_when(active_tab == 'create'), data: { toggle: 'tab' }, role: 'tab' }
%span
- if create_eks_enabled
= create_new_cluster_label(provider: params[:provider])
- else
= create_new_cluster_label(provider: 'gcp')
= create_new_cluster_label(provider: params[:provider])
%li.nav-item{ role: 'presentation' }
%a.nav-link{ href: '#add-cluster-pane', id: 'add-cluster-tab', class: active_when(active_tab == 'add'), data: { toggle: 'tab' }, role: 'tab' }
%span Add existing cluster
.tab-content.gitlab-tab-content
- if create_eks_enabled
.tab-pane{ id: 'create-cluster-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' }
= render new_cluster_partial(provider: params[:provider])
- else
.tab-pane{ id: 'create-cluster-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' }
= render new_cluster_partial(provider: 'gcp')
.tab-pane{ id: 'create-cluster-pane', class: active_when(active_tab == 'create'), role: 'tabpanel' }
= render new_cluster_partial(provider: params[:provider])
.tab-pane{ id: 'add-cluster-pane', class: active_when(active_tab == 'add'), role: 'tabpanel' }
= render 'clusters/clusters/user/header'
......
---
title: Enable creating Amazon EKS clusters from GitLab
merge_request: 20333
author:
type: added
......@@ -211,33 +211,9 @@ GitLab supports:
Before creating your first cluster on Amazon EKS with GitLab's integration,
make sure the following requirements are met:
- Self-managed GitLab instances have the `create_eks_clusters` feature flag enabled.
- An [Amazon Web Services](https://aws.amazon.com/) account is set up and you are able to log in.
- You have permissions to manage IAM resources.
##### Enable the `create_eks_clusters` feature flag **(CORE ONLY)**
Self-managed instances must have the feature flag `create_eks_clusters` enabled to create
EKS clusters. To enable EKS cluster creation, ask a GitLab administrator with Rails console access
to run the following command:
```ruby
Feature.enable(:create_eks_clusters)
```
To have it enabled for a specific project only, ask a GitLab administrator to run the following
command using a Rails console:
```ruby
Feature.enable(:create_eks_clusters, Project.find_by_full_path('my_group/my_project'))
```
To have this feature disabled, ask a GitLab administrator to run the following command:
```ruby
Feature.disable(:create_eks_clusters)
```
##### Additional requirements for self-managed instances
If you are using a self-managed GitLab instance, GitLab must first
......
......@@ -15948,9 +15948,6 @@ msgstr ""
msgid "Sign in via 2FA code"
msgstr ""
msgid "Sign in with Google"
msgstr ""
msgid "Sign in with Single Sign-On"
msgstr ""
......@@ -21263,9 +21260,6 @@ msgstr ""
msgid "opened %{timeAgoString} by %{user}"
msgstr ""
msgid "or %{link_start}create a new Google account%{link_end}"
msgstr ""
msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
......
......@@ -84,29 +84,11 @@ describe Admin::ClustersController do
GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(key)
end
before do
stub_feature_flags(create_eks_clusters: false)
allow(SecureRandom).to receive(:hex).and_return(key)
end
it 'has authorize_url' do
get_new
expect(assigns(:authorize_url)).to include(key)
expect(session[session_key_for_redirect_uri]).to eq(new_admin_cluster_path)
end
context 'when create_eks_clusters feature flag is enabled' do
before do
stub_feature_flags(create_eks_clusters: true)
end
context 'when selected provider is gke and no valid gcp token exists' do
it 'redirects to gcp authorize_url' do
get_new
context 'when selected provider is gke and no valid gcp token exists' do
it 'redirects to gcp authorize_url' do
get_new
expect(response).to redirect_to(assigns(:authorize_url))
end
expect(response).to redirect_to(assigns(:authorize_url))
end
end
end
......
......@@ -97,29 +97,15 @@ describe Groups::ClustersController do
end
before do
stub_feature_flags(create_eks_clusters: false)
allow(SecureRandom).to receive(:hex).and_return(key)
end
it 'has authorize_url' do
it 'redirects to gcp authorize_url' do
go
expect(assigns(:authorize_url)).to include(key)
expect(session[session_key_for_redirect_uri]).to eq(new_group_cluster_path(group))
end
context 'when create_eks_clusters feature flag is enabled' do
before do
stub_feature_flags(create_eks_clusters: true)
end
context 'when selected provider is gke and no valid gcp token exists' do
it 'redirects to gcp authorize_url' do
go
expect(response).to redirect_to(assigns(:authorize_url))
end
end
expect(session[session_key_for_redirect_uri]).to eq(new_group_cluster_path(group, provider: :gcp))
expect(response).to redirect_to(assigns(:authorize_url))
end
end
......
......@@ -95,29 +95,15 @@ describe Projects::ClustersController do
end
before do
stub_feature_flags(create_eks_clusters: false)
allow(SecureRandom).to receive(:hex).and_return(key)
end
it 'has authorize_url' do
it 'redirects to gcp authorize_url' do
go
expect(assigns(:authorize_url)).to include(key)
expect(session[session_key_for_redirect_uri]).to eq(new_project_cluster_path(project))
end
context 'when create_eks_clusters feature flag is enabled' do
before do
stub_feature_flags(create_eks_clusters: true)
end
context 'when selected provider is gke and no valid gcp token exists' do
it 'redirects to gcp authorize_url' do
go
expect(response).to redirect_to(assigns(:authorize_url))
end
end
expect(session[session_key_for_redirect_uri]).to eq(new_project_cluster_path(project, provider: :gcp))
expect(response).to redirect_to(assigns(:authorize_url))
end
end
......
......@@ -18,8 +18,6 @@ describe 'Gcp Cluster', :js do
let(:project_id) { 'test-project-1234' }
before do
stub_feature_flags(create_eks_clusters: false)
allow_any_instance_of(Projects::ClustersController)
.to receive(:token_in_session).and_return('token')
allow_any_instance_of(Projects::ClustersController)
......@@ -31,7 +29,8 @@ describe 'Gcp Cluster', :js do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
click_link 'Create new Cluster on GKE'
click_link 'Create new Cluster'
click_link 'Google GKE'
end
context 'when user filled form with valid parameters' do
......@@ -147,21 +146,6 @@ describe 'Gcp Cluster', :js do
end
end
context 'when user has not signed with Google' do
before do
stub_feature_flags(create_eks_clusters: false)
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
click_link 'Create new Cluster on GKE'
end
it 'user sees a login page' do
expect(page).to have_css('.signin-with-google')
expect(page).to have_link('Google account')
end
end
context 'when a user cannot edit the environment scope' do
before do
visit project_clusters_path(project)
......@@ -177,7 +161,6 @@ describe 'Gcp Cluster', :js do
context 'when user has not dismissed GCP signup offer' do
before do
stub_feature_flags(create_eks_clusters: false)
visit project_clusters_path(project)
end
......@@ -190,18 +173,10 @@ describe 'Gcp Cluster', :js do
expect(page).to have_css('.gcp-signup-offer')
end
it 'user sees offer on cluster GCP login page' do
click_link 'Add Kubernetes cluster'
click_link 'Create new Cluster on GKE'
expect(page).to have_css('.gcp-signup-offer')
end
end
context 'when user has dismissed GCP signup offer' do
before do
stub_feature_flags(create_eks_clusters: false)
visit project_clusters_path(project)
end
......
......@@ -49,41 +49,20 @@ describe 'Clusters', :js do
end
end
context 'when user has not signed in Google' do
context 'user visits create cluster page' do
before do
stub_feature_flags(create_eks_clusters: false)
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
click_link 'Create new Cluster on GKE'
click_link 'Create new Cluster'
end
it 'user sees a login page' do
expect(page).to have_css('.signin-with-google')
expect(page).to have_link('Google account')
it 'user sees a link to create a GKE cluster' do
expect(page).to have_link('Google GKE')
end
end
context 'when create_eks_clusters feature flag is enabled' do
before do
stub_feature_flags(create_eks_clusters: true)
end
context 'when user access create cluster page' do
before do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
click_link 'Create new Cluster'
end
it 'user sees a link to create a GKE cluster' do
expect(page).to have_link('Google GKE')
end
it 'user sees a link to create an EKS cluster' do
expect(page).to have_link('Amazon EKS')
end
it 'user sees a link to create an EKS cluster' do
expect(page).to have_link('Amazon EKS')
end
end
end
......@@ -4,15 +4,14 @@ import diffModule from '~/diffs/store/modules';
import SettingsDropdown from '~/diffs/components/settings_dropdown.vue';
import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('Diff settiings dropdown component', () => {
let vm;
let actions;
function createComponent(extendStore = () => {}) {
const localVue = createLocalVue();
localVue.use(Vuex);
const store = new Vuex.Store({
modules: {
diffs: {
......@@ -26,9 +25,10 @@ describe('Diff settiings dropdown component', () => {
extendStore(store);
vm = mount(SettingsDropdown, {
vm = mount(localVue.extend(SettingsDropdown), {
localVue,
store,
sync: false,
});
}
......
import Vue from 'vue';
import frequentItemsListItemComponent from '~/frequent_items/components/frequent_items_list_item.vue';
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { trimText } from 'spec/helpers/text_helper';
import { mockProject } from '../mock_data'; // can also use 'mockGroup', but not useful to test here
const createComponent = () => {
const Component = Vue.extend(frequentItemsListItemComponent);
return shallowMount(Component, {
propsData: {
itemId: mockProject.id,
itemName: mockProject.name,
namespace: mockProject.namespace,
webUrl: mockProject.webUrl,
avatarUrl: mockProject.avatarUrl,
},
});
};
const localVue = createLocalVue();
describe('FrequentItemsListItemComponent', () => {
let wrapper;
let vm;
beforeEach(() => {
wrapper = createComponent();
({ vm } = wrapper);
});
const createComponent = (props = {}) => {
wrapper = shallowMount(localVue.extend(frequentItemsListItemComponent), {
propsData: {
itemId: mockProject.id,
itemName: mockProject.name,
namespace: mockProject.namespace,
webUrl: mockProject.webUrl,
avatarUrl: mockProject.avatarUrl,
...props,
},
sync: false,
localVue,
});
};
afterEach(() => {
vm.$destroy();
wrapper.destroy();
wrapper = null;
});
describe('computed', () => {
describe('hasAvatar', () => {
it('should return `true` or `false` if whether avatar is present or not', () => {
wrapper.setProps({ avatarUrl: 'path/to/avatar.png' });
createComponent({ avatarUrl: 'path/to/avatar.png' });
expect(vm.hasAvatar).toBe(true);
expect(wrapper.vm.hasAvatar).toBe(true);
});
wrapper.setProps({ avatarUrl: null });
it('should return `false` if avatar is not present', () => {
createComponent({ avatarUrl: null });
expect(vm.hasAvatar).toBe(false);
expect(wrapper.vm.hasAvatar).toBe(false);
});
});
describe('highlightedItemName', () => {
it('should enclose part of project name in <b> & </b> which matches with `matcher` prop', () => {
wrapper.setProps({ matcher: 'lab' });
createComponent({ matcher: 'lab' });
expect(wrapper.find('.js-frequent-items-item-title').html()).toContain(
'<b>L</b><b>a</b><b>b</b>',
......@@ -55,7 +53,7 @@ describe('FrequentItemsListItemComponent', () => {
});
it('should return project name as it is if `matcher` is not available', () => {
wrapper.setProps({ matcher: null });
createComponent({ matcher: null });
expect(trimText(wrapper.find('.js-frequent-items-item-title').text())).toBe(
mockProject.name,
......@@ -65,13 +63,13 @@ describe('FrequentItemsListItemComponent', () => {
describe('truncatedNamespace', () => {
it('should truncate project name from namespace string', () => {
wrapper.setProps({ namespace: 'platform / nokia-3310' });
createComponent({ namespace: 'platform / nokia-3310' });
expect(trimText(wrapper.find('.js-frequent-items-item-namespace').text())).toBe('platform');
});
it('should truncate namespace string from the middle if it includes more than two groups in path', () => {
wrapper.setProps({
createComponent({
namespace: 'platform / hardware / broadcom / Wifi Group / Mobile Chipset / nokia-3310',
});
......@@ -84,6 +82,8 @@ describe('FrequentItemsListItemComponent', () => {
describe('template', () => {
it('should render component element', () => {
createComponent();
expect(wrapper.classes()).toContain('frequent-items-list-item-container');
expect(wrapper.findAll('a').length).toBe(1);
expect(wrapper.findAll('.frequent-items-item-avatar-container').length).toBe(1);
......
import Vue from 'vue';
import searchComponent from '~/frequent_items/components/frequent_items_search_input.vue';
import eventHub from '~/frequent_items/event_hub';
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
const createComponent = (namespace = 'projects') => {
const Component = Vue.extend(searchComponent);
const localVue = createLocalVue();
return shallowMount(Component, { propsData: { namespace } });
};
const createComponent = (namespace = 'projects') =>
shallowMount(localVue.extend(searchComponent), {
propsData: { namespace },
localVue,
sync: false,
});
describe('FrequentItemsSearchInputComponent', () => {
let wrapper;
......@@ -40,7 +42,7 @@ describe('FrequentItemsSearchInputComponent', () => {
spyOn(eventHub, '$on');
const vmX = createComponent().vm;
Vue.nextTick(() => {
localVue.nextTick(() => {
expect(eventHub.$on).toHaveBeenCalledWith(
`${vmX.namespace}-dropdownOpen`,
jasmine.any(Function),
......@@ -58,7 +60,7 @@ describe('FrequentItemsSearchInputComponent', () => {
vmX.$mount();
vmX.$destroy();
Vue.nextTick(() => {
localVue.nextTick(() => {
expect(eventHub.$off).toHaveBeenCalledWith(
`${vmX.namespace}-dropdownOpen`,
jasmine.any(Function),
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import Form from '~/jobs/components/manual_variables_form.vue';
const localVue = createLocalVue();
describe('Manual Variables Form', () => {
let wrapper;
const requiredProps = {
action: {
path: '/play',
......@@ -14,8 +17,10 @@ describe('Manual Variables Form', () => {
};
const factory = (props = {}) => {
wrapper = shallowMount(Form, {
wrapper = shallowMount(localVue.extend(Form), {
propsData: props,
localVue,
sync: false,
});
};
......@@ -23,8 +28,15 @@ describe('Manual Variables Form', () => {
factory(requiredProps);
});
afterEach(() => {
wrapper.destroy();
afterEach(done => {
// The component has a `nextTick` callback after some events so we need
// to wait for those to finish before destroying.
setImmediate(() => {
wrapper.destroy();
wrapper = null;
done();
});
});
it('renders empty form with correct placeholders', () => {
......@@ -71,7 +83,7 @@ describe('Manual Variables Form', () => {
});
describe('when deleting a variable', () => {
it('removes the variable row', () => {
beforeEach(done => {
wrapper.vm.variables = [
{
key: 'new key',
......@@ -80,6 +92,10 @@ describe('Manual Variables Form', () => {
},
];
wrapper.vm.$nextTick(done);
});
it('removes the variable row', () => {
wrapper.find(GlButton).vm.$emit('click');
expect(wrapper.vm.variables.length).toBe(0);
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlColumnChart } from '@gitlab/ui/dist/charts';
import ColumnChart from '~/monitoring/components/charts/column.vue';
const localVue = createLocalVue();
describe('Column component', () => {
let columnChart;
beforeEach(() => {
columnChart = shallowMount(ColumnChart, {
columnChart = shallowMount(localVue.extend(ColumnChart), {
propsData: {
graphData: {
queries: [
......@@ -28,6 +30,8 @@ describe('Column component', () => {
},
containerWidth: 100,
},
sync: false,
localVue,
});
});
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import EmptyChart from '~/monitoring/components/charts/empty_chart.vue';
const localVue = createLocalVue();
describe('Empty Chart component', () => {
let emptyChart;
const graphTitle = 'Memory Usage';
beforeEach(() => {
emptyChart = shallowMount(EmptyChart, {
emptyChart = shallowMount(localVue.extend(EmptyChart), {
propsData: {
graphTitle,
},
sync: false,
localVue,
});
});
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import SingleStatChart from '~/monitoring/components/charts/single_stat.vue';
import { graphDataPrometheusQuery } from '../mock_data';
const localVue = createLocalVue();
describe('Single Stat Chart component', () => {
let singleStatChart;
beforeEach(() => {
singleStatChart = shallowMount(SingleStatChart, {
singleStatChart = shallowMount(localVue.extend(SingleStatChart), {
propsData: {
graphData: graphDataPrometheusQuery,
},
sync: false,
localVue,
});
});
......
......@@ -72,6 +72,17 @@ describe('Dashboard', () => {
let mock;
let store;
let component;
let wrapper;
const createComponentWrapper = (props = {}, options = {}) => {
wrapper = shallowMount(localVue.extend(DashboardComponent), {
localVue,
sync: false,
propsData: { ...propsData, ...props },
store,
...options,
});
};
beforeEach(() => {
setFixtures(`
......@@ -81,13 +92,16 @@ describe('Dashboard', () => {
store = createStore();
mock = new MockAdapter(axios);
DashboardComponent = Vue.extend(Dashboard);
DashboardComponent = localVue.extend(Dashboard);
});
afterEach(() => {
if (component) {
component.$destroy();
}
if (wrapper) {
wrapper.destroy();
}
mock.restore();
});
......@@ -123,15 +137,8 @@ describe('Dashboard', () => {
});
describe('cluster health', () => {
let wrapper;
beforeEach(done => {
wrapper = shallowMount(DashboardComponent, {
localVue,
sync: false,
propsData: { ...propsData, hasMetrics: true },
store,
});
createComponentWrapper({ hasMetrics: true });
// all_dashboards is not defined in health dashboards
wrapper.vm.$store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, undefined);
......@@ -383,7 +390,6 @@ describe('Dashboard', () => {
});
describe('drag and drop function', () => {
let wrapper;
let expectedPanelCount; // also called metrics, naming to be improved: https://gitlab.com/gitlab-org/gitlab/issues/31565
const findDraggables = () => wrapper.findAll(VueDraggable);
......@@ -400,13 +406,7 @@ describe('Dashboard', () => {
});
beforeEach(done => {
wrapper = shallowMount(DashboardComponent, {
localVue,
sync: false,
propsData: { ...propsData, hasMetrics: true },
store,
attachToDocument: true,
});
createComponentWrapper({ hasMetrics: true }, { attachToDocument: true });
setupComponentStore(wrapper.vm);
......@@ -417,6 +417,10 @@ describe('Dashboard', () => {
wrapper.destroy();
});
afterEach(() => {
wrapper.destroy();
});
it('wraps vuedraggable', () => {
expect(findDraggablePanels().exists()).toBe(true);
expect(findDraggablePanels().length).toEqual(expectedPanelCount);
......@@ -502,7 +506,6 @@ describe('Dashboard', () => {
// https://gitlab.com/gitlab-org/gitlab-ce/issues/66922
// eslint-disable-next-line jasmine/no-disabled-tests
xdescribe('link to chart', () => {
let wrapper;
const currentDashboard = 'TEST_DASHBOARD';
localVue.use(GlToast);
const link = () => wrapper.find('.js-chart-link');
......@@ -511,13 +514,7 @@ describe('Dashboard', () => {
beforeEach(done => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
wrapper = shallowMount(DashboardComponent, {
localVue,
sync: false,
attachToDocument: true,
propsData: { ...propsData, hasMetrics: true, currentDashboard },
store,
});
createComponentWrapper({ hasMetrics: true, currentDashboard }, { attachToDocument: true });
setTimeout(done);
});
......@@ -614,19 +611,12 @@ describe('Dashboard', () => {
});
describe('dashboard edit link', () => {
let wrapper;
const findEditLink = () => wrapper.find('.js-edit-link');
beforeEach(done => {
mock.onGet(mockApiEndpoint).reply(200, metricsGroupsAPIResponse);
wrapper = shallowMount(DashboardComponent, {
localVue,
sync: false,
attachToDocument: true,
propsData: { ...propsData, hasMetrics: true },
store,
});
createComponentWrapper({ hasMetrics: true }, { attachToDocument: true });
wrapper.vm.$store.commit(
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import GraphGroup from '~/monitoring/components/graph_group.vue';
const localVue = createLocalVue();
describe('Graph group component', () => {
let graphGroup;
const findPrometheusGroup = () => graphGroup.find('.prometheus-graph-group');
const findPrometheusPanel = () => graphGroup.find('.prometheus-panel');
const createComponent = propsData => {
graphGroup = shallowMount(localVue.extend(GraphGroup), {
propsData,
sync: false,
localVue,
});
};
afterEach(() => {
graphGroup.destroy();
});
describe('When groups can be collapsed', () => {
beforeEach(() => {
graphGroup = shallowMount(GraphGroup, {
propsData: {
name: 'panel',
collapseGroup: true,
},
createComponent({
name: 'panel',
collapseGroup: true,
});
});
......@@ -33,12 +42,10 @@ describe('Graph group component', () => {
describe('When groups can not be collapsed', () => {
beforeEach(() => {
graphGroup = shallowMount(GraphGroup, {
propsData: {
name: 'panel',
collapseGroup: true,
showPanels: false,
},
createComponent({
name: 'panel',
collapseGroup: true,
showPanels: false,
});
});
......@@ -49,12 +56,7 @@ describe('Graph group component', () => {
describe('When collapseGroup prop is updated', () => {
beforeEach(() => {
graphGroup = shallowMount(GraphGroup, {
propsData: {
name: 'panel',
collapseGroup: false,
},
});
createComponent({ name: 'panel', collapseGroup: false });
});
it('previously collapsed group should respond to the prop change', done => {
......
......@@ -2,15 +2,14 @@ import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils';
import ReplyButton from '~/notes/components/note_actions/reply_button.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('ReplyButton', () => {
let wrapper;
beforeEach(() => {
const localVue = createLocalVue();
localVue.use(Vuex);
wrapper = mount(ReplyButton, {
wrapper = mount(localVue.extend(ReplyButton), {
sync: false,
localVue,
});
......
......@@ -12,7 +12,7 @@ describe('noteActions', () => {
const shallowMountNoteActions = propsData => {
const localVue = createLocalVue();
return shallowMount(noteActions, {
return shallowMount(localVue.extend(noteActions), {
store,
propsData,
localVue,
......
......@@ -14,7 +14,7 @@ describe('issue_note_form component', () => {
const createComponentWrapper = () => {
const localVue = createLocalVue();
return shallowMount(NoteForm, {
return shallowMount(localVue.extend(NoteForm), {
store,
propsData: props,
// see https://gitlab.com/gitlab-org/gitlab-foss/issues/56317 for the following
......
......@@ -10,6 +10,8 @@ import mockDiffFile from '../../diffs/mock_data/diff_file';
const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';
const localVue = createLocalVue();
describe('noteable_discussion component', () => {
let store;
let wrapper;
......@@ -22,8 +24,7 @@ describe('noteable_discussion component', () => {
store.dispatch('setNoteableData', noteableDataMock);
store.dispatch('setNotesData', notesDataMock);
const localVue = createLocalVue();
wrapper = mount(noteableDiscussion, {
wrapper = mount(localVue.extend(noteableDiscussion), {
store,
propsData: { discussion: discussionMock },
localVue,
......
......@@ -18,7 +18,7 @@ describe('issue_note', () => {
store.dispatch('setNotesData', notesDataMock);
const localVue = createLocalVue();
wrapper = shallowMount(issueNote, {
wrapper = shallowMount(localVue.extend(issueNote), {
store,
propsData: {
note,
......
......@@ -20,7 +20,7 @@ describe('RelatedMergeRequests', () => {
mock = new MockAdapter(axios);
mock.onGet(`${API_ENDPOINT}?per_page=100`).reply(200, mockData, { 'x-total': 2 });
wrapper = mount(RelatedMergeRequests, {
wrapper = mount(localVue.extend(RelatedMergeRequests), {
localVue,
sync: false,
store: createStore(),
......
......@@ -4,18 +4,19 @@ import MrWidgetPipeline from '~/vue_merge_request_widget/components/mr_widget_pi
import ArtifactsApp from '~/vue_merge_request_widget/components/artifacts_list_app.vue';
import { mockStore } from '../mock_data';
const localVue = createLocalVue();
describe('MrWidgetPipelineContainer', () => {
let wrapper;
const factory = (props = {}) => {
const localVue = createLocalVue();
wrapper = mount(localVue.extend(MrWidgetPipelineContainer), {
propsData: {
mr: Object.assign({}, mockStore),
...props,
},
localVue,
sync: false,
});
};
......
import { shallowMount } from '@vue/test-utils';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import GraphqlPagination from '~/vue_shared/components/pagination/graphql_pagination.vue';
const localVue = createLocalVue();
describe('Graphql Pagination component', () => {
let wrapper;
function factory({ hasNextPage = true, hasPreviousPage = true }) {
wrapper = shallowMount(GraphqlPagination, {
wrapper = shallowMount(localVue.extend(GraphqlPagination), {
propsData: {
hasNextPage,
hasPreviousPage,
},
sync: false,
localVue,
});
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment