Commit cfe32c2f authored by Anna Vovchenko's avatar Anna Vovchenko Committed by Paul Slaughter

Added cluster Actions menu to group and admin view

As we want to unify clusters views for all levels,
we are adding tabs and Actions menu to group and admin views.
As we don't support Agent for groups and admin yet,
there will be only certificate related options and tabs.

Changelog: changed
parent 9f23f82b
...@@ -23,11 +23,21 @@ export default { ...@@ -23,11 +23,21 @@ export default {
GlModalDirective, GlModalDirective,
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
inject: ['newClusterPath', 'addClusterPath', 'canAddCluster'], inject: ['newClusterPath', 'addClusterPath', 'canAddCluster', 'displayClusterAgents'],
computed: { computed: {
tooltip() { tooltip() {
const { connectWithAgent, dropdownDisabledHint } = this.$options.i18n; const { connectWithAgent, connectExistingCluster, dropdownDisabledHint } = this.$options.i18n;
return this.canAddCluster ? connectWithAgent : dropdownDisabledHint;
if (!this.canAddCluster) {
return dropdownDisabledHint;
} else if (this.displayClusterAgents) {
return connectWithAgent;
}
return connectExistingCluster;
},
shouldTriggerModal() {
return this.canAddCluster && this.displayClusterAgents;
}, },
}, },
}; };
...@@ -37,24 +47,27 @@ export default { ...@@ -37,24 +47,27 @@ export default {
<div class="nav-controls gl-ml-auto"> <div class="nav-controls gl-ml-auto">
<gl-dropdown <gl-dropdown
ref="dropdown" ref="dropdown"
v-gl-modal-directive="canAddCluster && $options.INSTALL_AGENT_MODAL_ID" v-gl-modal-directive="shouldTriggerModal && $options.INSTALL_AGENT_MODAL_ID"
v-gl-tooltip="tooltip" v-gl-tooltip="tooltip"
category="primary" category="primary"
variant="confirm" variant="confirm"
:text="$options.i18n.actionsButton" :text="$options.i18n.actionsButton"
:disabled="!canAddCluster" :disabled="!canAddCluster"
split :split="displayClusterAgents"
right right
> >
<gl-dropdown-section-header>{{ $options.i18n.agent }}</gl-dropdown-section-header> <template v-if="displayClusterAgents">
<gl-dropdown-item <gl-dropdown-section-header>{{ $options.i18n.agent }}</gl-dropdown-section-header>
v-gl-modal-directive="$options.INSTALL_AGENT_MODAL_ID" <gl-dropdown-item
data-testid="connect-new-agent-link" v-gl-modal-directive="$options.INSTALL_AGENT_MODAL_ID"
> data-testid="connect-new-agent-link"
{{ $options.i18n.connectWithAgent }} >
</gl-dropdown-item> {{ $options.i18n.connectWithAgent }}
<gl-dropdown-divider /> </gl-dropdown-item>
<gl-dropdown-section-header>{{ $options.i18n.certificate }}</gl-dropdown-section-header> <gl-dropdown-divider />
<gl-dropdown-section-header>{{ $options.i18n.certificate }}</gl-dropdown-section-header>
</template>
<gl-dropdown-item :href="newClusterPath" data-testid="new-cluster-link" @click.stop> <gl-dropdown-item :href="newClusterPath" data-testid="new-cluster-link" @click.stop>
{{ $options.i18n.createNewCluster }} {{ $options.i18n.createNewCluster }}
</gl-dropdown-item> </gl-dropdown-item>
......
...@@ -3,6 +3,7 @@ import { GlTabs, GlTab } from '@gitlab/ui'; ...@@ -3,6 +3,7 @@ import { GlTabs, GlTab } from '@gitlab/ui';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import { import {
CLUSTERS_TABS, CLUSTERS_TABS,
CERTIFICATE_TAB,
MAX_CLUSTERS_LIST, MAX_CLUSTERS_LIST,
MAX_LIST_COUNT, MAX_LIST_COUNT,
AGENT, AGENT,
...@@ -29,6 +30,7 @@ export default { ...@@ -29,6 +30,7 @@ export default {
}, },
CLUSTERS_TABS, CLUSTERS_TABS,
mixins: [trackingMixin], mixins: [trackingMixin],
inject: ['displayClusterAgents'],
props: { props: {
defaultBranchName: { defaultBranchName: {
default: '.noBranch', default: '.noBranch',
...@@ -42,6 +44,11 @@ export default { ...@@ -42,6 +44,11 @@ export default {
maxAgents: MAX_CLUSTERS_LIST, maxAgents: MAX_CLUSTERS_LIST,
}; };
}, },
computed: {
clusterTabs() {
return this.displayClusterAgents ? CLUSTERS_TABS : [CERTIFICATE_TAB];
},
},
watch: { watch: {
selectedTabIndex(val) { selectedTabIndex(val) {
this.onTabChange(val); this.onTabChange(val);
...@@ -49,10 +56,10 @@ export default { ...@@ -49,10 +56,10 @@ export default {
}, },
methods: { methods: {
setSelectedTab(tabName) { setSelectedTab(tabName) {
this.selectedTabIndex = CLUSTERS_TABS.findIndex((tab) => tab.queryParamValue === tabName); this.selectedTabIndex = this.clusterTabs.findIndex((tab) => tab.queryParamValue === tabName);
}, },
onTabChange(tab) { onTabChange(tab) {
const tabName = CLUSTERS_TABS[tab].queryParamValue; const tabName = this.clusterTabs[tab].queryParamValue;
this.maxAgents = tabName === AGENT ? MAX_LIST_COUNT : MAX_CLUSTERS_LIST; this.maxAgents = tabName === AGENT ? MAX_LIST_COUNT : MAX_CLUSTERS_LIST;
this.track(EVENT_ACTIONS_CHANGE, { property: tabName }); this.track(EVENT_ACTIONS_CHANGE, { property: tabName });
...@@ -69,7 +76,7 @@ export default { ...@@ -69,7 +76,7 @@ export default {
lazy lazy
> >
<gl-tab <gl-tab
v-for="(tab, idx) in $options.CLUSTERS_TABS" v-for="(tab, idx) in clusterTabs"
:key="idx" :key="idx"
:title="tab.title" :title="tab.title"
:query-param-value="tab.queryParamValue" :query-param-value="tab.queryParamValue"
......
...@@ -232,6 +232,12 @@ export const CERTIFICATE_BASED_CARD_INFO = { ...@@ -232,6 +232,12 @@ export const CERTIFICATE_BASED_CARD_INFO = {
export const MAX_CLUSTERS_LIST = 6; export const MAX_CLUSTERS_LIST = 6;
export const CERTIFICATE_TAB = {
title: s__('ClusterAgents|Certificate'),
component: 'clusters',
queryParamValue: 'certificate_based',
};
export const CLUSTERS_TABS = [ export const CLUSTERS_TABS = [
{ {
title: s__('ClusterAgents|All'), title: s__('ClusterAgents|All'),
...@@ -243,11 +249,7 @@ export const CLUSTERS_TABS = [ ...@@ -243,11 +249,7 @@ export const CLUSTERS_TABS = [
component: 'agents', component: 'agents',
queryParamValue: 'agent', queryParamValue: 'agent',
}, },
{ CERTIFICATE_TAB,
title: s__('ClusterAgents|Certificate'),
component: 'clusters',
queryParamValue: 'certificate_based',
},
]; ];
export const CLUSTERS_ACTIONS = { export const CLUSTERS_ACTIONS = {
......
import { GlToast } from '@gitlab/ui'; import { GlToast } from '@gitlab/ui';
import Vue from 'vue'; import Vue from 'vue';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import loadClusters from './load_clusters'; import { parseBoolean } from '~/lib/utils/common_utils';
import loadMainView from './load_main_view'; import createDefaultClient from '~/lib/graphql';
import ClustersMainView from './components/clusters_main_view.vue';
import { createStore } from './store';
Vue.use(GlToast); Vue.use(GlToast);
Vue.use(VueApollo); Vue.use(VueApollo);
export default () => { export default () => {
loadClusters(Vue); const el = document.querySelector('.js-clusters-main-view');
loadMainView(Vue, VueApollo);
if (!el) {
return null;
}
const defaultClient = createDefaultClient();
const {
emptyStateImage,
defaultBranchName,
projectPath,
kasAddress,
newClusterPath,
addClusterPath,
emptyStateHelpText,
clustersEmptyStateImage,
canAddCluster,
canAdminCluster,
gitlabVersion,
displayClusterAgents,
} = el.dataset;
return new Vue({
el,
apolloProvider: new VueApollo({ defaultClient }),
provide: {
emptyStateImage,
projectPath,
kasAddress,
newClusterPath,
addClusterPath,
emptyStateHelpText,
clustersEmptyStateImage,
canAddCluster: parseBoolean(canAddCluster),
canAdminCluster: parseBoolean(canAdminCluster),
gitlabVersion,
displayClusterAgents: parseBoolean(displayClusterAgents),
},
store: createStore(el.dataset),
render(createElement) {
return createElement(ClustersMainView, {
props: {
defaultBranchName,
},
});
},
});
}; };
import Clusters from './components/clusters.vue';
import { createStore } from './store';
export default (Vue) => {
const el = document.querySelector('#js-clusters-list-app');
if (!el) {
return null;
}
const { emptyStateHelpText, newClusterPath, clustersEmptyStateImage } = el.dataset;
return new Vue({
el,
provide: {
emptyStateHelpText,
newClusterPath,
clustersEmptyStateImage,
},
store: createStore(el.dataset),
render(createElement) {
return createElement(Clusters);
},
});
};
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import { parseBoolean } from '~/lib/utils/common_utils';
import createDefaultClient from '~/lib/graphql';
import ClustersMainView from './components/clusters_main_view.vue';
import { createStore } from './store';
Vue.use(VueApollo);
export default () => {
const el = document.querySelector('.js-clusters-main-view');
if (!el) {
return null;
}
const defaultClient = createDefaultClient();
const {
emptyStateImage,
defaultBranchName,
projectPath,
kasAddress,
newClusterPath,
addClusterPath,
emptyStateHelpText,
clustersEmptyStateImage,
canAddCluster,
canAdminCluster,
gitlabVersion,
} = el.dataset;
return new Vue({
el,
apolloProvider: new VueApollo({ defaultClient }),
provide: {
emptyStateImage,
projectPath,
kasAddress,
newClusterPath,
addClusterPath,
emptyStateHelpText,
clustersEmptyStateImage,
canAddCluster: parseBoolean(canAddCluster),
canAdminCluster: parseBoolean(canAdminCluster),
gitlabVersion,
},
store: createStore(el.dataset),
render(createElement) {
return createElement(ClustersMainView, {
props: {
defaultBranchName,
},
});
},
});
};
...@@ -28,8 +28,10 @@ module ClustersHelper ...@@ -28,8 +28,10 @@ module ClustersHelper
clusters_empty_state_image: image_path('illustrations/empty-state/empty-state-clusters.svg'), clusters_empty_state_image: image_path('illustrations/empty-state/empty-state-clusters.svg'),
empty_state_help_text: clusterable.empty_state_help_text, empty_state_help_text: clusterable.empty_state_help_text,
new_cluster_path: clusterable.new_path(tab: 'create'), new_cluster_path: clusterable.new_path(tab: 'create'),
add_cluster_path: clusterable.new_path(tab: 'add'),
can_add_cluster: clusterable.can_add_cluster?.to_s, can_add_cluster: clusterable.can_add_cluster?.to_s,
can_admin_cluster: clusterable.can_admin_cluster?.to_s can_admin_cluster: clusterable.can_admin_cluster?.to_s,
display_cluster_agents: display_cluster_agents?(clusterable).to_s
} }
end end
...@@ -38,7 +40,6 @@ module ClustersHelper ...@@ -38,7 +40,6 @@ module ClustersHelper
default_branch_name: clusterable.default_branch, default_branch_name: clusterable.default_branch,
empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'), empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'),
project_path: clusterable.full_path, project_path: clusterable.full_path,
add_cluster_path: clusterable.new_path(tab: 'add'),
kas_address: Gitlab::Kas.external_url, kas_address: Gitlab::Kas.external_url,
gitlab_version: Gitlab.version_info gitlab_version: Gitlab.version_info
}.merge(js_clusters_list_data(clusterable)) }.merge(js_clusters_list_data(clusterable))
......
...@@ -7,4 +7,4 @@ ...@@ -7,4 +7,4 @@
%span.btn.gl-button.btn-confirm.js-add-cluster.disabled.gl-py-2 %span.btn.gl-button.btn-confirm.js-add-cluster.disabled.gl-py-2
= s_("ClusterIntegration|Connect cluster with certificate") = s_("ClusterIntegration|Connect cluster with certificate")
#js-clusters-list-app{ data: js_clusters_list_data(clusterable) } .js-clusters-main-view{ data: js_clusters_list_data(clusterable) }
...@@ -14,10 +14,13 @@ describe('ClustersActionsComponent', () => { ...@@ -14,10 +14,13 @@ describe('ClustersActionsComponent', () => {
newClusterPath, newClusterPath,
addClusterPath, addClusterPath,
canAddCluster: true, canAddCluster: true,
displayClusterAgents: true,
}; };
const findDropdown = () => wrapper.findComponent(GlDropdown); const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
const findDropdownItemIds = () =>
findDropdownItems().wrappers.map((x) => x.attributes('data-testid'));
const findNewClusterLink = () => wrapper.findByTestId('new-cluster-link'); const findNewClusterLink = () => wrapper.findByTestId('new-cluster-link');
const findConnectClusterLink = () => wrapper.findByTestId('connect-cluster-link'); const findConnectClusterLink = () => wrapper.findByTestId('connect-cluster-link');
const findConnectNewAgentLink = () => wrapper.findByTestId('connect-new-agent-link'); const findConnectNewAgentLink = () => wrapper.findByTestId('connect-new-agent-link');
...@@ -47,26 +50,11 @@ describe('ClustersActionsComponent', () => { ...@@ -47,26 +50,11 @@ describe('ClustersActionsComponent', () => {
expect(findDropdown().props('text')).toBe(CLUSTERS_ACTIONS.actionsButton); expect(findDropdown().props('text')).toBe(CLUSTERS_ACTIONS.actionsButton);
}); });
it('renders a dropdown with 3 actions items', () => {
expect(findDropdownItems()).toHaveLength(3);
});
it('renders correct href attributes for the links', () => { it('renders correct href attributes for the links', () => {
expect(findNewClusterLink().attributes('href')).toBe(newClusterPath); expect(findNewClusterLink().attributes('href')).toBe(newClusterPath);
expect(findConnectClusterLink().attributes('href')).toBe(addClusterPath); expect(findConnectClusterLink().attributes('href')).toBe(addClusterPath);
}); });
it('renders correct modal id for the agent link', () => {
const binding = getBinding(findConnectNewAgentLink().element, 'gl-modal-directive');
expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
});
it('shows tooltip', () => {
const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
expect(tooltip.value).toBe(CLUSTERS_ACTIONS.connectWithAgent);
});
describe('when user cannot add clusters', () => { describe('when user cannot add clusters', () => {
beforeEach(() => { beforeEach(() => {
createWrapper({ canAddCluster: false }); createWrapper({ canAddCluster: false });
...@@ -80,5 +68,67 @@ describe('ClustersActionsComponent', () => { ...@@ -80,5 +68,67 @@ describe('ClustersActionsComponent', () => {
const tooltip = getBinding(findDropdown().element, 'gl-tooltip'); const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
expect(tooltip.value).toBe(CLUSTERS_ACTIONS.dropdownDisabledHint); expect(tooltip.value).toBe(CLUSTERS_ACTIONS.dropdownDisabledHint);
}); });
it('does not bind split dropdown button', () => {
const binding = getBinding(findDropdown().element, 'gl-modal-directive');
expect(binding.value).toBe(false);
});
});
describe('when on project level', () => {
it('renders a dropdown with 3 actions items', () => {
expect(findDropdownItemIds()).toEqual([
'connect-new-agent-link',
'new-cluster-link',
'connect-cluster-link',
]);
});
it('renders correct modal id for the agent link', () => {
const binding = getBinding(findConnectNewAgentLink().element, 'gl-modal-directive');
expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
});
it('shows tooltip', () => {
const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
expect(tooltip.value).toBe(CLUSTERS_ACTIONS.connectWithAgent);
});
it('shows split button in dropdown', () => {
expect(findDropdown().props('split')).toBe(true);
});
it('binds split button with modal id', () => {
const binding = getBinding(findDropdown().element, 'gl-modal-directive');
expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
});
});
describe('when on group or admin level', () => {
beforeEach(() => {
createWrapper({ displayClusterAgents: false });
});
it('renders a dropdown with 2 actions items', () => {
expect(findDropdownItemIds()).toEqual(['new-cluster-link', 'connect-cluster-link']);
});
it('shows tooltip', () => {
const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
expect(tooltip.value).toBe(CLUSTERS_ACTIONS.connectExistingCluster);
});
it('does not show split button in dropdown', () => {
expect(findDropdown().props('split')).toBe(false);
});
it('does not bind dropdown button to modal', () => {
const binding = getBinding(findDropdown().element, 'gl-modal-directive');
expect(binding.value).toBe(false);
});
}); });
}); });
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
AGENT, AGENT,
CERTIFICATE_BASED, CERTIFICATE_BASED,
CLUSTERS_TABS, CLUSTERS_TABS,
CERTIFICATE_TAB,
MAX_CLUSTERS_LIST, MAX_CLUSTERS_LIST,
MAX_LIST_COUNT, MAX_LIST_COUNT,
EVENT_LABEL_TABS, EVENT_LABEL_TABS,
...@@ -23,12 +24,12 @@ describe('ClustersMainViewComponent', () => { ...@@ -23,12 +24,12 @@ describe('ClustersMainViewComponent', () => {
defaultBranchName, defaultBranchName,
}; };
beforeEach(() => { const createWrapper = ({ displayClusterAgents }) => {
wrapper = shallowMountExtended(ClustersMainView, { wrapper = shallowMountExtended(ClustersMainView, {
propsData, propsData,
provide: { displayClusterAgents },
}); });
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); };
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -40,66 +41,90 @@ describe('ClustersMainViewComponent', () => { ...@@ -40,66 +41,90 @@ describe('ClustersMainViewComponent', () => {
const findComponent = () => wrapper.findByTestId('clusters-tab-component'); const findComponent = () => wrapper.findByTestId('clusters-tab-component');
const findModal = () => wrapper.findComponent(InstallAgentModal); const findModal = () => wrapper.findComponent(InstallAgentModal);
it('renders `GlTabs` with `syncActiveTabWithQueryParams` and `queryParamName` props set', () => { describe('when on project level', () => {
expect(findTabs().exists()).toBe(true); beforeEach(() => {
expect(findTabs().props('syncActiveTabWithQueryParams')).toBe(true); createWrapper({ displayClusterAgents: true });
}); trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
});
it('renders correct number of tabs', () => { it('renders `GlTabs` with `syncActiveTabWithQueryParams` and `queryParamName` props set', () => {
expect(findAllTabs()).toHaveLength(CLUSTERS_TABS.length); expect(findTabs().exists()).toBe(true);
}); expect(findTabs().props('syncActiveTabWithQueryParams')).toBe(true);
});
it('renders correct number of tabs', () => {
expect(findAllTabs()).toHaveLength(CLUSTERS_TABS.length);
});
describe('tabs', () => { describe('tabs', () => {
it.each` it.each`
tabTitle | queryParamValue | lineNumber tabTitle | queryParamValue | lineNumber
${'All'} | ${'all'} | ${0} ${'All'} | ${'all'} | ${0}
${'Agent'} | ${AGENT} | ${1} ${'Agent'} | ${AGENT} | ${1}
${'Certificate'} | ${CERTIFICATE_BASED} | ${2} ${'Certificate'} | ${CERTIFICATE_BASED} | ${2}
`(
'renders correct tab title and query param value',
({ tabTitle, queryParamValue, lineNumber }) => {
expect(findGlTabAtIndex(lineNumber).attributes('title')).toBe(tabTitle);
expect(findGlTabAtIndex(lineNumber).props('queryParamValue')).toBe(queryParamValue);
},
);
});
describe.each`
tab | tabName
${'1'} | ${AGENT}
${'2'} | ${CERTIFICATE_BASED}
`( `(
'renders correct tab title and query param value', 'when the child component emits the tab change event for $tabName tab',
({ tabTitle, queryParamValue, lineNumber }) => { ({ tab, tabName }) => {
expect(findGlTabAtIndex(lineNumber).attributes('title')).toBe(tabTitle); beforeEach(() => {
expect(findGlTabAtIndex(lineNumber).props('queryParamValue')).toBe(queryParamValue); findComponent().vm.$emit('changeTab', tabName);
});
it(`changes the tab value to ${tab}`, () => {
expect(findTabs().attributes('value')).toBe(tab);
});
}, },
); );
});
describe.each` describe.each`
tab | tabName tab | tabName | maxAgents
${'1'} | ${AGENT} ${1} | ${AGENT} | ${MAX_LIST_COUNT}
${'2'} | ${CERTIFICATE_BASED} ${2} | ${CERTIFICATE_BASED} | ${MAX_CLUSTERS_LIST}
`('when the child component emits the tab change event for $tabName tab', ({ tab, tabName }) => { `('when the active tab is $tabName', ({ tab, tabName, maxAgents }) => {
beforeEach(() => { beforeEach(() => {
findComponent().vm.$emit('changeTab', tabName); findTabs().vm.$emit('input', tab);
}); });
it('passes child-component param to the component', () => {
expect(findComponent().props('defaultBranchName')).toBe(defaultBranchName);
});
it(`changes the tab value to ${tab}`, () => { it(`sets max-agents param to ${maxAgents} and passes it to the modal`, () => {
expect(findTabs().attributes('value')).toBe(tab); expect(findModal().props('maxAgents')).toBe(maxAgents);
});
it(`sends the correct tracking event with the property '${tabName}'`, () => {
expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_CHANGE, {
label: EVENT_LABEL_TABS,
property: tabName,
});
});
}); });
}); });
describe.each` describe('when on group or admin level', () => {
tab | tabName | maxAgents
${1} | ${AGENT} | ${MAX_LIST_COUNT}
${2} | ${CERTIFICATE_BASED} | ${MAX_CLUSTERS_LIST}
`('when the active tab is $tabName', ({ tab, tabName, maxAgents }) => {
beforeEach(() => { beforeEach(() => {
findTabs().vm.$emit('input', tab); createWrapper({ displayClusterAgents: false });
}); });
it('passes child-component param to the component', () => { it('renders correct number of tabs', () => {
expect(findComponent().props('defaultBranchName')).toBe(defaultBranchName); expect(findAllTabs()).toHaveLength(1);
}); });
it(`sets max-agents param to ${maxAgents} and passes it to the modal`, () => { it('renders correct tab title', () => {
expect(findModal().props('maxAgents')).toBe(maxAgents); expect(findGlTabAtIndex(0).attributes('title')).toBe(CERTIFICATE_TAB.title);
});
it(`sends the correct tracking event with the property '${tabName}'`, () => {
expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_CHANGE, {
label: EVENT_LABEL_TABS,
property: tabName,
});
}); });
}); });
}); });
...@@ -92,6 +92,10 @@ RSpec.describe ClustersHelper do ...@@ -92,6 +92,10 @@ RSpec.describe ClustersHelper do
expect(subject[:new_cluster_path]).to eq("#{project_path(project)}/-/clusters/new?tab=create") expect(subject[:new_cluster_path]).to eq("#{project_path(project)}/-/clusters/new?tab=create")
end end
it 'displays add cluster using certificate path' do
expect(subject[:add_cluster_path]).to eq("#{project_path(project)}/-/clusters/new?tab=add")
end
context 'user has no permissions to create a cluster' do context 'user has no permissions to create a cluster' do
it 'displays that user can\'t add cluster' do it 'displays that user can\'t add cluster' do
expect(subject[:can_add_cluster]).to eq("false") expect(subject[:can_add_cluster]).to eq("false")
...@@ -114,6 +118,10 @@ RSpec.describe ClustersHelper do ...@@ -114,6 +118,10 @@ RSpec.describe ClustersHelper do
it 'doesn\'t display empty state help text' do it 'doesn\'t display empty state help text' do
expect(subject[:empty_state_help_text]).to be_nil expect(subject[:empty_state_help_text]).to be_nil
end end
it 'displays display_cluster_agents as true' do
expect(subject[:display_cluster_agents]).to eq("true")
end
end end
context 'group cluster' do context 'group cluster' do
...@@ -123,6 +131,10 @@ RSpec.describe ClustersHelper do ...@@ -123,6 +131,10 @@ RSpec.describe ClustersHelper do
it 'displays empty state help text' do it 'displays empty state help text' do
expect(subject[:empty_state_help_text]).to eq(s_('ClusterIntegration|Adding an integration to your group will share the cluster across all your projects.')) expect(subject[:empty_state_help_text]).to eq(s_('ClusterIntegration|Adding an integration to your group will share the cluster across all your projects.'))
end end
it 'displays display_cluster_agents as false' do
expect(subject[:display_cluster_agents]).to eq("false")
end
end end
end end
...@@ -145,10 +157,6 @@ RSpec.describe ClustersHelper do ...@@ -145,10 +157,6 @@ RSpec.describe ClustersHelper do
expect(subject[:project_path]).to eq(project.full_path) expect(subject[:project_path]).to eq(project.full_path)
end end
it 'displays add cluster using certificate path' do
expect(subject[:add_cluster_path]).to eq("#{project_path(project)}/-/clusters/new?tab=add")
end
it 'displays kas address' do it 'displays kas address' do
expect(subject[:kas_address]).to eq(Gitlab::Kas.external_url) expect(subject[:kas_address]).to eq(Gitlab::Kas.external_url)
end end
......
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